利用Redis实现分布式长效缓存

由于我们选择使用缓存,就必须接受缓存所带来的问题,数据的实时性就会降低,但是我们又希望对数据的实时性影响要尽量的小,如果将TTL设置太小,那么缓存就会大量失效,可能会导致比没有缓存的性能还差,如果缓存的时间太长,那么数据实时性影响就会非常大,因此调研对比了Varnish、Redis、Guava Cache、Caffeine Cache,决定结合缓存的优点开发一款兼顾数据实时性和性能,还必须支持分布式的Cache(因为Service为分布式部署,本地内存缓存容易造成数据一致性问题)
摘要由CSDN通过智能技术生成

个人站点原文:程军高的个人博客 | 详情

一、背景

缓存功能业务在所有公司里面都是很重要的,做为提升性能的重要法宝之一,具有举足轻重的地位,所在公司业务有一种场景需要使用缓存进行性能的改善,举例场景:A Service(提供对外服务,性能550ms)调用 B Service(性能受到多种制约无法优化,性能500ms),这个时候性能优化就需要寄希望于缓存这个法宝。

二、方案选择

由于我们选择使用缓存,就必须接受缓存所带来的问题,数据的实时性就会降低,但是我们又希望对数据的实时性影响要尽量的小,如果将TTL设置太小,那么缓存就会大量失效,可能会导致比没有缓存的性能还差,如果缓存的时间太长,那么数据实时性影响就会非常大,因此调研对比了Varnish、Redis、Guava Cache、Caffeine Cache,决定结合缓存的优点开发一款兼顾数据实时性和性能,还必须支持分布式的Cache(因为Service为分布式部署,本地内存缓存容易造成数据一致性问题)

优点不足备注
Redis可以实现分布式缓存;

无法主动刷新;

有网络损耗;

Guava Cache提供了主动刷新机制,可以实现长效缓存;

仅本地内存缓存,无法分布式;

API实现较为复杂;

GitHub - google/guava: Google core libraries for Java
Varnish

可以实现分布式;

天然Service缓存;

自带Grace功能;

无法主动刷新数据;

Grace提供的数据影响数据实时性;

GitHub - varnishcache/varnish-cache: Varnish Cache source code repository
Caffeine Cache提供了主动刷新机制,可以实现长效缓存;仅本地内存缓存,无法分布式;

基于Guava Cache API开发使用更加简单

GitHub - ben-manes/caffeine: A high performance caching library for Java

三、设计

3.1 设计目标

为了设计一款能分布式使用,且具有长效存储和兼顾数据实时性的缓存,我们可以结合Guava Cache和Redis来进行设计,因此我们进行如下设计:

(1)refreshAfterWrite, 在写入一定时间后,监听会主动刷新缓存

(2)expireAfterAccess,距离最后的缓存访问时间间隔超过了允许的时间,数据即失效,并且不再进行监听刷新。

(3)统一的分布式存储,提供网络访问方式,统一存储。

3.2 设计方案

(1)以Redis Cluster为存储媒介

(2)expireAfterAccess特性,使用Redis Key设置TTL实现,每次读取成功重新设置TTL

(3)refreshAfterWrite特性,设计一个监听器,监听Key写入的时间,根据设置的时间获取有效的缓存数据进行异步刷新,但是不更新数据的TTL。

(4)缓存数据设计使用Redis的String类型存储,KV设计为,

         K:${Bussiness}-${Hash(Key)}   V: {"key":${Key},"value":${Value}}

         Redis的Key设计使用业务名称加上缓存数据的Key对象的Hash值,Redis Value采用Json字符串存储(当然也设计可以使用二进制序列化数据,但是为了排查问题方便,设计为可读的Json字符较为方便)

(5)监听器设计为异步线程获取Redis一个Set数据,一个监听器的KV设计为,

         K:${Bussiness}-Listener-${DataTime}  V:[${Bussiness}-${Hash(Key)} ]

         Redis Key设计为按照时间产生的监听器,并不是按照每个缓存对象一个监听器,不然监听器的规模过于庞大,Redis Value是一个Set集,里面数据为缓存对象的Redis Key

(6)需设计一个分布式锁,由于微服务部署一般为分布式多节点部署,因此我们需要通过分布式锁控制监听器的执行权限,获取锁的监听线程,才能执行监听器,执行缓存数据的刷新动作,缓存刷新后,删除监听器的Redis Key,并释放锁并删除锁,重新设置下一轮监听器。

        分布式锁采用Redis设计,Redis Key为:${Bussiness}-Lock-${DataTime}

3.3 架构设计图

缓存分为三个模块角色设计,缓存操作模块、监听模块、缓存刷新模块

 四、项目源代码

beehive/beehive-cache/beehive-cache-common at master · chengjungao/beehive · GitHubContribute to chengjungao/beehive development by creating an account on GitHub.https://github.com/chengjungao/beehive/tree/master/beehive-cache/beehive-cache-common

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值