摘要
Count-Min Sketch
1 2 3 4 5 6
| 1.初始化一个二维数组 counter[d][w] 2.对每个元素 x: a. 通过 d 个哈希函数映射到 d 行中的 w 个位置 b. 对对应的 d 个计数器全部 +1 3.查询元素 x 的频次: a.取这 d 个计数器的 最小值(取最小值是为了尽量抵消哈希冲突带来的“多加”)
|
注意下图中的数组不是二进制的,每次映射都会+1

| 维度 |
说明 |
| 误差上界 |
≤ ε × 总插入次数 |
| 错误概率 |
≤ δ |
| 空间复杂度 |
O(1 / ε × log(1 / δ)) |
| 查询复杂度 |
O(d) |
| 更新复杂度 |
O(d) |
结论:数据量再大,内存不增长,代价是“精度换空间”
RedisBloom 中 CMS 的核心命令
创建 CMS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
CMS.INITBYDIM page:view 1000 10
OK
type page:view
CMSk-TYPE
CMS.INITBYPROB key 0.001 0.01
|
| 参数 |
数值 |
说明 |
error |
0.001 |
最大相对误差 ε = 0.1% |
probability |
0.01 |
只有 1% 的概率超过该误差 |
增加计数
1 2 3 4 5 6
| CMS.INCRBY page:view home 1 about 1 home 1
1) (integer) 1 2) (integer) 1 3) (integer) 2
|
查询计数
1 2 3 4 5 6
| CMS.QUERY page:view home about
1) (integer) 2 2) (integer) 1
|
合并 CMS
1 2 3 4 5 6 7 8 9
|
CMS.MERGE page:view 2 page:view:1 page:view:2 WEIGHTS 1 1
OK
|
获取 CMS 的信息
1 2 3 4 5 6 7 8 9
| CMS.INFO page:view
1) width 2) (integer) 1000 3) depth 4) (integer) 10 5) count 6) (integer) 3
|
CMS 的使用场景
场景1:网站PV统计
1 2 3 4 5 6 7 8
| CMS.INITBYPROB page:pv 0.001 0.01
CMS.INCRBY page:pv /home 1 /about 1 CMS.INCRBY page:pv /home 1
CMS.QUERY page:pv /home
|
场景2:接口调用频次限流前置统计
1 2 3 4 5 6
| CMS.INITBYPROB api:limit 0.001 0.01
CMS.INCRBY api:limit /api/user/list 1
CMS.QUERY api:limit /api/user/list
|