部门网站建设怎么做,php网站怎么搭建环境配置,常用网站开发技术,自己做鲜花网站怎么样什么是分布式 ID
分布式 ID 是指#xff0c;在分布式环境下可用于对数据进行标识且易存储的全局唯一的 ID 标识。 为什么需要分布式 ID
对于单体系统来说#xff0c;主键ID可能会常用主键自动的方式进行设置#xff0c;这种ID生成方法在单体项目是可行的。
对于分布式系统…什么是分布式 ID
分布式 ID 是指在分布式环境下可用于对数据进行标识且易存储的全局唯一的 ID 标识。 为什么需要分布式 ID
对于单体系统来说主键ID可能会常用主键自动的方式进行设置这种ID生成方法在单体项目是可行的。
对于分布式系统分库分表之后就不适应了比如订单表数据量太大了分成了多个库如果还采用数据库主键自增的方式就会出现在不同库或表中id一致的情况。 分布式 ID 需要满足的条件
分布式 ID 是我们在非常多的场景下用到的组件对其要求比较高其一般需要满足以下条件
全局唯一性ID是作为唯一的标识不能出现重复高性能高可用低延时ID 生成速度要快否则反倒会成为业务瓶颈高可用尽量保证服务的可用性多实例化避免因一个实例挂掉影响整个业务应用的运行容易接入要秉着拿来即用的设计原则在系统设计和实现上要尽可能的简单避免增加开发人员的使用成本趋势递增互联网比较喜欢MySQL数据库而MySQL数据库默认使用InnoDB存储引擎其使用的是聚集索引使用有序的主键ID有利于保证写入的效率单调递增保证下一个ID大于上一个ID这种情况可以保证事务版本号排序等特殊需求实现信息安全前面说了ID要递增但是最好不要连续如果ID是连续的容易被恶意爬取数据指定一系列连续的所以ID递增但是不规则是最好的常用分布式 ID 生成方案
下面列出的这几种方案都是生成 ID 的常用方法
使用 UUID 生成 ID使用数据库自增生成 ID使用数据库号段模式生成 ID使用 Redis 实现生成 ID使用 Zookeeper 生成 ID根据雪花算法Snowflake算法生成 ID百度Uidgenerator美团Leaf滴滴TinyID使用 UUID 生成 ID
UUID 是通用唯一识别码的缩写Universally Unique Identifier。UUID 一般是由一组 32 位数的 16 进制数字所构成以连字号分为五段形式为8-4-4-4-12的36个字符常包含时间戳和 MAC 地址信息这些元素标准的 UUID 格式为
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 优点
高性能实现简单不需要第数据库等第三方组件依赖
缺点
并不是趋势递增不方便排序生成的 ID 只能用字符串类型存储占用空间大生成的串没有规律出问题时不易根据 ID 进行排查使用数据库自增生成 ID
在分布式系统中我们可以多部署几台机器每台机器设置不同的初始值且步长和机器数相等。比如有两台机器设置步长step为2Server1的初始值为11357911…、Server2的初始值为2246810…。
这种方案看起来是可行的但是如果要扩容步长step等要重新设置假如只有一台机器步长就是1比如1,2,3,4,5,6这时候如果要进行扩容就要重新设置机器2可以挑一个偶数的数字这个数字在扩容时间内数据库自增要达不到这个数的然后步长就是2机器1要重新设置step为2然后还是以一个奇数开始进行自增。这个过程看起来不是很杂但是如果机器很多的话那就要花很多时间去维护重新设置。
优点
实现简单趋势递增
缺点
ID没有了单调递增的特性只能趋势递增有些业务场景可能不符合数据库压力还是比较大每次获取ID都需要读取数据库只能通过多台机器提高稳定性和性能水平扩展比较麻烦需要手动调整集群数据库中的初始值与步长使用数据库号段模式生成 ID
这种模式也是现在生成分布式ID的一种方法在使用号码模式时我们通常会先建立一张表用于记录上述的 ID 号段范围一般表内容如下
CREATE TABLE id_generator (id int(10) NOT NULL AUTO_INCREMENT,max_id bigint(20) NOT NULL COMMENT 当前最大id,step int(20) NOT NULL COMMENT 号段的布长,biz_type int(20) NOT NULL COMMENT 业务类型,version int(20) NOT NULL COMMENT 版本号,PRIMARY KEY (id)
)
每次从数据库中获取号段 ID 的范围时都会执行更新语句其中计算新号段范围最大值 max_id 的公式是 max_id step 组成所以 SQL 中设置 max_id max_idstep 来执行更新语句更新数据库中这个范围最大值 max_id然后再通过查询语句查询更新后 ID 最大值再根据最大值 max_id 与步长 step 计算出待生成的 ID 的范围其中操作的 SQL 如下
update id_generator set max_id #{max_idstep}, version version 1 where version # {version} and biz_type #{biz_type};SELECT max_id, step, version FROM myid WHERE biz_type #{biz_type};
优点
使用缓存机制容灾性高即使数据库不可用还能撑一段时间。可以自定义每次扩展的大小控制 ID 生成速度可以设置生成 ID 的初始范围方便业务从原有的 ID 方式上迁移过来。有比较成熟的方案像百度Uidgenerator美团Leaf
缺点
依赖于数据库实现数据库宕机会造成整个系统不可用。ID 号码不够随机可能够泄露发号数量的信息不太安全。 使用 Redis 实现生成 ID
Redis分布式ID实现主要是通过提供像 INCR 和 INCRBY 这样的自增原子命令由于Redis单线程的特点可以保证ID的唯一性和有序性。
优点
实现简单有序递增方便排序
缺点
强依赖于 Redis可能存在单点问题如果 Redis 超时可能会对业务造成影响占用宽带而且需要考虑网络延时等问题带来地性能冲击。使用 Zookeeper 生成 ID
在 Zookeeper 中主要通过节点数据版本号来生成序列号可以生成 32 位和 64 位的数据版本号客户端可以使用这个版本号来作为唯一的序列号。在 Zookeeper 中本身就是支持集群模式所以能保证高可用性且生成的 ID 为趋势递增且有序不过在实际使用中很少用 Zookeeper 来充当 ID 生成器因为 Zookeeper 中存在强一致性在高并发场景下其性能可能很难满足需求。 不过由于使用 Zookeeper 节点的版本号来充当 ID 号是比较繁琐需要创建节点获取生成的 ID然后去掉节点命令前缀只截取数字部分最后还要异步执行删除节点启动新的线程执行删除节点操作防止占用生成ID线程执行的实际。过程比较耗时且繁琐所以在操作 Zookeeper 时经经常不会采用该方案常使用 Curator 客户端提供的基于乐观锁的计数器来自增实现 ID 生成这个过程和数据库自增生成 ID 类似。
优点
高可用趋势递增
缺点
性能差定期删除之前生成的节点比较繁琐根据雪花算法Snowflake算法生成 ID
Snowflake雪花算法是由 Twitter 开源的分布式ID生成算法以划分命名空间的方式将 64-bit位分割成多个部分每个部分代表不同的含义64位在java中Long类型是64位的所以java程序中一般使用Long类型存储 其结构组成
第一部分第一位占用1bit始终是0是一个符号位不使用第二部分第2位开始的41位是时间戳。41-bit位可表示241个数每个数代表毫秒那么雪花算法可用的时间年限是(241)/(1000606024365)69 年的时间第三部分10-bit位可表示机器数即2^10 1024台机器。通常不会部署这么多台机器第四部分12-bit位是自增序列可表示2^12 4096个数。觉得一毫秒个数不够用也可以调大点
优点
高性能趋势递增可以灵活调整结构不需要第数据库等第三方组件依赖
缺点
强依赖时钟可能发生时钟回拨导致生成的 ID 重复百度 Uidgenerator
百度的 UidGenerator 是百度开源基于Java语言实现的唯一ID生成器是在雪花算法 snowflake 的基础上做了一些改进。
详细介绍请看官网。 美团 Leaf
Leaf 提供两种生成的ID的方式号段模式(Leaf-segment)和 snowflake 模式(Leaf-snowflake。你可以同时开启两种方式也可以指定开启某种方式默认两种方式为关闭状态。
详细介绍请看官网。 滴滴 TinyID
Tinyid 是用Java开发的一款分布式id生成系统基于数据库号段算法实现。Tinyid 扩展了 leaf-segment 算法支持了多数据库和 tinyid-client。
详细介绍请看官网。 参考
SmileNicky的博客
myf008的博客