性能对比
TODO
分布式ID方案的核心指标
- 全局(相同业务)唯一性:唯一性保证是ID的必要条件,假设ID不唯一就会产生主键冲突,这点很容易可以理解。
- 通常所说的全局唯一性并不是指所有业务服务都要唯一,而是相同业务服务不同部署副本唯一。 比如 Order 服务的多个部署副本在生成
t_order这张表的Id时是要求全局唯一的。至于t_order_item生成的ID与t_order是否唯一,并不影响唯一性约束,也不会产生什么副作用。 不同业务模块间也是同理。即唯一性主要解决的是ID冲突问题。
- 通常所说的全局唯一性并不是指所有业务服务都要唯一,而是相同业务服务不同部署副本唯一。 比如 Order 服务的多个部署副本在生成
- 有序性:有序性保证是面向查询的数据结构算法(除了Hash算法)所必须的,是二分查找法(分而治之)的前提。
- MySq-InnoDB B+树是使用最为广泛的,假设 Id 是无序的,B+ 树 为了维护 ID 的有序性,就会频繁的在索引的中间位置插入而挪动后面节点的位置,甚至导致频繁的页分裂,这对于性能的影响是极大的。那么如果我们能够保证ID的有序性这种情况就完全不同了,只需要进行追加写操作。所以 ID 的有序性是非常重要的,也是ID设计不可避免的特性。
- 吞吐量/性能(ops/time):即单位时间(每秒)能产生的ID数量。生成ID是非常高频的操作,也是最为基本的。假设ID生成的性能缓慢,那么不管怎么进行系统优化也无法获得更好的性能。
- 一般我们会首先生成ID,然后再执行写入操作,假设ID生成缓慢,那么整体性能上限就会受到限制,这一点应该不难理解。
- 稳定性(time/op):稳定性指标一般可以采用每个操作的时间进行百分位采样来分析,比如 CosId 百分位采样 P9999=0.208 us/op,即 0% ~ 99.99% 的单位操作时间小于等于 0.208 us/op。
- 百分位数 WIKI :统计学术语,若将一组数据从小到大排序,并计算相应的累计百分点,则某百分点所对应数据的值,就称为这百分点的百分位数,以Pk表示第k百分位数。百分位数是用来比较个体在群体中的相对地位量数。
- 为什么不用平均每个操作的时间:马老师的身价跟你的身价能平均么?平均后的值有意义不?
- 可以使用最小每个操作的时间、最大每个操作的时间作为参考吗?因为最小、最大值只说明了零界点的情况,虽说可以作为稳定性的参考,但依然不够全面。而且百分位数已经覆盖了这俩个指标。
- 自治性(依赖):主要是指对外部环境有无依赖,比如号段模式会强依赖第三方存储中间件来获取
NexMaxId。自治性还会对可用性造成影响。 - 可用性:分布式ID的可用性主要会受到自治性影响,比如SnowflakeId会受到时钟回拨影响,导致处于短暂时间的不可用状态。而号段模式会受到第三方发号器(
NexMaxId)的可用性影响。- 可用性 WIKI :在一个给定的时间间隔内,对于一个功能个体来讲,总的可用时间所占的比例。
- MTBF:平均故障间隔
- MDT:平均修复/恢复时间
- Availability=MTBF/(MTBF+MDT)
- 假设MTBF为1年,MDT为1小时,即
Availability=(365*24)/(365*24+1)=0.999885857778792≈99.99%,也就是我们通常所说对可用性4个9。
- 适应性:是指在面对外部环境变化的自适应能力,这里我们主要说的是面对流量突发时动态伸缩分布式ID的性能,
- SegmentChainId可以基于饥饿状态进行安全距离的动态伸缩。
- SnowflakeId常规位分配方案性能恒定409.6W,虽然可以通过调整位分配方案来获得不同的TPS性能,但是位分配方法的变更是破坏性的,一般根据业务场景确定位分配方案后不再变更。
- 存储空间:还是用MySq-InnoDB B+树来举例,普通索引(二级索引)会存储主键值,主键越大占用的内存缓存、磁盘空间也会越大。Page页存储的数据越少,磁盘IO访问的次数会增加。总之在满足业务需求的情况下,尽可能小的存储空间占用在绝大多数场景下都是好的设计原则。
分布式ID的核心算法
按位分区算法 (SnowflakeId)
| 性能(吞吐量) | 稳定性(百分位数) | 自治性(依赖) | 机器号分配器 | 机器号回收 | 使用方式 | |
|---|---|---|---|---|---|---|
| CosId | 4,096,000(ops/s) | P9999=0.244(us/op) | 首次启动,依赖机器号分配器 | 手动分配器、K8S、关系型数据库、Redis、ZooKeeper | 支持 | SDK(推荐)/RPC/RESTful |
| Leaf | ZooKeeper | |||||
| uid-generator | 关系型数据库 | |||||
| TinyID | 不支持按位分区算法 |
号段算法 (SegmentId)
| 性能(吞吐量) | 稳定性(百分位数) | 自治性(依赖) | 号段分发器 | 适应性 | 存储空间 | 使用方式 | |
|---|---|---|---|---|---|---|---|
| CosId | 127,439,148(ops/s) | P9999=0.208(us/op) | 依赖号段分发器 | 关系型数据库、Redis、ZooKeeper | 支持Step自动扩缩容 | 64-bit | SDK(推荐)/RPC/RESTful |
| Leaf | MySql | ||||||
| uid-generator | 不支持号段算法 | ||||||
| TinyID | 数据库 |
