暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

pgcat:一个 PostgreSQL 池化器

原创 小小亮 2022-11-22
2214

这篇文章是关于我最近遇到的一个新的 PostgreSQL 连接池:pgcat,它提供了一些我没有在其他池中看到的有用特性。请注意pgcat连接池处于测试阶段,他们实际上正在寻找测试人员!如果您有兴趣,请阅读pgcat beta 测试公告(https://github.com/levkk/pgcat/issues/35

pgcat是一个类似于pgbouncer的连接池,并且共享它工作的部分逻辑方式,但它有一个根本的区别:它允许为单个客户端连接使用多个数据库。pgbouncer只会将客户端连接到单个数据库。应该提到的是,有一种方法可以通过使用pgbouncer so_reuseport 设置来执行负载平衡,以允许多个 pgbouncer 在同一端口上运行。

pgcat似乎非常关注它的分片功能,它允许连接池将查询传播到分片。如果您想使用分片功能,它会执行非常漂亮的事情,例如解释 SQL 以将查询路由到正确的分片。

我的兴趣是因为分布式YugabyteDB数据库。这个 pooler 允许在服务器列表中定义 YugabyteDB 集群的 PostgreSQL 端点(具有“主”/“副本”角色,我不喜欢,因为我们在YugabyteDB中没有这些),然后让传入连接在服务器上保持平衡。pgcat检测到一个数据库连接已死时,它将与池中的下一个可用连接重新连接!

当然像这样的外部连接池只有在你不能使用应用程序连接池的情况下才应该使用,而对于YugabyteDB的使用,如果你可以使用YugabyteDB驱动程序,比如我们的java jdbc驱动程序,强烈建议这样做!

安装

pgcat的安装并不难,并且在 pgcat 页面上有很好的描述。目前,由于pgcat处于测试阶段,您必须自己构建可执行文件,或使用示例 Docker 部署。

自己构建它非常简单,因为您需要做的就是安装Rust、 git clone pgcat,然后使用以下命令构建它:cargo build --release

配置使用YugabyteDB

配置其实很简单。请参阅此配置以用于我的小型测试集群:

[general]
prometheus_exporter_port = 9930
admin_username = "admin_user"
admin_password = "admin_pass"
[pools.yugabyte]
pool_mode = "session"
default_role = "any"
query_parser_enabled = false
primary_reads_enabled = true
sharding_function = "pg_bigint_hash"
[pools.yugabyte.users.0]
username = "yugabyte"
password = "yugabyte"
pool_size = 50
statement_timeout = 0
[pools.yugabyte.shards.0]
servers = [
    [ "192.168.66.80", 5433, "primary" ],
    [ "192.168.66.81", 5433, "replica" ],
    [ "192.168.66.82", 5433, "replica" ]
]
database = "yugabyte"

这些是当前版本所需的最少设置。

我创建了一个名为“yugabyte”(pools.yugabyte) 的池,池模式为“会话”,以便会话保持与后端的连接。
我在 pools.yugabyte.shards.0(yugabyte 分片池 0)中创建了一个服务器池,其中包含YugabyteDB集群中的所有三个 YSQL 节点,并赋予其中一个角色“主要”,另外两个角色“复制品”。对于YugabyteDB YSQL 这没有意义。目前,pgcat允许所有角色都是“副本”,但不能有超过一个“主要”角色。

运行pgcat

现在配置已经完成,使用cargo运行pgcat

RUST_LOG=info cargo run --release
    Finished release [optimized] target(s) in 0.11s
     Running `target/release/pgcat`
[2022-11-14T13:24:03.175058Z INFO  pgcat] Welcome to PgCat! Meow. (Version 0.6.0-alpha1)
[2022-11-14T13:24:03.184314Z INFO  pgcat] Running on 0.0.0.0:5432
[2022-11-14T13:24:03.184323Z INFO  pgcat::config] Ban time: 60s
[2022-11-14T13:24:03.184325Z INFO  pgcat::config] Healthcheck timeout: 1000ms
[2022-11-14T13:24:03.184328Z INFO  pgcat::config] Connection timeout: 1000ms
[2022-11-14T13:24:03.184329Z INFO  pgcat::config] Shutdown timeout: 60000ms
[2022-11-14T13:24:03.184331Z INFO  pgcat::config] Healthcheck delay: 30000ms
[2022-11-14T13:24:03.184333Z INFO  pgcat::config] TLS support is disabled
[2022-11-14T13:24:03.184337Z INFO  pgcat::config] [pool: yugabyte] Maximum user connections: 50
[2022-11-14T13:24:03.184342Z INFO  pgcat::config] [pool: yugabyte] Pool mode: Session
[2022-11-14T13:24:03.184367Z INFO  pgcat::config] [pool: yugabyte] Connection timeout: 1000ms
[2022-11-14T13:24:03.184370Z INFO  pgcat::config] [pool: yugabyte] Sharding function: pg_bigint_hash
[2022-11-14T13:24:03.184372Z INFO  pgcat::config] [pool: yugabyte] Primary reads: true
[2022-11-14T13:24:03.184374Z INFO  pgcat::config] [pool: yugabyte] Query router: false
[2022-11-14T13:24:03.184376Z INFO  pgcat::config] [pool: yugabyte] Number of shards: 1
[2022-11-14T13:24:03.184378Z INFO  pgcat::config] [pool: yugabyte] Number of users: 1
[2022-11-14T13:24:03.184380Z INFO  pgcat::config] [pool: yugabyte][user: yugabyte] Pool size: 50
[2022-11-14T13:24:03.184456Z INFO  pgcat::config] [pool: yugabyte][user: yugabyte] Statement timeout: 0
[2022-11-14T13:24:03.185020Z INFO  pgcat::pool] [pool: yugabyte][user: yugabyte] creating new pool
[2022-11-14T13:24:03.185099Z INFO  pgcat::pool] Creating a new server connection Address { id: 0, host: "192.168.66.80", port: 5433, shard: 0, database: "yugabyte", role: Primary, replica_number: 0, address_index: 0, username: "yugabyte", pool_name: "yugabyte" }
[2022-11-14T13:24:03.196798Z INFO  pgcat::pool] Creating a new server connection Address { id: 1, host: "192.168.66.81", port: 5433, shard: 0, database: "yugabyte", role: Replica, replica_number: 0, address_index: 1, username: "yugabyte", pool_name: "yugabyte" }
[2022-11-14T13:24:03.209956Z INFO  pgcat::pool] Creating a new server connection Address { id: 2, host: "192.168.66.82", port: 5433, shard: 0, database: "yugabyte", role: Replica, replica_number: 1, address_index: 2, username: "yugabyte", pool_name: "yugabyte" }
[2022-11-14T13:24:03.222501Z INFO  pgcat] Config autoreloader: false
[2022-11-14T13:24:03.222540Z INFO  pgcat::stats] Events reporter started
[2022-11-14T13:24:03.222556Z INFO  pgcat] Waiting for clients

上面的日志记录是因为 RUST_LOG=info 在同一行的设置cargo run --release

请注意,默认设置绑定到所有网络接口上的端口 5432,这可能与本地运行的PostgreSQL数据库冲突。可以使用port = 6432(使用默认pgbouncer端口的示例)设置端口。还要注意YugabyteDB默认绑定到端口 5433。

通过pgcat 使用YugabyteDB进行负载平衡连接

现在pgcat已设置并运行,我们可以使用pgcat连接到YugabyteDB集群,并在连接后获得持久连接:

psql -h localhost -p 5432 -U yugabyte
psql (14.5 (Homebrew), server 11.2-YB-2.15.3.2-b0)
Type "help" for help.

yugabyte=# select inet_server_addr();
 inet_server_addr
------------------
 192.168.66.81

结论

pgcat项目看起来是一个非常有前途的项目,因为它允许使用具有 pgbouncer 简单性的连接池,YugabyteDB YSQL 端点集群上具有连接分布。

另一个优点是它使用Rust,它提供 C/C++ 速度和内存安全。

但是,必须注意该项目处于早期阶段,因此在考虑将其用于生产环境之前应该对其进行很好的测试。

附言。
我已经发现了一个问题:如果没有指定 dbname,pgcat 返回一个错误,而与 YSQL (=PostgreSQL) 的相同连接成功,因为如果没有指定 dbname,它应该使用用户名。


原文标题:pgcat: a PostgreSQL pooler

原文作者:Frits Hoogland
原文链接:https://dev.to/yugabyte/pgcat-a-postgresql-pooler-3a24

最后修改时间:2022-11-22 11:06:34
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论