ShardingJDBC的实核心流程和商户商家订单的分片实现

news2024/11/24 20:24:24

一、ShardingJDBC的核心流程

ShardingJDBC的核心流程主要分成六个步骤,分别是:SQL解析->SQL优化->SQL路由->SQL改写->SQL执行->结果归并,流程图如下:

img

4.1、SQL解析

分为词法解析和语法解析。 先通过词法解析器将SQL拆分为一个个不可再分的单词。再使用语法解析器对SQL进行理解,并最终提炼出解析上下文。 解析上下文包括表、选择项、排序项、分组项、聚合函数、分页信息、查询条件以及可能需要修改的占位符的标记。

SQL解析由ShardingJDBC的解析引擎负责处理

4.2、SQL优化

合并和优化分片条件,如OR等。

4.3、SQL路由

根据解析上下文匹配数据库和表的分片策略,并生成路由路径。 对于携带分片键的SQL,根据分片键的不同可以划分为单片路由(分片键的操作符是等号)、多片路由(分片键的操作符是IN)和范围路由(分片键的操作符是BETWEEN)。 不携带分片键的SQL则采用广播路由。

4.4、SQL改写

将SQL改写为在真实数据库中可以正确执行的语句。SQL改写分为正确性改写和优化改写。

SQL改写的主要场景有:

1、真实表名的改写:如查询逻辑表的SQL为:select * from user where user_id = 1000,需要改写成真实表的SQL:select * from user_0 where user_id = 1000

2、分页参数的改写:如两个真实表中分表存储数据为1、2、3、4;5、6、7、8;此时需要执行select * from user order by user_id limit 2,2 时,如果不改写的话,那么分别在两个真实表中取到的结果就是3、4和7、8,然后在合并结果之后得到的结果就是7和8,很显然数据是不对的,因为实际情况下取第二页的两条数据应该是3和4才对。所以需要将SQL改写成select * from user order by user_id limit 0,4。也就是说会取出前两页所有的数据,然后再内存中再进行排序取第二页的数据。(limit偏移量值越大,效率越低

不过如果SQL仅仅路由到一个节点,那么此时就不需要进行分页参数的改写,避免从偏移量0开始扫描数据。

3、批量拆分:当进行批量操作时,比如IN操作,假设两个表根据user_id的奇偶数来分片,执行SQL为select * from user where user_id in (1,2,3,4).如果不进行拆分,就会让这个SQL再两个表中都执行,很显然筛选的数据就多了,性能就差了,虽然对于结果没有影响。

另外如果是批量插入操作时,就必须进行拆分,否则就会导致多个表中存在相同的数据了。

4.5、SQL执行

SQL执行通过执行引擎来处理,ShardingJDBC采用一套自动化的执行引擎,负责将路由和改写完成之后的真实SQL安全且高效发送到底层数据源执行。 它不是简单地将SQL通过JDBC直接发送至数据源执行;也并非直接将执行请求放入线程池去并发执行。它更关注平衡数据源连接创建以及内存占用所产生的消耗,以及最大限度地合理利用并发等问题。 执行引擎的目标是自动化的平衡资源控制与执行效率。

4.5.1、连接模式

首先从数据库连接上来分析,当一个SQL条件中包含了多个库多个表中的数据时,如果每个真实SQL都占用一个连接的话,很容易就导致数据库连接数不够用了,会严重影响其他SQL的执行。但是如果一个SQL解析了很多的真实SQL,如果都采用一个连接来处理的话,就无法达到并行的效果,比如一个SQL拆分成了10个真实SQL,一个连接串行处理的话就会导致一个线程串行执行10次数据库查询操作,很显然效率又会大大的降低。

所以ShardingJDBC提供了两种数据库连接模式供用户选择,分别是内存限制模式和连接数限制模式

内存限制模式是每个真实SQL都分配一个连接去执行实现SQL的并行执行,达到效率的最大化

连接数限制模式是每个库只会分配一个连接,分库的情况下会分配多个连接,分表的情况下只会分配一个连接串行执行

对于这两种模式ShardingJDBC还提供了自动化执行引擎来动态的选择使用哪种模式,根据不同的SQL特点选择最优的模式来执行。

不过用户可以通过配置maxConnectionSizePerQuery来设置一次查询操作最多可以分配多少个连接来限制连接数

4.6、结果归并

将从各个数据节点获取的多数据结果集,组合成为一个结果集并正确的返回至请求客户端,称为结果归并。

ShardingSphere支持的结果归并从功能上分为遍历、排序、分组、分页和聚合5种类型,它们是组合而非互斥的关系。 从结构划分,可分为流式归并、内存归并和装饰者归并。流式归并和内存归并是互斥的,装饰者归并可以在流式归并和内存归并之上做进一步的处理。

由于从数据库中返回的结果集是逐条返回的,并不需要将所有的数据一次性加载至内存中,因此,在进行结果归并时,沿用数据库返回结果集的方式进行归并,能够极大减少内存的消耗,是归并方式的优先选择。

流式归并是指每一次从结果集中获取到的数据,都能够通过逐条获取的方式返回正确的单条数据,它与数据库原生的返回结果集的方式最为契合。遍历、排序以及流式分组都属于流式归并的一种。

内存归并则是需要将结果集的所有数据都遍历并存储在内存中,再通过统一的分组、排序以及聚合等计算之后,再将其封装成为逐条访问的数据结果集返回。

装饰者归并是对所有的结果集归并进行统一的功能增强,目前装饰者归并有分页归并和聚合归并这2种类型。

ShardingSphere对于分页查询进行了2个方面的优化。

首先,采用流式处理 + 归并排序的方式来避免内存的过量占用。由于SQL改写不可避免的占用了额外的带宽,但并不会导致内存暴涨。 与直觉不同,大多数人认为ShardingSphere会将1,000,010 * 2记录全部加载至内存,进而占用大量内存而导致内存溢出。 但由于每个结果集的记录是有序的,因此ShardingSphere每次比较仅获取各个分片的当前结果集记录,驻留在内存中的记录仅为当前路由到的分片的结果集的当前游标指向而已。 对于本身即有序的待排序对象,归并排序的时间复杂度仅为O(n),性能损耗很小。

其次,ShardingSphere对仅落至单分片的查询进行进一步优化。 落至单分片查询的请求并不需要改写SQL也可以保证记录的正确性,因此在此种情况下,ShardingSphere并未进行SQL改写,从而达到节省带宽的目的。 

二、商户商家订单的分片实现

用户下单,生成一个订单,把用户id【商户用商户ID】作为路由key,对user_id取hash值然后对表的数量进行取模,得到对应需要路由的表,然后写入数据。

引入和 参考:

基于ShardingJDBC的分库分表_shardingjdbc分库分表join查询_毕业即失业吗的博客-CSDN博客

分库分表后路由策略设计 - 掘金

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

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

相关文章

基于ESP32 蓝牙游戏手柄设计

使用 ESP32 并通过 BLE 通信的 DIY 手持游戏手柄 这个项目中使用的东西 硬件组件 esp32 1 ws2812b 6 操纵杆 2 角度按钮 2 按钮 8 18560电池和电池座 2 3路拨动开关 1 TP4056带保…

【从0到1了解Libarchive】带你了解Libarchive Libarchive的用途意义以及成功入门Libarchive

目录 0 如果你还不知道Libarchive是什么请一定要先看一下 1 简介 1.1 为什么实现Libarchive 1.2 到底都有谁在用呢? 1.3 Libarchive都有哪些功能 1.4 我们可以通过这些获取更多信息 1.5 如何贡献 2 Libarchive归档与压缩 3 Libarchive编译 4 Libarchive简…

ApplicationContext 和 BeanFactory 的区别

✏️作者:银河罐头 📋系列专栏:JavaEE 🌲“种一棵树最好的时间是十年前,其次是现在” 目录 ApplicationContext 和 BeanFactory 的区别 ApplicationContext 和 BeanFactory 的区别 那么这 2 种获取 Spring 上下文对象…

搭建electron-vue上

electron-vue 准备工作修改package.jsonappveyor.yml.travis.yml.gitignore.eslintrc.js.eslintignore.babelrcsrc/renderer/main.jssrc/renderer/App.vuesrc/renderer/store/index.jssrc/renderer/store/modules/Counter.jssrc/renderer/store/modules/Counter.jssrc/renderer…

渗透测试 | 目录扫描

0x00 免责声明 本文仅限于学习讨论与技术知识的分享,不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本文作者不为此承担任何责任,一旦造成后果请自行承担…

BUUCTF ciscn_2019_n_8

小白垃圾做题笔记而已,不建议阅读观看。 看到保护后我………………傻眼了。这保护全看根本无从下手嘛。 看到源程序后我依然有点迷茫。 我是小白,直到看到了大佬的wp,我才有有点头绪。 这里,var[13]里的不能为0 并且里边存储的还…

Java 基础入门篇(六)——— String 类详解

文章目录 一、String 类概述二、String 创建对象的方式2.1 创建对象的两种方式2.2 面试:两种方式的区别 ★2.3 常见面试题 ★ 三、String 类常用方法3.1 字符串内容比较3.2 常用 API:遍历、截取、替换、分割 一、String 类概述 java.lang.String 类代表…

R语言 | 日期和时间的处理

目录 一、日期的设定与使用 1.1 as.Date()函数 1.2 weekdays()函数 1.3 months()函数 1.4 quarters()函数 1.5 Sys.localeconv()函数 1.6 Sys.Date()函数 1.7 再谈seq()函数 1.8 使用不同格式表示日期 二、时间的设定与使用 2.1 Sys.time()函数 2.2 as.POSIXct()函数…

ChatGPT学习企业产品、服务内容、往期方案,处理所输入的客户需求,定制化生成解决方案

该场景对应的关键词库(6个): 企业产品和服务内容、客户需求和参数、营销方案和推广策略、数据处理和模型训练、客户满意度和营销效率、往期营销方案 提问模板: 场景产品问题 模板1: 场景:某家电公司生产的…

【Redis】Redis单线程和多线程

Redis单线程 Redis为什么是单线程 Redis的版本很多,比如3.x、4.x、6.x等,版本不同,架构不同: 3.x版本,最早的版本,单线程4.x版本,严格意义上来说不是单线程,负责处理客户端请求的…

使用Vue+axios+Vuex实现登录后前端数据本地化存储实战

前言 这已经是《Vue + SpringBoot前后端分离项目实战》专栏的前端部分第8篇博客了,服务端部分由天哥(天哥主页)负责,目前专栏目录如下: Vue + SpringBoot前后端分离项目实战 - 前端部分1. 手把手带你做一套毕业设计-征程开启2. 我应该把毕业设计做到什么程度才能过关?3.…

cpp: read and write utf-8 text file using vs 2022

/*****************************************************************//*** \file geovindu.h* \brief 业务操作方法** \author geovindu,Geovin Du* \date 2023-04-22 ***********************************************************************/ /*** https://learn.mi…

【Linux】如何创建进程?

🔥🔥 欢迎来到小林的博客!!       🛰️博客主页:✈️林 子       🛰️博客专栏:✈️ 小林的Linux之路       🛰️社区 :✈️ 进步学堂       &a…

【技术】《Netty》从零开始学netty源码(四十八)之缓存池ObjectPool

目录 ObjectPool创建对象池获取对象get()从本地池中获取对象claim()回收对象 ObjectPool 在分析PooledByteBuf的时候我们遇到了recycleHandler类,该类用于回收已经使用完毕的缓存对象并将其放回池中供下次循环利用,Netty的对象池工作过程大体如下&#…

数字图像处理简答题

目录 1.人类视觉对颜色的主观感觉包括哪三类? 2. 图像成像的过程包括哪三步? 3.图像的采样和量化分别指什么? 4、取k8时,将下图用相应矩阵表示 5、简述当限定了数字图像的数据量时采样和量化参数的选择遵循哪两条原则&#x…

荔枝派Zero(全志V3S)制作 IMG 镜像文件

文章目录 前言一、安装工具二、生成新的 img 文件三、分割虚拟磁盘四、挂载虚拟磁盘并格式化1、首先建立虚拟磁盘并分区2、格式化虚拟磁盘分区 五、开始备份六、卸载虚拟磁盘七、dd 烧录系统八、运行测试 前言 之前在玩板子时每次烧录镜像都是先烧录 uboot 到 SD 卡 8k 偏移处…

03 DQL-表数据的查询

1.数据准备(直接复制执行即可) -- 创建db1数据库 CREATE DATABASE db1;-- 使用db1数据库 USE db1;-- 创建数据表 CREATE TABLE product(id INT, -- 商品编号NAME VARCHAR(20), -- 商品名称price DOUBLE, -- 商品价格brand VARCHAR(10), -- 商品品牌stock INT, -- 商品库存…

【场景削减】基于 Kantorovich 距离的 SBR 算法场景削减研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

SpringCloud:微服务保护之雪崩问题及解决方案

1.雪崩问题 微服务中,服务间调用关系错综复杂,一个微服务往往依赖于多个其它微服务。 如图,如果服务提供者I发生了故障,当前的应用的部分业务因为依赖于服务I,因此也会被阻塞。此时,其它不依赖于服务I的业…

Redis学习笔记01 (数据结构,线程模型,持久化)

Background Redis(Remote Dictionary Server)是一种基于键值对的内存数据库,通常被称为数据结构服务器。它支持多种数据结构,例如字符串(String)、哈希(Hash)、列表(Li…