数据库分库分表

news2025/1/20 7:25:09

文章目录

      • 为什么要分库分表?
      • 数据切分
        • 垂直切分
        • 水平切分(每个表的结构相同)
          • 范围拆分
          • 取模拆分(一般为业务主键)
      • 分库分表带来的问题
        • 数据倾斜问题
        • 热点问题
        • 事务问题
        • 聚合查询问题
        • 分页问题
        • 非分区业务查询
      • 分库分表实现或工具
      • hash分库分表在线处理方案
        • 水平扩库

为什么要分库分表?

随着业务的发展,单库单表难以满足我们对性能的要求,在分库之前,可能我们经历了sql调优、索引优化、数据库参数优化、读写分离、使用分布式缓存来降低我们数据库的压力。但是随着业务再一步扩大,以上的方法可能就不适用了;
基本上就以下几种情况

  • IO瓶颈
    • 并发量过大,查询磁盘次数过大,特别是缓存命中率很低的时候更严重(分库)
    • 表太大,一次查询磁盘操作过多(分库、或分表,单表容量控制在2000万以内,根据业务增长预估提前规划)
    • 进出数据比较多,网络IO较大 (分库)
    • 数据库参数未优化,比如可以开启组提交来降低IO操作
    • 缓存设置过小
  • CPU瓶颈
    • 大SQL查询导致cpu彪高,单独从库,或者走大数据
    • 函数操作,特别是聚合、排序、分组、关联查询,能在程序中处理最好在程序中处理
    • 未走索引,优化sql,或者添加索引
  • 存储瓶颈
    • 比如阿里单实例最大3TB,业务数据过多无法存储(分库)
    • 一般不建议单实例存储太多的数据,存储数据多,代表着表多,表多了磁盘寻址也是个性能损耗
  • 连接数瓶颈
    • 并发量过大,链接数不够用(分库)
    • 死锁导致堆积,也会带来cpu瓶颈(实时监控与治理)
    • 慢查询,导致连接消耗也会带来cpu瓶颈

我还遇到一个因微服务拆分带来的分库需求,由单体拆出去以后多个项目共用一个数据库,多源写导致数据操作难以控制。

数据切分

既然要分库分表,那一定会涉及到数据的切分,一般有两种模式,垂直切分,和水平切分;

垂直切分

一种是分库

  • 将不同的系统模块的表拆解到不同的库中;
  • 将同一个系统模块中根据数据量或者业务规则拆到不同的库中(程序关联性大的放在一起);
  • 将不同的租户数据拆到不同的库里(表结构一样)

举个例子:比如我们授信系统,拆成了两个库auth 和auth2

image-20221214111216460

  • auth库里是用户授信记录
  • auth2库是风控相关的操作记录

一种是分表

  • 将字段特别多的表拆分为多个表;
  • 将大字段拆出(单行超过700多个字节的时候,会拆到额外的存储区域)

举个例子:

image-20221214112842853

还有我们在做业务的时候,也会不自觉的采用分表,比如我们的工单表和工单扩展表

水平切分(每个表的结构相同)

这个主要是解决单表数据量过大的问题,比如说,10亿的用户,单表存储不现实的吧,一般会拆成10张表;

水平拆分,一般由程序进行控制,一般有以下几种方式:

范围拆分
  • 按照id范围,比如id[11000万)一张表,id[1000万2000万)一张表,以此类推

    • 增删数据库实例方便,全量顺序查找方便
  • 按照创建时间,比如一个月或者一年一张表

    • 业务操作都得带着时间,比如查询最近一个月的账单,可以拆分出来查哪些库表
    • 交易订单、银行流水等按照时间排序的
  • 按照某个分类比如租户分表

    • 业务操作都得带租户,按租户查找方便,按租户新增库表方便

image-20221214144512589

优点:

  • 扩/缩容方便(增加或删除库表方便)
  • 归档方便

缺点:

  • 流量倾斜,热点数据不均衡(热点一般都是新进来的数据)
  • 某个库表压力过大
取模拆分(一般为业务主键)

note: 分表尽可能使用比较均匀的字段,同时要考虑到用户的行为习惯,比如手机号码,大部分人不会选择尾号为4的手机号,如果按尾号分,很容易出现尾号4的库表访问量少的问题,同时还有一个身份证,也存在同样的问题(x相对较少),如果必须要用这两个,建议hash以后再分

  • 如果是整数,直接进行取模,比如 id/10 路由到不同的库表中;
  • 如果是字符串,可以先hash,然后再取模(避免流量倾斜)

image-20221214144908550

优点:

  • 数据分散相对均匀
  • 数据库表的负载压力均衡

缺点:

  • 扩展能力差(增加库表,数据需要进行迁移)
  • 平衡难以把控,一次规划好,浪费资源,业务增量大,迁移麻烦

扩展能力差的问题,可以用一次性hash的方式来降低迁移的难度;

分库分表带来的问题

数据倾斜问题

  • 业务与倾斜要选一个平衡,比如电商类,在双十一和双十二的订单里会很大,避免不了的倾斜;
  • 数据倾斜不一定会出现热点问题;

热点问题

  • 热点问题,通过取模或一致性hash解决

事务问题

  • 一般互联网应用中不建议使用事务,建议业务补偿,保证最终一致性;
  • 分库时,尽可能将一个事务内的操作放入到一个库,避免跨库事务;
  • 实在避免不了,还必须用事务,用分布式事务解决
    • 本地消息表
    • TCC
    • RocketMQ的事务消息
    • 事件中心
    • saga

聚合查询问题

  • 一般是统计报表或数据分析,需要用到聚合函数或join,这种情况下不建议在业务系统里;
  • 如果是业务系统使用,一般会冗余一些字段,减少聚合查;
  • 一般互联网应用不建议聚合查,代码层进行组装,降低数据库的压力;

image-20221214151318987

  • 通过中间件将各分库的数据同步到聚合库,这个聚合库可以是hbase或者Cassandra里,也可以是oracle,当然也可以是mysql;
  • 分库以后各表的主键id建议使用分布式id,使用雪花算法yyyyMMddHHmmssSSS+机器位+内存序列,能保证数据相对有序,毫秒级的数据能落入到一个数据页中,性能损耗不大,根据实际需求,可以把自己定义机器位的大小和内存序列的大小;

分页问题

  • 如果是以分区主键来查询业务,分页问题就不是问题;
  • 如果是全局查,且分页,建议使用聚合库做查询分页,操作接口再到具体的分库分表上;
    • 根据业务属性增加一层处理机制,比如审核类的,我们分页查找一般都是进行中的,审核完的,只需要精确查找就行;
    • 我们抽出一个处理中的表,在这里进行业务操作处理;
    • 处理完的一般都是精确查找,如果需要业务分析,大数据处理
  • 如果不使用聚合库,只能使用全局查找,先把符合条件的数据查到,然后在内存中聚合,然后再分页,如果数据量大,oom了,同时对于数据库的压力也不小;

非分区业务查询

比如我们使用用户的uuid分表,然后我们要通过手机号mobile查用户的信息,怎么办?总不能来个全库扫描吧。那怎么办?

  • 关系映射

    • 将映射关系存储到一张索引表,通过旁路缓存查询
    • 直接永久缓存起来(需要考虑缓存失效的问题,缓存中没有怎么处理?)

    当通过mobile查询的时候,先查到uuid再去具体的表里查

  • 通过手机号生成uuid

    • 在往用户表插入数据的时候,通过一个固定方法把mobile转成uuid(需要考虑去重,极小的概率会重复)
  • 基因法(高低位存储)

    • 自己设计一个id生成器生成uuid,高位存储时间戳(20221201221126945)+3位机器位+3位内存毫秒级自增序列,
    • 低位(2~3位)存储分区规则,分区规则由mobile生成

分库分表实现或工具

  • 直接写mybatis插件自己实现
    • 通过库名和表名替换实现路由
  • TDDL(淘宝)
    • https://github.com/alibaba/tb_tddl 2012年后未更新
    • jar包的方式供应用调用,可以理解为自己实现的增强版
    • 通过规则匹配后做表名替换,然后将sql转发过去
  • Cobar中间件(阿里巴巴)
    • https://github.com/alibaba/cobar 2018年以后未更新
    • cobar是在amoeba基础上进化的版本
    • 代理方式
  • mycat 中间件
    • 基于ocbar开发的
    • http://mycatone.top/ 现在社区在推2.x的版本
    • 也是基于代理的方式,所有的规则都配置在mycat里;
  • ShardingSphere-JDBC 和ShardingSphere-Proxy
    • https://shardingsphere.apache.org
    • ShardingSphere-JDBC 仅支持java,低损耗、无中心化的工具
    • ShardingSphere-Proxy(代理)

大部分都是使用ShardingSphere-JDBC

hash分库分表在线处理方案

水平扩库

note: 如果生产上能对这个库的写拦截10秒左右最好,数据无损

中间件+程序改造

比如dts同步到kafka,然后消费kafka处理

image-20221214154051298

  1. 将最近一次备份库恢复;
  2. 将数据按分片规则清洗到不同的库里;
  3. 清洗完成后,回放备份时间点以后的binlog;
  4. 将binlog根据分片规则回放到不同的实例里;
  5. 确保同步是准实时;
  6. 将写入的数据缓存到分布式缓存里5分钟(确保时差内可以同步过去);
  7. 应用依次发布(新应用发布以后,老应用还在写数据,新应用优先从缓存里读);

从库机制

image-20221214154139996

  • 先给要分库的库挂对应数量的从库,比如要分10个库,挂10个从库

  • 同时申请10个VIP挂先挂指向主库db_user上

  • 增加路由规则,uuid%10=0的走u0.vip,其他的类似

  • 虽然路由到了不同的vip上,但是这个vip都指向了主库;

image-20221207180745831

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

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

相关文章

DSP篇--C6701功能调试系列之 UART串口测试

目录 1、原理 2、测试 调试的前期准备可以参考前面的博文:DSP篇--C6701功能调试系列之前期准备_nanke_yh的博客-CSDN博客 UART串口收发数据存在两种模式:通常的串口模式(McBSP in Serial Port Mode)和GPIO模式(McBS…

哈希表及其与Java类集的关系

目录 1.哈希表的概念 2.哈希冲突 3.如何避免哈希冲突? 3.1哈希函数设计 3.2 负载因子的调节 4.解决哈希冲突 4.1闭散列 4.1.1线性探测 4.1.2二次探测 4.2开散列(哈希桶) 5.HashMap 6.HashSet 1.哈希表的概念 假设有一组数据,要让你去搜索其中的一个关键码,这种场…

JWT快速入门及所需依赖

目录 1.JWT 1.1什么是JWT 1.2JWT的构成 jwt的头部 payload signature 1.3JWT快速入门案例 2Jwt认证(微服务) 2.1微服务下统一权限认证 2.2应用认证 3.无状态的JWT令牌如何实现续签功能? 3.1不允许改变Token令牌实现续签 3.2允许改…

计算机毕业设计django基于python大学生多媒体学习系统

项目介绍 随着计算机多媒体技术的发展和网络的普及。采用当前流行的B/S模式以及3层架构的设计思想通过Python技术来开发此系统的目的是建立一个配合网络环境的大学生多媒体学习系统的平台,这样可以有效地解决数据学习系统混乱的局面。 本文首先介绍了大学生多媒体学习系统的发…

eslint Parsing error: The keyword ‘export‘ is reserved

报错 原因 ECMAScript modules(import/export) 是 es6 的语法。 根据 eslint 官方文档 Configure language options ,eslint 默认使用 es5 语法: 解决 要让 eslint 知道我在使用 es6 的 modules 语法。有下面几种方法: 设置 env 为 es6&am…

喜讯 | 第三届国际科创节,企企通喜提两项大奖

近日,第三届国际科创节暨数服会STIF奖评选活动重磅揭晓,旨在向科技创新与数字化转型引领者致敬。企企通作为作为数字化采购平台领军者,凭借业内领先的技术实力与优秀的服务口碑,经过层层筛选和专业评审,企企通最终荣膺…

【LeetCode每日一题:1785. 构成特定和需要添加的最少元素~~~数组公式推导+防止整型溢出+向上取整+贪心】

题目描述 给你一个整数数组 nums &#xff0c;和两个整数 limit 与 goal 。数组 nums 有一条重要属性&#xff1a;abs(nums[i]) < limit 。 返回使数组元素总和等于 goal 所需要向数组中添加的 最少元素数量 &#xff0c;添加元素 不应改变 数组中 abs(nums[i]) < limi…

内存管理:虚拟地址空间和堆

准备用一个系列来总结一下内存管理涉及到的相关知识&#xff0c;范围从底层的数据结构和算法&#xff0c;到上层的API的使用&#xff0c;这里的内存管理&#xff0c;目前打算主要是侧重在堆的管理&#xff0c;本文作为一个引子&#xff0c;先粗略讲一下虚拟地址空间、堆管理、a…

​合并PDF文件什么方法很简单?看完你就明白了

想要将几个PDF文件合并到一起&#xff0c;什么方法使用起来是很简单的呢&#xff1f;PDF文件作为大家经常使用的文件之一&#xff0c;对它的编辑需求也很多&#xff0c;除了需要编辑文件的内容之外&#xff0c;还有需要将几个文件合并到一起使用的需求。那么我们如果遇到这种情…

traffic-forward

traffic-forward traffic-forward 是一款python开发的流量转发工具&#xff0c;可以使用python脚本行运行&#xff0c;也可以封装使用命令行&#xff0c;同样可以使用pyinstaller等工具进行封装成Macos&#xff0c;Linux, Windows 下的可执行文件运行&#xff0c;可用于本地流量…

简单理解HTML区块_HTML学习第七篇区块元素和内联元素

简单理解HTML区块_区块元素和内联元素HTML篇_第七章、区块一、区块元素和内联元素1.1块级元素1.2内联元素二、<div>元素三、<span>元素HTML篇_第七章、区块 一、区块元素和内联元素 HTML元素可以通过<div>和<span>元素组合起来&#xff0c;大多数 HT…

固定行数的纵向分栏

【问题】 what can ı configure the jasper report detail heapriider layout ? ı want to print datas side by side and every sides have 4 datas sub bottom 1 data1 5 data5 2 data2 6 data6 3 data3 4 data4 【回答】 整张报表纵向分栏可在 jasper 中设置分栏数&a…

性能高、上手快,实体类转换工具 MapStruct 到底有多强大

1.什么是MapStruct 1.1 JavaBean 的困扰 对于代码中 JavaBean之间的转换&#xff0c; 一直是困扰我很久的事情。在开发的时候我看到业务代码之间有很多的 JavaBean 之间的相互转化&#xff0c; 非常的影响观感&#xff0c;却又不得不存在。我后来想的一个办法就是通过反射&…

用Quasar开发Vue3+Electron跨平台应用的简单指南

1. 前言 Quasar是一个开源的vue.js基础框架&#xff0c;简单配置即可在其基础上进行SPA, SSR, PWA, 手机网站以及跨平台应用程序的开发&#xff0c;本文将简述如何基于Quasar Vue3 Vite Electron进行桌面应用开发。 2. 配置流程 2.1 框架构建 首先&#xff0c;在要存放代…

『NLP学习笔记』NER任务的CRF-layer的原理

NER任务的CRF-layer的原理 文章目录一. 预备工作二. BILSTM-CRF模型2.1. BiLSTM层输出2.2. 如果没有CRF层会怎么样2.3. CRF层可以从训练数据中学到约束三. CRF层3.1. 发射(Emission)分数3.2. 转移(Transition)分数3.3. CRF损失函数3.4. 实际路径得分3.5. 所有可能的路径的得分…

Ac-EEVVAC-pNA,389868-12-6

Ac-EEVVAC-pNA, chromogenic substrate for a continuous spectrophotometric assay of HCV NS3 protease. The sequence EEVVAC is derived from the 5A-5B cleavage junction of the HCV polyprotein. Ac-EEVVAC-pNA, HCV NS3蛋白酶连续分光光度法测定的显色底物。EEVVAC序列…

FPGA驱动24C04实现读写操作,提供工程源码和技术支持

目录1.24c04芯片手册解读2.纯verilog的i2c驱动3.24c04读写状态机设计4.上板调试验证5.福利&#xff1a;工程源码获取1.24c04芯片手册解读 24c04芯片手册很简单&#xff0c;原理图设计页很简单&#xff0c;这里只说代码设计需要注意的点&#xff1a; 1、写操作延时周期大于等于…

嵌入式软件工程师技能树——Linux应用编程+网络编程+驱动开发+操作系统+计算机网络

文章目录Linux驱动开发1、Linux内核组成2、用户空间与内核的通讯方式有哪些&#xff1f;3、系统调用read/write流程4、内核态用户态的区别5、bootloader内核 根文件的关系6、BootLoader的作用7、BootLoader两个启动阶段1、汇编实现&#xff0c;完成依赖于CPU体系架构的设置&…

推荐系统学习笔记--推荐系统简介

由来 互联网的出现和普及给用户带来了大量的信息&#xff0c;满足了用户在信息时代对信息的需求&#xff0c;但随着网络的迅速发展而带来的网上信息量的大幅增长&#xff0c;使得用户在面对大量信息时无法从中获得对自己真正有用的那部分信息&#xff0c;对信息的使用效率反而…

前三季度净亏损8.01亿元,亿咖通海外上市背后的「吉利阴影」

中国智能汽车产业链供应商正在通过SPAC方式在海外上市&#xff0c;或将成为新一轮资本浪潮的焦点。这些企业大多数已经具备一定规模&#xff0c;但仍处于亏损状态。 11月21日&#xff0c;亿咖通&#xff08;ECARX Holdings, Inc.&#xff09;宣布&#xff0c;之前与COVA Acqui…