shardingjdbc分库分表数据均衡性讨论

news2024/11/25 3:04:46

问题引入

最近一个业务系统中,因为数据量很大,经过技术选型,综合权衡选择了sharding-Jdbc,本文主要讨论的是分库分表的表达式

我们有一个批次总表A,还有一个明细表B,我们需要对明细表B进行水平拆分,考虑系统数据的可扩展性和mysql的负载,我们打算针对B表进行分表,分4个数据库,每个数据库64张表,使用A表的主键批次id【fnQpid】来作为分片键。

问题演进

第一版本

一开始选用了一个最简单的hash路由策略,如下:

分库策略为

fnQpid % 4

分表策略为

fnQpid % 64

乍一看,没啥问题,仔细琢磨后发现了一个问题,这样分会导致数据分布不均衡,为啥会导致数据不均衡呢?

假设某一个fnQpid的数据分在了0库的1分表,那么这个fnQpid需要满足什么条件呢?

第一,分在了0库需要满足,fnQpid=4m 【m为整数】 ====》可以推测出fnQpid为偶数

第二,分在1分表需要满足,fnQpid=64n+1 【n为整数】====》可以推测出fnQpid为奇数

毫无疑问,这样的fnQpid是不存在的,也就是某一个fnQpid的数据分在了0库的1分表这个假设不成立,也就是这样分库分表会导致数据分布不均衡。

第二版本

发现上面的问题后,优化了一版分库分表的算法

分库策略

(fnQpid % 256)/64

分表策略

(fnQpid % 256) % 64

简单介绍一下这个方案的思路

  • 先计算总的逻辑表的数量,也就是4*64=256
  • 然后计算fnQpid % 256的值,这个值的范围是[0,255],把这256个数据当成是一个整体来看,计算其所在的数据库(fnQpid % 256)/64,该值的范围是[0,3]
  • 最后计算所在分表(fnQpid % 256) % 64,该值的数据范围是[0,63]

按照这样的分库分表方式,不会出现第一种情况(有些表永远不会有数据出现),但是这样的路由策略有一个美中不足,如图

当批次号连续自增的时候,明细表的数据分布是这样的,前256个批次的数据在0库,接着在1库,接着在2库,最后在3库,再接着又回到0库,如此循环往复。

若每个批次有1000条数据,那么在短时间内,就会有256000的数据落在同一个数据库,这个瞬时数据的写入、查询都是一个不小的压力。可以说这个方案,数据物理上是分布均衡的,但是在短时间内,mysql单个数据库的负载是不均衡的。

第三版本

考虑到上面两种问题后,继续优化

分库策略为

fnQpid % 4

分表策略为

(fnQpid >> 2) % 64

简单介绍下这个方案
这个方案是在方案一的基础上,进行了分表策略的优化。
一开始是直接用fnQpid % 64,这样有问题是fnQpid的最后两位二进制已经参与了数据库(fnQpid % 4)的计算了,再参与分表的计算,就会互相影响。新的方案是,先踢掉最后两位二进制(fnQpid >> 2),再参与分表计算,数据流入如下图

可以看到,数据是按照顺序从0库到3库先填充满所有的0表,接着填充满所有的1表…,填充所有的63表,再填充满所有的0表,如此循环往复。当瞬时间有大量数据写入的时候,数据是分散在不同的数据库的,因此解决了方案二(数据库负载不均衡)的问题了

问题总结

为什么分表的数量是64呢?为什么不是100呢?

针对这个问题,大家可以思考下为什么HashMap的初始容量要设置成16(2的4次幂),redisCluser的哈希槽为什么是16384(2的14次幂)?

我个人认为,是为了提升速度。因为无论是HashMap还是redisCluser,都需要频繁的根据key来计算数组的index,这个操作是hash(key)%16、hash(key)%16384,这样做就差点意思。

看过hashMap源码的同学都知道,源代码上使用了hash(key)&15 来计算index,也就是hash(key)&15等价于hash(key)%16,延展下,

若n为2的整数次幂时 m % n 等价于 m & (n-1)

因此,我们的分库分表为了提速,分表数量选择了2的整数次幂。最终的分库分表的表达式是这样
分库策略为

fnQpid & 3

分表策略为

(fnQpid >> 2) & 63

针对分库分表的策略,大家还遇到过什么坑吗?欢迎评论区留言!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1033789.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文总结《A Closer Look at Few-shot Classification Again》

原文链接 A Closer Look at Few-shot Classification Again 摘要 这篇文章主要探讨了在少样本图像分类问题中,training algorithm 和 adaptation algorithm的相关性问题。给出了training algorithm和adaptation algorithm是完全不想关的,这意味着我们…

瑞芯微RK3568:Debian系统如何安装Docker

本文基于HD-RK3568-IOT评估板演示Debian系统安装Docker,该方法适用于RK356X全系产品。 HD-RK3568-IOT评估板基于HD-RK3568-CORE 工业级核心板设计(双网口、双CAN、5路串口),接口丰富,适用于工业现场应用需求&#xff…

怒刷LeetCode的第13天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一:滑动窗口 方法二:哈希表和双指针 方法三:动态规划 第二题 题目来源 题目内容 解决方法 方法一:深度优先搜索(DFS) 方法二:树结构 …

rv1126-rv1109-RkLunch.sh

RkLunch.sh是个脚本,来自哪里 书接上回:rv1126-rv1109-瑞芯微的 IPC 程序_旋风旋风的博客-CSDN博客 修改之后 屏蔽了两行之后,就没有开机自启rklunch了: # [ -f /oem/RkLunch.sh ] && source /oem/RkLunch.sh 就是运行source /oem/RkLunch.sh 这里就跑了RkL…

基于微信小程序的驾校报名系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境说明用户微信小程序端的主要功能有:驾校教练的主要功能有:管理员的主要功能有:具体实现截图详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考论文参考源码…

动手学深度学习(pytorch版)第二章-2.2数据预处理Note-pandas

1. 创建 import osos.makedirs(os.path.join(.., data), exist_okTrue) data_file os.path.join(.., data, house_tiny.csv) with open(data_file, w) as f:f.write(NumRooms,Alley,Price\n) # 列名f.write(NA,Pave,127500\n) # 每行表示一个数据样本f.write(2,NA,106000\…

平板用的触控笔什么牌子好?性价比高的触控笔推荐

随着平板电脑的普及,越来越多用户为了方便都选择了电容笔,电容笔已经完全代替了我们的手指,并且使我们的书写速度得到了极大的提升。然而,因为其的独特的重力压感功能与芯片技术,导致了原装笔的售价一直居高不下&#…

深入探析NCV7356D1R2G 单线CAN收发器各项参数

NCV7356D1R2G深力科是一款用于单线数据链路的物理层器件,能够使用多种具碰撞分解的载波感测多重存取 (CSMA/CR) 协议运行,如博世控制器区域网络 (CAN) 2.0 版。此串行数据链路网络适用于不需要高速数据的应用,低速数据可在物理介质部件和微处…

用selenium和xpath定位元素并获取属性值以及str字符型转json型

页面html如图所示: 要使用xpath定位这个div元素,并且获取其属性data-config的内容值。 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Optionshost127.0.0.1 port10808 …

线程安全,与多线程的应用

一、线程安全 1.什么是线程安全 2.用程序模拟线程安全问题 public class Account {private double money;//余额private String cardId;//卡号public Account() {}public Account(double money, String cardId) {this.money money;this.cardId cardId;}public void drawMone…

LeetCode 1993. 树上的操作:大模拟

【LetMeFly】1993.树上的操作:大模拟 力扣题目链接:https://leetcode.cn/problems/operations-on-tree/ 给你一棵 n 个节点的树,编号从 0 到 n - 1 ,以父节点数组 parent 的形式给出,其中 parent[i] 是第 i 个节点的…

基于微信小程序的健康评估系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境说明用户微信端的主要功能有:医生微信端的主要功能有:管理员的主要功能有:具体实现截图详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考论文参考源码获取…

iOS17正式版BUG汇总:无法正常拨打电话、小组件不可用、无线充电不可用等问题

今天凌晨 iOS 17 正式版发布,相信不少尝鲜派已经更新体验了iOS17的新功能了,但还有很多用户选择观望看是否要升级,小编汇总了目前已更新的用户反馈的已知BUG,供大家查看是否要更新iOS17正式版! 目前已知BUG&#xff1…

【LeetCode75】第六十二题 多米诺和托米诺平铺

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我一个数字n,表示我们有2*n大小的地板需要铺。 我们拥有两种瓷砖,一种的长度为2的多米诺,另一…

Jetpack Compose干货,如何让Compose Dialog从屏幕任意方向进入

一、前言 来个效果图,基于Compose Dialog,最终要实现的库能力如下: 这里使用的是这个包下面的: androidx.compose.ui.window.Dialog androidx.compose.material3.AlertDialog它内部调用的也是androidx.compose.ui.window.Dialog …

Centos7 安装部署 Kubernetes(k8s) 高可用集群

1:基础环境准备 宿主机系统集群角色服务器IP主机名称容器centos7.6master192.168.2.150ks-m1dockercentos7.6master192.168.2.151ks-n1dockercentos7.6master192.168.2.152ks-n2docker 1.1 服务器初始化及网络配置 VMware安装Centos7并初始化网络使外部可以访问*…

No2.详解【2023年全国大学生数学建模竞赛】C题——蔬菜类商品的自动定价与补货决策(代码 + 详细输出 + 数据集代码 下载)

只有不回避痛苦和迷茫的人,才有资格去谈乐观和坚定。命运不会厚待谁,悲喜也不会单为你准备。 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌿[2] 2023年城市之星领跑者TOP1(哈尔滨)🌿 🌟[3] 2022年度博客之星人工智能…

爬虫获取接口数据

上一讲讲的是获取静态网页数据的教程,适用于我们要爬取的数据在网页源代码中出现,但是还是有很多的数据是源代码中没有的,需要通过接口访问服务器来获得,下面我就来讲讲如何爬取这类数据。 以巨潮资讯网爬取比亚迪企业年报为例。…

解决windows端口占用

WINR打开cmd窗口;输入命令查看哪个进程占用,8848为要查询占用的端口号:netstat -ano | findstr 8848; 3.杀死进程,输入taskkill /f /t /im 10672 其中10672为上面命令查出来的进程号。

24. 图论 - 图的表示种类

Hi,你好。我是茶桁。 之前的一节课中,我们了解了图的来由和构成,简单的理解了一下图的一些相关概念。那么这节课,我们要了解一下图的表示,种类。相应的,我们中间需要穿插一些新的知识点用于更好的去理解图…