核心观点与关键数据
XSKY的SDDC产品管理面架构设计采用Postgres的逻辑复制(Logical Replication)和CDC(Change Data Capture)方案,替代传统消息队列,简化系统架构并提升性能。
关键问题与解决方案
-
消息传递方案选择
- 避免引入数据库消息队列,采用任务表+定时轮询、Trigger、逻辑复制和CDC四种方案对比,最终选择逻辑复制和CDC结合的方式。
- 逻辑复制:通过复制标识(主键)传递数据变更,支持跨Postgres版本和程序传递,但事件不完整需带外补充。
- CDC:近实时捕获数据变更,但仅表达数据变化,事件有序且不可随意消费。
-
性能验证
- 实现pglogrepl项目验证方案可行性,Postgres13环境下每分钟可发送超过50,000个事务。
-
问题预判与处理
- 事件丢失:通过带外方式补充缺失操作,并做好事件丢失的后备方案。
- WAL写满:需处理阻塞导致WAL写满的情况。
架构组件与交互
-
核心组件
- APIServer:用户交互及数据库读写,消费LR消息发送WebSocket消息。
- Controller:消费LR消息实现业务逻辑。
- Agent:触发informer重新载入数据,收敛业务逻辑(如虚拟机、块存储分组)。
- App:独立注册publication+slot,按顺序处理事件,不同App可处理同一事件。
-
交互机制
- App通过LR消息(APIserver与Controller)和informer(Controller与Agent)通信。
- 更新数据库时使用etag乐观锁,冲突时自动重试。
-
LR消息优化
- Postgres的LR消息过于原始,设计Event和EventGroup封装LR消息为ORMModel,简化应用开发。
特殊场景处理
-
Agent不直接消费CDC事件
- 为实现scale-out,Agent通过informer监听etcd缓存更新,避免直接访问数据库。
-
Slot管理问题
- 问题:Controller启动时可能丢失CDC事件,Failover时漏事件。
- 解决方案:将slot管理交由Patroni,通过slotsync命令初始化,自动同步restart_lsn,并处理重复事件幂等。
-
临时Slot应用
- 用于Websocket和APIClientManager等允许事件丢失的场景,避免Patroni管理冲突。
CDC事件重放机制
-
重放方案
- 在model中添加
CdcInserted和CdcUpdated字段标记重放事件,通过命令行工具sddc-managecdcreplay实现重放。
-
重放流程
- Insert事件通过删除再插入触发,Update事件通过更新UpdatedAt字段触发。
性能与稳定性
-
生产环境数据
- Controllerleader运行18天,接收LR消息:Update 966,961次,Insert 6,276次,Relation 1,149次。
- Slot数量:Persistent 40,Temporary 6。
-
亮点
- 逻辑复制简化架构,减少消息队列依赖,性能稳定。
- Golang生态对逻辑复制支持良好。
-
注意事项
- 需管理publication和slot,避免阻塞WAL,理解CDC思想避免误用,LR消费者需幂等。