• Redis 与 MySQL 一致性 实现方案


    正常情况下的流程是:请求来了,先检查 Redis 有没有数据,有返回;没有便查询 MySQL 然后 放入 Redis。

    此时,如果 MySQL 的数据发生了变化,所以需要同步到 Redis 中。

    解决方法:MySQL 中的数据更新的时候 ,在更新之前先删一次 Redis 中的数据,在更新之后再删一次 Redis 中的数据。

    工具类

    1. public class RedisUtil {
    2. private final static ScheduledExecutorService DELAY_EXECUTOR = new ScheduledThreadPoolExecutor(4);
    3. /**
    4. * 缓存延迟双删
    5. *
    6. * @param factory 目标任务
    7. * @param keys 插入':' 拼接成需要删除的缓存key
    8. * @param any object
    9. * @return 目标任务返回结果
    10. */
    11. public static T doubleDeletion(Supplier factory, Object... keys) {
    12. return RedisUtil.doubleDeletion(
    13. factory,
    14. () -> RedisUtil.getRedisTemplate().delete(
    15. RedisUtil.key(keys)
    16. )
    17. );
    18. }
    19. /**
    20. * 缓存延迟双删
    21. *
    22. * @param task 目标任务
    23. * @param keys 插入':' 拼接成需要删除的缓存key
    24. */
    25. public static void doubleDeletion(Runnable task, Object... keys) {
    26. RedisUtil.doubleDeletion(
    27. task,
    28. () -> RedisUtil.getRedisTemplate().delete(
    29. RedisUtil.key(keys)
    30. )
    31. );
    32. }
    33. /**
    34. * 缓存延迟双删
    35. *
    36. * @param factory 目标任务
    37. * @param key 需要删除的缓存key
    38. * @param any object
    39. * @return 目标任务返回结果
    40. */
    41. public static T doubleDeletion(Supplier factory, String key) {
    42. return RedisUtil.doubleDeletion(
    43. factory,
    44. () -> RedisUtil.getRedisTemplate().delete(key)
    45. );
    46. }
    47. /**
    48. * 缓存延迟双删
    49. *
    50. * @param task 目标任务
    51. * @param key 需要删除的缓存key
    52. */
    53. public static void doubleDeletion(Runnable task, String key) {
    54. RedisUtil.doubleDeletion(
    55. task,
    56. () -> RedisUtil.getRedisTemplate().delete(key)
    57. );
    58. }
    59. /**
    60. * 缓存延迟双删
    61. *
    62. * @param factory 执行的目标任务
    63. * @param deleteCacheTask 清除缓存的任务
    64. * @param any object
    65. * @return 执行目标任务的返回结果
    66. */
    67. public static T doubleDeletion(Supplier factory, Runnable deleteCacheTask) {
    68. deleteCacheTask.run();
    69. T data = factory.get();
    70. //延迟800毫秒秒再删一次
    71. DelayExecutor.DELAY_EXECUTOR.schedule(deleteCacheTask, 800, TimeUnit.MILLISECONDS);
    72. return data;
    73. }
    74. /**
    75. * 缓存延迟双删
    76. *
    77. * @param task 目标任务
    78. * @param deleteCacheTask 清除缓存任务
    79. */
    80. public static void doubleDeletion(Runnable task, Runnable deleteCacheTask) {
    81. RedisUtil.doubleDeletion(
    82. () -> {
    83. task.run();
    84. return null;
    85. },
    86. deleteCacheTask
    87. );
    88. }
    89. }

    用法 1

    1. RedisUtil.doubleDeletion(
    2. // 定义数据库更新操作
    3. () -> updateProcudt(product),
    4. // 定义 删除 redis 操作
    5. () -> RedisUtil.delete("product:" + id)
    6. );

  • 相关阅读:
    RocketMQ的架构及概念
    华为云云耀云服务器L实例评测|拉取创建canal镜像配置相关参数 & 搭建canal连接MySQL数据库 & spring项目应用canal初步
    算法书学习笔记
    JumpServer2023漏洞复现合集
    Git企业开发级讲解(五)
    Vue3知识总结-2
    uniapp滚动页面改变背景颜色
    minio + linux + docker + spring boot实现文件上传与下载
    python | 自动化exe程序
    代码随想录二刷Day 15
  • 原文地址:https://blog.csdn.net/weixin_42195284/article/details/134069535