华为云云数据库rds使用客户端驱动程序实现故障转移和读写分离_云淘科技
从PostgreSQL 10(libpq.so.5.10)开始,libpq驱动层开始支持故障转移和读写分离,JDBC驱动层则支持读写分离、故障转移和负载均衡。
PostgreSQL客户端连接程序向下兼容,对于RDS for PostgreSQL 9.5及9.6版本,使用新版本的libpq驱动程序也可以实现故障转移。
本章节中故障转移指的是读业务的故障转移。
libpq是PostgreSQL的C应用程序接口,包含一组库函数,允许客户端程序将查询请求发送给PostgreSQL后端服务器并接收这些查询的结果。
JDBC是Java语言中用来规范客户端程序如何访问数据库的应用程序接口,在PostgreSQL中JDBC支持故障转移和负载均衡。
驱动 |
读写分离 |
负载均衡 |
故障转移 |
---|---|---|---|
libpq驱动 |
√ |
× |
√ |
JDBC驱动 |
√ |
√ |
√ |
libpq实现故障转移和读写分离
通过libpq函数连接多个数据库,当出现故障时会自动切换到可用的数据库。
postgresql://[user[:password]@][netloc][:port][,…][/dbname][?param1=value1&…]
示例:连接1个RDS for PostgreSQL主实例数据库和对应的2个只读实例数据库,只要确保至少有一个数据库可用,读请求就不会失败。
postgres://10.6.10.194:5432,10.6.2.98:5432,10.6.9.43:5432/postgres?target_session_attrs=any
参数 |
说明 |
取值样例 |
---|---|---|
target_session_attrs |
允许连接到指定状态的数据库。 |
any:默认值,表示允许连接到任意数据库,会连接到第一个允许连接的数据库,如果连接的数据库出现故障导致连接断开,会尝试连接其他数据库,从而实现故障转移。 |
更多libpq的使用方法和参数说明请参见Connection Strings。
您还可以在应用程序中结合pg_is_in_recovery()函数,判断连接的数据库是主实例数据库(结果为“f”表示主数据库)还是只读实例数据库,进而实现读写分离。
使用Python代码的示例如下(psycopg2使用的为libpq):
import psycopg2 conn = psycopg2.connect(database="postgres",host="10.6.10.194,10.6.2.98", user="root", password="******", port="5432,5432", target_session_attrs="read-write") cur = conn.cursor() cur.execute("select pg_is_in_recovery()") row = cur.fetchone() print("recovery =", row[0])
JDBC实现故障转移和读写分离
您可以在连接URL中定义多个数据库(主机和端口),并用逗号分隔,驱动程序将尝试按顺序连接到它们中的每一个,直到连接成功。如果没有成功,会返回连接异常报错。
jdbc:postgresql://node1,node2,node3/${database}?targetServerType=preferSecondary&loadBalanceHosts=true
示例:
jdbc:postgresql://10.6.10.194:5432,10.6.2.98:5432,10.6.9.43:5432/${database}?targetServerType=preferSecondary&loadBalanceHosts=true
JDBC连接实例java实现代码请参考:通过JDBC连接RDS for PostgreSQL实例。
参数 |
说明 |
取值样例 |
---|---|---|
targetServerType |
允许连接到指定状态的数据库。 |
any:任何数据库。 |
loadBalanceHosts |
尝试连接数据库的顺序。 |
False:默认值,按URL中的定义顺序连接数据库。 |
区别数据库主从的方式是通过查询数据库是否允许写入,允许写入数据的判断为主数据库,不允许写入数据的判断为从数据库。参考libpq实现故障转移和读写分离中通过pg_is_in_recovery()函数来判断,结果为“f”表示为主数据库。
为实现读写分离,需要在配置JDBC时设置2个数据源,首先设置targetServerType=primary,用于写操作。另一个可以根据以下情况进行设置:
有一个只读实例,为实现高可用设置targetServerType=preferSecondary,用于读操作。假设主实例IP为10.1.1.1,只读实例IP为10.1.1.2。
jdbc:postgresql://10.1.1.2:5432,10.1.1.1:5432/${database}?targetServerType=preferSecondary
有两个以上只读实例,可设置targetServerType=any,用于读操作。假设只读实例IP分别为10.1.1.2、10.1.1.3。
jdbc:postgresql://10.1.1.2:5432,10.1.1.3:5432/${database}?targetServerType=any&loadBalanceHosts=true
父主题: RDS for PostgreSQL
同意关联代理商云淘科技,购买华为云产品更优惠(QQ 78315851)
内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家