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

Springboot 应用关闭清理 Redis 的 key

  •  
  •   nitouge · 127 天前 · 3554 次点击
    这是一个创建于 127 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前是 toB 项目,有些文件生产耗时比较久,生成的时候设置了锁,使用了 Redis,如果在生成阶段,应用停止,这些 key 会导致没有删除。目前有两种想法,1.需要应用关闭清理的 key ,在设置的使用同时也设置到一个统一的 Redis Set 中,在最后应用关闭的时候使用实现 DisposableBean 的 destroy 删除这些 key;2.可能就是把所有的前缀放到集合,通过 SCAN 方法,获取到也是 DisposableBean 的 destroy ;清理都是通过钩子函数去做 @PreDestroy 或者使用 ApplicationListener这些都可以。大家一般怎么做的。

    第 1 条附言  ·  127 天前
    统一回复下,时间是设置了的,可能有这种情况,有的 key 的时间较长,应用重新上新,关闭的时候 key 没有删除,重启后,再次访问可能 key 存在,导致无法操作
    37 条回复    2024-07-05 18:51:55 +08:00
    KongLiu
        1
    KongLiu  
       127 天前
    我们 redis 都是要设置过期时间的,让他自然过期
    kingbill
        2
    kingbill  
       127 天前
    Lifecycle 接口?
    635925926
        3
    635925926  
       127 天前
    设置过期时间
    lsk569937453
        4
    lsk569937453  
       127 天前
    设置锁的时候加一个过期时间啊。看你的描述是用的 java ,我记得有封装好的方法在 getlock 的时候默认加超时时间,还有看门狗机制。
    BBCCBB
        5
    BBCCBB  
       127 天前
    看 redisson lock
    Goooooos
        6
    Goooooos  
       127 天前
    心跳机制,key 设置 N 秒过期。
    应用[1,N)秒定时刷新 key 的有效期。
    BBCCBB
        7
    BBCCBB  
       127 天前
    只设置过期时间也不行, 还要续约.
    billbur
        8
    billbur  
       127 天前
    设置过期时间,java 的话有很多,有个叫 redisson 的可以直接用,不用自己实现锁
    Plutooo
        9
    Plutooo  
       127 天前
    直接引入 redisson 好了,设置好过期时间
    billbur
        10
    billbur  
       127 天前
    @billbur 还有就是 redisson 的锁是有看门狗机制的,可以不用开发者自己设置锁的超时时间,需要你自己评估
    yangyaofei
        11
    yangyaofei  
       127 天前   ❤️ 1
    为啥非要关闭的时候清空呢, 在启动的时候清空不也一样么, 还好实现
    nitouge
        12
    nitouge  
    OP
       127 天前
    @yangyaofei 通过 ContextRefreshedEvent 时间去清理吗
    nitouge
        13
    nitouge  
    OP
       127 天前
    @billbur 项目没引入 redisson ,新的项目中引入了,是不是可以时间不设置或者设置不那么长,通过续期解决,即使应用关闭了,到了过期时间也就删除了
    nitouge
        14
    nitouge  
    OP
       127 天前
    @Plutooo 是不是不能设置太长时间,靠 Redisson 续期来做
    billbur
        15
    billbur  
       127 天前
    @nitouge #13 具体可以去看 lock 的用法,不需要你自己续期,时间到了自然失效了
    BBCCBB
        16
    BBCCBB  
       127 天前
    ... 你们应用重启的时候做了优雅关闭吗? 你不得等正在跑的流程跑完了才重启??? 跑完了锁就会正常释放了呀.
    Misakas
        17
    Misakas  
       127 天前
    从程序的角度来说一下,可以在代码侧监听 signal 信号,一般使用 kill 命令、systemd 停止的时候会收到。当程序被要求停止时去把需要清理的给删一下。当然只在应用正常关闭时有用,崩溃是不行的
    Shinu
        18
    Shinu  
       127 天前
    "如果在生成阶段,应用停止,这些 key 会导致没有删除"

    没有做优雅关闭吗?
    如果不考虑优雅关闭, 也不需要考虑生成到一半的文件, 那就在启动的时候清理 key 呗
    Habyss
        19
    Habyss  
       127 天前
    toB 的话, 如果不是多服务使用这个 key, 就是如果是单体应用的话, 可以写在内存里 比如 Guava Cache

    还有如果关闭应用比较不好处理的话, 可以换个思路, 比如启动应用的时候清理? 这样是不是容易一些
    pota
        20
    pota  
       127 天前
    服务启动时初始化一个时间相关的 key 做为全局的 prefix ?
    z1829909
        21
    z1829909  
       127 天前
    加锁的时候, 把锁的 value 设置为当前时间.
    校验锁之前, 先 get 一下 value, 如果在应用启动时间之前, 作为脏数据覆盖掉
    然后就是和之前一样的逻辑, 拿锁, 操作, 释放
    这样虽然多了一步操作, 但是心智负担比较低.

    然后看有人提每次应用启动, 设置锁的 prefix 不一样, 感觉是一个更好的方法
    我感觉你如果扫描删除 key, 太依赖删除步骤的可靠性了, 总有特殊情况导致删除没成功, 或者没触发
    WispZhan
        22
    WispZhan  
       126 天前
    Graceful Shutdown 是合理诉求。
    Spring 的话看 SmartLifecycle

    强烈建议任何应用做好 Lifecycle 维护。
    yangyaofei
        23
    yangyaofei  
       126 天前
    @nitouge #12 随便吧, 或者怎么用的怎么清就好了, 这还非要用什么方式去实现么
    cdlnls
        24
    cdlnls  
       126 天前 via Android   ❤️ 2
    我想为啥不在启动的时候清空 redis 呢
    iseki
        25
    iseki  
       126 天前
    如果要增加超时机制,就必须考虑如果程序因为种种原因暂停(垃圾回收、VM 迁移)导致锁超时,恢复运行后,“以为”自己还持有锁会导致何种问题。考虑的最后往往是别用这个破锁了。
    kivmi
        26
    kivmi  
       126 天前
    生成好的和没有生成完的 key 都可以清理掉?
    kivmi
        27
    kivmi  
       126 天前
    你这个 redis 是用来做分布式锁么?还是进程级别的锁?生成文件用分布式锁,貌似吞吐很小啊
    dddd1919
        28
    dddd1919  
       126 天前   ❤️ 2
    如果要关闭服务清空,不如直接内存缓存,redis 多此一举
    nitouge
        29
    nitouge  
    OP
       126 天前
    @BBCCBB 我是接手的项目,没有启用优雅关闭,但是他这个项目有几个接口时间挺长的,但是他们不想做下载中心,业务也不提,就是觉得下载当前出来就行
    nitouge
        30
    nitouge  
    OP
       126 天前
    @Misakas 的确 kill -15 或者-2 可以检测到, -9 或者崩溃是不行的,关闭的资源不会清理
    nitouge
        31
    nitouge  
    OP
       126 天前
    @Shinu 没有启用优雅关闭,但是他这个项目有几个接口时间挺长的,但是他们不想做下载中心,业务也不提,就是觉得下载当前出来就行,感觉还是启动的时候做比较好
    nitouge
        32
    nitouge  
    OP
       126 天前
    @yangyaofei 倒不是非要什么方式,我只是随便说一个在启动时清理,感觉好实现还好点
    nitouge
        33
    nitouge  
    OP
       126 天前
    @kivmi 对的,分布式锁,耗时比较长,我刚接手,我想做下载中心,他这个下载的接口比较多,有的耗时比较长
    nitouge
        34
    nitouge  
    OP
       126 天前
    @z1829909 的确太依赖删除步骤的可靠性
    baoshijiagong
        35
    baoshijiagong  
       126 天前
    启动时候清空 redis 通配符。通配符为包空间,也就是说,所有当前程序用的 key 前都带上包名,以此清空当前程序的所有 redis ,不影响别的程序。
    kivmi
        36
    kivmi  
       126 天前
    加锁的目的是什么?
    zvvvvv
        37
    zvvvvv  
       123 天前 via iPhone
    看着描述像是单体应用,为啥不直接放内存里
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3159 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 12:28 · PVG 20:28 · LAX 04:28 · JFK 07:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.