zoukankan      html  css  js  c++  java
  • 【分布式】分布式ID生成算法

    在应用程序中,经常需要全局唯一的ID作为数据库主键。如何生成全局唯一ID?

      首先,需要确定全局唯一ID是整型还是字符串?如果是字符串,那么现有的UUID就完全满足需求,不需要额外的工作。缺点是字符串作为ID占用空间大,索引效率比整型低。

    如果采用整型作为ID,那么首先排除掉32位int类型,因为范围太小,必须使用64位long型。

    采用整型作为ID时,如何生成自增、全局唯一且不重复的ID?

    方案一:数据库的自增ID或者sequence序列,从1开始基本可以做到连续递增。Oracle可以用SEQUENCE,MySQL可以用主键的AUTO_INCREMENT,虽然不能保证全局唯一,但每个表唯一,也基本满足需求。

      数据库自增ID的缺点是数据在插入前,无法获得ID。数据在插入后,获取的ID虽然是唯一的,但一定要等到事务提交后,ID才算是有效的。有些双向引用的数据,不得不插入后再做一次更新,比较麻烦。

    方案二:采用第三方集中式ID生成器,比如Redis,可以是ZooKeeper,也可以利用数据库的表记录最后分配的ID。

        Redis的所有命令操作都是单线程的,本身提供像 incr 和 increby 这样的自增原子命令,所以能保证生成的 ID 肯定是唯一有序的。但这种方式最大的缺点是复杂性太高,需要严重依赖第三方服务,而且代码配置繁琐。一般来说,方案越是复杂的,越不可靠越难以控制并且测试比较痛苦。

    方案三:SnowFlake雪花算法。

        SnowFlake算法是Twitter设计的一个可以在分布式系统中生成唯一的ID的算法,它可以满足每秒上万条消息ID分配的请求,这些消息ID是唯一的且有大致的递增顺序,并且可以运行在符合分布式环境中。

        工作原理:

          SnowFlake算法产生的ID是一个64位的整型,结构组成部分(每一部分用“-”符号分隔),为什么不采用32位int类型呢,因为范围太小,必须使用64位long型。

          

          1. 第1部份只占1位,是最高位,正数是0,负数是1,一般生成的ID为正数,所以为0。

          2. 第2部份是时间戳,占41位【为什么是41位,后面会介绍】,最多可以表示2^41,大约是69年

          3. 第3部份是产生的机器号,占10位【也可以是其它位数,不一定非得是10位,官方约定是10位】,最多可以表示2^10,相当于1024台机器,这部分可以划成两个维度。

          4. 拿5位出来做为机房号,最多可以表示 2^5个机房号,也就是最多32个机房编号 - 3.2 拿5位出来做为机器号,最多可以表示 2^5台电脑,也就是最多32台电脑编号

          5. 最后一部份是时间戳,占12位,相当于在同一个毫秒内,可以最大支持2^12,也就是4096个序号,这个数一般计算机也达不到。

        美团点评分布式ID生成系统Leaf:https://tech.meituan.com/2017/04/21/mt-leaf.html

          Twitter的分布式自增ID算法snowflake:https://www.cnblogs.com/relucent/p/4955340.html

     
  • 相关阅读:
    ln 硬链接与软链接
    Fujitsu存储多路径管理
    Ansible 模块详解
    思科光纤交换机9124管理手册
    Fujitsu DX100S3配置方案
    富士通存储的TPP池和SDPV池
    Solaris 10 ZFS文件系统挂载
    经分测试M5000重启进入维护模式
    finally在return之后还是之前运行
    gradle构建
  • 原文地址:https://www.cnblogs.com/songgj/p/9367766.html
Copyright © 2011-2022 走看看