哈希分配

采用zookeeper进行分配workerId的时候,首先生成一个uuid,然后根据这个uuid进行对当前的命名空间的当前已分配的空间最大值进行取余,得到一个临时的下标,然后查看以这个下标作为的zookeeper节点,查看该节点是否被占用,也就是该节点中的过期时间是否过期,如果过期,则该下标就是对应的workerId。如果没有过期,则该下标+1,并重新判断,如果到达当前分配空间的最大值,则从0开始继续查找可用节点,如果最后找到最开始的节点,则说明当前空间中已经没有可用节点,则进入到扩容模块。
这里的扩容其实很简单,其实就是在初始节点个数(初始节点个数为16)上乘2,然后重新哈希。

其中数据在zookeeper中的节点分配如下

  1. /butterfly/sequence
  2. |
  3. |_bizType_1
  4. | |
  5. | |_config
  6. | |
  7. | |_worker_0
  8. | | |
  9. | | |_session
  10. | |
  11. | |_worker_1
  12. | | |
  13. | | |_session
  14. | |
  15. | ...
  16. |
  17. |_bizType_2
  18. | |
  19. | |_config
  20. | |
  21. | |_worker_0
  22. | | |
  23. | | |_session
  24. | |
  25. | |_worker_1
  26. | | |
  27. | | |_session
  28. | ...

节点解释:

butterfly/sequence:zookeeper中的固定节点
bizType_1/bizType_2:为对应的命名空间,实际命名空间为用户自定义
config:为每个命名空间中放置配置的节点,其中存储的信息如下,一个是bit分配值,一个是命名空间中节点对应的值,bit分配的值,是为了以后扩展使用,这里先放置在这里

{
    "currentMaxMachine":16,
    "sequenceBits":9,
    "timestampBits":41,
    "workerBits":13
}

worker_x:对应的workerId对应的节点,其中有个session节点,该节点为临时节点,如果不存在session节点,则表示当前节点没被占用,则不判断过期时间,直接在内部创建session节点,并将下标x作为workerId返回。如果被占用,采用的是查看worker_x中存储的下次过期时间,如果当前过期时间小于当前时间,则认为已经过期,即创建session节点,并更新worker_x中的信息,并将x作为workerId使用。

{
    "ip":"127.0.0.1",
    "lastExpireTime":1588955705615,
    "processId":"90705",
    "uidKey":"762bcaad-48f5-4da9-8a1d-5e05a28add18"
}

定时上报

没起对应的进程启动,并分配好workerId之后,就会启动每5s向该worker_x节点上报一次下次过期的时间,目前采用的下次过期时间为24小时,也就是说一个进程一旦占用一个节点,一般情况下都是异常断开后最多占用24小时。但是正常断开的话,会自动将这些信息清理掉。