让greenplum的oltp性能飞起来 - 直接读写数据节点
背景
直连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表,会使用行锁,因此可以并发的更新、删除。