设为首页 收藏本站
查看: 972|回复: 0

[经验分享] 分布式环境下的id生成方法

[复制链接]

尚未签到

发表于 2016-11-22 09:42:37 | 显示全部楼层 |阅读模式
  前几天研究数据库分表分库的问题,其中有一个关键的地方就是生成唯一键的问题,假如数据表有1亿条数据,而且还在不断的增加,这里我们就需要考虑到分表分库,假设我们采用Hash或者是用户取模求余的方法将这个表拆分成10个表,每个表的结构相同,其中有一个主键id,那么10个表中的id需要唯一不同,在单表的时候,使用数据表自增长是没有问题的。当分成10个表后,就无法用到数据库自增长了。
  当到这里的时候突然发现oracle数据库的序列真是好东西,在刚刚接触的时候还很郁闷这种设计真是没有mysql获sqlserver中的方便
  目前做唯一id的做法基本有三种
  1.使用uuid来实现,快速不重复,只是生成的id没有规则
  2.使用外部的id分发中心来实现,生存的id简短有规则,缺点是依赖于单点
  3.在数据库中做一个计数表来做,有点类是于oracle中的序列
  以下内容大部分来自于网络:

UUID
  UUID的目的,是让分散式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。
  一组UUID,是由一串16位组(亦称128位)的16进位数字所构成,是故UUID理论上的总数为216 x 8=2128,约等于3.4 x 1038。也就是说若每纳秒产生1兆个UUID,要花100亿年才会将所有UUID用完。
  UUID的标准型式包含32个16进位数字,以连字号分为五段,形式为8-4-4-4-12的36个字符。示例:

550e8400-e29b-41d4-a716-446655440000
twitter的Snowflake(id分发中心)
  Snowflake是twitter开源的一款独立的适用于分布式环境的ID生成服务器。生成的ID是64Bits,同时满足高性能(>10K ids/s),低延迟(<2ms)和高可用。与MongoDB ObjectID类似这里生成的ID也是时间上有序的。编码方式也和ObjectID类似,如下:

0           41     51     64
+-----------+------+------+
|time       |pc    |inc   |
+-----------+------+------+


  • 前41bits是以微秒为单位的timestamp。
  • 接着10bits是事先配置好的机器ID。
  • 最后12bits是累加计数器。

MongoDB ObjectID(类似UUID的方式)
  MongoDB中每一条记录都有一个’id’字段用来唯一标示本记录。如果用户插入数据时没有显示提供’id’字段,那么系统会自动生成一个。ObjectID一共12Bytes,设计的时候充分考虑了分布式环境下使用的情况,所以能保证在一个分布式MongoDB集群中唯一。ObjectID格式如下:

0        4      7    9      12
+--------+------+----+------+
|time    |pc    |pid |inc   |
+--------+------+----+------+


  • 前四个字节是Unix Timestamp。
  • 接着三个字节是当前机器“hostname/mac地址/虚拟编号”其中之一的MD5结果的前3个字节。
  • 接着两个字节是当前进程的PID。
  • 最后三个字节是累加计数器或是一个随机数(只有当不支持累加计数器时才用随机数)。
  最后生成的仍然是一个用16进制表示的串,如47cc67093475061e3d95369d。这里MongoDB的ObjectID相对UUID有个很大的优点就是ObjectID是时间上有序的。另外还有ObjectID本身也包含了很多其它有用的信息,通过直接解码ObjectID即可直接获得这些信息。

Ticket Server(数据库生存方式)
  这个是Flickr在遇到生成全局ID问题时采用的办法。利用了数据库中auto_increment的特性和MySQL特有的REPLACE INFO命令,专门一个数据库实例用来产生ID。大致的过程是这样的:


  • 首先建立一个表,比如用来产生64bitsID的,叫做’Ticket64&prime;

CREATE TABLE `Tickets64` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`stub` char(1) NOT NULL default '',
PRIMARY KEY  (`id`),
UNIQUE KEY `stub` (`stub`)
) ENGINE=MyISAM


  • 向里边插入一条记录后大致是这样:

+-------------------+------+
| id                | stub |
+-------------------+------+
| 72157623227190423 |    a |
+-------------------+------+


  • 当需要一个64Bits ID的时候,执行如下SQL 语句:

REPLACE INTO Tickets64 (stub) VALUES ('a');
SELECT LAST_INSERT_ID();

  另外为了防止这个Ticket Server单点故障,可以设置两个Ticket Server实例。其中一个产生奇数ID,另一个产生偶数ID。

TicketServer1:
auto-increment-increment = 2
auto-increment-offset = 1
TicketServer2:
auto-increment-increment = 2
auto-increment-offset = 2

  应用交替请求两个Server,这样不仅压力减小一半,故障风险也降低一半。不过这里也有个问题,就是当一台机器故障时,另一台正常机器产生的ID将会领先故障机器一截,可能会造成不再是时间上有序的ID。按照Flickr的说法,这并不影响他们的应用。

Instagram采用的方式(UUID方式)
  Instagram要将其中存储的图片分片到多个PostgreSQL中,其中生成ID的方案和MongoDB ObjectID类似。整个ID的长度为64Bits,设定为这个长度是为了优化在redis中的存储。ID的编码格式如下:


  • 41bits以微秒为单位的timestamp,时间起点从2011-01-01开始。
  • 13bits表示进行逻辑分片的Shard ID。
  • 10bits表示一个累加计数器。
  ID的生成逻辑用PL/PGSQL语言写到PostgreSQL数据库中,当每次插入数据时由数据库自动计算生成。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-303846-1-1.html 上篇帖子: 【原创】hadoop集群监控工具ambari安装 下篇帖子: 四种mysql可视化操作工具的对比
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表