单机每秒能吐出4096个严格递增、全局唯一的ID,而且不依赖任何中心服务器——这是Snowflake算法最常被拿出来讲的一点。但真正让工程师头疼的,从来不是它怎么发号,而是它在生产环境里怎么翻车。
![]()
先看它的位级结构。一个64位的长整型被切成四段:1位符号位、41位时间戳、10位机器ID、12位序列号。时间戳放在高位,意味着ID整体随时间趋势递增;机器ID负责把不同节点的发号空间隔离开,避免撞车;12位序列号则是同一毫秒内的计数器,2的12次方正好是4096。这套结构让它同时甩开了随机UUID的无序和自增主键的扩展性瓶颈。
问题出在两个地方。
时钟回拨是最大坑。机器时钟一旦往回拨,时间戳变小,就可能撞上之前已经发出去的ID。常见做法是回拨就拒绝发号、等时钟追上来;小回拨可以等,大回拨直接报警停机。这不是理论风险,是物理时钟本身就会出错。
另一个坑是机器ID的分配。静态配置在扩容时很难受,动态分配(比如走ZK)又引入了高可用依赖——你为了解决一个问题,请来了另一个可能出问题的组件。
对比一下号段模式。美团Leaf这类实现走的是内存批量取号(Segment)的路子,一次从数据库捞一批ID缓存在本地,发号速度不输Snowflake。但它有个绕不开的缺点:重启会跳号。Snowflake是实时发号,号段模式是批量预支,两者在可用性和连续性之间做了不同的工程妥协——你要的是绝不重复,还是绝不跳号,得先想清楚。
最后留一个思考题:ID里如果带了业务语义,安全边界在哪里?这个问题没有标准答案,但值得每个做分布式系统的人自己过一遍。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.