Twitter Snowflake

这是一篇两年前 Twitter 开发团队写的文章,今天挖出来研究了一下。原文地址 http://engineering.twitter.com/2010/06/announcing-snowflake.html

Twitter 早期用 MySQL 存储数据,随着用户的增长,单一的 MySQL 实例没法承受海量的数据,开发团队就开始用 Cassandra 和 sharded MySQL 替代原有的系统。然而和 MySQL 不同的是,Cassandra 没有内置为每一条数据生成唯一 ID 的功能,因为在一个分布式环境下,很难有完美的 ID 生成方案。

对于 Twitter 而言,这样的 ID 生成方案要满足两个基本的要求,一是每秒能生成几十万条 ID 用于标识不同的 tweet;二是这些 ID 应该可以有个大致的顺序,也就是说发布时间相近的两条 tweet,它们的 ID 也应当相近,这样才能方便各种客户端对 tweet 进行排序。

第一个要求意味着 ID 生成要以一种非协作的(uncoordinated)的方式进行,例如不能有一个全局的原子变量。

第二个要求使得 tweet 按 ID 排序后满足 k-sorted 条件。如果序列 A 要满足 k-sorted,当且仅当对于任意的 p, q,如果 1 <= p <= q - k (1 <= p <= q <= n),则有 A[p] <= A[q]。换句话说,如果元素 p 排在 q 前面,且相差至少 k 个位置,那么 p 必然小于或等于 q。如果 tweet 序列满足这个条件,要获取第 r 条 tweet 之后的消息,只要从第 r - k 条开始查找即可。

Twitter 解决这两个问题的方案非常简单高效:每一个 ID 都是 64 位数字,由时间戳、节点号和序列编号组成。其中序列编号是每个节点本地生成的序号,而节点号则由 ZooKeeper 维护。

具体的参数可以在这个 IdWorker.scala 中看到。序列编号有 12 位,意味着每个节点在每毫秒可以产生 4096 个 ID。节点号在源码中被分成两部分,数据中心的 ID 和节点 ID,各自占 5 位。时间戳则是记录了从 1288834974657 (Thu, 04 Nov 2010 01:42:54 GMT) 这一时刻到当前时间所经过的毫秒数,占 41 位(还有一位是符号位,永远为 0)。

时间: 2024-11-05 16:31:22

Twitter Snowflake的相关文章

Twitter的分布式自增ID算法Snowflake实现分析及其Java、Php和Python版

在分布式系统中,需要生成全局UID的场合还是比较多的,twitter的snowflake解决了这种需求,实现也还是很简单的,除去配置信息,核心代码就是毫秒级时间41位+机器ID 10位+毫秒内序列12位. 该项目地址为:https://github.com/twitter/snowflake是用Scala实现的. python版详见开源项目https://github.com/erans/pysnowflake. 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用

详解Twitter开源分布式自增ID算法snowflake,附演算验证过程

1.snowflake简介 互联网快速发展的今天,分布式应用系统已经见怪不怪,在分布式系统中,我们需要各种各样的ID,既然是ID那么必然是要保证全局唯一,除此之外,不同当业务还需要不同的特性,比如像并发巨大的业务要求ID生成效率高,吞吐大:比如某些银行类业务,需要按每日日期制定交易流水号:又比如我们希望用户的ID是随机的,无序的,纯数字的,且位数长度是小于10位的.等等,不同的业务场景需要的ID特性各不一样,于是,衍生了各种ID生成器,但大多数利用数据库控制ID的生成,性能受数据库并发能力限制,

分布式唯一ID生成器Twitter 的 Snowflake idworker有谁在用么

问题描述 Snowflake idworker在分布式部署到不同IDC服务器的时候,是否需要修改参数或配置才能达到产生的ID才会不重复?import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * @author zhujuan * From: https://github.com/twitter/snowflake * An object that generates IDs. * This is broken into a sepa

基于snowflake算法的网游服务器唯一标识码GUID生成方法

在分布式系统中,需要生成全局UID的场合还是比较多的,twitter的snowflake解决了这种需求,实现也还是很简单的,除去配置信息,核心代码就是毫秒级时间41位+机器ID 10位+毫秒内序列12位. 网上也有好多PHP写的插件模块,核心用了网络通讯将生成的ID发送给PHP使用,没深入研究PHP的模块写法. 废话不多说了,还是直接上代码好了. uuid.h #ifndef __UTIL_UUID_H__ #define __UTIL_UUID_H__ #include <stdint.h>

网游服务器中的GUID(唯一标识码)实现-基于snowflake算法

本文中的算法采用twitter的snowflake算法,具体请搜索介绍,原来是用Scala写的,因我项目需要,改写成C++语言,主要用于高效的生成唯一的ID, 核心算法就是毫秒级时间(41位)+机器ID(10位)+毫秒内序列(12位). 网上也有好多PHP写的插件模块,核心用了网络通讯将生成的ID发送给PHP使用,没深入研究PHP的模块写法. 废话不多说了,还是直接上代码好了. uuid.h #ifndef __UTIL_UUID_H__ #define __UTIL_UUID_H__ #inc

一个复杂系统的拆分改造实践

1 为什么要拆分? 先看一段对话. 从上面对话可以看出拆分的理由: 1)  应用间耦合严重.系统内各个应用之间不通,同样一个功能在各个应用中都有实现,后果就是改一处功能,需要同时改系统中的所有应用.这种情况多存在于历史较长的系统,因各种原因,系统内的各个应用都形成了自己的业务小闭环: 2)  业务扩展性差.数据模型从设计之初就只支持某一类的业务,来了新类型的业务后又得重新写代码实现,结果就是项目延期,大大影响业务的接入速度: 3)  代码老旧,难以维护.各种随意的if else.写死逻辑散落在应

乐视秒杀:每秒十万笔交易的数据架构解读

随着乐视硬件抢购的不断升级,乐视集团支付面临的请求压力百倍乃至千倍的暴增.作为商品购买的最后一环,保证用户快速稳定地完成支付尤为重要.所以在2015年11月,我们对整个支付系统进行了全面的架构升级,使之具备了每秒稳定处理10万订单的能力.为乐视生态各种形式的抢购秒杀活动提供了强有力的支撑. 一. 分库分表 在redis,memcached等缓存系统盛行的互联网时代,构建一个支撑每秒十万只读的系统并不复杂,无非是通过一致性哈希扩展缓存节点,水平扩展web服务器等.支付系统要处理每秒十万笔订单,需要

每秒处理10万订单的支付架构 乐视集团

作者:梁阳鹤,乐视网boss平台技术部架构师,主要负责乐视集团支付,乐视会员系统,商业运营平台等系统架构工作.开源数据访问层框架mango作者. 责编:钱曙光,关注架构和算法领域,寻求报道或者投稿请发邮件qianshg@csdn.net,另有「CSDN 高级架构师群」,内有诸多知名互联网公司的大牛架构师,欢迎架构师加微信qshuguang2008申请入群,备注姓名+公司+职位. 稿件:309933706@qq.com  随着乐视硬件抢购的不断升级,乐视集团支付面临的请求压力百倍乃至千倍的暴增.作

分片(Sharding)的全局ID生成

 这里最后redis生成ID的文章已经过时,新的请参考: http://blog.csdn.net/hengyunabc/article/details/44244951 前言 数据在分片时,典型的是分库分表,就有一个全局ID生成的问题.单纯的生成全局ID并不是什么难题,但是生成的ID通常要满足分片的一些要求: 不能有单点故障. 以时间为序,或者ID里包含时间.这样一是可以少一个索引,二是冷热数据容易分离. 可以控制ShardingId.比如某一个用户的文章要放在同一个分片内,这样查询效率高,修