1、简单干脆
使用redis生成全局唯一id
使用redis原因:
redis本身单线程,不会出现并发问题
redis自身有过期策略
使用RedisAtomicLong 自增
痛点:高并发,单点问题?
2、 redis ID生成器
3、https://yq.aliyun.com/articles/6063 基于redis的分布式ID生成器
结论:
- 单节点,qps约3w
- 可以线性扩展,3个结点足以满足绝大部分的应用
4、 MySQL分库分表环境下全局ID生成方案
1. 数据库自增ID——来自Flicker的解决方案 在我们的应用端需要做下面这两个操作,在一个事务会话里提交:这样我们就能拿到不断增长且不重复的ID了。
到上面为止,我们只是在单台数据库上生成ID,从高可用角度考虑,接下来就要解决单点故障问题:Flicker启用了两台数据库服务器来生成ID,通过区分auto_increment的起始值和步长来生成奇偶数的ID。
- 优点:充分借助数据库的自增ID机制,提供高可靠性,生成的ID有序。
- 缺点:占用两个独立的MySQL实例(一个实例单点问题),有些浪费资源,成本较高。
2. 独立的应用程序——来自Twitter的解决方案
Twitter在把存储系统从MySQL迁移到Cassandra的过程中由于Cassandra没有顺序ID生成机制,于是自己开发了一套全局唯一ID生成服务:Snowflake。GitHub地址:https://github.com/twitter/snowflake。
41位的时间序列(精确到毫秒,41位的长度可以使用69年)
10位的机器标识(10位的长度最多支持部署1024个节点)
12位的计数顺序号(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号)
最高位是符号位,始终为0。
- 优点:高性能,低延迟;独立的应用;按时间有序。
- 缺点:需要独立的开发和部署。 依赖机器时间 如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。
1. 数据库自增长序列或字段
最常见的方式。利用数据库,全数据库唯一。
优点:
1)简单,代码方便,性能可以接受。
2)数字ID天然排序,对分页或者需要排序的结果很有帮助。
缺点:
1)不同数据库语法和实现不同,数据库迁移的时候或多数据库版本支持的时候需要处理。
2)在单个数据库或读写分离或一主多从的情况下,只有一个主库可以生成。有单点故障的风险。
3)在性能达不到要求的情况下,比较难于扩展。
4)如果遇见多个系统需要合并或者涉及到数据迁移会相当痛苦。
5)分表分库的时候会有麻烦。
优化方案:
1)针对主库单点,如果有多个Master库,则每个Master库设置的起始数字不一样,步长一样,可以是Master的个数。比如:Master1 生成的是 1,4,7,10,Master2生成的是2,5,8,11 Master3生成的是 3,6,9,12。这样就可以有效生成集群中的唯一ID,也可以大大降低ID生成数据库操作的负载。
2. UUID
常见的方式。可以利用数据库也可以利用程序生成,一般来说全球唯一。
优点:
1)简单,代码方便。
2)生成ID性能非常好,基本不会有性能问题。
3)全球唯一,在遇见数据迁移,系统数据合并,或者数据库变更等情况下,可以从容应对。
缺点:
1)没有排序,无法保证趋势递增。
2)UUID往往是使用字符串存储,查询的效率比较低。
3)存储空间比较大,如果是海量数据库,就需要考虑存储量的问题。
4)传输数据量大
5)不可读。
7、http://weixin.niurenqushi.com/article/2017-04-21/4825259.html Leaf——美团点评分布式ID生成系统
目前Leaf的性能在4C8G的机器上QPS能压测到近5w/s,TP999
8、https://tech.meituan.com/MT_Leaf.html
Leaf——美团点评分布式ID生成系统
41-bit的时间
10-bit机器
12个自增序列号可以表示2^12个ID
理论上snowflake方案的QPS约为409.6w/s,这种分配方式可以保证在任何一个IDC的任何一台机器在任意毫秒内生成的ID都是不同的。
这种方式的优缺点是:
优点:
- 毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。
- 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。
- 可以根据自身业务特性分配bit位,非常灵活。
缺点:
- 强依赖机器时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。
9、
基于 Redis 的全局唯一性ID生成器的一些实现思路【HeyMoon】