网站开发合同模板下载,WORDPRESS 土木坛子,音乐中文网站模板下载,如何做seo一、概述
背景#xff1a;随着数据库数据量的增长, 基于性能原因需要进行分库分表#xff0c;分库分表会导致主键ID重复问题。 特点#xff1a; 全局唯一性[必须];趋势递增[非必须]。由于互联网大部分采用Mysql的Innodb引擎,因此保持有序主键ID有利于insert的效率;单调递增…一、概述
背景随着数据库数据量的增长, 基于性能原因需要进行分库分表分库分表会导致主键ID重复问题。 特点 全局唯一性[必须];趋势递增[非必须]。由于互联网大部分采用Mysql的Innodb引擎,因此保持有序主键ID有利于insert的效率;单调递增[非必须]。保证下一个ID大于上一个ID可以保证事务版本号,排序等特殊场景需求信息安全[非必须]。如果ID是连续的容易被爬虫爬取数据。 二、实现方案
2.1 Java原生UUID
Universally Unique Identifie通用唯一标识码的简称。为了保证唯一性通用UUID规范使用MAC地址、时间戳、名字空间以及随机数等元素保证UUID的唯一性。UUID通常由32个16进制数字以-分成5段形式为8-4-4-4-12因此UUID理论上总数为16^32个。 优点性能非常高本地生成不依赖网络 缺点ID是随机生成的不连续的影响性能。
2.2 自增ID 步长
利用数据库自增主键不同机器设置不同步长步长和机器数相同(参考主键生成策略)。 优点满足全局ID唯一性,同时利用了数据库自增主键ID提高了性能 缺点 只能趋势递增无法保证单调递增机器数是固定死的一旦需要扩容那么需要重新设置步长。 2.3 号段模式
从数据库中获取一个号段范围比如说[1,1000]生成1到1000的自增ID加载到内存中。需要额外设置一张表记录号段相关的信息。 优点由比较成熟的方案。类似于百度Uidgenerator美团Leaf 缺点依赖于数据库实现。
2.4 Redis实现
通过INCR和INCRBY类似的自增原子命令由于Redis单线程特点可以保证ID的唯一性和有序性。 优点Redis性能比较好且可以保持唯一性和有序性 缺点 在并发请求高的情况下需要Redis集群部署这就要求和Mysql类似设置步长;需要依赖Redis实现引入Redis组件 2.5 雪花算法(SnowFlake)
前言是Twitter开源的由64位整数组成分布式ID性能较高并且在单机上递增。 雪花算法总共64位具体信息为 1bit是符号位始终是0表示为正数;41bit是时间戳单位位毫秒。41位的二进制可以使用69年且时间是永恒递增的所以ID总趋势是递增的10bit是机器标识。可以全部当作机器ID也可以标识【机房ID 机器ID】最多可以表示位1024台机器12bit是计数序列号即在同一台机器同一时间前提下还可以生成不同的ID12bit理论上可以生成4096个ID。 优化点1 由于41位是时间戳我们的时间计算是从1970年开始的只能使用69年。因此可以考虑将1970修改为项目上线时间为了不浪费其实我们可以用【时间的相对值】也就是以项目开始的时间为基准时间往后可以使用69年。获取唯一ID的服务对处理速度要求比较高所以我们全部使用【位运算以及位移】操作获取当前时间可以使用System.currentTimeMillis()。 优化点2时间回拨问题 什么是时间回拨问题呢就是服务器上的时间突然倒退到之前的时间。 人为原因把系统环境的时间改了。有时候不同的机器上需要同步时间可能不同机器之间存在误差那么可能会出现时间回拨问题。 解决方案 回拨时间小的时候不生成 ID循环等待到时间点到达;如果间隔过大阻塞等待肯定是不可取的因此要么超过一定大小的回拨直接报错拒绝服务或者有一种方案是利用拓展位回拨之后在拓展位上加1就可以了这样ID依然可以保持唯一。但是这个要求我们提前预留出位数要么从机器id中要么从序列号中腾出一定的位在时间回拨的时候这个位置1 优点
1. 保证了全局唯一且在单机器上趋势是递增的并发场景下性能依然优异
2. 可根据自身业务特性分配bit位比较灵活。缺点
1. 强依赖时钟
2. 分布式下虽然趋势递增但不是单调递增的三、总结
最佳实践一般来说继续采用Mysql的主键ID当作逻辑主键ID没任何含义使用分布式全局ID当做业务主键ID定义为no_null和unique。