分布式ID
2023-06-03 16:33:08 6 举报
AI智能生成
分布式ID是用于在分布式系统中生成唯一标识符的一种方法。它能够保证在多个节点和服务器之间生成的ID是唯一且不重复的,从而避免了数据冲突和混乱。常见的分布式ID生成算法包括雪花算法、UUID等。这些算法通常基于时间戳、机器IP地址、序列号等信息进行组合生成,以确保ID的唯一性和有序性。分布式ID的实现需要考虑高并发、高可用性等因素,以保证系统的稳定性和可靠性。在实际应用中,分布式ID常常用于订单号、用户ID、消息队列等场景,为系统提供了唯一的标识和管理手段。
作者其他创作
大纲/内容
概述
什么是分布式ID?
在我们业务数据量不大的时候,单库单表完全可以支撑现有业务,数据再大一点搞个MySQL主从同步读写分离也能对付。
但随着数据日渐增长,主从同步也扛不住了,就需要对数据库进行 分库分表,但分库分表后需要有一个唯一ID来标识一条数据,数据库的自增ID显然不能满足需求;特别一点的如订单、优惠券也都需要有唯一ID做标识。此时一个能够生成全局唯一ID的系统是非常必要的。那么这个全局唯一ID就叫分布式ID
但随着数据日渐增长,主从同步也扛不住了,就需要对数据库进行 分库分表,但分库分表后需要有一个唯一ID来标识一条数据,数据库的自增ID显然不能满足需求;特别一点的如订单、优惠券也都需要有唯一ID做标识。此时一个能够生成全局唯一ID的系统是非常必要的。那么这个全局唯一ID就叫分布式ID
分布式ID需要满足哪些条件?
全局唯一:必须保证ID是全局性唯一的,基本要求
高性能:高可用低延时,ID生成响应要块,否则反倒会成为业务瓶颈
高可用:100%的可用性是骗人的,但是也要无限接近于100%的可用性
好接入:要秉着拿来即用的设计原则,在系统设计和实现上要尽可能的简单
趋势递增:最好趋势递增,这个要求就得看具体业务场景了,一般不严格要求
常用的分布式ID方案
UUID
优点
生成足够简单,本地生成无网络消耗,具有唯一性
缺点
- 无序的字符串,不具备趋势自增特性
- 没有具体的业务含义
- 长度过长16 字节128位,36位长度的字符串,存储以及查询对MySQL的性能消耗较大,MySQL官方明确建议主键要尽量越短越好,作为数据库主键 UUID 的无序性会导致数据位置频繁变动,严重影响性能。
- 插入性能低
- 数据库优化 : 无法排序
归根结底还是Mysql的索引结构问题,详细看Mysql索引原理
基于数据库自增ID
基于数据库的auto_increment自增ID完全可以充当分布式ID
数据库的自增原理看Mysql原理
优点
实现简单,ID单调自增,数值类型查询速度快
缺点
DB单点存在宕机风险,无法扛住高并发场景
基于数据库集群模式
多个MySQL实例的自增ID都从1开始,会生成重复的ID怎么办?
解决方案:设置起始值和自增步长`
那如果集群后的性能还是扛不住高并发咋办?就要进行MySQL扩容增加节点,这是一个比较麻烦的事。
优点
解决DB单点问题
缺点
不利于后续扩容,而且实际上单个数据库自身压力还是大,依旧无法满足高并发场景
基于数据库的号段模式
号段模式可以理解为从数据库批量的获取自增ID,每次从数据库取出一个号段范围
基于Redis模式
Redis也同样可以实现,原理就是利用redis的 incr 命令实现ID的原子性自增
Redis也可以采取号段模式, 每次拿一个步长的数据。 incr by step
基于雪花算法(Snowflake)模式
Snowflake生成的是Long类型的ID,一个Long类型占8个字节,每个字节占8比特,也就是说一个Long类型占64个比特。
Snowflake ID组成结构:正数位(占1比特)+ 时间戳(占41比特)+ 机器ID(占5比特)+ 数据中心(占5比特)+ 自增值(占12比特),总共64比特组成的一个Long类型。
第一个bit位(1bit):java中long的最高位是符号位代表正负,正数是0,负数是1,一般生成ID都为正数,所以默认为0。
时间戳部分(41bit):毫秒级的时间,不建议存当前时间戳,而是用(当前时间戳 - 固定开始时间戳)的差值,可以使产生的ID从更小的值开始;41位的时间戳可以使用69年,(1L << 41) / (1000L *60* 60 *24* 365) = 69年
工作机器id(10bit):也被叫做`workId`,这个可以灵活配置,机房或者机器号组合都可以。(`机器ID + 数据中心`)
序列号部分(12bit),自增值支持同一毫秒内同一个节点可以生成 `4096` 个ID 2^12`
同一机器同一时间截(毫秒)内产生的 4096 个ID序号 (极大程度上避免了分布式ID生产问题)
缺点
依赖机器时钟,如果机器时钟回拨,会导致重复ID生成;
在单机上是递增的,但是由于设计到分布式环境,每台机器上的时钟不可能完全同步,有时候会出现不是全局递增的情况(此缺点可以认为无所谓,一般分布式ID只要求`趋势递增`,并不会严格要求递增,90%的需求都只要求趋势递增)。
百度(uid-generator)
uid-generator是基于Snowflake算法实现的,与原始的snowflake算法不同在于,uid-generator支持自定义时间戳、工作机器ID`和 序列号 等各部分的位数,而且`uid-generator`中采用用户自定义`workId`的生成策略。
uid-generator需要与数据库配合使用,需要新增一个WORKER_NODE表。当应用启动时会向数据库表中去插入一条数据,插入成功后返回的自增ID就是该机器的workId数据由host,port组成。
官方文档
美团(Leaf)
Leaf`同时支持号段模式和snowflake算法模式
号段模式
snowflake 模式
滴滴(Tinyid)
0 条评论
下一页