所谓的一致性问题是指,在同时使用缓存和数据库的情况下,要确保数据在缓存与数据库中的更新操作保持同步。也就是当对数据进行修改时,无论是先修改缓存还是先修改数据库,最终都要保证两者的数据是一样的,不会出现数据不一样的问题。
1.一致性问题解决方案缓存和数据库一致性的经典解决方案有以下两个:
使用延迟双删 + MQ 保证数据的一致性。通过 Canal 监听 MySQL 的 Binlog 写入日志,之后将写入操作(增加、删除和修改)的信息发送至 Kafka,程序监听到 Kafka 的消息后更新 Redis,从而保证数据的最终一致性。需要注意的是,无论使用的是延迟双删还是 Canal,都会出现短暂数据不一致性的问题,但可以保证最终的数据一致性。
然而,如果使用的是延迟双删 + MQ 的这种方式的时候,有一个棘手的问题很难处理,那就是如何设置延迟时间?
如果延迟时间设置的比较短,那么在并发场景下会出现数据不一致的问题;如果延迟时间设置的比较长,那么在比较长的这段时间内还会有数据不一致的问题。这个问题归根到底的原因是,并发线程的调度时间不能人为的控制(由操作系统统一调度)。
所以基于以上原因,使用 Canal 来保证数据一致性问题变成了一个比较不错的解决 Redis 和 MySQL 数据一致性的有效手段。
2.Canal执行流程通过 Canal 保证数据一致性的实现流程如下图所示:
3.Canal操作流程使用 Canal 读取 MySQL 的 Binlog 配置步骤如下:
开启并配置 MySQL 的 Binlog 设置。重启 MySQL 服务。给 MySQL 配置 canal/canal 用户用于后续 Canal 同步数据(此步骤非必须)。安装并解压 Canal。修改 canal.properties 配置文件,让其将数据同步到 Kafka,并配置 Kafka 服务器信息。修改 example/instance.properties 配置文件,指定同步数据到 Kafka 某个主题。拷贝 plugin 中的 jar 包到 lib 目录,让 Canal 支持将数据同步到 MQ。启动 Canal 服务。在代码中监听 Kafka 主题,并判断并更新 Redis 缓存。Kafka 中存储的数据格式如下:
4.最后理论如同明灯照亮前行的道路,实践则是我们坚实的脚步。唯有将两者紧密结合,不断地练习和实践,我们才能在求知的旅程中稳步前行,收获真正的成长与进步。所以,一起行动起来,光看不练都是假把式。
本文已收录到我的面试小站 [www.javacn.site](https://www.javacn.site),其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。