我正在参与掘金创作者训练营第5期,点击了解活动详情
背景&目标
确保服务高可用的前提下,
- 降低后端服务的负载能力,对一些频繁读取的功能和复杂计算的的功能增加缓存,降低后端的负载
- 加快请求的响应时间,利用缓存优化数据读取,直接从缓存中读取比从 DB 中读取更快,从而优化用户的体验
现状分析
-
避免缓存滥用,统一封装提供缓存层 controller--sevice--cache--dao
-
部分业务功能因需强依赖缓存,需有容错机制或者可恢复机制
-
缓存更新策略
- 对于一致性要求比较高,在更新时数据时久更新缓存
- 若允许数据不一致,可通过设置过期时间。到期后就可以重新获取再放置在缓存中再设置缓存过期时间
- 缓存使用量超过预计最大值时可对现有数据进行删除,通过LRU/LFO/ FIFO算法进行删除
详细设计
规范缓存处理
制定缓存处理规范,避免所有的功能增加缓存时参差不齐,所以应该在一个项目里统一标准规范。要基于自己的项目情况考虑
- 统一缓存层处理缓存
- 确定场景是缓存还是存储,尽量避免强以来缓存
- 坚持原则:无它也可,有它更强
- set/hash/zset/list/tairhash/bloom/gis等大key(内部叫做godkey)不要超过3000,会记录sillylog
- 避免使用keys,hgetall,lrange0-1等大range(使用scan替代)
- 避免使用大value(10k以上就算大value,50k会记录)
详细的 redis 缓存规范可参考:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台
基于抽象工厂模式设计
-
定义 ICache 接口,其中定义了操作 Redis 的相关抽象方法
-
定义 2 个具体的缓存类,实现了 ICache 接口,并实现所有的接口方法
-
定义 1 个对外的 Cache 类,它也是实现了 ICache 接口。其中包含一个获取缓存 Client 的方法 driver 。实现了接口就要实现接口中所有的方法。每个方法都是完成具体的缓存 Client 的对应的方法
func get(key string) interface{} { return this.driver().get(key); }