分布式情况下生成数据库唯一ID的解决方案
来源:互联网 发布:工业设计 比赛软件 编辑:程序博客网 时间:2024/05/21 07:58
D作为业务的唯一标识,在数据设计中屡见不鲜,例如:
•商品 —— product_id
•订单 —— order_id
•消息 —— message_id
这些标识往往就是数据库的主键,MySQL会在主键是建立聚簇索引,这个索引直接指向数据地址。相比普通索引指向聚簇索引,减少了一次索引查询,速度很快。消息、订单类似业务一般会有按照时间倒序查询数据的需求,一种做法是在时间列上建立索引,更好的是依赖ID本身的插入有序性。所以,分布式ID需要满足两个核心条件:
•全局唯一
•时间趋势有序
可能有人会说了,直接用MySQL的auto_increment不就行了么。在创业初期的时候我也会选择这个方案,简单、高效、快速——创业公司还是得快速迭代,尽快出产品,而且产品经常变,花太多时间搞出的牛逼架构说不定不太用得上,浪费了宝贵的时间。但这个方案是存在一些问题的:
•影响并行插入——B记录依赖A记录的主键,需要等到A记录插入成功,拿到A.id,才能插入B记录
•数据恢复难度大——数据误删或者丢失后,由于日志中没有ID,不能直接确定数据关联性
•影响分库分表——由于ID要插入后才知道,不能根据业务的主键进行分库分表
所以,在业务稳定后,一定要抽出时间来还早期的技术债务。
常见方案
使用数据库的auto_increment来生成唯一ID
优点
•简单,使用已有功能,开发量小
•ID步长固定
缺点
•写入单点,非高可用
•即使按照不同auto_increment起点扩展多个主库,虽然提高了可用性,但却不能保证ID的严格有序
•每次都需要访问数据库,容易到达性能天花板
批量拉取ID,逐一分配
这种方案也是将ID数据存入数据库,ID服务每次从数据库中拉取N个ID,并将当前已用ID最大值更新为原始数据+N,ID服务每次接到ID生成请求时就从这N个ID中依次返回。
优点
•批量获取,不用每次访问数据库,数据库压力小
缺点
•整个服务还是单点
•服务宕机重启会造成ID不连续
•无法水平扩展
改进
增加一套备用服务,主服务挂了漂移到备用服务上,可以采用vip + keepalived或者增加proxy。
uuid
优点
•本地生成ID,没有单点问题,没有性能瓶颈
缺点
•不能保证递增有序
•长度过长,作为主键性能低
类snowflake算法
snowflake是twitter开源的分布式ID生成算法,其核心思想是:一个long型的ID,使用其中41bit作为毫秒数,10bit作为机器编号,12bit作为毫秒内序列号。这个算法单机每秒内理论上最多可以生成1000*(2^12),也就是400W的ID,完全能满足业务的需求。
借鉴snowflake的思想,结合各公司的业务逻辑和并发量,可以实现自己的分布式ID生成算法。
优点
•时间在高位,趋势递增
•实现简单,不依赖其它服务,方便扩展
缺点
•没有全局时钟,单机绝对有序,但从整个集群来看,是趋势有序的
注意事项
•由于ID常作为分库分表的标识,所以需要这些ID有一定的随机性,不至于分库后的数据不均匀,可以在每个毫秒开始时序列号不从1开始,二是从0-9中的任意一个开始
求指教
•基于Snowflake的思想,42bit作为毫秒数,12bit作为服务编号(ip末位8bit + 设置的进程标识4bit),10bit作为序列号,基于Golang实现了一个简单的id生成器,目前单进程,刚好能跑起来,会持续改进。项目托管在https://github.com/sanpili/snowflake上,本人是go新手,有何使用不当的地方,欢迎指教和PR。
0 0
- 分布式情况下生成数据库唯一ID的解决方案
- 在高并发分布式情况下生成唯一标识id
- flickr 对于分布式系统生成全局唯一ID的解决方案
- 分布式环境下全局唯一ID的生成方案
- HIVE下分布式生成整型唯一ID
- 分布式系统中唯一ID的生成
- php 生成分布式唯一ID
- 分布式唯一ID生成服务
- 分布式系统唯一ID生成
- 高并发、分布式交易场景下唯一ID生成方法
- 数据库中生成唯一的ID
- Oracle数据库,唯一标识ID的生成
- 高并发分布式环境中获取全局唯一ID[分布式数据库全局唯一主键生成]
- 分布式系统如何生成全局唯一的ID
- 分布式系统中, 怎么样生成全局唯一的 ID
- 分布式系统中唯一ID的生成方法
- 分布式系统中唯一 ID 的生成方法
- 分布式系统中生成全局唯一ID的方法
- linux-搭建web服务器系列--连接linux服务器(一)
- How tomcat works——4 Tomcat中默认连接器
- MySQL数据库的热备份和冷备份的优缺点
- Linux笔记
- JSP include编译指令和include动作指令区别
- 分布式情况下生成数据库唯一ID的解决方案
- 说说Zookeeper中的ACL
- Android工具下载网站
- 关于Android应用开发的时候内存的问题
- JZOJ 4937【GDKOI2017模拟1.12】与运算
- JMeter简单的使用(3.0+)-性能测试(压力)
- 新企业如何为员工办理社保
- 如何才能成为一名优秀的架构师
- 文本的关键字提取