背景
我一直以来都比较推荐plproxy这个PostgreSQL代理软件, 因为它小巧灵活好用, 效率高.
最近朋友邀请我给他们做个分布式的方案, 所以又把plproxy翻出来了.
本文讲一讲在单节点中如何快速的部署plproxy环境.



首先在http://git.postgresql.org/gitweb/?p=plproxy.git;a=summary下载plproxy.

创建proxy库, proxy角色, 在proxy库创建plproxyextension.

调整proxy库权限

创建digoal schema, 目的是和数据节点的schema匹配, 这样的话可以省去在代理函数中写target强行指定schema.

创建节点数据库

调整权限, 赋予给后面将要给user mapping中配置的option user权限.

使用超级用户在proxy数据库中创建server.

创建server时可以使用libpq中的选项. 例如本例使用了application_name.
将server权限赋予给proxy用户.

配置proxy用户的连接cluster_srv1的选项.

用户proxy连接到cluster_srv1时使用digoal用户连接, 这里不需要配置password, 因为我们将使用trust认证.
从proxy节点使用digoal用户连接数据库db0, db1, db2,db3使用trust认证.

使用超级用户创建plproxy函数, 然后把函数权限赋予给proxy权限.


在proxy节点中就可以访问数据节点了。
例如查询这个动态SQL.

前面那个会话不要断开, 在另一个会话中观察proxy发起的连接到数据节点的连接.

再次在proxy的同一会话中查询时, 这些会话会复用, 不会断开. 前面已经讲了plproxy是使用长连接的.
如果修改了server, 那么这些连接会断开, 重新连接. 所以不需要担心修改server带来的连接cache问题.

再次在proxy的同一会话中查询后, 我们发现4个连接都变了, 说明alter server后, 如果再次发起plproxy函数的查询请求, 那么proxy会重置连接.

在另一会话的查询结果 :

在数据节点创建测试表.

在数据节点创建插入数据的实体函数, 每个节点返回不一样的数字.

在proxy节点创建代理函数, 并且将执行权限赋予给proxy用户.

如果run on 的数字改成0-3以外的数字, 运行时将报错, 符合预期.

run on any表示随机的选择一个数据节点运行.

run on function()则使用函数结果的hash值计算得到运行节点.


run on all表示所有数据节点运行. 代理函数必须使用returns setof返回.

1. 设计时需要注意
plproxy函数所在的schema尽量和数据节点上实际函数的schema一致.
否则需要在plproxy函数中使用target指定schema.functionname;
2. 数据节点的个数请保持2^n,
这么做有利于后期的节点扩展, 例如2个节点扩展到4个节点时, 数据不需要发生跨节点的重分布.
例如

比较适合位运算的分布算法.
当然我们也可以使用一致性哈希的设计思路,参考
《一致性哈希在分布式数据库中的应用探索》
https://yq.aliyun.com/articles/57954
3. 如果业务为短连接的形式, 那么需要1层连接池, 在应用程序和plproxy数据库之间. 而不是plproxy和数据节点之间.
在应用程序和plproxy之间加连接池后, 其实对于plproxy来说就是长连接了, 所以在plproxy和数据节点之间也就不需要连接池了.
4. 长连接不需要连接池, 因为plproxy和数据节点之间的连接是长连接.
5. plproxy语法非常简洁,而且函数调用彻底避免了事务的问题
connect, cluster, run, select, split, target.
6. 关于连接密码
出于安全考虑, 建议在任何配置中不要出现明文密码, 所以最好是plproxy服务器到数据节点是trust验证, 保护好plproxy即可.
假设plproxy在172.16.3.2上. 数据节点有4个, 库名和用户名都为digoal. 那么在4个节点上配置pg_hba.conf如下.

7. run 详解:

8. 一个plproxy中只能出现一条connect语句, 符合预期, 否则报错.

9. 不要把plproxy语言的权限赋予给普通用户, 因为开放了trust认证, 如果再开放plproxy语言的权限是非常危险的.
正确的做法是使用超级用户创建plproxy函数, 然后把函数的执行权限赋予给普通用户.
千万不要这样省事 :

10. 如果有全局唯一的序列需求, 可以将序列的步调调整一下, 每个数据节点使用不同的初始值.
例如

考虑到扩容, 可以将步调调比较大, 例如1024. 那么可以容纳1024个节点.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69917105/viewspace-3119468/ ,如需转载,请注明出处,否则将追究法律责任。