redis——再补充

一、缓存的使用场景

缓存的使用场景:

  • 读密集型的应用;
  • 存在热数据的应用;
  • 对响应时效要求较高;
  • 对一致性要求不严格;
  • 需要实现分布式锁的时候;

不适合使用缓存的场景:

  • 读少
  • 更新频繁
  • 对一致性要求严格

二、redis与memcache

1、数据类型:都是键值对存储,但redis支持五种数据类型(String、List、Hash、Set、Sorted_Set);memcache仅支持String

2、线程模型:redis是单线程(fork子线程,不严格的单线程);不推荐在redis中存储较大内存,memcache是多线程的。

3、持久机制:redis提供两种持久机制(RDB+AOF);memcache仅用于缓存不支持持久化。

4、客户端:redis的客户端jedis是阻塞I/O,但提供连接池;memcache有很多客户端阻塞I/O,非阻塞I/O都有

5、高可用:redis提供多种集群方案(哨兵Sentinel、cluster);memcache不支持高可用模型。

6、队列支持:redis可实现队列和订阅模式;memcache不支持队列。

7、事务:redis是单线程的,所以单个指令是原子性(线程安全)的,一定程度上保证支持事务(ACID),但不是严格的事务安全(多个指令不保证原子性A);memcache与redis一样,单个指令是线程安全的,但说个指令不是原子性的,另外还不符合事务D:持久性

8、数据淘汰策略:redis采用近似LRU算法(随机算法+LRU算法)淘汰数据;memcache采用LRU算法淘汰数据。

9、内存分配:

 三、分布式缓存的设计与实践

1、设计点

① 容量规划:缓存内容大小、缓存内容数量、淘汰策略、缓存的数据结构、每秒的读峰值、每秒的写峰值

② 性能优化:线程模型、预热方案、缓存分片、冷热数据的比例

③ 高可用:复制模型、失效转移、持久策略、缓存重建

④缓存监控:缓存服务监控,缓存容量监控、缓存请求监控、缓存响应时间监控

⑤注意事项:是否有可能发生缓存穿透、是否有大对象、是否使用缓存实现分布式锁、是否使用缓存支持脚本(Lua)、是否避免了Race Condition

2、优秀实践

① 缓存系统主要消耗的是服务器的内存,所以需要准确评估缓存的大小、数据结构、容量、失效时间等等,按评估申请分配资源,避免资源浪费或者缓存空间不够。

② 建议将缓存业务进行分离,核心业务与非核心业务使用不同的缓存实例,从物理上隔离。(同一台服务器上可建立多个实例,避免不同应用造成的缓存key碰撞)

③ 根据缓存实例提供的内存大小推算应用需要使用的缓存实例数量。(RDB理论上会导致内存翻倍,所以也需要考虑进去)

④ 缓存访问的超时时间。缓存一般是用来加速数据库的读操作的,一般先访问缓存,后访问数据库,所以访问缓存的超时时间设置很重要,可能会拖垮客户端的线程池。

⑤ 所有的缓存实例都需要添加监控。

⑥ 不推荐共享缓存,推荐②中业务分离,但成本控制原因使用共享缓存时,需要加上应用的前缀,业务的前缀,进行隔离设计。

⑦ 缓存必须设置过期时间,但不能集中在某一点,防止出现缓存雪崩。

⑧ 低频率的访问数据不要放在缓存中。

⑨ 缓存数据不易过大,尤其是redis单线程

⑩ 对于存储较多value的key,尽量不要使用hgetAll操作,造成强求的阻塞。还有keys模糊匹配,尽量使用scan分片匹配

⑪ 缓存一般用于加速查询的场景,大量更新操作,请使用批量定时任务操作。

⑫ 写缓存时保证数据完整性

⑬ 缓存使用顺序:读操作,先缓存后数据库;写操作,先数据库后缓存

⑭ 使用本地缓存时(ehcache),严格控制缓存大小,过多的本地缓存极大浪费JVM性能,甚至导致内存溢出。

3、常见线上问题

① 某应用程序的数据库负载瞬时升高

可能原因:缓存雪崩,解决:使用随机过期时间,具体形式:固定过期时间+很短的随机过期时间

② 导致迁移前后两个系统的核心操作重复

解决:迁移应该从前往后,先关闭请求端。

③ 加入缓存后,数据库负载并没有明显下降

可能原因:缓存穿透,解决:① 数据校验:如上面id不能小于0;② 空缓存,在缓存中设置redis.set(id,null)并设置过期时间 ③ 布隆过滤器:redis布隆过滤器需要安装插件

④ 监控报警:redis中单个key的value占空内存空间过大

可能原因:redis的过期时间以key为单位,value中数据没有过期时间,不要随意扩容。解决:①业务控制value中数据过期时间,如使用hash数据结构时,业务清理value中数据,②将value拆分,采用其他数据结构

⑤ 缓存宕机导致业务逻辑中断,数据不一致。

可能原因:redis主从切换,导致瞬间内应用连接redis异常,应用没有对redis做缓存降级处理。解决:① 核心业务一定要有降级处理,当缓存出现异常时,暂时回源与数据库进行业务处理。

⑥ 应用系统负载升高,响应变慢,发现应用进行频繁GC,甚至出现OOM

可能原因:使用本地缓存,缓存大小过大,解决:① 使用本地缓存时一定要严格控制缓存大小,缓存的过期时间。

⑦ 应用突然报警线程数过高,之后很快出现内存溢出。

可能原因:由于缓存连接数达到最大,应用无法连接缓存,严重降低应用程序性能。解决:① 一定要使用缓存监控;并且控制远程缓存连接的超时时间。

⑧ 使用缓存存储业务数据时,上线后错误,不能短时间找到问题所在。

可能原因:缓存未知错误,解决:① 回退重新开发,②一定要有降级方案,缓存未知错误时,由数据库来处理业务请求,当然还要配置缓存监控。

⑨ 缓存相关业务上线后,时不时有一些未知的错误出现

可能原因:key冲突,解决:① 缓存时一定要有隔离设计。

posted on 2020-03-11 15:54  FFStayF  阅读(202)  评论(0编辑  收藏  举报