让greenplum的oltp性能飞起来 - 直接读写数据节点

2 minute read

背景

直连greenplum segment节点的方法 :

使用这种方式,不与其他节点通讯,只操作当前节点。也不会产生数据分布的概念。

$  PGOPTIONS='-c gp_session_role=utility' psql -p 40005  
psql (8.2.15)  
Type "help" for help.  
  
postgres=# \dt  
             List of relations  
 Schema | Name | Type  |  Owner   | Storage   
--------+------+-------+----------+---------  
 public | t    | table | digoal | heap  
 public | test | table | digoal | heap  
(2 rows)  
  
postgres=# select * from pg_locks;  
   locktype    | database | relation | page | tuple | transactionid | classid | objid | objsubid | transaction |  pid   |      mode       | granted | mppsessionid | mppiswriter | gp_segment_id   
---------------+----------+----------+------+-------+---------------+---------+-------+----------+-------------+--------+-----------------+---------+--------------+-------------+---------------  
 transactionid |          |          |      |       |        136604 |         |       |          |      136604 | 130724 | ExclusiveLock   | t       |            6 | t           |            -1  
 relation      |    10899 |    10333 |      |       |               |         |       |          |      136604 | 130724 | AccessShareLock | t       |            6 | t           |            -1  
(2 rows)  

注意使用PGOPTIONS='-c gp_session_role=utility'后,只操作本地节点

所以连到MASTER节点后,你会发现没有记录。 而segment节点有记录。

$psql -p # master  
  
psql (8.2.15)  
Type "help" for help.  
postgres=# select count(*) from test;  
 count   
-------  
     0  
(1 row)  
postgres=# \q  
  
  
$psql -p 40001 # segment  
  
psql (8.2.15)  
Type "help" for help.  
postgres=# select count(*) from test;  
  count    
---------  
 4166801  
(1 row)  

怎么让greenplum飞起来呢?

很简单,你首先要把greenplum的hash分布算法和你的分布式插件结合起来,让分布式插件支持同样的hash算法,这样在用户请求过来时,可以指向正确的数据节点。对于有跨节点的访问,则依旧扔给MASTER节点执行。

具体的实现就不说了,有兴趣的同学可以试一试哦。

下面就看看性能如何把?

$vi test.sql  
\setrandom id 1 500000000  
insert into t(id) values (:id);  
  
$./pgsql9.5/bin/pgbench -M prepared -n -r -f ./test.sql -P 1 -c 16 -j 16 -T 10000  
progress: 1.0 s, 11823.3 tps, lat 1.343 ms stddev 2.341  
progress: 2.0 s, 13868.0 tps, lat 1.152 ms stddev 0.557  
progress: 3.0 s, 13714.0 tps, lat 1.165 ms stddev 0.551  
progress: 4.0 s, 13757.0 tps, lat 1.162 ms stddev 0.624  
progress: 5.0 s, 13559.0 tps, lat 1.178 ms stddev 0.558  
progress: 6.0 s, 13960.0 tps, lat 1.145 ms stddev 0.568  
progress: 7.0 s, 13835.0 tps, lat 1.154 ms stddev 0.789  
progress: 8.0 s, 14033.0 tps, lat 1.138 ms stddev 0.577  
  
$vi test.sql  
\setrandom id 1 500000000  
update test set info=info where id=:id;  
$./pgsql9.5/bin/pgbench -M prepared -n -r -f ./test.sql -P 1 -c 16 -j 16 -T 10000  
progress: 1.0 s, 12416.2 tps, lat 1.276 ms stddev 0.785  
progress: 2.0 s, 12577.4 tps, lat 1.271 ms stddev 0.691  
progress: 3.0 s, 12562.9 tps, lat 1.272 ms stddev 0.682  
progress: 4.0 s, 12494.7 tps, lat 1.278 ms stddev 0.895  
progress: 5.0 s, 12395.0 tps, lat 1.289 ms stddev 0.913  
progress: 6.0 s, 12452.0 tps, lat 1.283 ms stddev 0.871  
progress: 7.0 s, 12499.0 tps, lat 1.279 ms stddev 0.820  

相比直连master性能提升了很多倍,目前这个性能主要取决于磁盘的IOPS能力,因为GP目前还不支持异步提交,未来的版本,开启异步提交后,性能估计能和PG持平,至少几十万行每秒的写入。

这里面还有很多细节需要考虑,但是一种思路。

关于锁

在Greenplum中,从master节点更新或删除数据时,属于表级锁,因此表级是无法并行(删或更新)的。

在segment节点操作时,对于AO表,依旧如此。但是对于HEAP表,会使用行锁,因此可以并发的更新、删除。

Flag Counter

digoal’s 大量PostgreSQL文章入口