1.分布式ID的更高要求
雪花算法依赖时钟,存在回拨问题;数据库号段方案需要频繁访问DB。美团的Leaf方案提供了两种模式:号段模式(Leaf-segment)和雪花模式(Leaf-snowflake),均用Java实现,解决了上述痛点。
参考:https://wkmsa.cn/category/sleep-environment.html
2.Leaf-segment号段模式
核心思路:每个业务(biz_tag)从数据库获取一个号段(max_id),缓存在内存中,使用时递增发号。当号段使用率达到一定阈值(如10%),异步加载下一个号段,避免阻塞。数据库表存储biz_tag、max_id、step、update_time。Java实现使用AtomicLong和双缓冲机制。
3.Leaf-snowflake模式
改进雪花算法:使用Zookeeper顺序节点生成workerID(全局唯一),并且定期上报时间戳到ZK。当检测到时钟回拨时,若回拨幅度小于5毫秒则等待,否则抛出异常。解决了单点时钟问题。
4.案例:订单号生成器(高并发)
某外卖平台日订单峰值1亿。使用Leaf-segment:
每个biz_tag(如order)在DB中step设为50000。
服务启动时加载号段到内存,双缓冲保证了无缝切换。
压测显示单节点QPS可达10万,平均耗时0.5ms。
并发冲突极低,数据库更新号段使用乐观锁(version字段)。
5.高可用部署
Leaf服务无状态(除了ZK依赖),可水平部署多实例,负载均衡。数据库主从切换时需注意号段丢失(最多丢失一个step)。Leaf提供监控接口(HTTP)查看每个biz_tag的当前号段使用率。
6.与UIDGenerator对比
百度的UIDGenerator也是Java实现,使用RingBuffer预分配ID,性能更高,但实现复杂。Leaf更轻量易用。
参考:https://wkmsa.cn/category/sleep-products.html
7.总结
Leaf是工业级分布式ID生成器的优秀实现。它兼顾了性能、可用性和简单性,适合大多数互联网场景。Java开发者可以直接参考其设计思想,或直接集成Leaf组件。