关于分布式id生成器生成单调递增id的思考
如何保证获取到的id单调递增?
约束条件:
1)集群中一台机器为Master,仅Master提供id生成服务
2)当获取id的请求路由到Master机器时,直接返回响应(一轮RPC)
当获取id的请求路由到非Master机器时,转发至Master机器(两轮RPC)
方案评估
评估 | |
---|---|
性能 |
1)请求最终由Master机器进行响应。单机能支持的最大QPS即为集群最大QPS。 2)请求路由到非Master机器时,需两轮RPC,会增加耗时。 3)请求最终由Master机器进行响应,导致同机房优先路由策略不适用,某些情况下,请求耗时较长。 |
扩展性 |
集群总QPS无法随集群机器数量的增加而线性扩展。 |
可用性 |
1)当发生Master切换时,会损失一定可用性 2)某些情况下,请求耗时较长,会导致可用性降低。 |
评估详情
性能
(1)当获取id的请求最终由Master进行响应。单机能支持的最大QPS即为集群最大QPS。
(2)由于仅Master能够提供id生成服务,同机房优先等路由规则不再适用
情况1:当获取id的请求路由到Master
当获取id的请求路由到Master,直接返回响应,一轮RPC
case1:
client和Master同城市,比如都在Beijing
client(Beijing)----->server(Master,Beijing)
case2:
client和Master不同城市,比如一个Beijing,一个Shanghai
client(Beijing)--(25ms+)--->server(Master,Shanghai)
跨城市调用,获取id的耗时将达到25ms+。
情况2:当获取id的请求路由到非Master
当获取id的请求路由到非Master,转发至Master,两轮RPC
case 1:
当client和Master同城市,比如都在Beijing
client(Beijing)----->server(非Master,Beijing)----->server(Master,Beijing)
case2:
当client和Master不同城市,比如一个Beijing,一个Shanghai
client(Beijing)----->server(非Master,Beijing)--(25ms+)--->server(Master,Shanghai)
跨城市调用,获取id的耗时将达到25ms+。
极端情况:第一次获取id,Master从DB加载号段,跨城市
client(Beijing)----->server(非Master,Beijing)--(25ms+)--->server(Master,Shanghai)--(25ms+)--->DB(Beijing)
总结
当client和Master机器在不同城市时,获取id耗时较长。
扩展性
集群总QPS无法随集群机器数量的增加而线性扩展。
无论集群中机器有多少台,集群QPS为单机最大QPS
可用性
1)由于同机房优先等路由规则不再适用,耗时明显增加,超时概率大大提高。
2)切换Master期间,id生成服务会短暂不可用,且不可避免
可导致Master切换的情况
1)禁用Master机器
2)重启Master
3)机器宕机
Master切换
1)探测到需要切换Master
当禁用Master机器的时候,怎么探测到需要切换Master?
2)选举新的Master
3)新Master提供服务
新Master从DB获取新号段,对于路由到非Master的请求将转发到新Master
如何处理Master切换时的id分发问题,保证在Master切换时的可用性?
Master切换期间,id生成服务短暂不可用,且不可避免,只能够尽量做到client端无明显感知
此处无明显感知是指
1)Master切换时,client端获取id的耗时无明显增加,否则导致超时增多
2)Master切换时,获取id服务短暂不可用,应保证获取到异常的id的数量无明显增加
附录
微信序列号生成器如何实现唯一、递增的
https://www.infoq.cn/article/wechat-serial-number-generator-architecture/
实现唯一、递增的约束条件:有且仅有一台server提供服务
解决方法:仅有一台Master提供服务,Master不可用时,切换新Master
总结就是:
1)单台Master提供id生成服务。
2)引入仲裁服务,仲裁服务探测Master可用性,当Master不可用时,指定新的Master
3)其他机器定时检测配置,判断新Master是不是自己,是的话,作为新Master提供服务
为了避免Master切换过程中,旧的Master产生脏数据,引入了租约机制。
但是租约机制会导致id生成服务一段时间内不可用,此时,微信通过重试解决这段时间的不可用问题。
(由于微信序列号生成器的使用场景的特殊性,对于短时间内id生成服务的不可用是可以容忍的)