Redis缓存使用技巧

缓存能够有效加速应用的访问速度,同时可以降低后端负载,在应用架构中起着至关重要的作用,本文主要介绍缓存使用的一些技巧。

缓存更新策略

  • LRU/LFU/FIFO算法剔除

    场景:数据一致性要求较低
    原理:缓存使用量超过了预设值,使用maxmemory-policy来选择何种剔除策略对现有数据进行删除
    问题:数据清理由算法决定,开发人员只能选择使用哪种算法,数据一致性最差
    
  • 超时剔除
    场景:数据一致性要求低
    原理:给缓存设置过期时间(expire),自动删除
    问题:一段时间窗口内存在一致性问题
    
  • 主动更新
    场景:数据一致性要求较高
    原理:真实数据更新后,立即更新缓存
    问题:主动更新发生问题,这条数据很长时间不会发生更新
    

总结:

低一致性业务使用最大内存+淘汰策略
高一致性业务使用超时剔除+主动更新

缓存粒度控制

缓存的粒度在缓存应用时也有着很重要的影响,究竟缓存全部属性还是部分属性?可以从三个维度来进行权衡。

  • 通用性

    缓存全部数据比部分更加通用,但是较多情况下,应用只需要其中几个重要的属性
    
  • 空间占用
    缓存全部数据占用更多的空间,可能会造成内存的浪费,而且每次传输产生的网络流量较大,极端情况会阻塞网络
    
  • 代码维护
    部分数据一旦表结构变动,增加新字段则需要修改业务代码,并且需要重新刷新缓存
    

总结:

缓存粒度问题容易被忽视,但是使用不当,可能造成更多无用空间的浪费、网络带宽的浪费、代码通用型较差等情况,需要综合以上三点进行取舍

缓存穿透优化

缓存穿透指查询一个不存在的数据,导致不存在的数据每次请求都要到存储层查询,使后端存储层负载过大,极端情况可能导致宕掉。

  • 缓存空对象

    原理:缓存不命中,查询存储层,仍然不命中,则将空对象保存至缓存层中,然后再返回
    场景:数据命中率不高,频繁变化实时性高
    问题:1.空值占用更多的键,占用更多的内存空间,如果被攻击,可能导致内存快速增长,利用较短的过期时间来自动剔除;
    2.缓存层和存储层一定时间窗口数据不一致,利用消息系统或者其它方式清楚缓存中空对象。
    
  • 布隆过滤拦截器
    原理:在缓存层和存储层之间,将存在的key用布隆过滤器提前保存,如果key存在,则不访问存储层,可以通过Bitmaps来实现。
    场景:数据命中率不高、数据相对固定、实时性低(数据集较大)
    问题:代码维护复杂
    

无底洞优化

业务增长导致需要增加缓存节点来提高性能,但是增加节点后性能不但没有反转反而下降。分布式场景下,一次批量操作需要访问多个Redis节点,需要多次网络访问时间。

  • 串行命令

    原理:n个key均匀分布在Redis Cluster各个节点上,逐次执行n个get命令
    耗时:n次网络时间+n次命令时间
    缺点:大量keys请求延迟
    
  • 串行IO
    原理: 使用JedisClusterCRC16计算出key的slot,然后找到对应的节点,将属于同一个节点的key进行归档,对每个节点执行mget操作
    耗时:node次网络时间+n次命令时间
    缺点:大量node延迟
    
  • 并行IO
    原理:对于串行IO中,得出每个节点的key列表,通过多线程来对每个节点进行mget操作
    耗时:max_slow(node网络时间)+n次命令时间
    缺点:变成复杂、多线程问题定位较难
    
  • hash_tag
    原理:利用Redis Cluster功能,将多个key强制分配到一个节点
    耗时:1次网络时间+n次命令时间
    缺点:业务维护成本高、数据倾斜
    

雪崩优化

缓存层由于某些原因不可用,所有请求到达存储层,压力暴增,可能导致存储层也会级联宕机。

  • 保证缓存层服务高可用:Redis Sentinel、Redis Cluster
  • 依赖隔离组件为后端限流降级:Hystrix
  • 提前演练:模拟缓存层宕掉,应用以及后端的负载情况和可能出现的问题

热点key重建优化

“缓存+过期时间”的策略绝大部分情况满足加速数据读写、保证数据定期更新的需求,但是也可能出现其它问题,假如某一个key是一个热点key,并发量很大,并且重建缓存遇到复杂SQL、多次IO等不可能短时间完成情况,当缓存失效的瞬间,大量线程重建,造成后端负载过大。

  • 互斥锁(分布式锁)

    原理:只允许一个线程重建缓存,其它线程等待,直接从缓存中获取数据
    实现:使用Redis setnx或者其它方式来实现
    问题:构建缓存过程出现问题或者时间过长,可能存在死锁和线程池阻塞的风险
    
  • 永远不过期
    原理:为每个value设置逻辑过期时间,当发现超过逻辑过期时间后,使用单独线程重新构建缓存
    问题:不保证一致性问题,代码维护成本和内存成本(每次重建)增加
    

    参考资料:《Redis开发与运维》

原文地址:https://www.cnblogs.com/handsomeye/p/9374680.html

时间: 2024-07-30 19:00:11

Redis缓存使用技巧的相关文章

Redis缓存服务部署

redis缓存服务部署

springboot redis 缓存对象

只要加入spring-boot-starter-data-redis , springboot 会自动识别并使用redis作为缓存容器,使用方式如下 gradle加入依赖 compile("org.springframework.boot:spring-boot-starter-data-redis:${springBootVersion}") redis configuration 中启用缓存 @Configuration @EnableCaching public class Re

asp.net性能优化之使用Redis缓存(入门)

1:使用Redis缓存的优化思路 redis的使用场景很多,仅说下本人所用的一个场景: 1.1对于大量的数据读取,为了缓解数据库的压力将一些不经常变化的而又读取频繁的数据存入redis缓存 大致思路如下:执行一个查询 1.2首先判断缓存中是否存在,如存在直接从Redis缓存中获取. 1.3如果Redis缓存中不存在,实时读取数据库数据,同时写入缓存(并设定缓存失效的时间). 1.4缺点,如果直接修改了数据库的数据而又没有更新缓存,在缓存失效的时间内将导致读取的Redis缓存是错误的数据. 2:R

使用redis缓存加索引处理数据库百万级并发

使用redis缓存加索引处理数据库百万级并发 前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1000万条数据,可以参考我之前的文章插入数据,这里不再细说.我大概的做法是这样的,编码使用多线程访问我的数据库,在访问数据库前先访问redis缓存没有的话在去查询数据库,需要注意的是redis最大连接数最好设置为300,不然会出现很多报错. 贴一下代码吧 1 2 3 4 5 6 7 8 9 10 1

Windows环境下使用Redis缓存工具的图文详细方法

网上找了两篇关于Redis的博客,记录下! Java 使用Redis缓存工具的图文详细方法 Windows环境下使用Redis缓存工具的图文详细方法

C# mvc 前端调用 redis 缓存的信息

新手 这几天网上学习下redis ,自己总结下过程,怕之后忘记了,基本会用最简单的,有的还是不懂,先记下来,自己摸索的. 没有安装redis的先安装,教程:http://www.cnblogs.com/yyy116008/p/7508681.html 安装好了之后再配置  教程:http://www.cnblogs.com/yyy116008/p/7520635.html 安装配置好了之后: 1 传一个list集合 转化成 对象 ,值用redis缓存对象 前端代码:

Redis 缓存 + Spring 的集成示例(转载)

1. 依赖包安装 pom.xml 加入: <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.6.0.RELEASE</version> </dependency> <dependency> <groupId>redis

Redis缓存集群方案

由于单台Redis服务器的内存管理能力有限,使用过大内存的Redis又会使得服务器的性能急剧下降,一旦服务器发生故障将会影响更大范围业务,而Redis 3.0 beta1支持的集群功能还不适合生产环境的使用.于是为了获取更好的Redis缓存性能及可用性,很多公司都研发了Redis缓存集群方案.现对NetFlix.Twitter.国内的豌豆荚在缓存集群方面的解决方案进行一个汇总,以供读者参考,具体内容如下: 1.NetFlix对Dynamo的开源通用实现Dynomite Dynomite是NetF

Linux之搭建redis缓存服务器

Linux之搭建redis缓存服务器(nginx+tomcat+redis+mysql实现session会话共享) 一.redis介绍 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hash(哈希类型).与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写