分库分表下ID如何设计??

2024-09-14 15:54:12 浏览数 (3)

根据时间/id对数据库数量取模

例如数据库有一条数据生成的时间为2024年9月12日 , 数据库有三个 , 每个数据库中数据表也有三个, 那么这条数据应该放在第三个数据库(2024 % 3 = 2)中的第一个表(12 % 3 = 0)中

这种方式实现简单,但是如果以后数据量继续增长,需要新增新的数据库和数据表的话那么数据扩容将会很复杂,以及如果某年或者某月行情好数据量明显比其他年份或月份多 , 那么会造成数据分布不均 , 导致负载不均衡以及性能下降

基因法

基因法常用于分表 , 例如传过来一个用户id为189,那么对应的基因法的步骤就是

  1. 将用户id转换为二进制为: 10111101
  2. 假如每个库中表的数量为2^n. 那么取id对应二进制的后n位为要插入的表 , 例如假如我数据库中有16张表 , 那么我应该取后四位作为我判断要插入哪个表中的依据

如果还想有其他业务上的优化 , 比如查询的时候不仅能根据用户id查询还能根据订单查用户 , 那么可以将后四位1101取代订单号(如果用雪花算法生成)的后四位再保存即可 , 要知道mysql跨库跨表查询的性能损耗是很大的

这种方法同样扩容难,并且要求表的数量为2^n方 , 但是查询速度快 , 可以避免查多表 , 另外分布式id生成方法大部分人可能都会选择雪花算法 , 但是当雪花算法作为我们的订单id时 , 极端条件下如果同一机器在一毫秒内生成id那么仍然会造成id重复 , 应为雪花算法的后四位被我们的基因所替代了, 实际上同一个用户的订单号后四位都是一样的 , uuid得128位才嗯那个保证不重复 , 64位的雪花更不用说

那么我们如何解决雪花算法拼接上基因后重复的问题?只需要在雪花算法中添加配置即可

雪花算法的格式如下,其中工作机器ID又分为5位数据中心(机房),5位机器id,也就是对应服务器

我们将12位的序列号前五位做为累加位 , 后7位用于基因位 , 基因位相比大家都知道, 就是我们基因到取代原本雪花的位数,是我们自己添加上去的, 那么累加位又是什么呢? 累加位在雪花算法中的作用是, 但同一时间戳内需要生成多个ID时, 累加位就会递增,如果一旦达到最大值,例如累加位为5如果同一时间戳内同一机房的同一机器要生成33的id, 那么必定会有一个与另外的32个重复, 可以看到累加位和我们生成ID的并发量有关, 因此我们要根据实际情况来设计机器 bit、累加位、用户基因位的大小

一致性Hash

什么是一致性Hash, 一致性Hash为了解决分布式系统中扩容或者缩容节点时造成大量数据迁移的问题 , 肥肠方便增删节点 , 我们先来看看一致性Hash是怎么存值的, 应该有很多人知道一致性Hash可以用于redis, 但是其实还能用于分库分表,下面我们来看看一致性Hash用于分库分表的优缺点

缺点:

由于数据都是随机离散分布到各个表或者库中,如果需要查某个用户下的所有订单时需要扫描所有表

优点:

数据散列均匀,扩容的时候只会影响扩容节点的下一个节点,其他节点的数据正常查询

  1. 首先有一个闭合圆, 范围一般为0-2^32, 占四字节, 所有节点存储的数据是不一样的, 首先对节点进行Hash, 将这个节点存在对应Hash上
  2. 之后将要存储的key进行Hash, 然后将其值要分布在这个闭合圆上
  3. 之后顺时针遍历这个圆环, 找到这个的一第一个节点就是这个key要存的位置

再举个李子, 我有一个闹钟, 其中 1 点 为节点, 我有一个数据经过计算Hash落在了2-3点的区间上, 我顺时针遍历查找节点, 发现到12点都还没有找到, 我继续顺时针遍历, 找了1点, 那么我的数据就会存在一点上

删除节点所带来的问题

下图中,我删除了node2节点, 那么原本存node2节点的数据就会跑到node4节点, 如果node4没抗住,那么就会导致所有数据跑到node3,如此循环, 可能导致所有节点崩溃, 出现雪崩情况

数据顷斜问题

节点太少, 可能造成数据倾斜, 一致性哈希算法虽然减少了数据迁移量,但是存在节点分布不均匀的问题

虚拟节点解决数据分布不均问题与雪崩问题

可以知道节点过少是导致问题出现的原因, 因此只要我们节点越多, 那么数据就会越趋于均匀, 实现起来也很简单, 就是多了一个虚拟节点和真实节点的映射, 比如我的node1映射one_1,one_2,one_3节点, node2映射two_1, two_2节点, 那么我们在插入的时候, 一个数据要插入到one_1节点, 那么我们根据虚拟节点找真实节点, 找到对应的真实节点为node1,那么我们就将其插入node1节点值得注意的是我们的虚拟节点数,可以根据节点的性能来进行动态设置,性能好的节点可以多设置点虚拟节点, 能者多生的感觉有木有

那么虚拟节点又是如何解决雪崩问题的呢,如下图节点real1节点又俩个虚拟节点v100和v101,real2有俩个虚拟节点v200和v201,real3节点有v300和v301俩个虚拟节点。如果节点1崩了的话那么对应的虚拟节点V100和V101都会崩, 那么如果V100的数据跑到节点3, V101的数据跑到V200, 这就是虚拟节点的好处如果

0 人点赞