zoukankan      html  css  js  c++  java
  • 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冲突,解决:① 缓存时一定要有隔离设计。

  • 相关阅读:
    UVA 11174 Stand in a Line,UVA 1436 Counting heaps —— (组合数的好题)
    UVA 1393 Highways,UVA 12075 Counting Triangles —— (组合数,dp)
    【Same Tree】cpp
    【Recover Binary Search Tree】cpp
    【Binary Tree Zigzag Level Order Traversal】cpp
    【Binary Tree Level Order Traversal II 】cpp
    【Binary Tree Level Order Traversal】cpp
    【Binary Tree Post order Traversal】cpp
    【Binary Tree Inorder Traversal】cpp
    【Binary Tree Preorder Traversal】cpp
  • 原文地址:https://www.cnblogs.com/wqff-biubiu/p/12462886.html
Copyright © 2011-2022 走看看