分库分表(以MySQL为例说明)



1、为什么要分库?
①减轻磁盘压力
②单库并发连接请求数有限,如果存在过多连接会出现too many connections的问题
2、为什么要分表?
①一般单表数据量超千万很大了,单表数据量过大会出现性能瓶颈,建索引、SQL优化、数据库连接参数优化等也挽救不了单库的压力
非常重要的一点,单表数据过多,树深度就会变深,一般3层的B+树索引就可以承载千万级别的数据了。超5000万数据,B+树深度可能会到4层,B+树越深,查找数据耗时越长。
有个公式可以计算3层B+树可承载的数据。B+树的存放总记录数=根结点指针数*单个叶子节点记录行数
MySQL数据存放是以数据页为单位的,一页16k。假设一行数据为1k,那么单个页子节点就可以存放16k/1k=16个记录数
根节点指针数,非叶子节点存放多少个指针呢?假设使用bigint作为主键,它占用64位,合计8字节。而指针在innodb源码中设置的是6字节,据此可推算出非叶子节点可容纳的指针数:16 * 1024/(8 + 6) ≈ 1170
所以3层B+树的存放总记录数= 16 * 1170 * 1170 = 21902400。超过3层,B+容纳的数据就是个天文数字了。不管怎么优化,都是问题
3、什么时候考虑分库分表?
参考阿里巴巴的《Java开发手册》:
单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。
4、如何选择分表键?
分表键,其实就是参于分库分表的字段。比如订单表可用订单ID作为分表键,用户表可用用户ID作为分表键,员工表可用员工工号作为分表键
分表键的选择要考虑到业务的主题。比如你的数据库表是一张企业的客户信息表,就可考虑用客户号做为分表键。
为什么考虑用客户号做分表键呢?
这是因为表是基于客户信息的,所以,需要保证同一个客户信息的数据,落到一个表中,避免触发全表路由。
5、非分表键如何查询?
分库分表后无法避免一些特殊的业务场景,比如使用非分表键来查询。
比如用户表,使用用户ID分库分表后,需要使用用户手机号登录,这个时候就需要用用户手机号查询用户信息,而手机号是非分表键
解决方案:
①遍历:遍历所有表,找到符合条件的手机号(一般人不会选择这种方案吧)
②数据冗余同步到ES,然后通过ES来 查询
③基因法:非分表键可以拆分出分表键来,比如生成订单号时可以把客户编号保存进去,通过订单号查询时可以解析出客户号。但是前面说的登录场景,手机号冗余用户ID似乎不太友好
6、分表策略选择
①range范围:还是以订单为例,订单表数据量很大,1~300w为一个表,300~600万一张表
优点:扩容简单
缺点:热数据聚集。可能某一段时间数据特别集中,比如双十一、双十二、618大促,订单量远高于平时,仅仅依靠订单ID做范围range分库分表就不太靠谱了
②hash取模:指定的路由key(一般是用户ID、订单ID、客户好作为key)对分表总数进行取模,把数据分散到各个表中。为尽可能分散数据,一般,一般会取哈希值,再做取余:Math.abs(orderId.hashCode()) / tableNumber
③一致性hash:使用hash取模方式,前期如果未做好规划,后期还是需要扩容二次分表,表数量需要增加,所以hash值需要重新计算,这时候就需要迁移数据了。
比如一开始分了10张表,随着业务扩展需要,增加到20张表。那问题随之产生,之前根据订单ID取模10后的数据分散在了各个表中,现在需要重新对所有数据重新取模20来分配数据
为了解决这个扩容迁移问题,可以使用一致性hash思想来解决。一致性哈希:在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表存在的动态伸缩等问题
7、如何避免热数据倾斜?
使用range范围+ hash哈希取模结合的分表策略。
例如双十一大促,订单量陡增,可先对订单ID按范围划分到不同库,然后针对单个库使用range方式将数据分散到不同的分表中
8、分库后事务如何解决?
未分库分表前,单库单表使用本地事务就好了,但是分库分表后,数据落到了不同库表中,传统事务处理方式就不行了,就要用到分布式事务。
分布式事务解决方案:
①2PC
②3PC
③TCC
④本地消息表
⑤seata
⑥saga
⑦最大努力通知
9、跨库join连接问题
分库分表后,数据分散在不同库表中,有时候一个需求需要跨多个库表访问,传统的库表连接就不适用啦
跨库join方案:
①字段冗余:把需要关联的字段放入主表,避免关联操作。例如订单中关联客户号,可将客户姓名冗余到订单表中
②全局表:系统中所有模块都会依赖的表可以在每个库中都保留一份
③数据抽象同步:定时将指定库表做同步,生成新的汇总表。可以借助ETL工具实现
④应用层代码组装:分多次查询不同模块,获取数据后,在应用层做数据过滤
10、order by、group by问题
count、order by、group by等聚合函数在分库分表后,都会面临一样的问题,会基于全部数据进行统计计算。可以先在每个节点得到结果,然后在应用层组装数据
11、分库分表后的分页问题
解决方案:
①全局视野:在每个节点得到结果,然后在应用层组装数据。
优点:业务无侵入,可精准返回所需数据
缺点:查询不需要的数据,加大网络传输压力。
②禁止跳页。类似于ES,数据量过大时,禁止跳页,只有上一页和下一页。分页时,根据时间排序,将最后一条数据的时间传到分页参数里,然后在每个节点查询大于这个时间的数据,然后在业务层面对数据聚合汇总,做内存排序后返回
12、分布式ID选择
①雪花算法(64位)
第一位:符号位(0正数,1负数),ID肯定是要正数,固定0
中间四十一位:给定时间依赖的毫秒值
十位:机器ID,防止冲突
最后十二位:每个机器上生成的ID序列号
②UUID
13、分库分表中间件选择
①sharding-jdbc(用过)
②mycat(用过)
③cobar
④Atlas
⑤TDDL
⑥Vitees
14、垂直分库、垂直分表、水平分库、水平分表
垂直分库:以表为拆分依据,根据表的不同业务归属,划分到不同库
垂直分表:以字段为拆分依据,按照字段活跃性(重要程度)将表的字段拆到不同表中(主表和子表)
水平分库:以字段为拆分依据,按照一定的拆分策略(range、hash),将一个库的数据拆分到多个库
水平分表:以字段为拆分依据,按照一定的拆分策略(range、hash),将一个表的数据,拆分到多个表
15、分库分表完成后,部署是否需要停服?不停服怎么做?
①提供代理层,添加一个开关是访问新的DAO还是旧的DAO,灰度期间,只访问旧的库
②全量发布后,保持双写分库和旧的库,增量新增或更新。用日志或者临时表记录新表ID起始值,旧表中小于这个ID的就是存量数据,需要迁移
③通过脚本,将旧表数据迁移到新表
④停读旧表,改读新表。新表已承载了读写请求,保持新旧表双写一段时间
⑤当读写新表一段时间后,没有问题,就可以直接停掉旧表了

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

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

相关文章

tinymce问题处理

Vite构建工具下Tinymce踩坑指南 解决方案是在路劲前面增加/,这个跟上面链接有些区别,区别原因应该是如果路由采用的是createWebHashHistory则应该去掉/,如果是createWebHistory则应该加上/ 页面引用,一种异步加载,一种同步加载&…

深度学习的启航:从零到一的完全指南

深度学习的启航:从零到一的完全指南 深度学习近年来已成为人工智能领域最耀眼的明星,其在图像识别、自然语言处理、游戏以及无人驾驶等领域取得的进展令人瞩目。如果你对深度学习充满好奇,想要开启一段全新的学习旅程,这篇文章将…

睿易售前初级认证课程R1.0睿网络命名选型-2023练习题答案

1、RG-RAP6260(G)可以用在什么场景下?【多选题】 A、别墅花园 B、冷库 C、大型仓库 D、海边 A B C D 2、AP选型要关注什么?【多选题】 A、使用场景 B、带机量 C、Wi-Fi5还是Wi-Fi6 D、千兆还是百兆 A B C D 3、带机60终端以上的Wi-Fi6千兆吸顶AP选哪款【多选题】 A、…

LeetCode 热题 100 | 二叉树(二)

目录 1 543. 二叉树的直径 2 102. 二叉树的层序遍历 3 108. 将有序数组转换为二叉搜索树 菜鸟做题,语言是 C 1 543. 二叉树的直径 这道题和 124. 二叉树中的最大路径和 太像了 题眼:二叉树的 直径 是指树中任意两个节点之间 最长路径的长度 。…

JS基础(三)-操作和流程控制

一 操作网页元素的步骤 1. 查找网页元素 给标签设置id属性&#xff0c;一个网页中的id值不允许重复 <button id"btn">按钮</button> 2. 给按钮绑定事件&#xff0c;监听用户操作 btn.onclick function(){ 一旦监听到用户的…

人工智能 — 特征选择、特征提取、PCA

目录 一、特征选择1、定义2、原因3、做法4、生成过程5、停止条件 二、特征提取三、PCA 算法1、零均值化&#xff08;中心化&#xff09;2、方差3、协方差4、协方差矩阵5、对协方差矩阵求特征值、特征矩阵6、对特征值进行排序7、评价模型8、代码实现9、sklearn 库10、鸢尾花实例…

【数据结构与算法(Java版)】深度剖析二分查找算法

【二分查找算法】的时间复杂度为O(log n)&#xff0c;其中n为数组的长度。因为每次查找都将查找范围缩小一半&#xff0c;所以算法的时间复杂度是对数级别的。 目录 前言 二分查找算法是什么&#xff1f; 算法实现 方式一&#xff1a;&#xff08;左闭右闭&#xff09; 文…

电机控制常见的外围器件

小型断路器&#xff1a; 这些通通都叫小型断路器&#xff0c;二十年的老电工不一定都认识&#xff0c;不信看看_哔哩哔哩_bilibili 1PIN 2PIN 3PIN 4PIN: 正常情况下火线和零线的电流是相等的&#xff0c;但是漏电的情况下&#xff0c;两线的电流差值大于30毫安&#xff0c;漏…

合纵连横 – 以 Flink 和 Amazon MSK 构建 Amazon DocumentDB 之间的实时数据同步

在大数据时代&#xff0c;实时数据同步已经有很多地方应用&#xff0c;包括从在线数据库构建实时数据仓库&#xff0c;跨区域数据复制。行业落地场景众多&#xff0c;例如&#xff0c;电商 GMV 数据实时统计&#xff0c;用户行为分析&#xff0c;广告投放效果实时追踪&#xff…

笔记本hp6930p安装Android-x86避坑日记

一、序言 农历癸卯年前大扫除&#xff0c;翻出老机hp6930p&#xff0c;闲来无事&#xff0c;便安装Android-x86玩玩&#xff0c;期间多次入坑&#xff0c;随手记之以避坑。 笔记本配置&#xff1a;T9600,4G内存&#xff0c;120G固态160G机械硬盘 二、Android-x86系统简介 官…

2023最新盲盒交友脱单系统源码

源码获取方式 搜一搜&#xff1a;万能工具箱合集 点击资源库直接进去获取源码即可 如果没看到就是待更新&#xff0c;会陆续更新上 或 源码软件库 最新盲盒交友脱单系统源码&#xff0c;纸条广场&#xff0c;单独抽取/连抽/同城抽取/高质量盒子 新增功能包括心动推荐&#xff…

js使用new Image()创建img对象不生效

我在做vue项目的时候&#xff0c;想获取到图片的宽高&#xff0c;然后把宽高发给后端&#xff0c;代码类似是这样的 function getFileData(file: File) {return new Promise(function (resolve, reject) {let reader new FileReader();reader.readAsDataURL(file);reader.onlo…

备考2024年高考全国甲卷文科数学:历年选择题真题练一练

距离2024年高考还有三个多月的时间&#xff0c;最后这个时间&#xff0c;同学们基本上是以刷题为主。刷题的时候最重要的是把往年的真题吃透&#xff0c;因为真题是严格按照考纲出的&#xff0c;掌握了真题后面的知识点&#xff0c;并能举一反三地运用&#xff0c;那么高考的高…

用Python Matplotlib画图导致paper中含有Type-3字体,如何解决?

用Python Matplotlib画图导致paper中含有Type-3字体&#xff0c;如何解决&#xff1f; 在提交ACM或者IEEE论文之前&#xff0c;都会有格式的检查&#xff0c;格式的其中一个要求是paper中不能含有Type-3的字体。因为Type-1和True Type字体都是矢量字体&#xff0c;而Type-3并不…

华为OD机试 - 数字排列(Java JS Python C C++)

题目描述 小明负责公司年会,想出一个趣味游戏: 屏幕给出 1 ~ 9 中任意 4 个不重复的数字,大家以最快时间给出这几个数字可拼成的数字从小到大排列位于第 N 位置的数字,其中 N 为给出数字中最大的(如果不到这么多数字则给出最后一个即可)。 注意: 2 可以当作 5 来使用…

老杨说运维 | 运维大数据价值探索

文末附有视频 伴随第六届双态IT乌镇用户大会的圆满完成&#xff0c;擎创科技“一体化数智管理和大模型应用”主题研讨会也正式落下了帷幕。 云原生转型正成为很多行业未来发展战略&#xff0c;伴随国家对信创数字化要求的深入推进&#xff0c;面对敏稳共存这一近年出现的新难…

MySQL死锁产生的原因和解决方法

一.什么是死锁 要想知道MYSQL死锁产生的原因,就要知道什么是死锁?在了解什么是死锁之前,先来看一个概念:线程安全问题 1.线程安全问题 1.1什么是线程安全问题 线程安全问题&#xff0c;指的是在多线程环境当中&#xff0c;线程并发访问某个资源&#xff0c;从而导致的原子性&a…

RocketMQ快速实战以及集群架构原理详解

RocketMQ快速实战以及集群架构原理详解 组成部分 启动Rocket服务之前要先启动NameServer NameServer 提供轻量级Broker路由服务&#xff0c;主要是提供服务注册 Broker 实际处理消息存储、转发等服务的核心组件 Producer 消息生产者集群&#xff0c;通常为业务系统中的一个功…

板块二 JSP和JSTL:第四节 EL表达式 来自【汤米尼克的JAVAEE全套教程专栏】

板块二 JSP和JSTL&#xff1a;第四节 EL表达式 一、什么是表达式语言二、表达式取值&#xff08;1&#xff09;访问JSP四大作用域&#xff08;2&#xff09;访问List和Map&#xff08;3&#xff09;访问JavaBean 三、 EL的各种运算符&#xff08;1&#xff09;.和[ ]运算符&…

《The Art of InnoDB》第二部分|第4章:深入结构-磁盘结构-redo log

4.3 redo log 目录 4.3 redo log 4.3.1 redo log 介绍 4.3.2 redo log 的作用 4.3.3 redo log file 结构 4.3.4 redo log 提交逻辑 4.3.5 redo log 持久化逻辑 4.3.6 redo log 检查点 4.3.7 小结