cachego只有按过期时间淘汰,没有上限控制和淘汰策略?
orca-zhang opened this issue · 12 comments
想测试一下缓存命中率,如果是现在的方式可能就不太好测试了,而且生产环境使用不当,被刷有可能会炸呀
一方面是内存爆增,一方面是map rehash时候的延迟
想测试一下缓存命中率,如果是现在的方式可能就不太好测试了,而且生产环境使用不当,被刷有可能会炸呀 一方面是内存爆增,一方面是map rehash时候的延迟
对的,目前没有做上限控制,所以需要开启定时清理,能保证一定时间内的过期数据被清理掉(其实上限控制这个很早就规划好了,但是一直没动 😓)
在 FUTURE.md 里面有写出来,我是准备做空间限制
和数量限制
两种,淘汰策略的话暂时没想好要怎么处理,可能会有直接拒绝
、TTL升序
、LRU
和LFU
这些吧,看实际情况而定
目前这个库是在线上做一些定时加载的数据容器和有 TTL 的数据缓存,偏功能向多一些,基本都是业务使用推动迭代和修复,性能上面其实没做特别多的优化哈
PS: 我一直很纠结的是内存缓存有没有必要做太多的优化,因为内存操作本身是一件很快的事情,太多的功能或者优化会不会让这个库变得过于复杂~
PPS: 毕竟,连简单的加 RWMutex 的缓存库都有几千 stars(对,我说的就是 go-cache 🤔)
另外,我前几天加入了 ecache 的对比,在 develop/_examples/performance_test.go 文件中,还没有发布 master,您也可以参考下~
那如果要做命中率测试的话,怎么做会比较好?
然后有没有可能是因为没有设置上限才导致性能表现没有想象中好呢?
看了下case,有点小问题,一个是随机数种子可以考虑保持一致,这样每个library的数据集大概率是一样的,然后的话,1024个key,对应256256的池子(freecache是10datasize),写测试默认是写不满的场景下的测试对吧?读我看意思是只保留最后的池子大小个,然后随机取部分,命中和不命中波动应该会比较大
那如果要做命中率测试的话,怎么做会比较好?
我理解缓存命中率应该是业务或者监控有关了,这个是打算用 monitor 去做,就是我在缓存内部一些位置打下钩子,然后用户自定义实现这些函数即可,还可以做各种监控指标~
或者,您是想做什么命中率测试呢
然后有没有可能是因为没有设置上限才导致性能表现没有想象中好呢?
应该不会吧,测试的使用场景中,上限好像没啥影响 😀
看了下case,有点小问题,一个是随机数种子可以考虑保持一致,这样每个library的数据集大概率是一样的,然后的话,1024个key,对应256_256的池子(freecache是10_datasize),写测试默认是写不满的场景下的测试对吧?读我看意思是只保留最后的池子大小个,然后随机取部分,命中和不命中波动应该会比较大
随机数可以保持一致,这样确实大家的读取数据是一样的~
这边测试写入的数据都是一样的哈,都是 dataSize 个,并以 i 为 key:
for i := 0; i < dataSize; i++ {
key := strconv.Itoa(i)
c.Set(key, key)
}
读取的话只是 key 是随机的,但是都会命中~
key := strconv.Itoa(rand.Intn(dataSize))
c.Get(key)
所以波动应该还好,每次测试的时候多测试几遍取个中位就可以了哈哈(可能是我懒 😅)
或者,您是想做什么命中率测试呢
缓存一般都会有一个命中率的测试,除了过期会导致缓存未命中以外,缓存池满被驱逐也会,如果没有驱逐的话,那和其他的库不太一样,也就是驱逐导致的未命中部分就没有了
或者,您是想做什么命中率测试呢
缓存一般都会有一个命中率的测试,除了过期会导致缓存未命中以外,缓存池满被驱逐也会,如果没有驱逐的话,那和其他的库不太一样,也就是驱逐导致的未命中部分就没有了
噢噢,这个测试我倒没有考虑过哎。。
我理解过期未命中的情况应该和配置(过期时间)、业务(数据的粒度、维度)有关,所以在数据存活的时候命中率应该是 100%,数据不存活的时候应该是 0% 😅
对于缓存池满了被驱逐的情况,感觉是不是也和配置(内存、数量限制大小)、业务(不管是 LRU 还是 LFU 这些算法都是访问维度处理的)有点关系~
所以不同的配置、业务(或使用方式)测试出来的命中率是不是都有很大区别,而我们要保证的,其实是在符合配置、业务(或使用方式)的前提下是有正确命中结果的吧(个人理解哈)
PS:
我一直很纠结的点是,绝对值的限定配置其实不太好配,比如限定使用内存 1G,限定数量 10w 个,都没法完全保证不会占满内存(虽然可以大幅降低概率),因为程序实际运行的环境千变万化,绝对值没办法做到自适应~
所以感觉最好是配置相对值,比如限定最多占用内存的 50%。但这样也有问题,就是缓存的利用率没法控制了,比如有些机器资源少,缓存的数据就少,如果缓存 miss 后是可以穿透的,那这些机器的缓存命中率和穿透次数会明显不佳。。
还有一个点就是,可能我们业务中比较多的场景是定时加载不穿透(一般是访问量很大,但是总量不大、更新也不频繁的数据),还有就是秒杀活动性质的热点数据(访问量很大,但是总量不大),这时候为了性能上的考虑,内存使用变得不是这么重要(因为这些活动的顺利进行收益性远大于增加机器带来的成本,几乎不会发生内存不够而触发缓存淘汰策略的情况),所以内存限定变得不是这么必要。。
当然我不是在说限制使用没用哈,只是侧重的点不同 😁
不管绝对值还是相对值,设置限制是对服务本身可用性的保障,内存用满导致正常业务无法进行,反而得不偿失
看上去你们的使用场景确实符合不需要考虑上限的情况,甚至连一致性问题都不需要考虑
没事,命中率单项测试我这边跳过就好
不管绝对值还是相对值,设置限制是对服务本身可用性的保障,内存用满导致正常业务无法进行,反而得不偿失
看上去你们的使用场景确实符合不需要考虑上限的情况,甚至连一致性问题都不需要考虑
没事,命中率单项测试我这边跳过就好
理论上说确实需要限制的,只是我们的场景来说限制不是非常重要哈哈
所以我规划了这个功能但一直没加。。(捂脸)