Greenplum hash分布算法
背景
Greenplum,如果从master节点写入数据的话,写入性能实际上是比较差的,但是我们可以直接连数据节点来写入:
这种用法需要客户端从master获取gp_segment_configuration,同时需要获取表的分布键,同时需要使用cdbhash算法算出记录应该写入哪个segment节点,这种方法不保证全局一致性,建议选择场景使用。
hash算法
src/backend/cdb/cdbhash.c
算出的值对应gp_segment_configuration.content.
获取GPDB集群配置
postgres=# select * from gp_segment_configuration ;
dbid | content | role | preferred_role | mode | status | port | hostname | address | replication_port | san_mounts
------+---------+------+----------------+------+--------+-------+-------------------+-----------+------------------+------------
1 | -1 | p | p | s | u | 15432 | .sqa.tbc | localhost | |
2 | 0 | p | p | s | u | 25432 | .sqa.tbc | localhost | |
3 | 1 | p | p | s | u | 25433 | .sqa.tbc | localhost | |
4 | 2 | p | p | s | u | 25434 | .sqa.tbc | localhost | |
5 | 3 | p | p | s | u | 25435 | .sqa.tbc | localhost | |
6 | 4 | p | p | s | u | 25436 | .sqa.tbc | localhost | |
7 | 5 | p | p | s | u | 25437 | .sqa.tbc | localhost | |
8 | 6 | p | p | s | u | 25438 | .sqa.tbc | localhost | |
9 | 7 | p | p | s | u | 25439 | .sqa.tbc | localhost | |
content就是hash value,注意-1表示master,0开始表示segment,如果有mirror的话,content会重复,每个content id都有两条,分别表示primary 和 mirror。
通过role判断当前属于什么角色,选择primary写入。
注意有MIRROR时,如果PRIMARY挂了会自动切换到MIRROR,所以建议写入时,如果发现失败,再从master获取新的gp_segment_configuration,找到对应content id的当前role=p的连接。
hostname, port表示节点的真实连接断开和主机名。
获取分布键
********* QUERY **********
SELECT attrnums
FROM pg_catalog.gp_distribution_policy t
WHERE localoid = '721689'
**************************
********* QUERY **********
SELECT attname FROM pg_attribute
WHERE attrelid = '721689'
AND attnum = '1'
**************************
如果gp_distribution_policy获取到的attrnums是空,表示随机分布。