Theine - 新一代高性能&高命中率泛型内存缓存 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
matrix1010

Theine - 新一代高性能&高命中率泛型内存缓存

  •  
  •   matrix1010
    Yiling-J Apr 14, 2023 4406 views
    This topic created in 1109 days ago, the information mentioned may be changed or developed.

    先上链接和 benchmarks:

    https://github.com/Yiling-J/theine-go

    cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz BenchmarkGetTheineParallel-12 32432190 36.39 ns/op 0 B/op 0 allocs/op BenchmarkGetRistrettoParallel-12 63978058 18.86 ns/op 17 B/op 1 allocs/op BenchmarkSetTheineParallel-12 20791834 84.49 ns/op 0 B/op 0 allocs/op BenchmarkSetRistrettoParallel-12 23354626 65.53 ns/op 116 B/op 3 allocs/op BenchmarkZipfTheineParallel-12 14771362 74.72 ns/op 1 B/op 0 allocs/op BenchmarkZipfRistrettoParallel-12 21031435 61.82 ns/op 100 B/op 3 allocs/op 

    由于充分利用 sync pool 以及 atomic ,Theine 的 GC 压力很低,同时有着和 Ristretto 同一数量级的性能。

    相比于 Ristretto ,Theine 最大的特点其实是极高的缓存命中率,benchmark 结果都是图片,可以直接去 README 看: hit-ratios。简单来说 Ristretto 是通过丢弃请求来达到高性能,代价就是高写入下大量 Set 请求丢弃导致缓存命中率大幅下降。而 Theine 则通过合理的架构避免了这个问题。

    同时 Theine 也有 Python 版本: https://github.com/Yiling-J/theine. 所以你也许会觉得看到这个名字眼熟。Theine-Go 的 TinyLFU 部分其实是直接从 Python 版本转过来的,但在提高性能方面 Python 和 Go 版本的 Theine 都根据对应的语言特性做了优化

    26 replies    2023-05-02 10:13:42 +08:00
    artnowben
        1
    artnowben  
       Apr 14, 2023
    请教一下应用场景,学习下,谢谢
    matrix1010
        2
    matrix1010  
    OP
       Apr 14, 2023
    @artnowben 应用场景可参考同类的[caffeine]( https://github.com/ben-manes/caffeine), [ristretto]( https://github.com/dgraph-io/ristretto). 简单来说存在内存里就是快,同时不需要序列化 /反序列化。但内存空间有限,所以要想办法提高缓存命中率
    victorc
        3
    victorc  
       Apr 14, 2023
    这方向属于做 mini-mini 市场,缓存的刚需是基于分布式缓存,这是云原生-微服务-无状态架构浪潮推动的。in-process ,一个 map 不就行了
        4
    matrix1010  
    OP
       Apr 14, 2023
    @victorc 很多 web 框架都支持内存缓存以及多级缓存,毫无疑问内存缓存的性能远高于分布式缓存。另一方面对于数据库或者持久化 KV ,一般也都有内存缓存层来提高性能,比如 pebble 就是用的 clock pro 。当然市场 /浪潮什么的作为 cto 可能比较关心,但我作为普通开发人员还是致力于写出高性能并且有点意思的东西
    Kould
        5
    Kould  
       Apr 14, 2023   1
    感觉不错
    victorc
        6
    victorc  
       Apr 14, 2023
    @matrix1010 性能不是首先考虑项,微服务:多个节点+不保存状态,只能用基于网络的缓存,就是大用特用 redis 。

    从整个架构来评估性能,很少会去抠某一个 in-memory cache 的 get/set 性能,time cost 大头不在这里
    matrix1010
        7
    matrix1010  
    OP
       Apr 14, 2023
    @victorc 你要说微服务只能用网络缓存有点武断了,唯一没法用内存缓存的情况就是 serverless 。至于实际用什么,怎么用完全取决于产品的技术需求和公司的实际情况。
    qile1
        8
    qile1  
       Apr 14, 2023 via Android
    @matrix1010 现在我想 fastapi 里面的医生字典和科室字典能不能放到这个缓存里面,当我更新字典时候能不能更新字典,或者用户登录的 token 能不能放这里,放这里怎么获取有没有方法?能不能当 radis 用?
    jorneyr
        9
    jorneyr  
       Apr 14, 2023
    @matrix1010 微服务,负载均衡的请求下,一个请求可能被路由到不同的服务,不用网络缓存,服务之间应该怎么共享缓存,怎么做呢?
    matrix1010
        10
    matrix1010  
    OP
       Apr 14, 2023
    @qile1 你说的是 Python 版本吧。由于不确定你的架构,比如几台服务器,一致性需求等我没法直接回答你。简单来说你就可以把 Theine 当作一个字典,只是这个字典能设定最多存储多少内容和内容的过期时间。超过最大 size 这个字典会根据一定的规则自动删除数据。如果这样能满足你的需求你可以试一试
    sadfQED2
        11
    sadfQED2  
       Apr 14, 2023 via Android
    单机缓存直接一个 map ,分布式缓存直接一个 redis
    matrix1010
        12
    matrix1010  
    OP
       Apr 14, 2023
    @jorneyr 比如你的微服务 A 需要从微服务 B 获取用户信息。获取时先检查本地缓存,如果本地缓存有就用,没有就从微服务 B 获取然后存入本地缓存。这里有 2 个问题,1 是一致性,如果你可以接受短期不一致设个几十秒的 ttl 自动过期就行,或者你可以通过 mq 之类的同步,但总会有一定的不一致。第 2 是并发问题,比如微服务 B 有 10 个 pods ,那这 10 个 pods 都没有缓存的话会同时发请求,如果你的单个微服务有几千个 pods 而且全部同时 miss 可能会瞬间有很大压力
    FrankAdler
        13
    FrankAdler  
       Apr 14, 2023
    支持一下
    djoiwhud
        14
    djoiwhud  
       Apr 14, 2023 via Android
    go 缓存只有两种。一种 redis ,一种 map 。
    jorneyr
        15
    jorneyr  
       Apr 14, 2023
    @matrix1010
    同一个服务高可用呢,服务名一样,负载均衡的情况。
    还有通过 mq 做缓存,太有想法了。
    matrix1010
        16
    matrix1010  
    OP
       Apr 14, 2023
    说缓存只有两种, redis 和 xxx 的,memcached 要哭了
    matrix1010
        17
    matrix1010  
    OP
       Apr 14, 2023
    @jorneyr 感觉没有理解你想表达什么。但就像我说的实际使用方法取决于你的产品和架构,我只是来推广一下我这个库而已
    realpg
        18
    realpg  
    PRO
       Apr 14, 2023
    @matrix1010 #16
    2023 年你还见过新建项目用 memcached 的么?
    matrix1010
        19
    matrix1010  
    OP
       Apr 14, 2023
    @realpg 我在的公司没用过。但至少 aws 的 whitepaper 还是挺推荐 memcached 的: https://docs.aws.amazon.com/whitepapers/latest/scale-performance-elasticache/memcached-vs.-redis.html
    Kould
        20
    Kould  
       Apr 19, 2023
    感觉不少人对缓存应用的概念有着不是很恰当的认知,楼主这类的缓存框架与 map 类似主要还是服务于业务层代码,而不少人一下子就开始以分布式的宏大场景去讨论且与 Redis 相提并论。离谱
    matrix1010
        21
    matrix1010  
    OP
       Apr 19, 2023
    @Kould 这令我想到了这几天在 zhihu 上看到的帖子,游戏服务器为什么不用 Redis 。毕竟互联网天天都和 Redis 打交道,面试也是各种卷 Redis ,这么信仰 Redis 也挺正常
    cuebyte
        22
    cuebyte  
       Apr 22, 2023   1
    支持!
    zhujq
        23
    zhujq  
       Apr 25, 2023   1
    支持支持
    zzl22100048
        24
    zzl22100048  
       Apr 28, 2023
    如果能加上一个过期回调就好了,这样可以当延迟队列用
    matrix1010
        25
    matrix1010  
    OP
       Apr 28, 2023 via iPhone
    @zl22100048 最新版本已经加上回调了。不过由于 timingwheel 的特性过期回调触发的时间不是精确的,只能保证最终会发生
    matrix1010
        26
    matrix1010  
    OP
       May 2, 2023
    顺带补充一点,Redis 的 client-side caching 其实就是 redis+local 两级 cache ,缓存失效时 client1->redis server->client2 发通知。有些 redis 的 client 没有这个功能,有些则使用简单 LRU, 这也是 Theine 的潜在使用场景。client-side caching 的设计可以看: https://redis.io/docs/manual/client-side-caching/#the-redis-implementation-of-client-side-caching
    About     Help     Advertise     Blog     API     FAQ     Solana     5395 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 69ms UTC 05:50 PVG 13:50 LAX 22:50 JFK 01:50
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86