如何在副本集的多数据库服务器间生成连续序号?
解决副本集场景下用户友好型连续序号的方案
针对你遇到的副本集ID不连续、用户体验不佳的问题,以下是几个实用的解决方案,结合你正在使用Google Cloud的场景给出适配建议:
方案一:基于Redis的独立序号生成服务
利用Google Cloud Memorystore(托管Redis)的原子自增特性生成连续序号,这是最直接且易维护的方案:
- 操作步骤:
- 在GC上创建Memorystore Redis实例(根据并发量选择单节点或集群模式)
- 应用在创建实体前,调用Redis的
INCR命令获取全局唯一的连续序号(针对不同实体类型可使用不同key,如user_display_id、order_display_id) - 将获取到的序号存入实体表的单独字段(如
display_id),前端仅展示该字段
- 优势:Redis单线程天然保证原子性,性能极高,完全适配GC生态,故障切换时不影响序号连续性
- 注意:需给Redis实例配置合适的备份策略,避免数据丢失导致序号断层
方案二:数据库原生序列生成器
如果你的数据库支持全局序列(比如MySQL 8.0+、PostgreSQL),可以直接在主库创建全局序列,无需额外服务:
- 操作示例(以MySQL为例):
-- 创建全局序列 CREATE SEQUENCE entity_display_seq START WITH 1 INCREMENT BY 1 MINVALUE 1 NO MAXVALUE CACHE 10; -- 插入实体时获取序列值 INSERT INTO entities (display_id, ...) VALUES (NEXTVAL(entity_display_seq), ...); - 优势:完全依赖数据库原生能力,无需额外维护成本,副本集切换后主库的序列会自动延续
- 注意:确保数据库版本支持序列功能,部分老版本MySQL可能需要用自定义函数模拟序列
方案三:应用层生成业务友好型标识符(非严格连续但用户可接受)
如果对“严格连续”要求不是绝对刚性,可以生成带业务含义的标识符,既解决用户体验问题,又避免依赖额外服务:
- 示例格式:
ORD-20240520-0001(前缀+日期+当日序号)、USER-XXXX(前缀+随机4位数字,需数据库唯一约束兜底) - 操作步骤:
- 应用根据业务规则生成标识符,当日序号可通过查询当日已创建实体数自增
- 给实体表的
display_id字段添加唯一约束,避免并发冲突 - 若生成时出现冲突,自动重试生成
- 优势:灵活适配业务场景,无额外依赖,用户接受度高
- 注意:高并发场景下可能需要增加重试逻辑,严格连续的需求不适用此方案
方案选择建议
- 若你已经在使用GC生态,优先选方案一,Redis的部署和维护成本极低,且性能、可靠性完全满足需求
- 若不想引入额外组件,且数据库支持序列功能,选方案二,最轻量化
- 若对连续要求不高,想结合业务场景优化用户体验,选方案三
内容的提问来源于stack exchange,提问作者Shereth S
相关产品推荐
相关产品推荐

