分库分表实践

news/2024/5/14 15:25:37/文章来源:https://blog.csdn.net/qq_17236715/article/details/126925494

分库分表实践

分库分表概念以及使用场景

分库分表用来解决单表数据量太大,引起的性能问题。使用分库分表后能够根据特定路由键值将数据分布在不同库以及不同表中,解决了单表数据量的性能、运维等问题。一般来讲,单一数据库实例的数据的阈值
在 1TB 之内,是比较合理的范围。关于mysql 单表的数据量,一般单表数据量不超过2000万,这里和B+tree有关系,具体和每行数据大小,这里的2000万是根据跟行数据是1kb的前提下算出来的,当超过2000万,叶子节点会超过三层,此时性能会受到影响。其次还有到系统、磁盘io等硬件、软件的影响。

分库和分表均可以有效的避免由数据量超过可承受阈值而产生的查询瓶颈。除此之外,分库还能够用于有效的分散对数据库单点的访问量;分表虽然无法缓解数据库压力,但却能够提供尽量将分布式事务转化为本地事务的可能,
一旦涉及到跨库的更新操作,分布式事务往往会使问题变得复杂。使用多主多从的分片方式,可以有效
的避免数据单点,从而提升数据架构的可用性。

数据分片一般乐可以按垂直拆分和水平擦拆分。垂直拆分是按照业务来拆分表,例如拆成订单和用户表,往往需要对架构和设计进行调整。水平拆分是对表的水平拓展,解决单表或者单库的瓶颈问题。

分库分表同样是一把双刃剑,后会带来以下的问题:

1.运维难度加大

2.分表导致表名称的修改,或者分页、排序、聚合分组等操作的不正确处理,例如时间聚合查询时不能像以前一样单表分页查询,对业务的带来很多场景上的不适配。解决方案一般是同步到es这种Nosql数据库中进行聚合分析查询。

3.分布式事务,多库之间的DML操作事务不一致的问题,业务上尽量需要避免,同时也需要提供就柔性事务的解决方案,强一致性解决方案性能上存在问题。

shardingjdbc

ShardingSphere‐JDBC 定位为轻量级 Java 框架,它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC和各种 ORM 框架。

全面支持 DML、DDL、DCL、TCL 和常用 DAL。支持分页、去重、排序、分组、聚合、表关联等复杂查
询。支持 PostgreSQL 和 openGauss 数据库 SCHEMA DDL 和 DML 语句。• 适用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接
使用 JDBC;
• 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, HikariCP 等;
• 支持任意实现 JDBC 规范的数据库,目前支持 MySQL,PostgreSQL,Oracle,SQLServer 以及任何
可使用 JDBC 访问的数据库。

常见概念:

分片键: 数据路由字段,根据改字段落到库和表中

分片算法:对分片键进行计算得到的表架构,可以用常见的运算表达式,也可以自定义算法

分布式主键:雪花算法、Uuid等算法

springboot使用可以参考如下配置文件方式配置,配置了分库分表的分片键以及对应算法,当然也可以自定义算法。这里也用了DruidDataSource数据源,来配置shardingjdbc,并且配置了数据源的监控。

这里配置了双数据源对应两个而不同的库,然后定义了父子关系表,以及两张表的路由方式和表的主键由雪花算法生成。user_id为分库路由键,order_id为分表路由键,具体代码可以参考该项目,https://github.com/luozijing/springLearning,欢迎关注!

CREATE TABLE `pay_parent_0` (`id` bigint NOT NULL AUTO_INCREMENT,`user_id` int NOT NULL,...
) ENGINE=InnoDB AUTO_INCREMENT=1571152425171070979 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_binCREATE TABLE `pay_parent_item_1` (`id` bigint NOT NULL AUTO_INCREMENT,`order_id` bigint NOT NULL,`user_id` int NOT NULL,...
) ENGINE=InnoDB AUTO_INCREMENT=1571152424793583629 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
spring:main:allow-bean-definition-overriding: trueshardingsphere:props:sql:show: truedatasource:demo0:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://xxxxx:3306/demo0?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTTusername: rootpassword: xxxtype: com.alibaba.druid.pool.DruidDataSourcemaxActive: 20min-idle: 5connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000filters: stat,wall,log4j2demo1:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://xxx:3306/demo1?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTTusername: rootpassword: xxxxtype: com.alibaba.druid.pool.DruidDataSourcemaxActive: 20min-idle: 5connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000filters: stat,wall,log4j2names: demo0,demo1sharding:binding-tables: pay_parent,pay_parent_itembroadcast-tables: t_addressdefault-database-strategy:inline:algorithm-expression: demo$->{user_id % 2}sharding-column: user_idtables:pay_parent:actual-data-nodes: demo$->{0..1}.pay_parent_$->{0..1}key-generator:column: idprops:worker:id: 123type: SNOWFLAKEtable-strategy:inline:algorithm-expression: pay_parent_$->{id % 2}sharding-column: idpay_parent_item:actual-data-nodes: demo$->{0..1}.pay_parent_item_$->{0..1}key-generator:column: idprops:worker:id: 123type: SNOWFLAKEtable-strategy:inline:algorithm-expression: pay_parent_item_$->{order_id % 2}sharding-column: order_id

场景问题分析

为了模拟实际场景,模拟并发插入将近50w数据,利用这50w数据来分析实际场景中的一些聚合分析,每张表大概分到12.5w数据,说明雪花算法分布还是随机比较均匀的算法。
在这里插入图片描述

Limit分页查询

分页查询时由于不带任务路由键,所以是数据全量数据查询,然后按照主键id排序,这个效率十分低下,当带上路由键时,会路由到指定库,效率才会提升。所以在实际业务中,路由键十分重要,决定了业务的使用。

1.查询所有用户数据
SELECT COUNT(*) AS total FROM pay_parent WHERE deleted = 0
-》
Actual SQL: demo0 ::: SELECT COUNT(*) AS total FROM pay_parent_0 WHERE deleted = 0
Actual SQL: demo0 ::: SELECT COUNT(*) AS total FROM pay_parent_1 WHERE deleted = 0
Actual SQL: demo1 ::: SELECT COUNT(*) AS total FROM pay_parent_0 WHERE deleted = 0
Actual SQL: demo1 ::: SELECT COUNT(*) AS total FROM pay_parent_1 WHERE deleted = 0
各个库和各类表累加SELECT id,status,user_id,create_time,update_time,creator,updater,deleted FROM pay_parent WHERE deleted=0 ORDER BY id DESC LIMIT ?
-》
Actual SQL:SELECT  id,status,user_id,create_time,update_time,creator,updater,deleted  FROM pay_parent_0 WHERE  deleted=0
.....2.查询指定用户数据
Actual SQL: demo0 ::: SELECT  id,status,user_id,create_time,update_time,creator,updater,deleted  FROM pay_parent_0  WHERE  deleted=0 AND (user_id = ?) ORDER BY id DESC LIMIT ? ::: [54, 10]
Actual SQL: demo0 ::: SELECT  id,status,user_id,create_time,update_time,creator,updater,deleted  FROM pay_parent_1  WHERE  deleted=0 AND (user_id = ?) ORDER BY id DESC LIMIT ? ::: [54, 10]

关联分页查询

两张表的关联,这里入参利用userID,数据源路由键,可以路由到具体的数据库,然后联表查询,联表时很明显由于没有路由键,这里查询的数量是笛卡尔积,效率上也是大打折扣。

 Actual SQL: demo0 ::: selectl.id, l.user_id, l.status,r.id as item_id, r.order_id, r.status as item_status, r.user_id as item_user_idfrom pay_parent_1 as lleft join pay_parent_item_0 r on l.id = r.order_idwhere 1= 1and l.user_id = ? LIMIT ? ::: [56, 10]
Actual SQL: demo0 ::: selectl.id, l.user_id, l.status,r.id as item_id, r.order_id, r.status as item_status, r.user_id as item_user_idfrom pay_parent_1 as lleft join pay_parent_item_1 r on l.id = r.order_idwhere 1= 1 Actual SQL: demo0 ::: selectl.id, l.user_id, l.status,r.id as item_id, r.order_id, r.status as item_status, r.user_id as item_user_idfrom pay_parent_0 as lleft join pay_parent_item_0 r on l.id = r.order_idwhere 1= 1and l.user_id = ? LIMIT ? ::: [56, 10]Actual SQL: demo0 ::: selectl.id, l.user_id, l.status,r.id as item_id, r.order_id, r.status as item_status, r.user_id as item_user_idfrom pay_parent_0 as lleft join pay_parent_item_1 r on l.id = r.order_idwhere 1= 1and l.user_id = ? LIMIT ? ::: [56, 10]

总结

在实施分库分表时,要结合实际业务的需求来制定分库分表的规则以及路由的字段。一般来说,为了保障实际业务的性能,会将路由键带入查询条件中,路由到单库单表,此中情况性能较高。其次,经过上面验证,shardingjdbc能够满足mybatis 联表查询和分页查询的适配,其中联表在没有路由键是笛卡儿积的数量,验证数据准确,在实际业务中,分库分表改造后,对现有sql的需要一一验证有效性,包括性能和准确性上,改造成本还是不小。后续还将会继续探讨分库分表相关话题。

参考

https://blog.csdn.net/Edwin_Hu/article/details/124897224?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-124897224-blog-125905356.pc_relevant_multi_platform_featuressortv2dupreplace&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-124897224-blog-125905356.pc_relevant_multi_platform_featuressortv2dupreplace&utm_relevant_index=1 --单表数据量 2000w

https://download.csdn.net/download/qq_17236715/86542410?spm=1001.2014.3001.5503 -ShardingSphere 中文文档

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

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

相关文章

【网络】HTTP协议详解

😀大家好,我是白晨,一个不是很能熬夜😫,但是也想日更的人✈。如果喜欢这篇文章,点个赞👍,关注一下👀白晨吧!你的支持就是我最大的动力!&#x1f4…

svn 代码迁入gitlab

window中安装好git客户端,右键空白处,点选git bash here进入git界面,输入命令 将svn38163之后的所有记录都备份那:git svn clone -r 38163:HEAD svn地址 --no-metadata trunk(本地电脑目录名) --username *** 备份所有提交记录:git svn clone svn地址 --no-metadata …

Linux安装Python 以及过程中的命令详细介绍

下载源码包 打开 Python 官网 找到需要的安装包 获取了资源的链接后,进入Linux下载,wget意思是webget, 即下载 wget https://www.python.org/ftp/python/3.10.7/Python-3.10.7.tgz目录下会新增 这样源码包就下载好了。 如果下载太慢&…

二叉树与递归问题

目录 一:求二叉树的深度 二:二叉树反转 三:二叉树镜像判断 四:递归的终止条件 用递归解决的问题必须注意的: 递归的终止条件,也就是递归的出口(否则:栈溢出)递归的过…

决策树简介

决策树简介 决策树实际上是一个布尔函数,它的输出可以是“0 或 1”或“-1 或 +1”或“-1、0 或 +1”。决策树的大小等于其中存在的节点数,其深度等于从顶部到根的最长路径的长度。 错误率:训练集始终是给模型的标记示例,模型训练得越多,其错误率就越低。 训练样本 = { set…

程序里对象很深很大,可以用这个设计模式缓解一下

如果一个类的有非常多的属性,层级还很深。这个妥妥的是我的对象很大,你创建的时候忍一下......那你每次要创建的时候都忍一下?有没有一种好的方式让我们创建太的时候使用体验更好一点呢? 今天的文章里就给大家介绍一种设计模式,来…

C++多线程的线程返回值问题

对于多线程可执行对象的返回值是何时返回,以及得到的呢? 对于需要用到线程返回值的线程要使用future类对象来实现 文章目录future对象async()launch::deferred参数launch::async参数packaged_taskpromisefuture对象 是一个类模板 提供访问异步对象的操作…

优化 | Management Science 7-8月文章精选: 信息系统中的运筹学

作者:Evelyn Yao 清华大学本科在读 在“Management Science近期论文精选”中,我们有主题、有针对性地选择了Management Science中一些有趣的文章,不仅对文章的内容进行了概括与点评,而且也对文章的结构进行了梳理,旨在…

非零基础自学Java (老师:韩顺平) 第13章 常用类 13.5 StringBuffer类

非零基础自学Java (老师:韩顺平) ✈【【零基础 快速学Java】韩顺平 零基础30天学会Java】 第13章 常用类 文章目录非零基础自学Java (老师:韩顺平)第13章 常用类13.5 StringBuffer类13.5.1 基本介绍13.5.2 String VS StringBuffer13.5.3 String 和 Str…

HashMap

1.HashMap集合 1.1HashMap集合概述和特点【理解】 HashMap底层是哈希表结构的依赖hashCode方法和equals方法保证键的唯一如果键要存储的是自定义对象,需要重写hashCode和equals方法 1.2 特点 HashMap是线程不安全的实现; HashMap可以使用null作为key…

【Pytorch深度学习实战】(9)神经语言模型(RNN-LM)

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

第一视角体验搭载全志T507-H的开发板MYD-YT507H开发板

如今车规级芯片市场潜力巨大,需求旺盛,芯片都在逐渐走向国产化。本文要介绍的主角是MYD-YT507H开发板,该开发板是米尔科技结合全志国产工业级平台CPU——全志T507-H芯片研制的CPU模组,全志T507-H可广泛用于电力物联网、汽车电子、…

目标检测开源框架YOLOv6全面升级,更快更准的2.0版本来啦

9月5日,美团视觉智能部发布了YOLOv6 2.0版本,本次更新对轻量级网络进行了全面升级,量化版模型 YOLOv6-S 达到了 869 FPS,同时,还推出了综合性能优异的中大型网络(YOLOv6-M/L),丰富了…

一个div靠左另一个靠右

1.使用flex布局<style>#back{border: red solid 1px;width: 800px;height: 500px;display: flex;align-items: center;}#left{border: blue 1px solid;width: 100px;height: 100px;justify-content: flex-start;}#right{border: blue 1px solid;width: 100px;height: 100…

【前端进阶】-TypeScript类型声明文件详解及使用说明

前言 博主主页&#x1f449;&#x1f3fb;蜡笔雏田学代码 专栏链接&#x1f449;&#x1f3fb;【TypeScript专栏】 前三篇文章讲解了TypeScript的一些高级类型 详细内容请阅读如下&#xff1a;&#x1f53d; 【前端进阶】-TypeScript高级类型 | 泛型约束、泛型接口、泛型工具类…

Google Pub/Sub入门

什么是Google Pub/Sub&#xff1f; 首先他是一个messaging buffer/coupler消息缓冲区/耦合器&#xff0c;Decouples senders and receivers解耦发送者和接收者。 一些特性&#xff1a; 使用 Dataflow 注入分析事件并将其流式插入到 BigQuery免运维、安全、可伸缩的消息传递系…

MySQL基础总结合集

MySQL是啥&#xff1f;数据库又是啥&#xff1f; MySQL&#xff1a; MySQL 是最流行的关系型数据库管理系统&#xff0c;在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System&#xff1a;关系数据库管理系统)应用软件之一。 数据库&#xff1a; 数…

基于nodejs+vue的读书会网站

实行网上读书会网站&#xff0c;对其改善目前人们读书现状提供一些帮助和优化措施&#xff0c;为人们在未来看书节约了很多时间&#xff0c;使得人们在未来利用自己有限的时间可以看到更多对自己有益的书籍。 基于Vue的读书会网站的实现&#xff0c;通过网上系统的研发构造&…

你是否想过,GitHub Pages也可以自动构建?|原创

本文讲述了如何利用 GitHub Actions 来自动构建 GitHub Pages 项目&#xff0c;免去繁琐的手动构建再提交过程&#xff0c;让你专注于写作。点击上方“后端开发技术”&#xff0c;选择“设为星标” &#xff0c;优质资源及时送达GitHub Actions 自动构建之前的文章我们已经讲过…

Tomcat 在IDEA中运行Tomcat,控制台乱码问题的解决方案

IDEA中运行Tomcat,控制台乱码问题的解决方案试了好多种网上的方案(只有这一种能解决)环境:jdk 11 idea 2022.2.4 tomcat 9.0.54解决方案: 1.打开tomcat的配置文件(apache-tomcat-9.0.54\conf\logging.properties)将文件中的java.util.logging.ConsoleHandler.encoding =…