V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Nazz
V2EX  ›  程序员

golang 内存 kv 缓存怎么做 gc 优化?

  •  
  •   Nazz · 2023-02-21 13:11:07 +08:00 · 3275 次点击
    这是一个创建于 641 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概几百万到一千万个 key

    第 1 条附言  ·  2023-02-22 08:56:58 +08:00
    已经了解到, 尽量去使用值类型和切片就能缓解 GC 压力了, 谢谢各位. 可以完全使用切片去实现一个 HashMap, uint32 模拟前后指针实现链表, 使用[]byte 作为 KV, 这应该是目前最安全便利的方案了.
    42 条回复    2024-10-21 08:35:08 +08:00
    selca
        1
    selca  
       2023-02-21 13:14:13 +08:00
    挪到 redis 去,让 redis 自己优化
    Nazz
        2
    Nazz  
    OP
       2023-02-21 13:17:29 +08:00 via Android
    @selca 要的就是避免网络 IO😂
    zoharSoul
        3
    zoharSoul  
       2023-02-21 13:19:10 +08:00
    没得优化, 等堆外吧. 估计下个版本就出了
    fioncat
        4
    fioncat  
       2023-02-21 13:36:06 +08:00   ❤️ 5
    提供一种思路,如果是容器应用,可以外挂一个 redis sidecar 来储存。通过 socket 进行通信。
    同一个 network namespace 下的 socket 通信开销几乎可以忽略的。
    我们通过这种方案解决过缓存占用问题,要知道 redis 的优化肯定会比你自己做好的。
    Nazz
        5
    Nazz  
    OP
       2023-02-21 13:39:09 +08:00
    @zoharSoul 小技巧应该是有的
    Nazz
        6
    Nazz  
    OP
       2023-02-21 13:40:03 +08:00
    @fioncat 可行性不错, 不知道领导满不满意
    8355
        7
    8355  
       2023-02-21 13:54:32 +08:00
    同楼上 本质上还是本机应用 开销忽略不计 这样也好维护管理 可用性更高
    Nasei
        8
    Nasei  
       2023-02-21 14:12:08 +08:00
    这个量级的 key fastcache 也满足不了吗
    Nazz
        9
    Nazz  
    OP
       2023-02-21 14:21:02 +08:00
    @Nasei 感觉 freecache 比 fastcache 好. 还在想要不要自研, slice 的 hashmap 和 map + heap 的 ttl 我都造过轮子
    Nazz
        10
    Nazz  
    OP
       2023-02-21 14:24:46 +08:00
    @Nasei fastcache 也不错, ttl 部分可以自己撸
    qieqie
        11
    qieqie  
       2023-02-21 14:28:48 +08:00 via iPhone
    cgo
    dqzcwxb
        12
    dqzcwxb  
       2023-02-21 14:35:14 +08:00
    你可以参考 caffeine 实现一个比较完善的本地缓存,如果只需要最简单的 LRU 那么只需要 Linkedhashmap 的数据结构就可以完成
    WhereverYouGo
        13
    WhereverYouGo  
       2023-02-21 15:37:15 +08:00
    蹲一下
    Nazz
        14
    Nazz  
    OP
       2023-02-21 16:08:20 +08:00
    @qieqie cgo 太不清真了
    zeonll
        15
    zeonll  
       2023-02-21 16:46:46 +08:00
    如果使用 redis side car 的话,还得加一个 redis 的监控?
    biubiuF
        16
    biubiuF  
       2023-02-21 16:51:44 +08:00 via Android
    用大数组存 kv
    cheng6563
        17
    cheng6563  
       2023-02-21 17:26:11 +08:00
    不如直接用 unix socket 算了,性能高得很。
    Nazz
        18
    Nazz  
    OP
       2023-02-21 17:30:04 +08:00
    @zeonll 有过期时间不加也没事, pod 本身有内存监控
    Nazz
        19
    Nazz  
    OP
       2023-02-21 17:30:46 +08:00
    @cheng6563 还是觉得纯 Go 方案优雅些
    ToughGuy
        20
    ToughGuy  
       2023-02-21 17:46:24 +08:00
    leveldb 有 cgo 的封装及原生实现,但是不知道可靠性与原生的 leveldb 相比如何。
    sampeng
        21
    sampeng  
       2023-02-21 19:01:53 +08:00
    rocksdb 。
    PiersSoCool
        22
    PiersSoCool  
       2023-02-21 19:51:19 +08:00
    问问是什么样业务 这么时延敏感吗 gc 要多久
    777777
        23
    777777  
       2023-02-21 20:06:06 +08:00   ❤️ 1
    https://go.dev/doc/gc-guide 看一遍官方文档,你就会了
    kaf
        24
    kaf  
       2023-02-21 20:21:32 +08:00
    https://github.com/bluele/gcache 是要实现这个?
    securityCoding
        25
    securityCoding  
       2023-02-21 20:40:02 +08:00
    我工作的原则就是不做任何 gc 优化 233 ,不管是 java 还是 go ,横向拓展就好 233
    Nazz
        26
    Nazz  
    OP
       2023-02-21 20:44:01 +08:00 via Android
    @securityCoding key 太多了还是要优化的
    Nazz
        27
    Nazz  
    OP
       2023-02-21 20:44:54 +08:00 via Android
    @PiersSoCool 不做任何优化太浪费 CPU 和内存
    Nazz
        28
    Nazz  
    OP
       2023-02-21 20:46:48 +08:00 via Android
    @kaf 实现类似的东西
    kiddult
        29
    kiddult  
       2023-02-21 21:05:29 +08:00
    直接用现成的 bigcache 、freecache 那类就行,虽然多多少少有点坑,胜在能用
    fuxiaohei
        30
    fuxiaohei  
       2023-02-21 21:06:42 +08:00   ❤️ 1
    最近有文章的 Ristretto 可以看看
    Nazz
        31
    Nazz  
    OP
       2023-02-21 21:27:38 +08:00 via Android
    @kiddult 学习一下它们的实现方式也不错
    Nasei
        32
    Nasei  
       2023-02-21 22:50:10 +08:00
    @Nazz 既然准备优化的话,是已经影响性能了?已经做过 profile 了吗?
    Nazz
        33
    Nazz  
    OP
       2023-02-21 23:25:31 +08:00 via Android
    @Nasei 影响比较大
    lesismal
        34
    lesismal  
       2023-02-22 00:17:43 +08:00
    如果是通用缓存基础设施,用已有的那几个就可以了。但通用缓存都是走了一道序列化的,如果追求性能,表现会差一些。
    如果不是通用缓存则不需要序列化,性能可以最大化,但要根据具体业务结合 kv 类型定制去指针化了。
    lesismal
        35
    lesismal  
       2023-02-22 00:23:16 +08:00   ❤️ 1
    可以搜下几位专家的一些帖子看看,结合自己的数据类型定制+测试优化下就差不多了:
    真实环境下大内存 Go 服务性能优化一例
    曹大带我学 Go ( 11 )—— 从 map 的 extra 字段谈起
    Nazz
        36
    Nazz  
    OP
       2023-02-22 07:23:52 +08:00 via Android
    Nazz
        37
    Nazz  
    OP
       2023-02-22 07:28:02 +08:00 via Android
    @lesismal 有空自己写一个玩玩😀
    带 TTL 的 ConvurrentMap 和切片实现的 HashMap 我都实现过
    janxin
        38
    janxin  
       2023-02-22 08:30:44 +08:00
    arena 试过了吗?
    Nazz
        39
    Nazz  
    OP
       2023-02-22 08:47:55 +08:00
    @janxin 没用过
    Nazz
        40
    Nazz  
    OP
       2023-02-22 09:00:24 +08:00
    @lesismal codec 的开销可以接受
    CloveAndCurrant
        41
    CloveAndCurrant  
       2023-02-22 10:17:00 +08:00
    使用 arena 自己手动管理内存,不走 go 的 gc
    grzhan
        42
    grzhan  
       33 天前
    fastcache 的方案是 mmap 自己申请管理 kv 的内存,也绕过了 gc 。

    但是它的 hash -> idx ( bucket.m ) 索引本质是个 int->int 值类型的 map ,如果特别关注 gc 的话可能还是有一点优化的空间。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2996 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 00:14 · PVG 08:14 · LAX 16:14 · JFK 19:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.