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

Springboot 应用关闭清理 Redis 的 key

  •  
  •   nitouge · 2 天前 · 3054 次点击

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

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

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

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

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

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