Ignite FieldsQueryCursor吞吐量是否与投影宽度呈非线性关系?
测试场景与环境
- Ignite版本:2.15
- 部署架构:本地客户端节点+数据节点;后续扩展为3节点集群
- 缓存配置:ATOMIC缓存
- 查询方式:eager模式下启用
keepBinary的SqlFieldsQuery,执行无过滤条件的简单SELECT语句 - 数据集:
- 本地测试:15MB总数据量,3500条记录,每条约包含60个字段
- 集群测试:80GB总数据量
本地测试实际结果
| 投影字段数 | 延迟(毫秒) | 数据量(字节) | 速率(MB/秒) |
|---|---|---|---|
| 3个字段 | 23 | 300K | 13 |
| 20个字段 | 38 | 3M | 79 |
| 全部字段 | 80 | 14M | 175 |
预期理想结果(恒定吞吐量175MB/秒)
| 投影字段数 | 延迟(毫秒) | 数据量(字节) | 速率(MB/秒) |
|---|---|---|---|
| 3个字段 | 1.7 | 300K | 175 |
| 20个字段 | 17 | 3M | 175 |
| 全部字段 | 80 | 15M | 175 |
集群测试补充结果(3节点集群,80GB数据集)
| 投影字段数 | 速率(MB/秒) |
|---|---|
| 3个字段 | 51 |
| 20个字段 | 283 |
问题与解答
问题:Ignite中Cursor吞吐量是否与投影宽度呈非线性关系?若是,原因是什么?
是的,Ignite Cursor吞吐量与投影宽度呈现明显的非线性正相关关系,核心原因来自以下几个维度:
序列化/反序列化的固定开销分摊差异
服务端序列化结果、客户端解析二进制数据时,都会产生固定开销(比如二进制协议头、字段元数据标识等)。当投影字段数少的时候,单条记录的有效数据量小,固定开销占总处理时间的比例极高,拉高了单位数据的处理成本;随着投影字段增多,固定开销被分摊到更多有效数据上,单位数据的处理成本被摊薄,吞吐量随之大幅提升。网络传输的批量效率差异
Ignite采用批量方式传输查询结果。投影字段少的场景下,单条记录数据量小,每个网络数据包的有效载荷占比低(大量空间被记录元数据占用),同时频繁的数据包交互会带来额外的TCP协议开销(如ACK确认、连接维护);而投影字段多的场景中,每个数据包的有效数据占比更高,网络传输效率被最大化,整体吞吐量显著提升。服务端字段筛选的额外开销
服务端提取部分字段时,需要遍历记录的所有字段并筛选出目标字段,这个筛选逻辑会产生额外CPU开销。当投影字段数极少时,筛选逻辑的开销与直接读取整条记录的开销相比占比极高;随着投影字段增多,筛选逻辑的相对占比逐渐降低,服务端处理效率趋近于读取整条记录的最优状态。客户端结果处理的开销分摊
客户端调用cursor.getAll()时,即使启用keepBinary,也需要解析二进制结构。投影字段少的场景下,每条记录的解析逻辑中,元数据处理的占比更高;随着投影字段增多,解析逻辑的开销被更多有效数据分摊,单位数据的处理速度更快。
内容的提问来源于stack exchange,提问作者Anton Shkrunin

