当高并发来袭:StarRocks Query Cache 一招搞定!

news2025/5/15 21:45:50

您是否曾经遇到这样的情况?每天早上或业务活动高峰期,大量用户涌入报表平台或数据应用,希望查看特定业务领域的最新指标或趋势。这些用户可能会基于庞大的数据集进行大量类似的聚合查询,造成集群的 CPU 负载持续攀升,从而导致查询性能不断下滑。
针对这种高并发且呈现一定规律的查询,是否存在一种方法可以让集群在处理时智能地“精简计算量”呢?

1、StarRocks Query Cache(查询缓存)

为了解决这一问题, StarRocks 研发了 Query Cache(查询缓存)。它的作用是将本地聚合的中间结果缓存在内存中,以供后续复用。 当执行查询时,StarRocks 会优先检查 Query Cache。如果发现相同查询语义的结果已经存在于缓存中,就可以直接复用这些中间结果,避免重复计算,从而节省了磁盘访问和部分计算开销,有效提升查询性能。

值得注意的是,Query Cache 并不是 Result Cache,它缓存的是查询过程中的聚合中间结果而不是最终结果, 因此大大提升了缓存的命中率。即便对于不完全一致的查询,也能起到加速作用。据测试结果显示,在高并发场景下,Query Cache 可以将查询效率提高 3 至 17 倍, 从而有效减轻集群的负载压力,提供更快速的查询响应时间,使得整个系统在高峰期依然能够保持高性能运行。


(Query Cache 机制)

2、面向更多场景设计,最大限度提升缓存复用率

StarRocks 的 Query Cache 在设计时就考虑了如何能够让缓存的信息最大程度得到复用。整体来讲,下列三个场景均可以利用到 Query Cache:

  • 语义等价的查询
  • 扫描分区重合的查询:基于谓词的查询拆分
  • 仅涉及追加写入(无删除及更新)数据的查询:多版本缓存能力

(1)语义等价的查询


类似上图的例子,左图的子查询与右图在语义上是等价的,因此在执行了其中一个后,另一个查询就可以复用缓存中的结果加速查询。

语义等价还包含非常多的场景,更多例子请见:(https://docs.starrocks.io/zh-cn/latest/using_starrocks/query_cache)#语义等价的查询

(2)扫描分区重合的查询:基于谓词的查询拆分

在上图的两个查询中,ts 是分区列,查询仅在分区列的筛选区间上有区别,并且其中一部分区间是重叠的。在执行任意查询时,StarRocks 会将谓词中的区间按照分区来切割,并按照分区级别缓存聚合中间结果。在下次执行时,就可以复用有重叠的分区结果,达到查询加速的效果。

更多例子请见:
https://docs.starrocks.io/zh-cn/latest/using_starrocks/query_cache#扫描分区重合的查询

(3)仅涉及追加写入数据的查询:多版本缓存能力

除了上述在不同查询中尽可能复用 Cache,还有一类场景需要考虑:如果数据变化了该如何应对?Query Cache 可以在只有追加写入(append)的场景下被复用。

总体来说,随着数据导入,Tablet 会产生新的版本,进而导致 Query Cache 中缓存结果的 Tablet 版本落后于实际的 Tablet 版本。这时候,多版本 Cache 机制会尝试把 Query Cache 中缓存的结果与磁盘上存储的增量数据合并,确保新查询能够获取到最新版本的 Tablet 数据。

更多例子请见:https://docs.starrocks.io/zh-cn/latest/using_starrocks/query_cache#仅涉及追加写入数据的查询

3、在这些场景上,Query Cache 能事半功倍

根据上面的讲解,可以看出相比基于结果的 Result Cache,基于聚合中间结果的 Query Cache 能够被更大程度地利用。因而 Query Cache 就更适用于以下的查询场景:

  • 聚合类查询执行比较频繁,包含针对宽表的聚合查询与星型模型 JOIN 后的聚合查询
  • 两个语言相似的查询,但允许不完全相同
  • 数据只会追加写入,没有更新操作

这样的查询特征在很多场景中都很常见,例如:

  • 监控或报表平台: 数据集会随着时间的推移逐渐增加,而且用户会对不同时间段的数据汇总结果感兴趣
  • 面向用户的高并发分析: 包含按照特定维度指标进行汇总的查询

在这些场景中,Query Cache 可以通过重复使用查询的中间结果,避免重复计算,加快查询的响应速度。同时,由于缓存机制的使用,系统的可扩展性也得到了提升,从而可以更好地处理高并发的查询请求,为用户提供更好的体验。

4、最佳实践

为了更高效地利用 Query Cache,建表时需要根据查询设置合理的分区策略,并选择合适的数据分布方式, 包括:

  • 选择一个单独的 date/datetime 类型的列为分区列。 这个列的数据最好随着导入单调增加,并且查询会基于该列进行区间筛选。
  • 选择合适的分区大小。 因为随着导入,最近的分区数据很有可能会经常变动,从而导致缓存失效。因此过大或过小的分区都会影响缓存的命中率。
  • 确保分桶数量在数十个左右。 如果分桶数量过小,那么当 BE 需要处理的 Tablet 数量小于 pipeline_dop 参数的取值时,Query Cache 无法生效。

并且,因为每个 BE 节点在内存中维护自己的本地缓存,只要 BE 节点上有查询所需的副本数据,查询就可以被分配给该 BE。所以,为了能够最大程度地应用到 Cache,查询应该至少执行与副本数(replication_num)相同的次数。不过,Query Cache 也并不是只有在完全加载后才起作用。

5、如何使用 Query Cache

在这一节我们将用通过一个简单的例子来展示 StarRocks Query Cache 是如何工作的。

(1)准备工作

Query Cache 默认情况下是禁用的。您可以通过会话变量来启用它。 在例子中我们在单个 BE 集群中创建一副本的表,为了使 Query Cache 能够发挥作用,也需要对 pipeline_dop 进行调整。为了确认 Query Cache 的使用情况,还需要打开 Profile。

--打开 Query Cache
set enable_query_cache=true;
--因为只有1副本,因此调整 pipeline dop 为1
set pipeline_dop=1;
--打开 Query Profile
set is_report_success = true;
set enable_profile = true;

建表和导入语句请见:https://docs.starrocks.io/zh-cn/3.1/using_starrocks/query_cache#数据集

(2)示例查询

接下来我们将用一个简单的例子来激活 Query Cache 并查看它的使用情况。
首先我们执行第一个基础查询:

-- Q1: 基础查询
SELECT
    date_trunc('hour', ts) AS hour,
    k0,
    sum(v1) AS __c_0
FROM
    t0
WHERE
    ts between '2022-01-03 00:00:00'
    and '2022-01-03 23:59:59'
GROUP BY
    date_trunc('hour', ts),
    k0;

执行后我们查看 BE 的缓存情况。其usage相关指标被填充,说明 Query Cache 已经被填充:

curl http://127.0.0.1:8040/api/query_cache/stat
{
    "capacity": 536870912,
    "usage": 3889,
    "usage_ratio": 0.000007243826985359192,
    "lookup_count": 42,
    "hit_count": 0,
    "hit_ratio": 0.0 

接下来执行语义等价的查询:

-- Q2: 语义等价的查询
SELECT
    (
        ifnull(sum(murmur_hash3_32(hour)), 0) + ifnull(sum(murmur_hash3_32(k0)), 0) + ifnull(sum(murmur_hash3_32(__c_0)), 0)
    ) AS fingerprint
FROM
    (
        SELECT
            date_trunc('hour', ts) AS hour,
            k0,
            sum(v1) AS __c_0
        FROM
            t0
        WHERE
            ts between '2022-01-03 00:00:00'
            and '2022-01-03 23:59:59'
        GROUP BY
            date_trunc('hour', ts),
            k0
    ) AS t;

执行后我们继续查看 BE 的缓存情况。这里可以看到,Query Cache 被命中:

curl http://127.0.0.1:8040/api/query_cache/stat
{
    "capacity": 536870912,
    "usage": 3889,
    "usage_ratio": 0.000007243826985359192,
    "lookup_count": 44,
    "hit_count": 2,
    "hit_ratio": 0.045454545454545459

进一步分析此次查询的 Profile。可以发现 Profile 中出现 Cache 节点,Populate 相关指标均为 0,说明没有新的聚合结果被缓存;并且 Scan 节点的 RawRowsRead 指标为 0,说明实际并没有读取数据:

-- Cache节点populate相关指标均为0
- CachePopulateBytes: 0.00 
- CachePopulateChunkNum: 0
- CachePopulateRowNum: 0
- CachePopulateTabletNum: 0

-- Scan节点RawRowsRead为0
- RawRowsRead: 0M (0)

6、性能报告

尽管 StarRocks 的 Query Cache 不是 Result Cache,但是重复利用中间计算结果仍然可以带来很大的性能提升。这不仅适用于聚合查询,还能加速 JOIN 操作。现在让我们来看一些性能数据。为简单起见,我们将结果表示为 RT 比率,即查询延迟的 no_cache/cache_hit 比率。

注意,下方所有测试中 Query Cache 均已经被充分加载。

(1)宽表测试

硬件3 x (CPU: 16cores, 内存: 64GB)
数据集SSB 100GB 宽表
并发量10


(Query Cache vs. 冷查询)

可以看到,在 10 并发的单表聚合查询中,Query Cache 命中可以带来高达 10 倍的性能提升。

(2)星型模型测试

硬件3 x (CPU: 16cores, 内存: 64GB)
数据集SSB 100GB 多表
并发量10

可以看到,在 10 并发的多表聚合查询中,Query Cache 命中可以带来高达 17 倍的性能提升。

7、总结

Query Cache 可以极大地提升聚合查询的性能。通过将本地聚合的中间结果存储在内存中,Query Cache 可以避免对类似于先前查询的新查询进行不必要的磁盘访问和计算。Query Cache 还可以处理不完全相同的查询和数据,这使得它比 Result Cache 更加灵活。在高并发场景中,许多用户在大型复杂数据集上运行类似的查询时,Query Cache 尤其有用。借助 Query Cache,StarRocks 可以为聚合查询提供快速而准确的结果,节省时间和资源,并实现更好的可扩展性。

💬 Query Cache 讨论专区
为了帮助用户更好的使用 query cache,社区在论坛上开了一个相关的讨论帖,欢迎来分享你们都是怎么使用 query cache,或是使用过程中遇到了什么问题。性能提升的招式,大家都学起来!👉🏻 https://forum.mirrorship.cn/t/topic/8468

参考资料 https://docs.starrocks.io/zh-cn/latest/using_starrocks/query_cache

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

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

相关文章

基于随机森林的乳腺癌诊断

在当今的现实生活中存在着很多种微信息量的数据,如何采集这些数据中的信息并进行利用,成了数据分析领域里一个新的研究热点。随机森林以它自身固有的特点和优良的分类效果在众多的机器学习算法中脱颖而出。 随机森林算法由Leo Breiman和 Adele Cutler提出,该算法结合了…

JMeter使用方法

一、基础简介 界面 打开方式 双击 jmeter.bat双击 ApacheJMeter.jsr命令行输入 java -jar ApacheJMeter.jar 目录 BIN 目录:存放可执行文件和配置文件 docs目录:api文档,用于开发扩展组件 printable-docs目录:用户帮助手册 li…

海思Hi3861L开发一-环境搭建

一、简介 之前的文章中有详细介绍了HarmonyOS的Hi3861开发,但是该开发是基于HarmonyOS来的。实际在项目开发中,可能不会用到HarmonyOS,用的还是原生的Hi3861。那这次就重新学习Hi3861L。 二、环境搭建 环境:Ubuntu18.04.5 关于Ubuntu的环境搭建,还是参考之前的文章,附上…

musl libc ldso 动态加载研究笔记:动态库的加载次序与初始化次序

前言 musl ldso 是按照什么次序加载动态链接的应用程序的共享库的?如果共享库之间有依赖, musl ldso 如何处理先初始化哪个 共享库? musl ldso 的代码可以在 musl 官方代码: ldso\dlstart.c 与 ldso\dynlink.c,其中动…

table,设置 数据相同时, 合并列

<el-table :data"tableData" :span-method"objectSpanMethod" border style"width: 100%" show-summary><el-table-column type"index" label"序号" width"100" /><el-table-column prop"dat…

c++(8.23)类,this指针,构造函数,析构函数,拷贝构造函数

设计一个Per类&#xff0c;类中包含私有成员&#xff1a;姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员&#xff1a;成绩、Per类对象 p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #include <iostream>u…

idea的断点调试

1、行断点 首先在代码的最左侧点击会显示红色的圆圈 第二步在main方法中右键选中debug run进行运行 会出现下面图片的情况 出现上图之后&#xff0c;点击console 下一步 这个时候就可以看到调试的结果了 6、方法调用栈&#xff1a;这里显示了该线程调试所经过的所有方法&…

SQL注入之堆叠查询

文章目录 堆叠查询是什么&#xff1f;堆叠查询修改所有用户密码堆叠查询删除数据库恢复数据库 堆叠查询是什么&#xff1f; 在SQL中&#xff0c;分号;是用来表示一条sql语句的结束。试想一下我们在; 结束一个sql语句后继续构造下一条语句&#xff0c;会不会一起执行&#xff1f…

漏洞挖掘和安全审计的技巧与策略

文章目录 漏洞挖掘&#xff1a;发现隐藏的弱点1. 源代码审计&#xff1a;2. 黑盒测试&#xff1a;3. 静态分析工具&#xff1a; 安全审计&#xff1a;系统的全面评估1. 渗透测试&#xff1a;2. 代码审计&#xff1a;3. 安全策略审查&#xff1a; 代码示例&#xff1a;SQL注入漏…

VB.NET调用VB6 Activex EXE实现PowerBasic和FreeBasic的标准DLL调用

VB6写的ActiveX EXE公共对象是外置进程&#xff0c;因此&#xff0c;尽管它是x86 32位的进程&#xff0c;但可以集成到 VB.NET的x64和x32程序中使用。 VS2022的VB.NET程序&#xff0c;调用ActiveX DLL对象我在上篇笔记中写了 VB.NET通过VB6 ActiveX DLL调用PowerBasic及FreeB…

【网络】DNS | ICMP | NAT | 代理服务器

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《网络》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 前面几篇文章虽然讲介绍了整个网络通信的协议栈&#xff0c;我们也知道了完整的网络通信过程&#xff…

线性回归的正则化改进(岭回归、Lasso、弹性网络),最小二乘法和最大似然估计之间关系,正则化

目录 最小二乘法 极大似然估计的思想 概率&#xff1a;已知分布参数-对分布参数进行估计 概率描述的是结果;似然描述的是假设/模型​编辑 似然&#xff1a;已知观测结果-对分布参数进行估计​编辑 对数函数消灭连乘-连乘导致算法参数消失 极大似然估计公式&#xff1a;将乘…

Android BatteryManager的使用及BatteryService源码分析

当需要监控系统电量时&#xff0c;用 BatteryManager 来实现。 参考官网 监控电池电量和充电状态 获取电池信息 通过监听 Intent.ACTION_BATTERY_CHANGED 广播实现&#xff0c;在广播接收器中获取电池信息。 这是个粘性广播&#xff0c;即使过了广播发出的时间点后再注册广…

基于数据采集网关的工业锅炉远程监控运维系统

随着社会经济的不断发展&#xff0c;工业生产规模不断扩大&#xff0c;生产工艺也在不断创新&#xff0c;工业锅炉已经实现自动化控制&#xff0c;但管理模式仍存在缺陷&#xff0c;目前锅炉主要以人工巡检为主&#xff0c;这种方式费时费力且无法及时发现生产中的隐患&#xf…

javaScript:带你深入了解基本数据类型和引用类型

目录 一.前言 二.Ecmascript 规定的变量有两种 补充 1.基本数据类型&#xff08;重点掌握&#xff09; 基本数据类型的特点 2.引用数据类型 &#xff08;重点掌握&#xff09; 引用数据类型的特点 三.什么是栈&#xff1f;堆&#xff1f; 下面代码帮助了解 解释 官…

线性数据结构:数组与链表的探索与应用

文章目录 1. 数组&#xff1a;连续存储的有序元素集合1.1 创建和访问数组1.2 数组的搜索与排序 2. 链表&#xff1a;非连续存储的动态数据结构2.1 单链表与双链表2.2 链表的操作与应用 3. 数组与链表的比较与应用3.1 数组与链表的比较3.2 数组与链表的应用 4. 总结与展望 &…

Docker基本部署和相关操作

1.安装docker服务&#xff0c;配置镜像加速器 1、yum安装并且添加源信息 yum install yum-utils device-mapper-persistent-data lvm2 -y yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo2、修改一些配置信息 sed…

跨境电商系统开发:解锁海外财富,轻松实现财富自由

了解跨境电商系统开发的重要性 随着全球化和科技发展的进程&#xff0c;跨境电商已经成为一种崭新且热门的商业模式。跨境电商系统开发为企业提供了进军海外市场的机会&#xff0c;解锁了海外财富&#xff0c;帮助实现财富自由。 跨境电商系统的基本架构 跨境电商系统的基本架…

反腐力度空前,医药行业全面合规势在必行!

“公立医院改革、临床试验自查、医疗反腐、分级诊疗、药品集中采购、一致性评价、最严限抗、两票制等一系列政策卷起了医疗界阵阵反腐风暴。据报道&#xff0c;全国已有至少155家医院的院长和书记接受了调查。。。” 医药行业是与人们的生命和健康息息相关的重要领域&#xff…

一云多芯,智能化转型的下一个工程化挑战

进入2023年&#xff0c;产业数字化和智能化转型升级进入了大规模工程化落地阶段。根据中国信通院《中国数字经济发展研究报告&#xff08;2023&#xff09;》&#xff0c;数字经济已经占我国GDP比重达到41.5%&#xff0c;相当于第二产业占国民经济的比重。随着产业数字化和智能…