帮你快速理解、总结文档立即下载

自动读写分离介绍

最近更新时间:2026-08-31 14:51:31
我的收藏
本文主要介绍云数据库 PostgreSQL 数据库代理服务的自动读写分离、功能优势、读写分离路由规则。

自动读写分离

目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压力,可以创建一个或多个只读实例,利用只读实例满足大量的数据库读取需求。但此类解决方案需要业务侧支持读写分离改造,其代码的健壮性决定了业务读写分离的质量,对用户的技术要求较高,而且灵活性和可扩展性较差。
故创建只读实例后,可以通过开通数据库代理,配置访问地址策略,然后在应用程序中配置数据库代理地址,使写请求自动转发到主实例,读请求自动转发到各个只读实例。数据库代理除了具备自动读写分离功能,也能为其他业务痛点提供更好的解决方案,具体如下:
负载无法预测或波动不规律/负载“洪峰”现象明显的场景
在互联网业务场景中,业务负载和访问压力往往是不可预估、不平稳的,会出现频繁的波动和“洪峰”。如果业务侧大量使用短连接访问数据库,那么在这些场景中很容易产生大量的新建连接,即数据库与应用程序间的连接数,容易随着业务访问压力的频繁变动而波动。
数据库代理的连接管理,使用户可以通过有效重用数据库连接,来适当扩展处理不可预测工作负载的应用程序连接问题。首先,使多个应用程序连接可以共享数据库连接,以有效利用数据库资源;其次,允许用户通过调节打开的数据库连接数,来保持数据库性能;最后,可删除无法使用的应用程序请求,以保留应用程序的整体性能和可用性。
应用程序与数据库频繁建立和断开连接的场景
基于无服务器、PHP 或 Ruby on Rails 等技术构建的应用程序,可能会频繁打开和关闭数据库连接来满足应用程序请求。
数据库代理可以帮助用户维护数据库连接池,以避免对数据库计算和用于建立新连接的内存造成不必要的压力。
数据库访问连接长时间处于空闲状态并未释放的场景
SaaS 或电子商务行业中的传统应用程序,可能会使数据库连接保持空闲状态,以最大程度减少用户重新参与的响应时间。用户可以使用数据库代理来保留空闲连接,仅根据需要建立数据库连接,而不是为支持大多数空闲连接过度调大阈值或升级为更高配的数据库。
提高数据库 PaaS 服务故障转移场景下的平滑和稳定
使用数据库代理,用户可以构建可透明容忍数据库故障转移(主动/被动)的应用程序,而无需编写复杂的故障处理代码。数据库代理自动将读流量路由到新的数据库实例,同时保留应用程序连接。


功能优势

自助读写分离,统一访问地址。
原生链路支持,提升性能,减少维护成本。
可设权重和阈值,可供用户灵活选择。
具备故障转移能力,即使数据库代理故障请求也能正常访问主库。
主实例发生切换、变配、只读实例增减等情况,数据库代理可动态热加载配置,不会出现网络中断或重启。

功能说明

云数据库 PostgreSQL 数据库代理服务具备自动读写分离能力,并支持为读写实例和多个只读实例做读权重的分配,需注意,此处的权重是面向读请求(非事务)权重的分配策略。

路由规则与注意事项

判定依据:函数是否强制路由主实例以 pg_proc.provolatile 为准,仅 volatile 强制主实例,stable / immutable 按读请求分流至 RO。
自查方法:select proname, provolatile from pg_proc where proname = '<函数名>';
需要确定性读主实例状态时使用 /* master */ hint,或改用主实例直连地址。
读写分离下涉及实例自身状态、参数、统计信息的查询,结果可能来自 RO 实例且在多 RO 间变化,不应用于主实例状态判断。

已知返回值差异的函数清单

各函数的 provolatile 请以目标内核版本上 pg_proc 实测为准。
SELECT p.proname, p.provolatile
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname = 'pg_catalog'
AND p.provolatile IN ('s', 'i')
AND (p.proname ~ '^(inet_|pg_stat_|pg_current_|pg_last_|pg_control_|pg_is_|pg_backend|pg_postmaster|pg_conf_|pg_ls_)'
OR p.proname IN ('current_setting', 'version'))
ORDER BY p.provolatile, p.proname;
其中 provolatile 为 s / i 的项才会被分流到 RO。
类别
典型函数 / 视图
落 RO 时的表现
连接与实例身份
inet_server_addr(实测 s)、inet_server_port(实测 s)、inet_client_addr(实测 s)、pg_backend_pid、pg_postmaster_start_time、pg_conf_load_time
返回 RO 节点自身的地址/端口/PID/启动时间,与主实例不同;多 RO 时漂移
参数与配置
current_setting('...')、SHOW <param>、pg_settings
主 / RO 规格或参数模板不同时取值不同(max_connections、work_mem、hot_standby、default_transaction_read_only 等)
统计与运行态视图
pg_stat_activity、pg_stat_replication、pg_replication_slots、pg_stat_database、pg_locks、pg_stat_user_tables
看不到主实例的会话复制槽统计,或统计口径不同;业务做连接数监控、会话 kill、延迟监控时结论错误
恢复 / 角色状态、WAL 位点
pg_is_in_recovery、pg_last_wal_replay_lsn、pg_current_wal_lsn、pg_control_checkpoint
若这些函数在目标版本为 v,按规则已走主实例;若为 s,则落 RO 后语义反转(主 f / RO t)或位点落后