目录

方案设计的场景

代码实现

结束语


方案设计的场景

项目中以redis为主要数据源,所有查询都查询redis以提高程序并发能力。数据库仅做为持久化数据备份,当redis出现宕机情况,可以从数据库中恢复数据。

  • 提问:为什么不使用redis自带的持久化文件进行恢复?
  • redis持久化策略有两种AOF、RDB,AOF是将每一条操作命令记录到文件中,配置上默认是每秒一次写入文件,AOF文件过大时可以使用rewrite进行指令整理;RDB是redis数据快照,有save和bgsave两种方式生成RDB文件,前者是会阻塞主进程,后者是由主进程fork一个子进程进行异步操作,但相对占用更多的内存资源,但数据过大时还是会导致客户端暂停服务。
  • AOF对数据的完整性保存的较好,但AOF文件较大,恢复速度较RDB慢,损失1秒数据;RDB一般做冷备,五分钟或者更长时间进行一次备份,损失数据量较大,但恢复速度快,文件不易较AOF不易损坏。
  • 这两种AOF虽然损失一定性能,但数据完整性较好,建议开启;RDB仅在业务闲时进行备份即可。但考虑到我们在业务中使用redis作为类似持久化存储的方案,还是需要完全保证数据完整性,数据库中有完整数据,使用恢复程序,读取数据库再重建redis数据的方式进行恢复。(不过数据库数据可能也会不准,而且数据恢复程序导致开发量增大了,可能在数据结构调整、脏数据清理时程序还是有点用的。)

 

为了进一步减少对redis的访问,使用caffeine作为本地缓存。如此形成二级缓存方案,以redis作为二级缓存,caffeine作为一级缓存。由于caffeine是本地缓存,在分布式环境中其他进程更新redis后,本进程的本地缓存会和redis中的数据不一致。

为实现分布式二级缓存方案,考虑使用redis的发布订阅功能解决。当一个进程操作redis进行修改或者删除时,向指定topic发布一条信息,携带涉及的缓存和对应的键值;其他订阅相同topic的进程将会收到其发布的信息,将指定缓存中的key删除。这里使用redisson来进行发布订阅。

  • 提问:1、为什么是删除?2、为什么使用redis作为消息中间件?3、为什么使用redisson进行发布订阅?
  • 解释1:如果在PUT操作时将对象主动设置到缓存中的话,同一进程并发可能因为顺序问题导致数据不一致。解决方法是使其顺序操作,但同时多进程并发问题无法解决,需要做分布式加锁处理,才能解决多进程并发问题。由于本方案在多进程之间本身就会有一定的数据不一致的时间,即redis发布订阅的时间。与其加锁不如直接清除缓存然后在get操作时读取redis。
  • 解释2:可以使用其他的消息中间件,但在项目中引入新的组件也需要更多资源和调研工作。本身项目用到redis,而且使用中仅发布小数据量的信息,又不必为此扩张架构,采用redis作为消息中间件就是很好的选择。
  • 解释3:redisson是redis分布式应用最佳实践,在项目中已经使用了分布式锁的功能,而其中同样封装了发布订阅功能,代码实现上简单方便。

 

代码实现

MyCacheManager用于统一管理Cache,并提供操作Cache的get、put、evict方法。

直接在构造器中注入所有Cache,然后创建RedissonClient和进程唯一标识。

redisson 异步删除判断返回值 redis异步存储_分布式

 

在PostConstruct注释的方法中创建Topic和对Topic进行监听。(构造方法后,init方法前执行,因为topicName参数用@Value进行注入,而调用构造方法时还未注入)

onMessage方法,主要是在收到消息后,判断是否是本进程自己的消息,若不是则清除指定缓存中指定的key。

redisson 异步删除判断返回值 redis异步存储_分布式_02

 

提供get方法,可以到指定Cache中获取缓存信息,若获取不到则,调用callable进行处理,也就是说向二级缓存获取对象的逻辑就交给具体业务开发者进行编写了。

redisson 异步删除判断返回值 redis异步存储_redisson 异步删除判断返回值_03

 

提供put方法,方法中其实没有设置缓存信息到Cache中,原因上面分析了,然后二级缓存设置的逻辑也交给具体业务开发者进行编写啦。

另外evict方法,直接调用put方法了。

redisson 异步删除判断返回值 redis异步存储_redis_04

结束语

如果加入数据库,则数据库作为三级缓存,在二级缓存查询失败的情况下查询数据库,当然这注意在进行数据库操作时要加上分布式锁,只允许一个线程进行查询,然后设置查询信息到二级缓存中,避免大量访问直接查询数据库。

redisson作为分布式锁的分析,可以参考:。