服装行业网站模板,手机网站 asp,汉中建筑信息平台,台州做优化redis 实现布隆过滤器实现方法#xff1a;
1、redis 的 setbit 和 getbit
特点#xff1a;对于某个bit 设置0或1#xff0c;对于大量的值需要存储#xff0c;非常节省空间#xff0c;查询速度极快#xff0c;但是不能查询整个key所有的bit#xff0c;在一次请求有大量…redis 实现布隆过滤器实现方法
1、redis 的 setbit 和 getbit
特点对于某个bit 设置0或1对于大量的值需要存储非常节省空间查询速度极快但是不能查询整个key所有的bit在一次请求有大量的值需要过滤的场景会出现多次请求getbit性能会急剧下降需要把多个gitbit合并成批次使用lua脚本或者pipeline执行提高效率。
2、redis 的 BF.RESERVEBF.MADD和 BF.MEXISTS
特点redis 4.0 以上官方提供的一个插件原生Bloom过滤器参数包括 布隆过滤器的大小误差率等支持批量写入和批量查询性能更优针对一次大量请求批量查询接口性能更快。
以上两种布隆过滤器性能测试结果对比
硬件单节点 redis2G内存2核cpu
测试条件布隆过滤器容量都是 10000容错率都是0.001 场景一次请求需要过滤10000个id每100个批量查询一次redis 如此循环 10次。
序号redis setbit getbit时延单位毫秒redis BF.RESERVEBF.MADD和 BF.MEXISTS 时延单位毫秒115561238214751164317349894303417015153212546157911797154111778156710459169812161016891275平均1740.51223.8
3、基于以上的测试结果如果一次推荐请求用户已经看过10000个视频需要过滤10000个视频时延会上涨到秒级以上这样对于高并发情况性能是不行的还有其他的办法嘛 能不能一次性把整个布隆过滤器读到本地再进行过滤
在推荐场景布隆过滤器设置了容量5000个容错率是0.001布隆过滤器的最大值为17972 byte约 17K如果每次写入和查询都查询整个布隆过滤器1000qps 占用的网络带宽为: 13.92 Mbps。
测试可行性本地构造一个布隆过滤器对象 BitSetBitSet的最大值是int的最大从redis查询出来序列化成BitSet对象再进行读写操作如果是写操作再序列化写入redis。
private BitSet get(long userId) {String key TestBloomP.getBitMapKey(userId, 111);log.info(get bitset key:{}, key);return (BitSet) redisTemplate.opsForValue().get(key);
}private void add(long userId, ListLong filterItems) {BitSet bitSet new BitSet();for (Long item : filterItems) {String uniqueKey userId : item;ListInteger offsets TestBloomP.getOffsets(uniqueKey);for (Integer offset : offsets) {bitSet.set(offset);}}String key TestBloomP.getBitMapKey(userId, 111);log.info(add bitset key:{}, size:{}, key, bitSet.size());redisTemplate.opsForValue().set(key, bitSet);
}redis 使用java默认的序列化工具JdkSerializationRedisSerializer测试结果 如下写操作会先读再写 时延都是很低
add bitset key:shop_video:filter_exposed:1607433260630157, size:143808, add count:1, time:36 get bitset time:9, bitset :143808