V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
admirez
V2EX  ›  问与答

用 hashmap 的缓存管理有什么好的定时清理思路吗?比如进入缓存超过五分钟就丢弃

  •  
  •   admirez · 2018-01-10 09:02:56 +08:00 via iPhone · 5036 次点击
    这是一个创建于 2491 天前的主题,其中的信息可能已经有所发展或是发生改变。
    21 条回复    2019-03-30 00:35:16 +08:00
    Boyizmen
        1
    Boyizmen  
       2018-01-10 09:10:59 +08:00
    java 里有个 WeakHashMap,key 不再被引用就会自动清理
    archer2ee
        2
    archer2ee  
       2018-01-10 09:11:59 +08:00 via iPhone
    guavaa cache,自带过期失效。
    chocotan
        3
    chocotan  
       2018-01-10 09:16:56 +08:00
    MarcoQin
        4
    MarcoQin  
       2018-01-10 09:26:17 +08:00
    进入缓存带上时间戳,取的时候每次都比较时间戳,若是超过 5 分钟就清楚并重新获取数据进行缓存
    qianlv7
        5
    qianlv7  
       2018-01-10 09:45:17 +08:00
    LRU
    admirez
        6
    admirez  
    OP
       2018-01-10 10:07:31 +08:00 via iPhone
    @MarcoQin 如果只是取的时候比较,那么一直没有被缓存命中的怎么办?
    admirez
        7
    admirez  
    OP
       2018-01-10 10:09:08 +08:00 via iPhone
    @Boyizmen key 不再被引用那一秒钟就被释放达不到缓存目的,或者我理解错误?
    justfly
        8
    justfly  
       2018-01-10 10:30:54 +08:00
    如果要求对空间要求比较高,那就定时(比如每秒)在另一个线程扫一遍,可以加一个辅助一个按时间顺序的 List,找到 5min 以外的就可以。

    不要求太精确空间控制的话,或者限制单线程场景下,每次写入的时候做一下上面的扫描清除逻辑。

    或者再复杂,参考 redis 的过期策略,取样、算比例、清理,可以读下 redis 的过期逻辑。
    MarcoQin
        9
    MarcoQin  
       2018-01-10 11:03:12 +08:00
    @admirez #6 一直没有被命中的情况我猜是请求频率太低导致的?那这样的话是否还需要缓存……

    取的时候如果没有命中,那就再重新写入缓存……当然,这种方式适合临时做或少量的缓存。大量应用缓存的话,用定时任务做可能好一些,比如楼上说的那样
    Boyizmen
        10
    Boyizmen  
       2018-01-10 11:06:40 +08:00
    @admirez 应该是,文档我也没细看
    xcolder
        11
    xcolder  
       2018-01-10 11:14:27 +08:00
    Guava Cache + 1
    rockyou12
        12
    rockyou12  
       2018-01-10 11:16:39 +08:00
    lz 要不是有什么特别业务直接用 google guava 里的 cache 就行了,很简单的
    yangg
        13
    yangg  
       2018-01-10 11:23:26 +08:00
    同求 node 或者 js 的
    innoink
        14
    innoink  
       2018-01-10 11:29:07 +08:00
    LRU,双链表
    noe132
        15
    noe132  
       2018-01-10 12:11:17 +08:00 via Android
    node 有 lru-cache。可以设置个定时任务清理过期的缓存
    bazingaterry
        16
    bazingaterry  
       2018-01-10 12:19:51 +08:00 via iPhone   ❤️ 1
    參考一下 Redis 的實現唄
    honeycomb
        17
    honeycomb  
       2018-01-10 13:08:46 +08:00 via Android
    guava cache

    eviction 机制比较优雅,而且要使用 weak/soft 引用也没问题,回调 /权重 /load 接口,错误处理 /性能统计,builder 等都预先准备好了。
    HaoyangWei
        18
    HaoyangWei  
       2018-01-10 14:25:41 +08:00
    如果说自己造轮子的话,map+双向链表=>LRU map
    使用时读取前检查时间,写入前检查时间并最多尝试淘汰 2 个元素
    就好啦:)
    th00000
        19
    th00000  
       2018-01-10 15:13:00 +08:00
    可以参考热点缓存机制, 简单来说就是维护一个 1000 长度的队列, 每次用的时候就放到队列头, 每 5 分钟清除队列尾部的 200 条数据, 再从数据库中拿 200 条来补充. 以此来实现
    argsno
        20
    argsno  
       2018-01-10 15:14:03 +08:00
    Redis 在读取数据的时候判断是否过期,以及定期删除过期的键
    c4f36e5766583218
        21
    c4f36e5766583218  
       2019-03-30 00:35:16 +08:00
    Guava CacheBuilder
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3190 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:18 · PVG 08:18 · LAX 16:18 · JFK 19:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.