snowflake算法学习 作者: nbboy 时间: 2020-08-03 分类: 默认分类 评论 ###起源 内部IM项目需要标识不同消息的唯一性,我设计了一个ID值用来作为标识,关键在于这个值如何生成。该ID值需要满足以下需求: - 在高并发的时候也要保证多机唯一性 - 生成速度足够快,因为我们是IM系统,对实时性有需求 - 最好是数字的,这样排序可能更快一些 ###方案 查了下资料,Twitter 开源出一种ID生成算法,叫snowflake算法。学习了一下,其实也没什么新鲜东西,关键点也是可以想到的,就是时间戳+序列进行唯一性的保证。 SnowFlake算法是Twitter设计的一个可以在分布式系统中生成唯一的ID的算法,它可以满足Twitter每秒上万条消息ID分配的请求,这些消息ID是唯一的且有大致的递增顺序。 SnowFlake的算法是产生一个int64整型的ID,这段ID一共分为4部分,通过标示部分、时间戳、worker的Id、生成ID的序号来组合成为一个自增的ID,并且是全局唯一的。 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000  1. 1位标识部分 由于最高位是符号位,正数是0,负数是1,所以一般为0 1. 41位时间戳部分,这个是毫秒级别的的时间,但是使用的是当前时间减去系统开始时的差值,因为如果使用现在的值,会减少生成ID的唯一性, 1. 10位节点部分,前5位作为数据中心的标示,后5位作为机器标示,可以部分1024个节点 1. 12位序号,支持同一毫秒内同一个节点可以生成4096个ID; ###坑 网上也说了,这个算法就像其他基于time的算法一样,都不可避免的有一个漏洞,就是时间回拨问题,这个如何保证?其实在我这个项目中,因为简单原则,我们IM部署机器也不多,就几台,发号只需要集中在1,2台进行发号就可以。对于1,2台还是可以通过人工周期性同步或者脚本检测的方法来预防的。 最后,源码我放在GITHUB上了[Snowflake](https://github.com/x-debug/xfsnowflake.git "Snowflake"),欢迎读者来喷我!