搜索关注微信公众号"捉虫大师",后端技术分享,架构设计、性能优化、源码阅读、问题排查、踩坑实践。

本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star。

Cobar 虽然是一款“古老”的数据库中间件,但目前不少公司仍然在用它,且它包含了不少有意思的算法和实现,今天就来分享 Cobar 提出的一种在分库场景下对 Order By / Limit 的优化。

原算法描述参考: https://github.com/alibaba/cobar/blob/master/doc/cobarSolution.ppt

背景

Cobar 最重要的功能就是分库分表,通常读取性能瓶颈可以通过增加从库或缓存来解决。

但写入性能在 MySQL 上只能通过分库分表来提升。

当我们把数据分布到不同的数据库上时,再查询时如果是单条数据只要找到这条数据对应的库即可,但如果是多条数据,可能分布在不同的库上时,Cobar 就需要先查询,再聚合。

来个具体例子:

如果我们要查询 tb1 表的 c1 字段,且取 c1 正序的下标(从0开始)为4、5的数据。假设分了三个库,我们为了取到正确数据,需要去这三个分库都取下标0-5的数据,假设取到如下数据:

取到3堆已排序的数据,对这3堆数据从小开始丢弃0、1、2、3号数据,保留第4、5号数据即是我们需要的。

这个算法看起来没啥问题,但如果数据量稍微变化一下,比如:

select c1 from tb1 order by c1 limit 9999999, 4

如果还按照上述的方法来做,首先得去每个分库查询 0 - 10000003的数据,然后再合并丢弃0-9999998号数据。

相当于丢弃了大约不分库时3倍的数据。这多少显得有点浪费了。

算法优化

  • Step1:将这条语句拆分成3条语句发给3个分库:

  • Step2:找出查询结果的最大和最小值,这里假设最小值为3,最大值为11

  • Step3:以最小值和最大值为条件再次查询

假设我们取得的数据如图,那么我们是不是很容易推断出这些结果之前还有多少数据?

  • Step4:反查出每一个返回结果的 offset,这里我们就能推断出分库1在最小值之前还有3333332条数据,分库2在最小值之前还有3333333条数据,分库3在最小值之前还有3333331条数据

这时,我们就可以丢弃合并后的0-9999998号数据了,分库1、2、3将最小值之前的数据都丢弃共丢弃了0-9999995号数据,再丢弃3个最小值3刚好够到了9999998,所以9999999号数据开始依次是4、5、5、6

算法分析

效率

以上例来说明,未优化前:

  • 1次查询,查询的数据总量大约 3kw,丢弃9999999条数据

优化后:

  • 第1次查询,查询数据总量约 1kw
  • 第2次查询,数据总量17
  • 丢弃3条数据

从这个例子可以看出,查询的数据量大大减少,需要计算丢弃的量也大大减少

非理想情况

可能大家能看出来,上述例子是非常理想的情况,如果数据没这么“理想”,结局又是怎样?

  • Step4 中反查的最小值之前不够丢弃怎么办,比如:

  • Step4 中反查的最小值之前的数据比需要丢弃的数据多怎么办?

可以看出,如果是这两种情况,这种算法就没法再次生效了。

优化的前提

根据上述两种情况来看,可以总结出该算法生效的前提是:

数据(排序字段)在各个分库上的分布要均匀

其实可以做个极端的假设,比如只有第一个分库上有数据,其他数据库没有数据,那么这个算法就失效了

总结

这么来看,这个算法是不是很废?确实比较废,就连 Cobar 中也没有使用。

但在某些场景下还是有比较大的提升的,分库的数据大部分时候是按字段进行取模,所以可以认为几乎是分布均匀的,此时如果 Order By / Limit 是比较深度翻页的数据,可以采取此策略,但也要进行兜底,如果返回的数据不满足条件,继续退化为最初的算法,所以单次效率可能不高,但从统计值上来看其效率可能是更高的。


搜索关注微信公众号"捉虫大师",后端技术分享,架构设计、性能优化、源码阅读、问题排查、踩坑实践。

Cobar提出的一种在分库场景下对Order By / Limit 的优化的更多相关文章

  1. Ironic几种不同的场景下的网络拓扑

    最近帮领导做了几页ppt,总结几种场景下ironic管理物理机网络的网络拓扑,简单做成一份文章记录下.只是方便自己记忆,没有认真修改.如果对ironic有一定了解,可以看下,加深理解. 1. vlan ...

  2. C++高并发场景下读多写少的优化方案

    概述 一谈到高并发的优化方案,往往能想到模块水平拆分.数据库读写分离.分库分表,加缓存.加mq等,这些都是从系统架构上解决.单模块作为系统的组成单元,其性能好坏也能很大的影响整体性能,本文从单模块下读 ...

  3. 超大规模商用 K8s 场景下,阿里巴巴如何动态解决容器资源的按需分配问题?

    作者 | 张晓宇(衷源)  阿里云容器平台技术专家 关注『阿里巴巴云原生』公众号,回复关键词"1010",可获取本文 PPT. 导读:资源利用率一直是很多平台管理和研发人员关心的话 ...

  4. Redis11种Web应用场景

    Redis的一个非常大优点就是能够不用整个转入到这个数据库,而是能够沿用之前的MySQL等数据库,而仅在一些特定的应用场景通过Redis的特性提高效率.本文列出了11个这种Web应用场景,如显示最新的 ...

  5. Redis 11种Web应用场景举例

    在"怎样让redis在你的系统中发挥作用"一文中,salvatore 'antirez' sanfilippo告诉我们如何利用redis独有的数据结构处理能力来解决一些常见问题.一 ...

  6. Redis能干啥?细看11种Web应用场景

    下面列出11种Web应用场景,在这些场景下可以充分的利用Redis的特性,大大提高效率. 1.在主页中显示最新的项目列表. Redis使用的是常驻内存的缓存,速度非常快.LPUSH用来插入一个内容ID ...

  7. Redis能干啥?细看11种Web应用场景[转]

    下面列出11种Web应用场景,在这些场景下可以充分的利用Redis的特性,大大提高效率. 1.在主页中显示最新的项目列表. Redis使用的是常驻内存的缓存,速度非常快.LPUSH用来插入一个内容ID ...

  8. Gartner提出的7种多租户模型

    下面,我们就来看看在SaaS应用搭建过程中,可以采用什么样的多租户模型.从而能较为清晰地了解未来使用PaaS平台开发的SaaS,可以为用户提供哪些多租户的服务.        Gartner提出了7种 ...

  9. SSD固态盘应用于Ceph集群的四种典型使用场景

    在虚拟化及云计算技术大规模应用于企业数据中心的科技潮流中,存储性能无疑是企业核心应用是否虚拟化.云化的关键指标之一.传统的做法是升级存储设备,但这没解决根本问题,性能和容量不能兼顾,并且解决不好设备利 ...

随机推荐

  1. js基本数据类型之间的转换

    常见五大基本数据类型 1.number 2.string 3.boolean 4.undefined 5.null 一.转换为string ①调用toString() 方法 因为null和undefi ...

  2. LeetCode通关:通过排序一次秒杀五道题,舒服!

    刷题路线参考:https://github.com/chefyuan/algorithm-base 大家好,我是拿输出博客督促自己刷题的老三,前面学习了十大排序:万字长文|十大基本排序,一次搞定!,接 ...

  3. 灵魂画手:漫画图解 SSH

    OpenSSL 本身是一个软件库,这个软件被广泛的应用在系统服务器当中,他的主要功能是在网络通信的过程中,保证数据的一致性以及数据传输过程中的安全性.软件本身是由C语言编写,这使得他具备了跨平台的特性 ...

  4. Redis的配置文件redis.conf的解析

    1.redis的配置文件为redis.conf 2.redis配置文件redis.conf中关于网络的配置 3.redis配置文件redis.conf中的日志配置 4.redis配置文件redis.c ...

  5. 基于Vue+Vuex+Vue-Router+axios+mint-ui的移动端电商项目

    第一步:安装Node 1.打开NodeJS的官网,下载和自己系统相配的NodeJS的安装程序,包括32位还是64位一定要选择好,否则会出现安装问题. 下载地址:https://nodejs.org/e ...

  6. 20210826 Lighthouse,Miner,Lyk Love painting,Revive

    考场 T1 这不裸的容斥 T2 这不裸的欧拉路,先从奇数度点开始走,走不了就传送 T3 什么玩意,暴力都不会 T4 点分树??? 仔细想了一波,发现 T1 T2 都好做,T3 二分答案后可以暴力贪心, ...

  7. SQL Server数据表设计编辑后无法保存处理办法

    关于使用 SQL Server 企业管理器,表[设计]界面,修改数据表字段或类型无法保存的问题处理过程: 使用SQL Server数据库的你是否遇到过每次数据库编辑工具内点击设计修改表字段或类型要保存 ...

  8. Mysql常用sql语句(6)- limit 限制查询结果的条数

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 实际工作中,我们的数据表数据肯定都是万级别的,如 ...

  9. Winform EF CodeFist方式连接数据库

    直接生成ado.net 实体数据模型挺方便的,但只有一步步的手写代码才能更好的理解EF,在学习asp.net core过程中手写代码已经明白了怎么回事,但实现过程有些麻烦不知道如何记录,但Winfor ...

  10. Hibernate持久层ORM框架

    一.概念 hibernate交互数据库时,对象的属性转成sql,mybatis直接写sql,性能更高: 二.