数据库专题——分库分表

  • 一. 分库分表介绍
  • 二. 分库分表实践

一. 分库分表介绍

1.1 分库分表解决了什么问题

  • 先说分库:
    • 《高性能MySQL》中提到了两种数据库扩展方式:垂直扩展和水平扩展。前者意味着买更多性能强悍的硬件,但是总会达到扩展的天花板,且成本较高。分库则是后者的一种实现方式。
    • 流量瓶颈:主要是写多的场景(读多可以通过读写分离,缓存等方式解决问题),而单集群写在大流量下是易达到瓶颈的。
    • 容量瓶颈:数据量大的情况下,单集群磁盘不够存储(尤其对于订单类的业务,即使有归档等手段,也难以支撑一定时间范围内的数据存储)。
  • 再说分表
    • 分表主要解决单表过大问题(DBA推荐单表容量在1000万行左右):随着表增大,从经验上看会引起慢查询(即使SQL语句很简单且走了索引),分表有利于提高读写效率

1.2 分库分表的方式

分表通常可分为水平分表和垂直分表

  • 垂直分表:把大表的字段拆分,拆成小表。如把order表拆成order_major(包含热点字段)和order_extra(包含冷门字段)
    • 优点:热点数据分离,热点表走主库,冷门表走从库
  • 水平分表:水平分表就是指以行为单位对数据进行拆分,一般分库分表指的就是水平分表
    • 优点:优化单表行数过大,提高性能

1.3 分库分表的基本原理

选择一个或多个路由键(routeKey,也可称分片),根据该路由键及路由规则,将SQL路由至不同的分库及分表。

  • 如分10库,每库100表,路由键为userId
    • 库路由规则:#userId#%10
    • 表路由规则:(#userId#).intdiv(10)%100
  • 代表含义:uid=100001会路由到1库0表中;uid=100329会路由到9库32表中

1.4 分库分表需要注意的问题

  • (1)自增主键无法标识唯一id,需要依赖分布式ID生成服务
  • (2)路由键的选择(拆分的维度):如订单表,假如又要根据订单id查询,又要根据用户id查询,该怎么解决
    • 思路一:系统拆分(实现成本高)
    • 思路二:建路由表(订单表以订单id为路由键;新建一张用户id与订单id的路由表,以用户id作为路由键)——> 注意分布式事务问题
  • (3)分布式事务问题:跨库就会涉及到分布式事务问题,除非所有操作的表都基于相同的路由键与路由规则
  • (4)路由键的选择:数据倾斜
  • (5)可扩展性:如果当前已经是分库分表,未来再扩容,建议以倍数扩(如2—>4,4—>8)。不然会复杂
  • (6)数据迁移过程中的平滑稳定

1.5 分库分表的实现方案

业界主要两种:服务端代理 和 客户端代理

  • 服务端代理:通过部署代理服务,背后管理多个数据库实例。应用层通过一个普通的数据源(c3p0、druid、dbcp等)与代理服务器建立连接,所有的SQL语句都是发送给这个代理,由这个代理去路由底层数据库,开发人员无需关注底层逻辑
  • 客户端代理:应用层内部管理了多个普通的数据源(c3p0、druid、dbcp等),每个普通数据源各自与不同的库建立连接。应用层通过路由规则路由给各个普通的数据源去执行,并返回结果。数据源代理通常也实现了JDBC规范定义的API,因此能够直接与orm框架整合。这种方案下开发人员需要修改代码

主流的实现方案对比

  • 数据库代理
    • 目前的实现方案有:阿里巴巴开源的cobar,mycat团队在cobar基础上开发的mycat,mysql官方提供的mysql-proxy,奇虎360在mysql-proxy基础开发的atlas。目前除了mycat,其他几个项目基本已经没有维护。
    • 优点:多语言支持。也就是说,不论你用的php、java或是其他语言,都可以支持。原因在于数据库代理本身就实现了mysql的通信协议,你可以就将其看成一个mysql 服务器。mysql官方团队为不同语言提供了不同的客户端驱动,如java语言的mysql-connector-java,python语言的mysql-connector-python等等。因此不同语言的开发者都可以使用mysql官方提供的对应的驱动来与这个代理服务器建通信。
    • 缺点:实现复杂。因为代理服务器需要实现mysql服务端的通信协议,因此实现难度较大。
  • 数据源代理
    • 目前的实现方案有:阿里巴巴开源的tddl,大众点评开源的zebra,当当网开源的sharding-jdbc。需要注意的是tddl的开源版本只有读写分离功能,没有分库分表,且开源版本已经不再维护。大众点评的zebra开源版本代码已经很久更新,基本上处于停滞的状态。当当网的sharding-jdbc目前算是做的比较好的,代码时有更新,文档资料比较全。
    • 优点:更加轻量,可以与任何orm框架整合。这种方案不需要实现mysql的通信协议,因为底层管理的普通数据源,可以直接通过mysql-connector-java驱动与mysql服务器进行通信,因此实现相对简单。
    • 缺点:仅支持某一种语言。例如tddl、zebra、sharding-jdbc都是使用java语言开发,因此对于使用其他语言的用户,就无法使用这些中间件。版本升级困难,因为应用使用数据源代理就是引入一个jar包的依赖,在有多个应用都对某个版本的jar包产生依赖时,一旦这个版本有bug,所有的应用都需要升级。而数据库代理升级则相对容易,因为服务是单独部署的,只要升级这个代理服务器,所有连接到这个代理的应用自然也就相当于都升级了。
  • ORM框架代理
    • 目前有hibernate提供的hibernate-shards,也可以通过mybatis插件的方式编写。相对于前面两种方案,这种方案可以说是只有缺点,没有优点。

二. 分库分表实践

2.1 路由键的选择

  • 确定业务逻辑上的主体,并确认大部分数据库操作都基于这个主体进行(如用户ID)。
  • 路由键在业务上不应被update,应是一个稳定的数据。且不应该为Null
  • 数据倾斜问题,确保散列均匀

2.2 分库分表数决策

  • 分表数量决策:
    • 单表建议:不超过1000万行数据
    • 通常可以预估2到5年的数据增长量,用估算出的总数据量除以总的物理分库数,再除以建议的最大数据量1000万,即可得出每个物理分库上需要创建的物理分表数
      • (未来3到5年内总共的记录行数) / 单张表建议记录行数
  • 分库数量决策:
    • 提前规划好未来2到5年的峰值流量+容量

2.3 路由规则

  • 路由键自身散列均匀:可通过取模的形式
    • 例如:库路由规则:#user_id#%10;表路由规则:(#user_id#).intdiv(10)%100
  • 路由键自身不散列均匀:对路由键作hash
    • 例如:crc32(#user_id#)%8

2.4 其他挑战

  • 自增主键:分布式自增id
  • 分库分表数据迁移过程的双写:
    • 思路一:mq事务消息,对于老表的事务,通过mq异步对新表重新执行,失败则补偿
      • 缺点:异步极端情况下非实时(mq消息延迟),代码改动大
      • 优点:老表 与 新表的最终数据一致性可保证
    • 思路二:监听老表binlog,异步对新表执行。与思路一差不多
    • 思路三:代码内部双写事务(设置两个事务管理器来处理)
      • 优点:可通过切面形式实现,代码嵌入改造量小
      • 缺点:①极端情况下无法保证两个事务的一致性(已提交事务A,准备提交B时宕机);②双写流程中接口性能下降
  • 迁移过程整体思路:建分库分表—>双写(增量)—>刷存量—>数据核验—>切读流量—>切写流量—>下线双写—>收尾
  • 小部分业务场景下没有路由键:
    • 思路:空间换时间,建路由表(订单表以订单id为路由键;新建一张用户id与订单id的路由表,以用户id作为路由键)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数字信号处理:傅里叶分析

本文主要参考视频如下: 数字信号处理9-1_线性时不变系统对复指数信号的响应_哔哩哔哩_bilibili 傅里叶分析的主要研究内容如下所示: 注意,计算机中使用的离散傅里叶变换并不是离散时间傅里叶变换; 前四种都是理论上的变换方式&…

mysql 2-21

约束的分类 添加约束 查看表约束 非空约束 唯一性约束 复合的唯一性约束 只要有一个字段不重复,就可以添加成功 主键约束 自增列 mysql 8.0具有持久化,重启服务器会继续自增 外键约束 创建外键 关联必须有唯一性约束,或者是主键 约束等级 …

创意办公:专注 ONLYOFFICE,探索办公新境界

一.ONLYOFFICE 介绍 ONLYOFFICE 是一个基于 Web 的办公套件,提供了文档处理、电子表格和演示文稿编辑等功能。它被设计为一个协作工具,支持多人实时协作编辑文档,并且可以在本地部署或者作为云服务使用。 二.ONLYOFFICE 特点和功能 以下是 …

Eclipse的Java Project的入口main函数

在使用Eclipse创建java project项目的时候,一个项目里面通常只有一个main,那么一个项目里面是否可以有多个main函数呢?其实可以的,但是运行java application的时候要选择执行哪个main函数。 下面举个例子: 1、创建一个…

Unity3d Shader篇(七)— 纹理采样

文章目录 前言一、什么是纹理采样?1. 纹理采样的工作原理2. 纹理采样的优缺点优点缺点 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数 三、效果四、总结使用场景 前言 纹理采样是一种常用的图形学技…

线性代数:向量组的秩

目录 回顾“秩” 及 向量组线性表示 相关特性 向量组的秩 例1 例2 矩阵的“秩” 及 向量组线性表示 相关特性 向量组的秩 例1 例2

详解动态内存管理!

目录 ​编辑 1.为什么要用动态内存分配 2.malloc和free 2.1 malloc 2.2 free 3.calloc和realloc 3.1 calloc 3.2 realloc 4.常见的动态内存的错误 4.1 对NULL的解引用操作 4.2 对动态内存开辟空间的越界访问 4.3 对非动态内存开辟空间用free释放 4.4 使用free释放动…

⭐北邮复试刷题106. 从中序与后序遍历序列构造二叉树__递归分治 (力扣每日一题)

106. 从中序与后序遍历序列构造二叉树 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7], postor…

RLT8762D---WDG 模块

0 Preface/Foreword 1 working mechanism 1.1 看门狗配置 1.2 喂狗定时器驱动 喂狗定时器回调函数: 1.3 初始化定时器 1.3.1 启动喂狗定时器 1.3.2 使能ROM看门狗 1.4 喂狗 定时器发送喂狗消息。 WDG_Restart()用于喂狗,comment out之后&#xff0…

Stable Diffusion 绘画入门教程(webui)-ControlNet(姿态预处理器openpose)

本片文章接着上篇文章ControlNet介绍他的控制类型,本篇介绍的预处理器为openpose 预处理器:openpose 模型:control_v11p_sd15_openpose 没下载模型的看上篇文章去下载一下哦,不然用不了 文章目录 一、干什么用的二、详细用法1、选…

YOLO-World技术小结

infopaperhttps://arxiv.org/abs/2401.17270codehttps://github.com/AILab-CVC/YOLO-Worldorg腾讯demohttps://huggingface.co/spaces/stevengrove/YOLO-World个人博客位置http://www.myhz0606.com/article/yolo_world 1 Motivation 这篇文章从计算效率的角度解决开集目标检测…

ping 8.8.8.8和ping www.baidu.com都OK,但是打不开网页

ping 8.8.8.8和ping www.baidu.com都OK,但是打不开网页 打开设置 -> 网络 找到IPV4, DNS栏输入 8.8.8.8 , apply 设置里界面变成这样 然后网页就能加载了

开源软件的利弊

目录 开源软件 优势 免费 透明 可更改 可协作 影响力 坏处 安全隐患 良莠不齐 学习成本 持续性问题 未知风险 开源软件 开源软件是一种基于开放协作和共享的软件开发模式,其利弊对于软件产业和社会发展具有重要意义 优势 免费 谁能拒绝不要钱的东西…

C# redis 菜鸟级别 订阅与频道,发送消息

// 建立 Redis 连接 发送部分代码 using StackExchange.Redis; ConnectionMultiplexer redis ConnectionMultiplexer.Connect("127.0.0.1:6379,password123456"); // 获取发布者 ISubscriber publisher redis.GetSubscriber(); // 发布消息到指定频道 string c…

day4 2/21

1>使用多线程完成两个文件的拷贝&#xff0c;第一个线程拷贝前一半&#xff0c;第二个线程拷贝后一半&#xff0c;主线程回收两个线程的资源 #include<myhead.h> typedef struct Inof {const char*srcfile;const char*destfile;int start;int len; }inof;int do_len…

洗地机哪一款好用?洗地机热门品牌测评

虽然说现在市面上有很多洗地机牌子不断推陈出新&#xff0c;但是洗地机的功能使用总是不分你我&#xff0c;因为不管产品怎么变&#xff0c;一款优秀的洗地机都必须要具备良好的操控性能以及优秀的续航水平&#xff0c;另外在此基础上&#xff0c;继续考察其贴边清洁效果和杀菌…

【医学大模型】InMD-X:超精细化 + 内科医生的大语言模型

InMD-X&#xff1a;超精细化 内科医生的大语言模型 提出背景数据训练持续预训练监督式微调参数高效微调 提出背景 论文&#xff1a;https://arxiv.org/pdf/2402.11883.pdf 现有的医学语言模型往往将医疗健康视为一个单一领域&#xff0c;忽视了其复杂的子专业。 解法: 将内科…

【代码随想录python笔记整理】第十二课 · 位置互换

前言:本笔记仅仅只是对内容的整理和自行消化,并不是完整内容,如有侵权,联系立删。 一、变量交换的实现 这节我们讨论一个简单的问题——怎么交换两个变量的值。比如说,一个瓶子里是水,一个瓶子里是油,想要将两个瓶子中的东西互换,我们应该怎么做呢?要实现上述过程,我们…

测试环境搭建整套大数据系统(四:ubuntu22.4创建普通用户)

一&#xff1a;创建用户&#xff0c;修改密码&#xff0c;增加sudo权限。 useradd dolphinscheduler #输入密码 passwd dolphinscheduler # 配置 sudo 免密 sed -i $adolphinscheduler ALL(ALL) NOPASSWD: NOPASSWD: ALL /etc/sudoers sed -i s/Defaults requirett/#Defa…

【OpenSSH+Jenkins搭建项目自动化部署】

OpenSSHJenkins搭建项目自动化部署 一、Windows安装OpenSSH1.下载2.解压3.安装4.启停服务5.SSH免密登录 二、Jenkins安装1.下载2.安装启动3.登录 三、项目自动化部署1.SSH配置2.项目配置3.权限控制 一、Windows安装OpenSSH 1.下载 https://github.com/PowerShell/Win32-0penS…
最新文章