Space Saving Algorithm
Summary
topk问题:从一个数组中取出出现频率最高的k个元素。这个问题最简单的想法就是弄一个map,用来保存key和value,(value表示key出现的次数)。最后选择value最大的前k个key,就可以得到解决。但是当元素的数量很多的时候,那么map里的key会非常多,如果超过了机器的内存的话,这个方法就不可行了。我们需要一个方法来解决这个问题,那就是Space Saving Algorithm, 这是一个概率性的方法,存在一定的误差,但是基本可以解决topk的问题。至于为什么叫Space Saving,大概就是因为它只需要保存k个 key,value,比起原始的保存所有的kv更节省空间?
这里我们会分为三个大点来介绍SS。
- Space Saving Algorithm(最原始的方法)
- Filtered Space Saving Algorithm(优化方向1)
- Parallel Space Saving Algotithm(优化方向2)
- ClickHouse中的SpaceSaving
Space Saving Algorithm
- 用一个cap为k的map来记录结果,count初始化为0
- 读取key并存入map,count++,直到map.size() == k
- 如果遇到新的key
- key in map: 对应的count++(i.e.map[key]++)
- key not in map: 把count最小的key替换为新key,并且count++;
- 最后读取完数据流之后,返回最后的map
Filtered Space Saving Algorithm
比起基本的SS算法, FSS在遇到新key的替换策略上做了优化,使得出现误差的可能性更低。detail paper 加了一个bitcount的数据结构来处理新key。
Parallel Space Saving Algorithm
CK中的Space Saving Algorithm
CK中的topk函数使用的SpaceSaving结合了上面的两个论文里的优点,就是PSS 方法中的SS替换成了FSS.