*Redis CF.RESERVE 命令

CF.RESERVE 创建一个空的 Cuckoo Filter,可指定容量和高级参数。


*语法

CF.RESERVE key capacity [BUCKETSIZE bucketsize] [MAXITERATIONS maxiterations] [EXPANSION expansion]

*参数说明

参数 类型 必填 说明
key String Cuckoo Filter 的键名
capacity Integer 过滤器的预估容量(会被向上取整到最近的 2n)
BUCKETSIZE bucketsize Integer 每个桶的大小(1-255,默认 2)
MAXITERATIONS maxiterations Integer 最大迭代次数(1-65535,默认 20)
EXPANSION expansion Integer 扩展倍率(0-32768,默认 1)

*返回值

  • OK:过滤器创建成功
  • Simple error reply:参数错误、键已存在或内存不足时返回

*时间复杂度

O(1)

*

*示例

*基本用法

> CF.RESERVE cf 1000
OK

*键已存在时创建

> CF.RESERVE cf 1000
(error) ERR item exists

*自定义参数创建

> CF.RESERVE cf_params 1000 BUCKETSIZE 8 MAXITERATIONS 20 EXPANSION 2
OK

*创建小容量高精度过滤器

> CF.RESERVE cf_precise 1000 BUCKETSIZE 1 EXPANSION 0
OK

*常见错误

错误 原因 解决
ERR wrong number of arguments 参数数量不足 提供 key 和 capacity 参数
ERR item exists 键已存在 使用不同的键名,或先删除现有键
ERR bad capacity 容量参数无效 确保 capacity 为正整数
ERR bad bucketsize Bucket size 超出范围 确保 bucketsize 在 1-255 之间
ERR bad maxiterations Max iterations 超出范围 确保 maxiterations 在 1-65535 之间
ERR bad expansion Expansion 超出范围 确保 expansion 在 0-32768 之间

*最佳实践

  • 预留额外容量:Cuckoo Filter 通常不会填满到 100% 容量,建议预留 20-30% 的额外空间以避免过早扩展
  • Bucket size 权衡:默认值为 2,提供较好的平衡。更小的值(如 1)降低错误率但降低填充率;更大的值提高填充率但增加错误率和轻微性能损耗
  • Expansion 设置:默认值为 1,表示每次扩展时新过滤器大小翻倍。设置为 0 禁止自动扩展,适合需要严格控制内存或错误率的场景
  • Max iterations 权衡:默认值 20 适合大多数场景。更高的值提高填充率但降低插入性能;更低的值提高性能但可能更早触发扩展
  • 容量规划:容量会被向上取整到最近的 2n。例如指定 1000 实际会分配 1024 个槽位
  • 错误率估算:最小错误率约为 2/255 ≈ 0.78%(Bucket size = 1 时)。Bucket size = 3 时错误率约为 2.35%,线性增长

*FAQ

Q1: CF.RESERVE 创建的容量是精确值吗? A: 不是精确值。容量会被向上取整到最近的 2n。例如指定 1000 实际会取 1024,指定 1500 也会取 2048。实际可存储的元素数量通常不会达到这个容量的 100%。

Q2: 如果过滤器满了会怎样? A: 如果 EXPANSION > 0,过滤器会自动创建新的子过滤器,大小为前一个的 expansion 倍。如果 EXPANSION = 0,后续插入会返回 -1(已满)。自动扩展会增加错误率和降低性能。

Q3: BUCKETSIZE 对性能有什么影响? A: 更大的 BUCKETSIZE 可以存储更多指纹,提高填充率,但也会导致:1) 更高的错误率;2) 每次查询需要检查更多位置,轻微降低性能。默认 2 是大多数场景的平衡点。

Q4: 什么时候应该设置 EXPANSION 为 0? A: 当需要严格控制内存上限或错误率时。例如,如果错误率预算非常紧张,不希望扩展导致错误率上升。但此时需要确保预留足够容量,否则插入会失败。

Q5: 可以修改已创建过滤器的参数吗? A: 不可以。Cuckoo Filter 的参数在创建时确定,无法动态修改。如果需要不同的参数,只能删除并重新创建过滤器。可以使用 CF.SCANDUMP + CF.LOADCHUNK 迁移数据到新过滤器。