ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

StarRocks Block Cache Warmup 实战指南:用 CACHE SELECT 主动预热远端数据

StarRocks Block Cache Warmup 实战指南:用 CACHE SELECT 主动预热远端数据 StarRocks Block Cache Warmup 实战指南用 CACHE SELECT 主动预热远端数据【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks缓存预热Cache Warmup是 StarRocks 应对数据湖分析、共享数据集群shared-data高要求查询场景的重要能力。本文围绕 StarRocks v3.3 引入的 Block Cache Warmup 特性系统讲解其原理、CACHE SELECT 语法、四类返回指标、与 SUBMIT TASK 结合的周期调度方案以及源码级实现细节与使用限制帮助你在 BI 报表、PoC 性能测试等场景中把远端数据提前搬到本地磁盘缓存显著降低查询延迟。在数据湖分析和共享数据集群场景中查询引擎需要从 HDFS 或对象存储等远端存储反复拉取数据远程 I/O 开销和热点数据重复读取是两大性能瓶颈。Block Cache 把远端文件按块切分后缓存到 BE/CN 节点的本地磁盘而 Block Cache Warmup 则进一步把查询时被动填充缓存升级为主动预取让热数据在查询真正到来之前就绪。从被动填充到主动预热Block Cache Warmup 的定位要理解 Block Cache Warmup先要清楚它与 Block Cache 的关系。Block Cache 是 StarRocks 自 v2.5 引入的磁盘级缓存当查询首次读取远端数据时系统将原始文件按固定大小切分成数据块block以块为最小缓存单元写入本地磁盘后续查询命中缓存后直接从本地读取避免重复访问远端存储。其缓存命中与读取流程可概括为三步系统按缓存键cache key检查本地节点 Block Cache 中是否存在目标块命中则直接从本地磁盘读取未命中则从远端存储拉取并同步写入本地 Block Cache 供后续查询复用。这里的缓存键由三部分构成hash(filename) fileModificationTime blockId。文件名哈希用于定位文件修改时间用于感知远端文件是否变化blockId 则标识文件切分后的第几个块。从缓存填充方式看普通 Block Cache 是被动填充——数据在查询过程中被顺带写入缓存而 Block Cache Warmup 是主动填充——它通过 CACHE SELECT 语句在查询发生前主动从远端存储抓取目标数据写入缓存。两者互补被动填充覆盖已查询过的数据主动预热覆盖将要被查询的数据。关于 Block Cache 的切分机制、SLRU/LRU 替换策略、Data Cache 的整体架构与 BE 配置项可参考同一目录下的 Data Cache 文档。适用场景与前置条件什么场景值得预热磁盘容量远大于待预热数据量如果块缓存磁盘容量小于待预热数据量预热效果会大打折扣。例如需要预热 100 GB 数据但磁盘只有 50 GB则只能缓存 50 GB且后写入的 50 GB 会替换先前缓存的 50 GB最终可能什么都没留下。缓存磁盘上的数据访问相对稳定如果预热期间出现访问量激增预热效果同样难以保证。例如磁盘 200 GB、待预热 100 GB条件一满足但若预热过程中有 150 GB 新数据写入缓存或一个异常的大冷查询需要装载 150 GB 数据都可能触发缓存淘汰eviction导致已预热的数据被挤出。换句话说预热的前提是有足够空间装下热数据且空间不会被意外的数据洪峰冲垮。使用前必须确认已启用 Block Cache 特性。Data Cache 自 v3.3.0 起默认开启由 BE 配置项datacache_enable默认true控制总开关Block Cache 独立开关为block_cache_enable默认true。若你曾手动关闭过需要先恢复启用。具备目标表的 SELECT 权限。CACHE SELECT 的执行走正常查询链路权限校验与普通 SELECT 一致。CACHE SELECT 语法与参数详解CACHE SELECT 是实现 Block Cache Warmup 的核心语法完整形式如下CACHE SELECT column_name [, ...] FROM [catalog_name.][db_name.]table_name [WHERE boolean_expression] [PROPERTIES(verbosetrue)]参数说明column_name要获取的列可使用*获取外部表的全部列catalog_nameCatalog 名称默认为 DEFAULT_CATALOG使用SET CATALOG切换后可不指定db_name数据库名称切换到目标库后可不指定table_name要获取数据的表名boolean_expressionWHERE 中的过滤条件用于细粒度预热PROPERTIES目前仅支持verbose属性用于返回更详细的预热指标CACHE SELECT 是同步过程一次只能预热一张表。执行成功后返回预热相关指标。从语法解析层看这条语句在 StarRocks.g4 中定义CACHE SELECT selectItem (, selectItem)* FROM qualifiedName (WHERE whereexpression)? properties?它被解析为 DataCacheSelectStatement内部实际包装了一个InsertStmt——这也解释了为什么预热能按正常查询流程执行CACHE SELECT 本质上是一条特殊的 INSERT 语句目标为 BLACKHOLE见下文实现原理一节。分析器对参数与属性的校验DataCacheStmtAnalyzer 在分析阶段会完成以下校验与解析查询必须为纯表扫描查询关系必须是TableRelation否则报错 Cache select only support olap table, external table or materialized view.共享无共享shared-nothing模式不支持本地 OLAP 表CACHE SELECT若针对默认内部 Catalog 的表且集群为 shared-nothing 模式会报错 Currently cache select is not supported in local olap tableverbose属性通过Boolean.parseBoolean(properties.getOrDefault(verbose, false))解析默认关闭priority属性只能取 0 或 1默认为 0用于标记缓存数据的优先级ttl属性采用 ISO-8601 时长格式如P1Y、PT0M表示缓存数据保持有效的时间当priority 0时必须指定非零 TTL否则报错 TTL must be specified when priority 0。这些属性校验在仓库单元测试 DataCacheStmtAnalyzerTest.java 中有完整覆盖例如校验 verbose 大小写不敏感、priority1必须搭配 TTL、TTL 格式非法时报错等场景。预热实操四种典型用法预热外部表全量数据下面的例子将 Hive Cataloghive_catalog下test_db.lineitem表的所有数据预热到缓存mysql cache select * from hive_catalog.test_db.lineitem; ---------------------------------------------------------------------------- | READ_CACHE_SIZE | WRITE_CACHE_SIZE | AVG_WRITE_CACHE_TIME | TOTAL_CACHE_USAGE | ---------------------------------------------------------------------------- | 48.2MB | 3.7GB | 59ms | 96.83% | ---------------------------------------------------------------------------- 1 row in set (19.56 sec)返回字段含义READ_CACHE_SIZE所有节点从块缓存中读取的数据总大小WRITE_CACHE_SIZE所有节点写入块缓存的数据总大小AVG_WRITE_CACHE_TIME每个节点写入块缓存的平均耗时TOTAL_CACHE_USAGE本次预热完成后整个集群块缓存的磁盘空间使用率可用于评估块缓存空间是否充足。指定列 过滤条件细粒度预热通过指定列与谓词可以实现细粒度预热显著减少预热数据量降低磁盘 I/O 与 CPU 消耗mysql cache select l_orderkey from hive_catalog.test_db.lineitem where l_shipdate1994-10-28; ---------------------------------------------------------------------------- | READ_CACHE_SIZE | WRITE_CACHE_SIZE | AVG_WRITE_CACHE_TIME | TOTAL_CACHE_USAGE | ---------------------------------------------------------------------------- | 957MB | 713.5MB | 3.6ms | 97.33% | ---------------------------------------------------------------------------- 1 row in set (9.07 sec)预热共享数据集群中的云原生表cloud-native table同理。下面的示例预热ssb库中lineorder表的lo_orderkey列mysql cache select lo_orderkey from ssb.lineorder; ---------------------------------------------------------------------------- | READ_CACHE_SIZE | WRITE_CACHE_SIZE | AVG_WRITE_CACHE_TIME | TOTAL_CACHE_USAGE | ---------------------------------------------------------------------------- | 118MB | 558.9MB | 200.6ms | 4.66% | ---------------------------------------------------------------------------- 1 row in set (29.88 sec)注意此例中TOTAL_CACHE_USAGE仅为 4.66%说明缓存空间非常充裕预热数据可长期驻留无需担心 SLRU 淘汰。Verbose 模式查看每个 BE 的明细指标默认返回的指标是所有 BE 聚合后的结果。在语句末尾追加PROPERTIES(verbosetrue)可获取每个 BE 的详细指标mysql cache select * from hive_catalog.test_db.lineitem properties(verbosetrue); ---------------------------------------------------------------------------------------------------------------- | IP | READ_CACHE_SIZE | AVG_READ_CACHE_TIME | WRITE_CACHE_SIZE | AVG_WRITE_CACHE_TIME | TOTAL_CACHE_USAGE | ---------------------------------------------------------------------------------------------------------------- | 172.26.80.233 | 376MB | 127.8micros | 0B | 0s | 3.85% | | 172.26.80.231 | 272.5MB | 121.8micros | 20.7MB | 146.5micros | 3.91% | | 172.26.80.232 | 355.5MB | 147.7micros | 0B | 0s | 3.91% | ---------------------------------------------------------------------------------------------------------------- 3 rows in set (0.54 sec)Verbose 模式会额外返回一个指标AVG_READ_CACHE_TIME块缓存命中时每个节点读取数据的平均耗时。从 DataCacheSelectMetrics.java 的实现可以看到两种输出模式的差异简单模式将各 BE 的读写字节数取平均、写入耗时按总次数平均后聚合成一行verbose 模式则按 BE 逐行输出 IP、读写大小、平均读写时间与缓存使用率其中平均读写时间是readTimeNs / count计算得到的纳秒值再格式化输出。聚合模式下TOTAL_CACHE_USAGE的计算方式是所有 BE 的(磁盘已用 内存已用) / (磁盘配额 内存配额)之和的比值。用 SUBMIT TASK 实现周期调度预热CACHE SELECT 是一次性的同步操作配合 SUBMIT TASK 即可实现周期性自动预热。下面的示例每 5 分钟预热一次lineitem表的l_orderkey列mysql submit task always_cache schedule every(interval 5 minute) as cache select l_orderkey from hive_catalog.test_db.lineitem where l_shipdate1994-10-28; ------------------------- | TaskName | Status | ------------------------- | always_cache | SUBMITTED | ------------------------- 1 row in set (0.03 sec)查看已创建的任务任务提交后可查询default_catalog.information_schema.tasks查看任务定义与调度信息mysql select * from default_catalog.information_schema.tasks; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | TASK_NAME | CREATE_TIME | SCHEDULE | CATALOG | DATABASE | DEFINITION | EXPIRE_TIME | PROPERTIES | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | always_cache | 2024-04-11 16:01:00 | PERIODICAL START(2024-04-11T16:01) EVERY(5 MINUTES) | emr_hive_test | zz_tpch_sf1000_hive_orc_zlib | cache select l_orderkey from lineitem where l_shipdate1994-10-28 | NULL | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 row in set (0.21 sec)查看任务执行历史查询default_catalog.information_schema.task_runs可查看每次预热执行的明细其中EXTRA_MESSAGE字段记录着 CACHE SELECT 的指标mysql select * from default_catalog.information_schema.task_runs; ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | QUERY_ID | TASK_NAME | CREATE_TIME | FINISH_TIME | STATE | CATALOG | DATABASE | DEFINITION | EXPIRE_TIME | ERROR_CODE | ERROR_MESSAGE | PROGRESS | EXTRA_MESSAGE | PROPERTIES | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 55b30204-f7da-11ee-b03e-7ea526d0b618 | always_cache | 2024-04-11 16:06:00 | 2024-04-11 16:07:22 | SUCCESS | emr_hive_test | zz_tpch_sf1000_hive_orc_zlib | cache select l_orderkey from lineitem where l_shipdate1994-10-28 | 2024-04-12 16:06:00 | 0 | NULL | 100% | AlreadyCachedSize: 15.7GB, AvgReadCacheTime: 1ms, WriteCacheSize: 0B, AvgWriteCacheTime: 0s, TotalCacheUsage: 75.94% | | | a2e3dc7e-f7d9-11ee-b03e-7ea526d0b618 | always_cache | 2024-04-11 16:01:00 | 2024-04-11 16:02:39 | SUCCESS | emr_hive_test | zz_tpch_sf1000_hive_orc_zlib | cache select l_orderkey from lineitem where l_shipdate1994-10-28 | 2024-04-12 16:01:00 | 0 | NULL | 100% | AlreadyCachedSize: 15.7GB, AvgReadCacheTime: 1.2ms, WriteCacheSize: 0B, AvgWriteCacheTime: 0s, TotalCacheUsage: 75.87% | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 2 rows in set (0.04 sec)注意上例中第二次执行WriteCacheSize: 0B、AlreadyCachedSize: 15.7GB说明该表数据此前已全部预热本次任务仅做了命中验证未产生新的写入——这正是周期调度预热场景中常见的缓存已就绪状态。删除任务不再需要周期预热时使用 DROP TASK 删除DROP TASK task_name调度任务的实现路径从源码结构看周期调度下的 CACHE SELECT 由 DataCacheSelectProcessor 处理它作为BaseTaskRunProcessor的子类在任务运行时通过ctx.executeSql(context.getDefinition())重新执行 CACHE SELECT 语句从子执行器sub StmtExecutor的 Coordinator 中取回预热指标写回任务状态EXTRA_MESSAGE并调用updateBackendDataCacheMetrics刷新各节点的缓存用量指标。这就是task_runs.EXTRA_MESSAGE中能看到完整预热指标的原因。典型业务场景PoC 性能测试评估 StarRocks 性能时如果不想让外部存储系统的网络延迟干扰测试结果可先用 CACHE SELECT 把待测表数据全部装入块缓存再进行基准查询。这样测得的查询性能即为纯本地缓存命中下的表现。固定时点的 BI 报表业务团队每天早晨 8 点查看 BI 报表。为保证查询性能相对稳定可在每天 7 点调度一个预热任务将报表涉及的数据提前装好mysql submit task BI schedule START(2024-02-03 07:00:00) EVERY(interval 1 day) AS cache select * from hive_catalog.test_db.lineitem where l_shipdate1994-10-28; ------------------------- | TaskName | Status | ------------------------- | BI | SUBMITTED | ------------------------- 1 row in set (0.03 sec)最小化资源消耗的预热为减少预热对常规查询的影响可在 SUBMIT TASK 中通过 session 变量控制资源占用例如指定资源组、调整并行度DOP、用 WHERE 缩小预热范围mysql submit task cache_select properties(pipeline_dop1, resource_groupwarmup) schedule EVERY(interval 1 day) AS cache select * from hive_catalog.test_db.lineitem where l_shipdate1994-10-28; ------------------------- | TaskName | Status | ------------------------- | cache_select | SUBMITTED | ------------------------- 1 row in set (0.03 sec)实现原理CACHE SELECT 底层是如何工作的深入 DataCacheSelectExecutor.java 可以看到 CACHE SELECT 的执行骨架CACHE SELECT 语句在 AST 层包装了一个InsertStmt目标为 BLACKHOLE即它本质上是INSERT INTO BLACKHOLE() SELECT ...因此走的是完整查询执行链路预热开销与普通查询相当执行器会按 warehouse 下可用的计算资源Compute Resource拆分出多个子执行上下文sub ConnectContext逐一创建内部StmtExecutor执行同一个 INSERT 语句再聚合各子执行器的指标关键的一点是buildCacheSelectConnectContext 在克隆会话变量时强制设置了与缓存相关的参数保证预热必然写入缓存setEnableScanDataCache(true)与setEnablePopulateDataCache(true)强制开启扫描缓存与缓存填充setDataCachePopulateMode(ALWAYS)填充模式固定为始终填充确保所有被访问的数据都必须写入缓存setEnableDataCacheAsyncPopulateMode(false)关闭异步填充采用同步填充保证一次预热完成全部写入setEnableDataCacheIOAdaptor(false)关闭 I/O 适配器避免磁盘高负载时部分请求被路由回远端存储而漏缓存setDataCacheEvictProbability(100)与可选的priority、ttl控制缓存写入的淘汰概率、优先级与有效期。这解释了为什么 CACHE SELECT 与普通查询行为不同普通 SELECT 会受populate_datacache_mode等会话变量影响决定是否填充缓存而 CACHE SELECT 无条件强制执行填充。使用限制与注意事项使用 CACHE SELECT 前必须启用 Block Cache 特性且对目标表拥有SELECT 权限。CACHE SELECT只支持单表预热不支持 ORDER BY、LIMIT、GROUP BY 等操作符——分析器要求查询关系必须是对单张表的直接扫描TableRelation。CACHE SELECT 在shared-nothing 与 shared-data 集群中均可使用但 shared-nothing 模式下仅支持外部表本地 OLAP 表会被拒绝共享数据集群中可预热云原生表。可预热的远端文件格式包括TEXT、ORC、Parquet。已预热的数据不保证永久驻留仍可能依据 Block Cache 的 SLRU 规则被淘汰。数据湖用户可通过SHOW BACKENDS\G或SHOW COMPUTE NODES\G查看块缓存剩余容量评估 SLRU 淘汰风险共享数据集群用户可通过集群指标查看块缓存使用情况。当前 CACHE SELECT 的实现基于 INSERT INTO BLACKHOLE()走正常查询流程因此性能开销与普通查询相当。官方说明未来版本会优化性能。后续版本展望官方文档指出未来 StarRocks 将引入自适应 Block Cache Warmupadaptive Block Cache Warmup结合数据访问模式与缓存命中情况动态调整预热策略以进一步提升缓存命中率。当前版本下建议你结合上文的磁盘容量评估、细粒度列/谓词筛选与周期调度手段把预热成本与收益控制在合理范围内。【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表