Issue:FieldQueryCache 不支持 Value::BigUint
问题类型
- 类型:Bug / 性能问题
- 组件:
wp-knowledge
- 影响版本:
0.16.0
- 影响场景:OML 使用
ip_to_biguint 进行 IP 数值转换后执行 SQL 查询
问题描述
当前 wp-knowledge 0.16.0 中的 FieldQueryCache 仅支持以下参数类型:
Value::Chars
Value::Digit
Value::IpAddr
不支持 Value::BigUint。
OML 的 ip_to_biguint 会生成 Value::BigUint。因此,使用转换结果作为 SQL 参数时,即使查询参数和查询结果完全相同,本地字段查询缓存也无法命中。
复现方式
OML 规则示例:
__sip_ip_num = pipe @__sip | ip_to_biguint;
__sip_country_code, __sip_country_name = select country_iso_code, country_name
from geo.ip_geo
where start_ip_num <= @__sip_ip_num
and end_ip_num >= @__sip_ip_num
order by start_ip_num desc
limit 1;
连续发送相同 IP,使 @__sip_ip_num 每次生成相同的 BigUint 值。
实际行为
FieldQueryCache 的本地索引逻辑没有处理 Value::BigUint,该类型会落入默认分支:
结果如下:
- 查询前无法通过
BigUint 参数查找本地缓存。
- 查询完成后无法使用
BigUint 参数保存本地缓存索引。
- 后续相同查询持续发生本地缓存 miss。
预期行为
对于相同的 SQL、相同的参数类型以及相同的 BigUint 参数值:
- 第一次查询访问 provider 并写入本地缓存。
- 后续查询命中
FieldQueryCache。
- 后续查询不再重复访问 PostgreSQL provider。
性能影响
当前 IP 查询压测结果:
- PostgreSQL 单独执行真实 IP 查询:平均约
0.010 ms,串行 QPS 约 97,179。
- 整体 OML 规则关闭全局结果缓存:吞吐仅为几千级。
- 开启全局结果缓存:吞吐提升到约
2 万级。
这说明全局结果缓存已经生效,但 BigUint 查询仍无法使用 FieldQueryCache 本地缓存。
为什么全局缓存开启后仍然会变快
当前系统存在两层缓存:
FieldQueryCache:OML 查询使用的本地字段缓存,目前不支持 BigUint。
- 全局 SQL 结果缓存:缓存完整 SQL 查询结果,支持
BigUint 参数哈希。
因此,即使本地缓存 miss,开启全局结果缓存后仍可能走以下路径:
OML 查询
-> FieldQueryCache miss
-> 全局 SQL 结果缓存 hit
-> 直接返回缓存结果
关闭全局结果缓存时,路径变为:
OML 查询
-> FieldQueryCache miss
-> PostgreSQL 查询
-> 结果转换与字段拷贝
全局缓存命中可以绕过连接池获取、网络通信、PostgreSQL 执行、结果读取和部分 provider 开销,因此即使没有修复 BigUint 的 local cache,enabled = true 仍然会明显提升性能。
根因
FieldQueryCache 的参数索引逻辑未覆盖 Value::BigUint:
get_idx 不支持 BigUint。
try_up_idx 不支持 BigUint。
- 索引达到上限重置时没有清理
BigUint 索引。
修复建议
为 FieldQueryCache 增加独立的 BigUint 索引,例如:
biguint_idx: HashMap<String, usize>
并在以下位置增加 Value::BigUint 处理:
get_idx
try_up_idx
- 本地索引重置逻辑
建议使用规范化十进制字符串或 BigUint 本身作为索引键,并保持类型隔离,避免以下两个值发生冲突:
Value::Chars("1")
Value::BigUint(1)
验收标准
- 相同
BigUint 参数可以命中本地缓存。
- 不同
BigUint 参数不会发生缓存碰撞。
Chars、Digit、IpAddr 和 BigUint 之间不会发生缓存碰撞。
- 本地索引达到重置阈值后,
BigUint 索引也会被清理。
- provider generation 变化时,缓存失效行为保持不变。
- 增加单参数和多参数
BigUint 查询的单元测试。
- 开启全局结果缓存和关闭全局结果缓存时,缓存命中统计符合预期。
相关说明
当前 PostgreSQL 的 IP 查询执行计划和索引正常,问题重点不在 PostgreSQL 索引,而在 OML 查询链路中的缓存分层以及 BigUint 类型支持不完整。
Issue:
FieldQueryCache不支持Value::BigUint问题类型
wp-knowledge0.16.0ip_to_biguint进行 IP 数值转换后执行 SQL 查询问题描述
当前
wp-knowledge 0.16.0中的FieldQueryCache仅支持以下参数类型:Value::CharsValue::DigitValue::IpAddr不支持
Value::BigUint。OML 的
ip_to_biguint会生成Value::BigUint。因此,使用转换结果作为 SQL 参数时,即使查询参数和查询结果完全相同,本地字段查询缓存也无法命中。复现方式
OML 规则示例:
连续发送相同 IP,使
@__sip_ip_num每次生成相同的BigUint值。实际行为
FieldQueryCache的本地索引逻辑没有处理Value::BigUint,该类型会落入默认分支:_ => None结果如下:
BigUint参数查找本地缓存。BigUint参数保存本地缓存索引。预期行为
对于相同的 SQL、相同的参数类型以及相同的
BigUint参数值:FieldQueryCache。性能影响
当前 IP 查询压测结果:
0.010 ms,串行 QPS 约97,179。2 万级。这说明全局结果缓存已经生效,但
BigUint查询仍无法使用FieldQueryCache本地缓存。为什么全局缓存开启后仍然会变快
当前系统存在两层缓存:
FieldQueryCache:OML 查询使用的本地字段缓存,目前不支持BigUint。BigUint参数哈希。因此,即使本地缓存 miss,开启全局结果缓存后仍可能走以下路径:
关闭全局结果缓存时,路径变为:
全局缓存命中可以绕过连接池获取、网络通信、PostgreSQL 执行、结果读取和部分 provider 开销,因此即使没有修复
BigUint的 local cache,enabled = true仍然会明显提升性能。根因
FieldQueryCache的参数索引逻辑未覆盖Value::BigUint:get_idx不支持BigUint。try_up_idx不支持BigUint。BigUint索引。修复建议
为
FieldQueryCache增加独立的BigUint索引,例如:并在以下位置增加
Value::BigUint处理:get_idxtry_up_idx建议使用规范化十进制字符串或
BigUint本身作为索引键,并保持类型隔离,避免以下两个值发生冲突:验收标准
BigUint参数可以命中本地缓存。BigUint参数不会发生缓存碰撞。Chars、Digit、IpAddr和BigUint之间不会发生缓存碰撞。BigUint索引也会被清理。BigUint查询的单元测试。相关说明
当前 PostgreSQL 的 IP 查询执行计划和索引正常,问题重点不在 PostgreSQL 索引,而在 OML 查询链路中的缓存分层以及
BigUint类型支持不完整。