当前位置: 首页 > 后端技术 > Java

分布式ID详解(5分布式ID生成方案)

时间:2023-04-02 00:37:47 Java

分布式架构会涉及分布式全局唯一ID的生成。今天详细讲解一下分布式全局唯一ID以及分布式全局唯一ID的实现方案@mikechen什么是分布式系统的唯一ID在复杂的分布式系统中,往往需要对大量的数据进行唯一标识,并且消息。比如在金融、电商、支付等产品系统中,数据都在与日俱增。数据分库分表后,需要一个唯一的ID来标识一条数据或一条消息。显然,数据库的自增ID不能满足需求。这时候一个能够生成全球唯一ID的系统就必不可少了。分布式系统唯一ID的特点全局唯一:不能出现重复的ID号。既然是唯一标识,这是最基本的要求。增加趋势:聚簇索引用于MySQLInnoDB引擎。由于大多数RDBMS使用B-tree数据结构来存储索引数据,因此我们在选择主键时应尽量使用有序的主键来保证写入性能。单调递增:保证下一个ID必须大于上一个ID,比如交易版本号、IM增量消息、排序等特殊需求。信息安全:如果ID是连续的,很容易被恶意用户窃取作品,直接按顺序下载指定的URL即可;如果是订单号,那就更危险了,竞争对手可以直接知道我们每天的订单量。因此,在一些应用场景中,需要ID是不规则的,不规则的。同时,除了对身份证号码本身的要求外,业务对身份证号码生成系统的可用性也有极高的要求。想象一下,如果身份证号码生成系统瘫痪,将带来一场灾难。由此总结出下一代ID生成系统应该做到以下几点:平均时延和TP999时延尽可能低;可用性是5个九;高QPS\分布式系统唯一ID实现方案1.UUIDUUID(UniversallyUniqueIdentifier)标准形式包含32个16进制数字,用连字符分成5段,36个字符,形式为8-4-4-4-12,例子:550e8400-e29b-41d4-a716-446655440000,到目前为止业界有五种生成UUID的方法。具体参见IETF发布的UUID规范AUniversallyUniqueIDentifier(UUID)URNNamespace。UUID的优点:非常高性能:本地生成,无网络消耗。UUID的缺点:不易存储:UUID太长,16字节128位,通常用36位长度的字符串表示,很多场景不适用;信息不安全:基于MAC地址生成UUID的算法可能会导致MAC地址泄露,该漏洞曾被用于寻找Melissa病毒创建者的位置;当使用ID作为主键时,在特定环境下会出现一些问题。比如在使用DB主键的场景下,UUID就很不适用。\2。数据库生成的ID以MySQL为例。为字段设置auto_increment_increment和auto_increment_offset,保证ID自增。各业务使用如下SQL读写MySQL获取身份证号。数据库生成ID的优点:非常简单,利用现有数据库系统的功能实现,成本低,DBA专业维护。ID号单调递增,可以实现一些对ID有特殊要求的业务。数据库ID生成的缺点:对DB的依赖性强,当DB出现异常时,整个系统不可用,这是一个致命的问题。配置主从复制可以尽可能的提高可用性,但是在特殊情况下数据的一致性很难保证。主从切换时不一致可能会导致重复编号。ID发行的性能瓶颈仅限于单个MySQL的读写性能。\3。Redis生成ID当使用数据库生成ID性能不够时,我们可以尝试使用Redis生成ID。这个主要是依赖Redis是单线程的,所以也可以用来生成全局唯一的ID。可以用Redis原子操作INCR和INCRBY来实现。每天用Redis生成从0开始的序号比较合适。比如订单号=日期+当天的自增号。每天可以在Redis中生成一个Key,使用INCR累积。RedisID生成的优点:1)不依赖于数据库,灵活方便,性能优于数据库。2)数字身份证是自然排序的,这对于分页或者需要排序的结果很有帮助。\RedisID生成缺点:1)如果系统中没有Redis,需要引入新的组件,增加系统的复杂度。2)编码和配置的工作量比较大。4.使用zookeeper生成唯一ID。Zookeeper主要通过其znode数据版本生成序号。它可以生成32位和64位数据版本号。客户端可以使用这个版本号作为唯一的序列号。Zookeeper很少用于生成唯一ID。主要是需要依赖zookeeper,需要分步调用API。如果竞争比较多,就需要考虑使用分布式锁。因此在高并发的分布式环境下性能并不理想。5.雪花雪花算法生成ID。该方案大致是一种通过划分命名空间生成ID的算法(UUID也算在内,因为比较常用,所以单独分析)。该方案将64-bits分别分成多个段来标记机器、时间等,例如snowflake中的64-bit表示如下图(图片来自网络):41-bittime可以表示(1L<<41)/(1000L360024*365)=69年,10位机器分别可以表示1024台机器。如果我们有IDC划分的需求,我们也可以将10bit划分为IDC划分为5bit,工作机划分为5bit。这样就可以表示32个IDC,每个IDC可以有32台机器,可以根据自己的需要来定义。12个自增序列号可以代表2^12个ID。理论上,雪花方案的QPS约为409.6w/s。这种分发方式可以保证任何一个IDC中任何一台机器在任何毫秒内生成的任何ID都是不同的。雪花算法ID的优点:毫秒数在高位,自增序列在低位,整个ID趋于递增。不依赖数据库等第三方系统,以服务形式部署,稳定性更高,生成ID的性能更高。比特可以根据自己的业务特点进行分配,非常灵活。雪花算法ID的缺点:对机器时钟依赖性强,如果拨回机器时钟,会导致重复发号或服务不可用。以上作者简介陈睿|mikechen,10年+大厂架构经验,《BAT架构技术500期》系列文章作者,专注于互联网架构技术。更多技术文章看mikechen的互联网架构合集JavaConcurrency|JVM|MySQL|Spring|Redis|Distributed|HighConcurrency