Apache Doris 进阶:高并发点查(Point Query)最佳实践指南
本文介绍了如何在Apache Doris中优化高并发点查(Point Query)性能。通过启用短路路径(Short Circuit)机制,绕过传统OLAP查询流程,实现仅需一次RPC即可完成查询。优化方案包括:1)建表时配置Unique Key模型、Merge-On-Write和行存储;2)客户端使用JDBC预处理语句;3)服务端开启行缓存;4)通过EXPLAIN验证是否命中SHORT-CIRC
在现代数据架构中,Apache Doris 不仅在海量数据 OLAP 分析场景下表现优异,随着版本的演进,它也开始越来越多地承接面向 C 端或高频请求的**高并发点查(Point Query)**业务。
为了在这类场景下达到极致的性能(类似于取代部分 HBase 或 Redis 的查询场景),我们需要在表结构设计、客户端连接、服务端缓存以及执行路径上进行一系列的专门优化。
本文将详细介绍如何在 Doris 中配置并使用高并发点查功能,核心优化主要集中在 Doris 的**主键模型(Unique Key)**上。
核心原理简述:什么是“短路路径(Short Circuit)”?
在传统的 OLAP 查询中,一条 SQL 需要经过复杂的解析、规划、生成分布式执行计划,并进行多次 RPC 通信来拉取数据。对于简单的 SELECT * FROM table WHERE id = ? 这种点查,传统的流程显得过于沉重。
Doris 针对此类场景设计了短路路径(Short Circuit)。当满足特定条件时,查询会绕过复杂的优化器规划,直接定位到数据所在的 Tablet 并精准读取,仅需执行一次 RPC 即可完成查询,从而大幅降低系统开销,提升 QPS。
⚠️ 注意: 目前 Doris 的点查优化 仅支持对 Key 列(主键)的等值(
=)查询。
下面我们按完整的实施步骤进行实战讲解。
步骤一:建立专门优化的表结构
要启用高并发点查优化,建表时必须满足特定的属性配置。点查优化高度依赖于 Unique Key 模型、Merge-On-Write(MOW)机制以及行存格式。
示例建表 DDL:
CREATE TABLE `tbl_point_query` (
`key` int(11) NULL,
`v1` decimal(27, 9) NULL,
`v2` varchar(30) NULL
-- ... 其他字段
) ENGINE=OLAP
UNIQUE KEY(`key`)
DISTRIBUTED BY HASH(`key`) BUCKETS 1
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"light_schema_change" = "true",
"store_row_column" = "true"
);
关键参数解析(必须开启):
enable_unique_key_merge_on_write:是否开启 MOW 模式。点查场景下必须开启。 MOW 机制保证了读取时不需要在 Server 端进行数据的多版本合并,极大提升了读取性能。light_schema_change:是否开启轻量化表结构变更。因为点查的底层优化依赖轻量级表结构变更中的列唯一 ID 来快速定位列,点查场景下必须开启。store_row_column:是否启用行存(Row Storage)。Doris 默认是列存,列存对于分析极为友好,但在SELECT *获取整行数据的点查时,行存可以避免多次读取多个列文件再进行组装的开销。点查场景下必须开启。
当这三个参数同时开启时,针对主键的等值点查就会触发短路路径优化。
步骤二:MySQL JDBC 客户端开启预处理语句
在客户端(如 Java 应用)发起查询时,高并发意味着大量的 SQL 解析开销。我们可以通过 JDBC 的**预处理语句(Prepared Statement)**特性将 SQL 解析结果缓存起来。
当开启预处理语句时,SQL 及表达式将被提前计算,并缓存到 Doris 的 Session 级别的内存缓存中。后续相同的查询模式只需传递参数,直接使用缓存对象,能有效提升 SQL 解析的效率。
1. 修改 JDBC URL 参数
在配置数据源连接字符串时,加上 useServerPrepStmts=true 参数:
# 示例 JDBC URL
url = jdbc:mysql://127.0.0.1:9030/ycsb?useServerPrepStmts=true
2. 代码实现层面(Java 示例)
在业务代码中,必须使用 ? 作为占位符,并通过 PreparedStatement 来执行查询:
// 使用 "?" 对参数进行占位设置
String sql = "SELECT * FROM tbl_point_query WHERE key = ?";
PreparedStatement readStatement = conn.prepareStatement(sql);
// 设置具体的 SQL 参数
readStatement.setInt(1, 1234);
// 执行点查 SQL
ResultSet resultSet = readStatement.executeQuery();
// 处理结果...
步骤三:服务端开启行缓存(Row Cache)
除了执行路径的优化,缓存是应对高并发的最后一道防线。Doris 内部提供了一个基于 LRU(Least Recently Used)策略的行缓存,用于直接在内存中命中整行数据。
默认情况下,行缓存是关闭的。我们需要修改 Doris BE 节点的配置文件 be.conf,并重启 BE 节点使其生效。
be.conf 配置项:
disable_storage_row_cache:是否关闭行缓存。(将其设置为false代表开启行缓存)。row_cache_mem_limit:行缓存占用 BE 节点内存的百分比。默认值为20%,可根据实际机器内存和业务需求进行调整。
💡 提示: 开启行缓存后,对于热点数据的点查请求,Doris 可以直接从内存中返回数据,进一步降低磁盘 I/O 开销,显著提升吞吐量。
步骤四:验证 SQL 是否真正命中了点查优化路径
配置完成后,我们不能凭感觉确认优化是否生效。高并发点查性能提升的核心在于必须保障 SQL 走到了点查路径(短路路径)。
我们可以使用 EXPLAIN 命令来查看 SQL 的执行计划:
mysql> EXPLAIN SELECT * FROM tbl_point_query WHERE `key` = -2147481418;
观察执行计划输出
如果优化成功生效,您将在执行计划的叶子节点扫描部分(如 VOlapScanNode)看到醒目的 SHORT-CIRCUIT 关键字。
+-------------------------------------------------------------------------------+
| Explain String |
+-------------------------------------------------------------------------------+
| ... |
| 0:VOlapScanNode |
| TABLE: test.tbl_point_query(tbl_point_query), PREAGGREGATION: ON |
| PREDICATES: `key` = -2147481418 AND `test`.`tbl_point_query`.`__DORIS_DELETE_SIGN__` = 0 |
| partitions=1/1 (tbl_point_query), tablets=1/1, tabletList=360065 |
| cardinality=9452868, avgRowSize=833.31323, numNodes=1 |
| pushAggOp=NONE |
| SHORT-CIRCUIT |
| ... |
+-------------------------------------------------------------------------------+
只要出现了 SHORT-CIRCUIT,就说明您的 SQL 已经成功绕过了复杂的优化器引擎,采用了最轻量级的执行方式!
总结
要在 Apache Doris 中完美压榨高并发点查的性能,需要打出一套组合拳:
- 表设计先行:MOW (
enable_unique_key_merge_on_write) + 行存 (store_row_column) + 轻量表变更 (light_schema_change) 缺一不可。 - 客户端配合:开启 JDBC Server 端的 PrepareStatement 支持。
- 服务端提速:BE 节点合理分配并开启
Row Cache。 - 验证闭环:通过
EXPLAIN认准SHORT-CIRCUIT标识。
掌握这套方法论,不仅能让 Doris 轻松应对百万级的日志分析,也能在毫秒级延迟的高并发线上服务中游刃有余。
更多推荐


所有评论(0)