twitter snowflake: kubernetes+docker+zookeeper实现workerId的自动分配

设想公司有两个datacenter.

1.出于性能考虑, 每个datacenter都有独立的zookeeper.

2.datacentor内有若干snowflake的实例,都放在docker里面运行, 通过RESTful API来生成全局流水号.

   可批量生成, 比如每次生成8000个流水号.

3.datacentor用kubernetes来管理所有的docker实例.



 

那么, 我们知道, snowflake需要两个关键配置: datacentorId和workerId. 一般在kubernetes环境, 我们可以把datacentorId和workerId放在kubernetes的configMap中. 但configMap也有不足之处:

1. 需要人工管理workerId的分配, 并且手动将分配的workerId配置到configMap.

2. 不能从技术上杜绝workerId重复的可能.

3. 不能动态跟踪实际活动的worker的变化, 不能动态分配workerId和动态回收workerId.

综上, 我们希望实现这样的功能:

1. datacenter是极少变化的, 所以可以放到kubernetes的configMap中.

2. workerId将结合zookeeper, 实现动态分配和回收, 不需要人工干预. 

原理:

1. docker容器启动后, 启动snowflake服务实例. 

2. snowflake服务尝试在zookeeper中创建名"workerIdN"的临时节点(0<=N<=31>), 如果节点已经存在则跳过, 如果创建成功则立即终止,从0到31一共尝试32次; 如果32次都没成功, 就是说已经有32个snowflake实例了, 则实例数量已经饱和, 该snowflake将不能提供流水号生成服务.

   在该临时节点中可以存储当前docker容器的HOSTNAME, 便于跟踪调试. kubernetes确保了该HOSTNAME是唯一的.

3. 创建临时节点workerIdN成功后, snowflake服务从configMap中取得datacenterId, 完成初始化, 开始对外提供基于RESTful的流水号生成服务. 

这样, 在configMap中就不需要配置workerId. 随着容器的启动和下线, workerId就可以实现动态分配. 当然这需要一些简单的开发工作, 再次就不赘述了.

猜你喜欢

转载自rickgong.iteye.com/blog/2368386