雪花算法
应用场景
集群高并发情况下生成全局唯一id
1. id 生成规则的硬性要求:
- 全局唯一
- 趋势递增
- 单调递增
- 信息安全
- 含事件戳
2. id号生成系统的可用性要求:
- 高可用
- 低延迟
- 高并发
3. 生成全局唯一的id主流方案
1. UUID 为什么无序的UUID 会导致入库性能变差呢?
-
- 分布式id一般都会作为主键,但是MYSQL官方推荐主键越短越好
- UUID无序,作为主键会导致索引分裂,大大降低索引的性能。
数据库自增id 在分布式里面,数据库的自增id机制的原理是:数据库自增id和mysql的replace into 实现的(没有新增有则替换,字段创建唯一索引),缺点:系统水平扩展困难。
redis单线程天生保证原子性,可以使用原子操作incr和incr by 来实现
redis 集群情况下,需要设置不同的步长,同时key一定要设置有效期,通过redis集群来获取更高的吞吐量。 (强烈不推荐入库)
2. 雪花算法 Twitter的snowflake用糊涂工具包
1. 为什么叫雪花算法
在大自然中几乎找不出两朵完全相同的雪花。(这么说,这个算法还是很牛逼)
2. 组成
41位时间戳 + 10 位机器ID + 12位序号(自增),转换成长度为18的长整型。
雪花算法会生成一个64位的二进制数据,为一个Long型。(转换成字符串后长度最多19)
一个可能会重复的数 + 一个永远不可能重复的数 = 永远不可能重复的数
-
-
-
为什么 1bit 是无意义
-
-
因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。
-
-
-
41 bit 时间戳 ,单位是毫秒
-
-
41 bit 可以表示的数字多达 2^41 - 1,也就是可以标识 2 ^ 41 - 1 个毫秒值,换算成年就是表示 69 年的时间。
-
-
-
10 bit:记录工作机器id,代表的是个服务最多可以部署在2 ^ 10 台机器上,也就是1024 台机器。
-
-
但是10 bit 里面5个bit代表机房id,5个bit代表机器id。意思就是最多代表 2 ^ 5 个机房(32个机房),每个机房里面可以代表2^5个机器(32台机器),这里可以随意拆分,比如拿出4位标识业务号,其他6位作为机器号。可以随意组合。
-
-
-
12 bit: 这个是用来记录同一个毫秒内产生的不同id。
-
-
12 bit 可以代表的最大正整数是 2 ^ 12 -1 = 4096,也就是说可以用这个12bit 代表的数字来区分同一个毫秒内的4096个不同的id。也就会是同一毫秒内同一台机器所生成的最大ID数量为4096。