Redis学习

本文详细探讨了Redis在缓存、一致性问题、过期策略、内存管理以及与数据库交互中的应用,包括缓存穿透解决方案、缓存击穿和雪崩的处理方法,以及Redis的内存淘汰策略和最佳实践。
摘要由CSDN通过智能技术生成

1.redis使用场景
缓存、分布式锁、计数器、保存token、消息队列、延迟队列...
2.缓存穿透
当查询一个不存在的数据(mysql查询不到数据也不会写入缓存)就会导致每次请求都查询数据库
解决方案
方案一:缓存空数据,查询返回的数据为空,仍把这个空结果进行缓存
优点:简单
缺点:消耗内存,可能会发生数据不一致问题(后期空数据有值了,但是缓存空数据没值)
方案二:方案二:布隆过滤器(拦截不存在的数据)。先查询布隆过滤器,如果不存在直接返回;存在则查询redis,如果redis也不存在再查询mysql;添加缓存的同时,也要把数据添加到布隆过滤器。
3.缓存击穿
给某个key设置了过期时间,当key过期的时候,恰好这个时间点对这个key有大量请求并发过来,会瞬间把DB压垮
解决方案一:互斥锁。当缓存失效时,不立即去load db ,先使用redis的setnx去设置一个互斥锁,当操作成功返回时再进行load db的操作并设置缓存,否则重试get缓存的方法。

扩展解释:其实排它锁底层使用的时setnx ,保证了同时只能有一个线程操作锁住的方法。

解决方案二:逻辑过期。在设置key的时候,设置一个过期时间字段一块存入缓存中,不给当前key设置过期时间;当查询的时候,从redis取出数据后判断时间是否过期;如果过期则开启另外一个线程进行数据同步,当前线程正常返回数据(此时这个数据不是最新的)
4.缓存雪崩
是指在同一时段大量的缓存key同时失效或者redis服务宕机,导致大量请求到达数据库,带来巨大压力。
解决方案:
给不容的key的TTL添加随机值
利用redis集群提高服务的可用性(哨兵模式、集群模式)
给缓存业务添加降级限流策略(nginx、springcloud gateway)
给业务添加多级缓存
5.先删缓存还是先改数据库?(双写一致性)

延迟双删(有脏数据风险)当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,设定超时时间
写操作:延迟双删
分布式锁(强一致性)共享锁:读锁readLock,加锁之后,其他线程可以共享读操作      
排他锁:独占锁writeLock也叫,加锁之后,阻塞其他线程读写操作

异步通知保证数据的最终一致性(MQ)

需要保证MQ的可靠性

基于Canal的异步通知(

canal是基于mysql的主从同步来实现的

利用canal中间件,不需要修改业务代码,伪装为mysql的一个从节点,canal通过读取binlog数据更新缓存二进制日志。(BINLOG)记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但不包括数据查询(SELECTSHOW)语句。

6.redis的数据过期策略有哪些?

在redis中提供了两种数据过期删除策略 惰性删除 + 定期删除两种策略进行配合使用
惰性删除在设置该key过期时间后,我们不去管它,当需要该key时,我们检查其是否过期,如果过期就删除它
定期删除每隔一段时间我们就对一些key进行检查,删除里面过期的keySLOW模式是定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配置文件redis.conf 的hz 选项来调整这个次数
FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms

7.假如缓存过多,内存是有限的,内存被占满了怎么办?其实就是想问redis的数据淘汰策略是什么?

当Redis中的内存不够用时,此时在向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。
Redis支持8种不同策略来选择要删除的key:
noeviction: 不淘汰任何key,但是内存满时不允许写入新数据,默认就是这种策略。
volatile-ttl: 对设置了TTL的key,比较key的剩余TTL值,TTL越小越先被淘汰
allkeys-random:对全体key ,随机进行淘汰。
volatile-random:对设置了TTL的key ,随机进行淘汰。
allkeys-lru: 对全体key,基于LRU算法进行淘汰
volatile-lru: 对设置了TTL的key,基于LRU算法进行淘汰
allkeys-lfu: 对全体key,基于LFU算法进行淘汰
volatile-lfu: 对设置了TTL的key,基于LFU算法进行淘汰

数据淘汰策略-使用建议
1.优先使用 allkeys-lru 策略。充分利用 LRU 算法的优势,把最近最常访问的数据留在缓存中。如果业务有明显的冷热数据区分,建议使用。
2.如果业务中数据访问频率差别不大,没有明显冷热数据区分,建议使用 allkeys-random,随机选择淘汰。
3.如果业务中有置顶的需求,可以使用 volatile-lru 策略,同时置顶数据不设置过期时间,这些数据就一直不被删除,会淘汰其他设置过期时间的数据。
4.如果业务中有短时高频访问的数据,可以使用 allkeys-lfu 或 volatile-lfu 策略。

8.数据库有1000万数据 ,Redis只能缓存20w数据, 如何保证Redis中的数据都是热点数据 ?

使用allkeys-lru(挑选最近最少使用的数据淘汰)淘汰策略,留下来的都是经常访问的热点数据

9.Redis的内存用完了会发生什么?主要看数据淘汰策略是什么?如果是默认的配置( noeviction ),会直接报错

10.Redis是单线程的,但是为什么还那么快?
Redis是纯内存操作,执行速度非常快;
采用单线程,避免不必要的上下文切换可竞争条件,多线程还要考虑线程安全问题
使用I/O多路复用模型,非阻塞IO
IO多路复用:是利用单个线程来同时监听多个Socket ,并在某个Socket可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。
不过监听Socket的方式、通知的方式又有多种实现,常见的有:select、poll、epol
select和poll只会通知用户进程有Socket就绪,但不确定具体是哪个Socket ,需要用户进程逐个遍历Socket来确认;
epoll则会在通知用户进程Socket就绪的同时,把已就绪的Socket写入用户空间。


源码安装redis-stable

yum install gcc -y  #安装C依赖
wget http://download.redis.io/redis-stable.tar.gz  #下载稳定版本
tar zxvf redis-stable.tar.gz  #解压
cd redis-stable
make PREFIX=/app/redis install   #指定目录编译,也可以不用指定
make install
mkdir /etc/redis   #建立配置目录
cp redis.conf /etc/redis/6379.conf # 拷贝配置文件
cp utils/redis_init_script /etc/init.d/redis  #拷贝init启动脚本针对6.X系统
chmod a+x  /etc/init.d/redis  #添加执行权限
vi /etc/redis/6379.conf #修改配置文件: 
bind 0.0.0.0      #监听地址
maxmemory 4294967296   #限制最大内存(4G):
daemonize yes   #后台运行

####启动与停止
/etc/init.d/redis start
/etc/init.d/redis stop
 

使用客户端工具连接 报错

解决方案

[root@node1 etc]# redis-cli -p 6379 config get protected-mode
1) "protected-mode"
2) "yes"

需要将 "protected-mode"  改成  no

[root@node1 etc]# redis-cli -p 6379 config set protected-mode no
OK
[root@node1 etc]# 

或者修改/etc/redis/6379.conf #修改配置文件: protected-mode no

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值