互联网的分布式ID的示例分析

  介绍

本篇文章为大家展示了互联网的分布式ID的示例分析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

ID是数据的唯一标识,传统的做法是利用UUID和数据库的自增ID,在互联网企业中,大部分公司使用的都是Mysql,并且因为需要事务支持,所以通常会使用Innodb存储引擎,UUID太长以及无序,所以并不适合在Innodb中来作为主键,自增ID比较合适,但是随着公司的业务发展,数据量将越来越大,需要对数据进行分表,而分表后,每个表中的数据都会按自己的节奏进行自增,很有可能出现ID冲突。这时就需要一个单独的机制来负责生成唯一ID、生成出来的身份证也可以叫做<强>分布式ID 强,或<强>全局ID 强。下面来分析各个生成分布式ID的机制。互联网的分布式ID的示例分析”>这篇文章并不会分析的特别详细,主要是做一些总结,以后再出一些详细某个方案的文章。</p> <h3>数据库自增ID </h3> <p>第一种方案仍然还是基于数据库的自增ID,需要单独使用一个数据库实例,在这个实例中新建一个单独的表:</p> <p>表结构如下:</p> <pre> CREATE  DATABASE “SEQID”;
  
  CREATE  TABLE  SEQID.SEQUENCE_ID  (
  id 长整型数字(20),unsigned  NOT  NULL  auto_increment,,
  stub  char (10), NOT  NULL  default  & # 39; & # 39;
  PRIMARY  KEY  (id),
  UNIQUE  KEY  stub (存根)
  以前),引擎=MyISAM; </> <p>可以使用下面的语句生成并获取到一个自增ID </p> <>前开始;
  replace  into  SEQUENCE_ID (存根),VALUES  (& # 39; anyword& # 39;);
  select  last_insert_id ();
  之前提交;</> <p>存根字段在这里并没有什么特殊的意义,只是为了方便的去插入数据,只有能插入数据才能产生自增id。而对于插入我们用的是替换,替换会先看是否存在存根指定值一样的数据,如果存在则先删除再插入,如果不存在则直接插入。</p> <p>这种生成分布式id的机制,需要一个单独的Mysql实例,虽然可行,但是基于性能与可靠性来考虑的话都不够,<强>业务系统每次需要一个id时,都需要请求数据库获取,性能低,并且如果此数据库实例下线了,那么将影响所有的业务系统。</强> </p> <p>为了解决数据库可靠性问题,我们可以使用第二种分布式id生成方案。</p> <h3>数据库多主模式</h3> <p>如果我们两个数据库组成一个<强>主从模式</强>集群,正常情况下可以解决数据库可靠性问题,但是如果主库挂掉后,数据没有及时同步到从库,这个时候会出现id重复的现象。我们可以使用<强>双主模式</强>集群,也就是两个Mysql实例都能单独的生产自增id,这样能够提高效率,但是如果不经过其他改造的话,这两个Mysql实例很可能会生成同样的id。需要单独给每个Mysql实例配置不同的起始值和自增步长。</p> <p>第一台Mysql实例配置:</p> <pre> set  @@auto_increment_offset =, 1,,,,,,,,起始值
  set  @@auto_increment_increment&nbsp=, 2,,,,,步长</pre> <p>第二台Mysql实例配置:</p> <pre> set  @@auto_increment_offset =, 2,,,,,,,,起始值
  set  @@auto_increment_increment&nbsp=, 2,,,,,步长</pre> <p>经过上面的配置后,这两个Mysql实例生成的id序列如下:mysql1,起始值为1,步长为2,id生成的序列为:1,3,5,7,9,……mysql2,起始值为2,步长为2,ID生成的序列为:2,4,6,8,10,……</p> <p>对于这种生成分布式ID的方案,需要单独新增一个生成分布式ID应用,比如DistributIdService,该应用提供一个接口供业务应用获取ID、业务应用需要一个ID时,通过rpc的方式请求DistributIdService, DistributIdService随机去上面的两个Mysql实例中去获取ID。</p> <p>实行这种方案后,就算其中某一台Mysql实例下线了,也不会影响DistributIdService, DistributIdService仍然可以利用另外一台Mysql来生成ID。</p> <p>但是这种方案的扩展性不太好,如果两台Mysql实例不够用,需要新增Mysql实例来提高性能时,这时就会比较麻烦。</p> <p>现在如果要新增一个实例mysql3,要怎么操作呢?第一,mysql1, mysql2的步长肯定都要修改为3,而且只能是人工去修改,这是需要时间的第。二,因为mysql1和mysql2是不停在自增的,对于mysql3的起始值我们可能要定得大一点,以给充分的时间去修改mysql1, mysql2的步长。第三,在修改步长的时候很可能会出现重复ID,要解决这个问题,可能需要停机才行。</p> <p>为了解决上面的问题,以及能够进一步提高DistributIdService的性能,如果使用第三种生成分布式ID机制。<h2 class=互联网的分布式ID的示例分析