Pgbouncer最佳实践:系列三


Pgbouncer最佳实践:系列三
文章图片
作者:王志斌 , 曾获得中国PostgreSQL数据库管理工程师(PGCE) , 是PostgreSQL官方认证讲师 , 盘古云课堂特邀金牌讲师 。
PgBouncer具有三种可用的池模式:事务池 , 会话池和语句池:
事务连接池
数据库客户端很少在不间断的情况下执行连续的事务 。 而是通常在事务之间执行非数据库工作 。 这意味着服务器连接在等待新工作到达时会花费大量时间空闲 。
事务池模式试图减少服务器连接的空闲时间 , 如下所示:
Pgbouncer最佳实践:系列三】池程序在开始事务时将服务器连接分配给客户端 。
客户端的事务完成后 , 池程序将释放连接分配 。
注意事项:
如果客户端运行多个事务 , 则每个事务可以在不同的服务器连接上执行 。
单个服务器连接可以在其生命周期内运行由不同客户端发出的事务 。

Pgbouncer最佳实践:系列三
文章图片
图6事务连接池
与服务器所允许的连接相比 , 允许活动客户端的数量要多得多 。 尽管取决于给定的工作负载 , 但经常会看到10倍或更多的活动客户端连接与服务器连接比率 。
这确实带来了一个重要的警告:客户端不再期望对数据库会话状态所做的更改在同一客户端进行的连续事务中继续存在 , 因为这些事务可能在不同的服务器连接上运行 。 此外 , 如果客户端进行会话状态更改 , 它们可能并且很可能会影响其他客户端 。
以下是一些使用上面的事务池示例:
如果客户端1在T1中的第一个服务器连接上将会话设置为只读 , 而客户端2的T3是写事务 , 则T3将失败 , 因为它在现在的只读服务器连接上运行 。
如果客户端1运行PREPAREa1AS...在T1上运行EXECUTEa1... , 在T2上 , 则T2将失败 , 因为预编译语句对于运行T1的服务器连接是本地的 。
如果客户端2在T3中创建了一个临时表并尝试在T4中使用它 , 则T4将失败 , 因为该临时表对于运行T3的服务器连接是本地的 。
有关使用事务池时不支持的会话状态功能和操作的完整列表 , 请参见PgBouncer的列表
会话连接池
分配给客户端的服务器连接在客户端连接的整个生命周期内持续 。 这看起来好像根本不使用连接池一样 , 但是有一个重要的区别:当分配的客户端断开连接时 , 服务器连接不会被破坏 。 当客户端断开连接时 , 池管理器将:
清除客户端所做的任何会话状态更改 。
将服务器连接返回到池中 , 以供其他客户端使用 。

Pgbouncer最佳实践:系列三
文章图片
图7会话连接池
语句连接池
在此 , 服务器连接分配仅在单个语句的持续时间内持续 。 这具有与事务池模式相同的会话状态限制 , 同时还破坏了事务语义 。

Pgbouncer最佳实践:系列三
文章图片
图8语句连接池
这使得所有客户端连接的行为就像在“自动提交”模式下一样 。 如果客户端尝试开始多语句事务 , 则合并程序将返回错误 。 尽管这是有限制的 , 但与事务池相比 , 它允许的活动客户端连接数更高 。 良好的用例包括为大量简单的键查找或单语句写入 。
表3连接池模式对比

Pgbouncer最佳实践:系列三
文章图片
从上述对比情况来看 , 在连接池的选择上 , 需要依据业务环境特点来进行选择 , 默认情况下推荐使用事务连接池 , 它兼顾了执行事务的特性 , 尤其多语句的支持 , 并且不会像会话连接池那样 , 尝尝处于等待状态 。 当然事务模式并不支持预编译语句 。 而根据具体业务场景的特殊需要 , 有些时候需要客户端与服务器端保持连接 , 或者支持预编译语句 , 这样只能选择会话池模式 。 还有一些特例情况 , 某些业务场景只是单语句执行 , 那么语句池模式可能更适合 。 因此对比这三种模式 , 可以发现从对客户端操作的支持程度来讲 , 会话池支持度最高 , 其次是事务池 , 最后是语句池模式 。 但是从支持的连接数来讲 , 可能刚好是相反的顺序 。
表4SQL特性对照表

Pgbouncer最佳实践:系列三
文章图片
上表为会话连接池和事务连接池的SQL特性对比情况 , 可以通过对比具体业务场景与SQL特性的符合度 , 来对连接池模式进行选型 。
下面列举了一些示例场景: