一,重客户端
写入缓存:
image.png
应用同时更新数据库和缓存
如果数据库更新成功,则开始更新缓存,否则如果数据库更新失败,则整个更新过程失败.
判断更新缓存是否成功,如果成功则返回
如果缓存没有更新成功,则将数据发到 MQ 中
应用监控 MQ 通道,收到消息后继续更新 Redis.
问题点:如果更新 Redis 失败,同时在将数据发到 MQ 之前的时间,应用重启了,这时候 MQ 就没有需要更新的数据,如果 Redis 对所有数据没有设置过期时间,同时在读多写少的场景下,只能通过人工介入来更新缓存.
读缓存:
如何来解决这个问题?那么在写入 Redis 数据的时候,在数据中增加一个时间戳插入到 Redis 中.在从 Redis 中读取数据的时候,首先要判断一下当前时间有没有过期,如果没有则从缓存中读取,如果过期了则从数据库中读取最新数据覆盖当前 Redis 数据并更新时间戳.具体过程如下图所示:
image.png
二,客户端数据库与缓存解耦
上述方案对于应用的研发人员来讲比较重,需要研发人员同时考虑数据库和 Redis 是否成功来做不同方案,如何让研发人员只关注数据库层面,而不用关心缓存层呢?请看下图:
image.png
应用直接写数据到数据库中.
数据库更新 binlog 日志.
利用 Canal 中间件读取 binlog 日志.
Canal 借助于限流组件按频率将数据发到 MQ 中.
应用监控 MQ 通道,将 MQ 的数据更新到 Redis 缓存中.
可以看到这种方案对研发人员来说比较轻量,不用关心缓存层面,而且这个方案虽然比较重,但是却容易形成统一的解决方案.
推荐图书
最后推荐一本很不错的技术书籍《深入分布式缓存》
来源: http://www.jianshu.com/p/fbe6a7928229