只读副本与连接路由
使用 PgBouncer 或智能驱动将只读流量路由到副本,并接受由此带来的数据陈旧性权衡
只读副本与连接路由 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。
为什么要使用读副本
读密集型工作负载可以将 SELECT 分流到副本:
- 主库负责写入
- 副本负责大部分读取
- 无需分片即可实现横向读扩展
最终一致性注意事项
副本会落后于主库。刚刚下单的用户可能暂时无法在副本上看到订单。可采用以下方式:
- 将写入后的读取路由到主库
- 等待副本追上进度
- 在应用中缓存写入后的状态
路由策略
- 应用层路由——由应用代码选择主库或副本
- 驱动层路由——使用能够识别主库和副本的 JDBC、pgjdbc 或 pgxpool 连接池
- 代理层路由——使用能够检测读写操作的 pgpool、pgbouncer 或 HAProxy
应用路由
两个连接池,每个角色一个:
const primary = new Pool({ host: 'primary', ... });
const replica = new Pool({ host: 'replica', ... });
// reads go to replica:
await replica.query('SELECT ...');
// writes (and read-your-writes) go to primary:
await primary.query('INSERT ...');PgPool-II
可解析 SQL 的代理,将 SELECT 路由到副本,将写入路由到 primary。支持负载均衡和连接池:
# pgpool.conf
backend_hostname0 = 'primary'
backend_hostname1 = 'replica1'
load_balance_mode = on带 pg_isready 检查的 HAProxy
HAProxy 无法理解 SQL,但可以按端口进行路由——一个前端用于写入(指向 primary),另一个用于读取(指向副本并执行健康检查):
frontend writes
bind *:5432
default_backend primary_pool
frontend reads
bind *:5433
default_backend replicas_pool
balance roundrobinAWS RDS 端点
RDS 提供一个写入端点和一个读取端点,后者会在所有副本之间进行负载均衡——这是云环境中最简单的方案。
复制延迟注意事项
监控延迟,避免将请求路由到落后过多的副本:
-- On primary:
SELECT client_addr, replay_lag FROM pg_stat_replication;
-- HAProxy / pgpool can use a custom health check that fails if replay_lag > threshold.粘性会话模式
对于“读取自己写入的数据”:写入后 N 秒内,将用户会话固定到 primary。或者记录写入的 LSN,并在提供读取服务前等待副本完成重放。
基于 LSN 的等待
写入后捕获 LSN;在副本上读取前,等待副本重放到该 LSN:
-- After write on primary:
SELECT pg_current_wal_lsn(); -- save this
-- Before read on replica:
SELECT pg_last_wal_replay_lsn() >= $saved_lsn;
-- spin or wait until true将缓存作为副本
有时 Redis / Memcache 可以作为用于读扩展的“replica”——对于热点键,其速度远快于另一个 PostgreSQL 实例。
何时不使用副本
如果您的工作负载以写入为主,副本大多只会增加成本,却不会提升速度。如果在 primary 上读取已经足够快,您可能并不需要副本。
灾难恢复与读扩展
用于 HA 故障转移的副本与用于读扩展的副本是两种不同的用途。通常您会同时采用两者。
总结
读副本可以扩展读取能力,但会产生延迟。
- 应用程序 / 驱动程序 / 代理路由
- 复制延迟 = 最终一致性
- 固定到 primary,或等待 LSN,以实现读取自己写入的数据
- 监控延迟,若落后过多则切回 primary
快速检查
用户发布评论后立即刷新页面。页面从副本读取,却没有显示评论。问题是什么?请给出一种修复方法。
常见问题解答
「只读副本与连接路由」课时是免费的吗?
是的 — 「只读副本与连接路由」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。
「只读副本与连接路由」这节课中我会学到什么?
使用 PgBouncer 或智能驱动将只读流量路由到副本,并接受由此带来的数据陈旧性权衡 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 SQL Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「只读副本与连接路由」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 SQL Academy 课中编写并运行代码吗?
能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。