什么是libpq
libpq是应用程序使用PostgreSQL的C接口。libpq是一个库函数的集合,它们允许客户端程序传递查询给PostgreSQL后端服务器并且接收这些查询的结果。libpq也是很多其他PostgreSQL应用接口的底层引擎,包括为 C++、Perl、Python、Tcl 和 ECPG编写的接口。
类似于Redis或者Mongodb的客户端,libpq自身可以实现客户端的故障转移,也就是说,PostgreSQL可用数据库集群故障转移之后,客户端也能探测到数据库的身份的变化,无须修改连接字符串的情况下实现“自动故障转移”。
libpq客户端故障转移和负载均衡
libpq的自动故障转移,是根据连接信息中的par_session_attrs来实现的,可以分为以下几种情况:
1,target_session_attrs="read-write"或者“primary”
数据库连接总是会去找主节点,如果主节点宕机切故障转移到其他节点,连接会连接到新的主节点
2,target_session_attrs=“read-only”
数据库连接总是会去找standby节点,如果standby节点宕机,则连接失败
3,target_session_attrs=“prefer-standby”
数据库连接总是会去找standby节点,如果standby节点宕机,可以连接到可用的主节点
4,target_session_attrs=“any”
理论上来说会去连接集群中的任意一个节点,实际测试发现他只会去连接standby节点,如果standby节点宕机,才回去连主节点,如果standby节点正常之后,又只会连standby节点
5,load_balance_hosts='random',
在PostgreSQL 16中也有一个负载均衡的增强load_balance_hosts特性,可以再连接串里设置load_balance_hosts为random
当设置了load_balance_hosts为random之后,在target_session_attrs=“any”的情况下,会随机连接集群中的所有节点。
测试代码如下
import psycopg2
import time
def get_conn_by_attrs(par_session_attrs):
conn = psycopg2.connect(host="192.168.152.100,192.168.152.101,192.168.152.102",#集群节点IP
port="****",
database="postgres",
user="postgres",
password="******",
#load_balance_hosts='random',
target_session_attrs=par_session_attrs)
with conn.cursor() as cur:
cur.execute("select inet_server_addr();")
var = cur.fetchall()
print(var)
time.sleep(1)
conn.close()
if __name__ == "__main__":
while 1 > 0:
try:
#测试不同target_session_attrs获取连接的差异
#get_conn_by_attrs(par_session_attrs="read-write")
#get_conn_by_attrs(par_session_attrs="primary")
#get_conn_by_attrs(par_session_attrs="read-only")
#get_conn_by_attrs(par_session_attrs="prefer-standby")
get_conn_by_attrs(par_session_attrs="any")
except Exception as err:
print(err)
time.sleep(3)
客户端故障转移解决了什么问题
1,客户端也能探测到数据库的身份变化之后,实现“自动故障转移”的方式连接到目的节点,应用程序端不需要做任何修改
2,主动实现负载均衡
因此,是否还有必要使用第三方proxy之类的中间件?
标签:PostgreSQL,standby,libpq,session,attrs,节点,conn,客户端 From: https://www.cnblogs.com/wy123/p/18548034