- 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。
- 对数据分库分表后需要有一个唯一ID来标识一条数据或消息,数据库的自增ID显然不能满足需求;此时一个能够生成全局唯一ID的系统是非常必要的。
- 全局唯一性
- 趋势递增:在MySQL InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用B-tree的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能。
- 单调递增:保证下一个ID一定大于上一个ID,例如事务版本号、IM增量消息、排序等特殊需求。
- 信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,会需要ID无规则、不规则。
- 同时除了对ID号码自身的要求,业务还对ID号生成系统的可用性要求极高,想象一下,如果ID生成系统瘫痪,整个美团点评支付、优惠券发券、骑手派单等关键动作都无法执行,这就会带来一场灾难。
- 平均延迟和TP999延迟都要尽可能低;
- 可用性5个9;
- 高QPS。
- 分布式Redis集群(Master-Slave),每个Redis集群分别产生不同的Id序列; 每个Redis起点不同步长一样,比如3个Reids节点则产生序列号如下,步长3, 高效, 热Key分别在多台集群中产生:
节点 | 第1次生成数据 | 第2次生成数据 | 第3次生成数据 | 第4次生成数据 | ..... |
---|---|---|---|---|---|
Redis1-Master | 0 | 3 | 6 | 9 | ... |
Redis2-Master | 1 | 4 | 7 | 10 | ... |
Redis3-Master | 2 | 5 | 8 | 11 | ... |
- TODO