ShardingJDBC 数据库分片 流式处理+归并排序 优化原理刨析

news2024/11/29 2:50:08

1. 分库分表下的分页查询

业务数据达到一定数据量时,必定会引入数据库分片,但当对于分片的情况下,分页查询是如何做到的?

比如: 数据库db1,中有三个user表,user_0,user_1,user_2,三个表的分片策略是以userId 与 3 取余。分片配置入下

# 指定user表的数据分布情况
spring.shardingsphere.sharding.tables.user.actual-data-nodes = db1.user_$->{0..2}

# 指定user表的分片策略,分片策略包括分片键和分片算法
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column = id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression = user_$->{id % 3}

现在执行分页查询语句

select * from `user` order by id limit 10000,10;

考虑到三个表的分片策略,如果要正确获取到 10000-100010 区间的数据的话,需要将三个表都查询出100010 条数据,再做归并排序,最后才能得到正确的结果集。

这样便产生了最让人担忧的问题,如果没张表都要查询那么多数据在我内存中排序,如果我有上百张表,那内存迟早溢出,产生OOM?

2. ShardingJDBC 的优化

官方文档在这里:shardingsphere

ShardingSphere 对分片查询的优化是通过使用 流式归并+优先级队列 实现的,可以减少对本地内存的占用(只有每个数据源的游标而已),但是并不能减少带宽资源的消耗。

ShardingJDBC 对这种分片查询的处理方式为:

  1. 从各个数据节点获取对应的数据集。
  2. 将上述获取的数据集,进行组合、归并, 最后得到一个符合预期的数据集。
  3. 将正确的数据集返回。

上述三个步骤中最重要的就是 归并的策略…

ShardingJDBC 的归并由归并引擎负责,归并引擎提供了三种归并方式
流式归并、内存归并和装饰者归并

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

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

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

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

3. 流式归并的原理

ShardingJDBC 的流式处理和JDBC的ResultSet的原理是一样的,主要是通过和数据库保持长连接,每次next都只取当前游标所在位置的一条数据,然后在内存中进行归并。

具体流程如下:

假设user表分为 db0: user_0, db1: user_1, db2: user_2 三张表
查询语句为:
select * from user order by id limit 10,10;

  1. 因不确定数据分布关系,所以,下发到三个表的sql指令都为 select * from user_$ order by id limit 0,20;

在这里插入图片描述

  1. 数据源执行了sql后,并不会将查询到的数据集直接返回给客户端,而是先将结果集存储在数据源本地,等待client通过游标一条条读取。每一个表都会维护一个自己表的游标,初始位置为第一条记录。
    在这里插入图片描述

  2. 每一轮都只传输游标当前指向的记录,client会将接收到的记录加入优先级队列,第一轮的时候client 维护的优先级队列如下所示。优先级队列是按照sql要求的排序字段排序。
    在这里插入图片描述

  3. 优先级队列队首出队,会执行next,去对应的db中取下一条记录,此时数据源维护的游标要向下移动一格。上述例子中,便会去user_1 中取出下一条记录,再重新入队进行排序,第二轮的结果如下图所示。

在这里插入图片描述

  1. 优先级队列操作next的同时,内部维护了一个 rowNumber,用来表示当前记录是第几个,每次取next时,都会 +1 ,源码部分如下:
    在这里插入图片描述
    limit分页的时候,便是通过这个字段找到对应开始的记录,开始拼接有效的结果集。

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

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

相关文章

FreeRTOS 信号量(五) ------ 递归互斥信号量

文章目录 一、递归互斥信号量简介二、创建互斥信号量1. xSemaphoreCreateRecursiveMutex()2. xSemaphoreCreateRecursiveMutexStatic() 三、递归信号量创建过程分析四、释放递归互斥信号量五、获取递归互斥信号量六、递归互斥信号量使用示例 一、递归互斥信号量简介 递归互斥信…

Linux学习[8]文件权限深入2 默认权限umask SUID/SGID/SBIT file指令

文章目录 前言1. 默认权限umask1.1 默认权限含义1.2 查看默认权限1.3 默认权限在文件与目录的异同 2. 特殊权限2.1 SUID2.2 SGID2.3 SBIT2.4 SUID/SGID/SBIT 权限设置2.4.1 数字法2.4.2 符号法 3. file指令 前言 在linux学习6里面,通过ls -al命令列出文件的所有详细…

2023/4/30周报

目录 摘要 论文阅读 1、题目和现存问题 2、知识空间理论、GRU和自注意力机制 3、模型构建 4、实验准备 5、实验结果 深度学习 1、GRU 2、代码实例 3、GRU和GCN结合的可能性 总结 摘要 本周在论文阅读上,阅读了一篇基于自注意力机制和双向GRU神经网络的…

【MATLAB数据处理实用案例详解(17)】——利用概念神经网络实现柴油机故障诊断

目录 一、问题描述二、利用概念神经网络实现柴油机故障诊断原理三、算法步骤3.1 定义样本3.2 样本归一化3.3 创建网络模型3.4 测试3.5 显示结果 四、运行结果五、完整代码 一、问题描述 柴油机的结构较为复杂,工作状况非常恶劣,因此发生故障的可能性较大…

linux常用命令大全

作为开发者,Linux是我们必须掌握的操作系统之一。因此,在编写代码和部署应用程序时,熟练使用Linux命令非常重要。这些常用命令不得不会,掌握这些命令,工作上会事半功倍,大大提高工作效率。 一. 文件和目录…

python使用迭代法验证角谷猜想

def fun(n):print(n)while n ! 1:n 3 * n 1 if n % 2 else n / 2print(finished)for i in range(2,1000):fun(i) 1、了解了什么是"角谷猜想" 对于任意一个自然数n,若n为偶数,则将其除以2;若n为奇数,则将其乘以3,然后再加1。如此经过有限次运算后,总可以得到自然数…

【VQ-VAE-2论文精读】Generating Diverse High-Fidelity Images with VQ-VAE-2

【VQ-VAE-2论文精读】Generating Diverse High-Fidelity Images with VQ-VAE-2 0、前言Abstract1 Introduction2 Background2.1 Vector Quantized Variational AutoEncoder 3 Method3.1 Stage 1: Learning Hierarchical Latent Codes3.2 Stage 2: Learning Priors over Latent …

【STM32】知识补充 晶振的基本原理及其应用

【STM32】知识补充 晶振的基本原理及其应用 概述晶振的基本原理晶振的性能参数晶振的分类晶振的应用晶振器在 STM32 上的应用总结 概述 晶振作为现代电子技中的重要组件, 广泛应用于各种电子设备中, 起到稳定时钟信号的作用. 本文将为您解释晶振的基本原理及其在实际应用中的用…

第 02 章 OSPF实验

2.1 OSPF 回顾 2.1.1 实验目的 在 CCNA 中,我们学习到了 OSPF 是一个链路状态路由协议,和 RIP 以及 EIGRP 的最大 不同在于对于它们对于网络的认识以及根本的算法的不同。通过对 CCNA 中 OSPF 配置实验 的回顾,从中加强我们对 OSPF 的理解。…

带你学c带你飞-P7取值范围

比特位 CPU能读懂的最小单元——比特位,bit,b 字节 内存机构的最小寻址单元——字节,Byte,B 1Byte8bit 进制 怎么算 注意:int默认是signed类型,signed类型第一位是符号位 符号位 存放signed类型的存…

对比体验 ChatGPT,聊聊文心一言的优缺点

在昨天文心一言发布后,我第一时间拿到了体验的资格,但第一次使用后却不禁有些失望。他的逻辑能力极度缺乏、创造力也差点意思。不过,今天再次高强度使用后,却又让我对这款产品的想法有了些许改变。 前言 将 2023 年称为 AI 纪元…

西门子PLC沿脉冲类指令汇总

S7-1200CPU提供了四种沿脉冲指令供用户使用,分别为:扫描操作数信号边沿指令、在信号边沿置位操作数的指令、扫描RLO的信号边沿指令以及检测信号边沿指令。 信号从0--1的时刻称为上升沿,信号从1--0的时刻称为下降沿,不管是上升沿还…

【VM服务管家】VM4.0平台SDK_2.1环境配置类

目录 2.1.1 环境配置:CSharp二次开发环境配置方法2.1.2 环境配置:Qt二次开发环境配置方法2.1.3 环境配置:MFC二次开发环境配置方法2.1.4 环境配置:VB.Net二次开发环境配置方法2.1.5 环境配置:运行出现Vm.Core.Solution…

python+django+vue消防知识宣传网站

开发语言:Python 框架:django Python版本:python3.7.7 数据库:mysql 数据库工具:Navicat 开发软件:PyCharm 层随着移动应用技术的发展,越来越多的消防单位借助于移动手机、电脑完成生活中的事…

Ubuntu目录和文件的相关操作

目录 1、目录的切换 2、查看目录及文件 3、目录的常见操作 4、文件的常见操作 1、目录的切换 打开终端窗口(”ctrlaltt“) 一般使用(”pwd“)显示当前所在的目录 比如:当前目录是在home下面的,与用户…

01_JUC概述

1. JUC是什么? 在 Java 5.0 提供了 java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常用的工具类。此包包括了几个小的、已标准化的可扩展框架,并提供一些功能实用的类,没有这些类,一些功能会很难实现或…

玩手机打电话识别监测算法 yolov8

玩手机打电话识别监测系统通过YOLOv8网络模型技术,玩手机打电话识别监测算法对现场有人玩手机抽烟打电话时可以立即自动进行抓拍存档。YOLOv8 算法的核心特性和改动可以归结为如下:提供了一个全新的 SOTA 模型,包括 P5 640 和 P6 1280 分辨率…

【全年汇总】2023年CCF人工智能会议截稿时间汇总(持续更新)

本博文是根据2022年CCF会议推荐的人工智能领域相关会议目录撰写。 一、截稿时间总览 截稿时间的总时间轴内容将会持续更新...... 往年投稿及录用情况及链接详见图片后面的内容。 二、会议详细目录 由于一些会议的投稿时间还没公开,因此根据往年投稿时间在表格中使…

石化企业数字化防爆融合通信解决方案

项目背景 石化工业是我国国民经济和社会发展的基础性、战略性产业,其发展和壮大受到了党和国家的高度重视。随着石化企业厂区规模的不断扩大以及技术的快速发展,现有石化企业专网通信系统建设相对滞后,缺乏结合人员管理、安全生产、安全通信…

商品详情API接口如何获取淘宝数据

淘宝是中国最大最受欢迎的电商平台之一,汇集了大量的商家和买家。在淘宝上热门商品的销量经常十分巨大,因此有些开发者和网站想要获取淘宝商品数据来进行一些分析。下面是一篇关于淘宝商品详情API接口获取淘宝数据的文章。 一、淘宝商品API接口介绍 淘…