学习记录篇:Redis缓存 (二)

本文介绍了Redis的两种持久化方式——RDB和AOF,包括各自特点和应用场景。AOF重写用于压缩日志文件。接着讨论了Redis事务特性。然后,针对缓存穿透和缓存雪崩问题,提出了布隆过滤器、设置合理的过期时间和集群解决方案。最后,简述了Redis分片集群的哈希取余法和一致性哈希,以及哈希槽分区法,强调了其在服务器增减时的优势。
摘要由CSDN通过智能技术生成

目录

前言

一、Redis持久化的方式

RDB持久化

AOF持久化

AOF重写

 Redis事务

二、Redis可能会产生的问题

缓存穿透

布隆过滤器

缓存雪崩

三、Redis分片集群

哈希取余法

一致性哈希算法

哈希槽分区法

总结



前言

上一篇我们完成了对Redis的入门了解以及Redis的基本数据类型。这里我们引出一个问题,那么既然Redis是基于内存的,那当我们的服务器重启后,Redis中的数据就都消失了,如果我们希望重启后数据还能够存在的话,就需要持久化到磁盘上,Redis重启后从磁盘上再把信息读取回来。

一、Redis持久化的方式

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

RDB持久化

RDB持久化方式也叫快照持久化方式,Redis 可以通过创建快照来获得存储在内存⾥⾯的数据在某个时间点上的副本。Redis 创建快照 之后,可以对快照进⾏备份,可以将快照复制到其他服务器从⽽创建具有相同数据的服务器副本 (Redis 主从结构,主要⽤来提⾼ Redis 性能),还可以将快照留在原地以便重启服务器的时候 使⽤。

简单来说,RDB持久化方式就是在一定的时间间隔内,将Redis中的数据集快照写入到磁盘中。

RDB的过程:redis会单独创建fork一个子进程来进行持久化操作,先将数据写到一个临时文件中,等持久化过程都结束了,再用这个临时文件替换原文件。整个过程中,主进程是不进行IO操作的,保证了性能。但是缺点是最后一次持久化的内容可能会丢失。

 RDB持久化方式是Redis默认的持久化方式,在Redis.conf文件中有如下配置。

save 900 1 #在900秒(15分钟)之后,如果⾄少有1个key发⽣变化,Redis就会⾃动触发
BGSAVE命令创建快照。
save 300 10 #在300秒(5分钟)之后,如果⾄少有10个key发⽣变化,Redis就会⾃动触发
BGSAVE命令创建快照。
save 60 10000 #在60秒(1分钟)之后,如果⾄少有10000个key发⽣变化,Redis就会⾃动
触发BGSAVE命令创建快照。

AOF持久化

与RDB持久化相⽐, AOF 持久化 的实时性更好,因此已成为主流的持久化⽅案。Redis会将所有写的操作以日志的形式记录下来,这样在下一次redis启动的时候会读取该文件然后进行数据的更新。
默认情况下 Redis 没有开启 AOF append only file )⽅式的持久化,可以通过 appendonly 参数开启:
appendonly yes
开启 AOF 持久化后每执⾏⼀条会更改 Redis 中的数据的命令, Redis 就会将该命令写⼊硬盘中
AOF ⽂件。 AOF ⽂件的保存位置和 RDB ⽂件的位置相同,都是通过 dir 参数设置的,默认的
⽂件名是 appendonly.aof
Redis 的配置⽂件中存在三种不同的 AOF 持久化⽅式,它们分别是:
appendfsync always #每次有数据修改发⽣时都会写⼊AOF⽂件,这样会严重降低Redis的速度
appendfsync everysec #每秒钟同步⼀次,显示地将多个写命令同步到硬盘
appendfsync no #让操作系统决定何时进⾏同步
为了兼顾数据和写⼊性能,⽤户可以考虑 appendfsync everysec 选项 ,让 Redis 每秒同步⼀次
AOF ⽂件, Redis 性能⼏乎没受到任何影响。⽽且这样即使出现系统崩溃,⽤户最多只会丢失⼀
秒之内产⽣的数据。当硬盘忙于执⾏写⼊操作的时候, Redis 还会优雅的放慢⾃⼰的速度以便适
应硬盘的最⼤写⼊速度。

AOF重写

我们知道,AOF的持久化方式在于Redis会把对数据进行修改操作的指令都存到一个AOF文件中来实现。那么这个AOF文件肯定是不能够无限增大的,想象一下,一个AOF文件里有成千上万条指令,别说人了,机器估计都看的眼花缭乱吧哈哈哈。

那么AOF文件既然要保存所有的指令,就说明我们不能丢弃掉以前的指令,那我们怎么控制日益庞大的AOF文件呢。

答案是通过 AOF压缩重写机制来进行。

意思是,当我们进行AOF文件的重写时,会将整个AOF文件的指令压缩成一条指令,然后放到我们新的AOF文件中,然后用新的AOF文件替换原来那个。 

默认情况下,当我们当前的AOF文件大于上一次AOF文件一倍且大于64M的时候,就会自动执行重写压缩操作。

在执⾏ BGREWRITEAOF (重写)命令时,Redis 服务器会维护⼀个 AOF 重写缓冲区,该缓冲区会在⼦
进程创建新 AOF ⽂件期间,记录服务器执⾏的所有写命令。当⼦进程完成创建新 AOF ⽂件的⼯
作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF ⽂件的末尾,使得新旧两个 AOF ⽂
件所保存的数据库状态⼀致。最后,服务器⽤新的 AOF ⽂件替换旧的 AOF ⽂件,以此来完成
AOF ⽂件重写操作

 Redis事务

终于到了事务部分啦,Redis作为一个数据库,而且是当下如此热门使用的情况下,如果没有事务的存在,那将会丢失掉十分多重要的数据!!

Redis事务不同于我们熟知的MySQL事务的ACID原则,Redis不支持事务的回滚,所以Redis没有原子性和持久性。

1. 原⼦性( Atomicity ): 事务是最⼩的执⾏单位,不允许分割。事务的原⼦性确保动作要么
全部完成,要么完全不起作⽤;
2. 隔离性( Isolation ): 并发访问数据库时,⼀个⽤户的事务不被其他事务所⼲扰,各并发
事务之间数据库是独⽴的;
3. 持久性( Durability ): ⼀个事务被提交之后。它对数据库中数据的改变是持久的,即使数
据库发⽣故障也不应该对其有任何影响。
4. ⼀致性( Consistency ): 执⾏事务前后,数据保持⼀致,多个事务对同⼀个数据读取的结
果是相同的;

二、Redis可能会产生的问题

缓存穿透

缓存穿透,顾名思义,可以理解为,外界的请求穿透了Redis,直接流入到了我们后端的数据库中

简单的说,就是请求的Key在Redis中查找不到,那当然就要到我们的数据库中去找啦,那如果这样请求的Key非常非常多,我们就要多次在数据库中找,那我们设置缓存的意义就没有了,数据库表示我顶不住呀。

解决方案:

  1. 对空值做缓存。
  2. 设置可访问的名单(白名单)
  3. 采用布隆过滤器
  4. 对redis进行实时监控,当发现redis命中率降低的时候,设置黑名单拦截请求

布隆过滤器

布隆过滤器是⼀个⾮常神奇的数据结构,通过它我们可以⾮常⽅便地判断⼀个给定数据是否存在
于海量数据中。我们需要的就是判断 key 是否合法,有没有感觉布隆过滤器就是我们想要找的那
具体是这样做的:把所有可能存在的请求的值都存放在布隆过滤器中,当⽤户请求过来,先判断
⽤户发来的请求的值是否存在于布隆过滤器中。不存在的话,直接返回请求参数错误信息给客户
端,存在的话才会⾛剩下的流程。
布隆过滤器的原理:
当我们加入一个元素的时候,使⽤布隆过滤器中的哈希函数对元素值进⾏计算,得到哈希值(有⼏个哈希函数得到⼏个哈 希值)。
根据得到的哈希值,在位数组中把对应下标的值置为 1
我们再来看⼀下, 当我们需要判断⼀个元素是否存在于布隆过滤器的时候,会进⾏哪些操作:
1. 对给定元素再次进⾏相同的哈希计算;
2. 得到值之后判断位数组中的每个元素是否都为 1 ,如果值都为 1 ,那么说明这个值在布隆过
滤器中,如果存在⼀个值不为 1 ,说明该元素不在布隆过滤器中。
然后,⼀定会出现这样⼀种情况: 不同的字符串可能哈希出来的位置相同。 (可以适当增加位数
组⼤⼩或者调整我们的哈希函数来降低概率)。

缓存雪崩

缓存雪崩指的是Redis突然不可用了 有可能是因为Redis服务器宕机了,也有可能是因为我们缓存的Key突然在同一时间过期了,这样请求也会大量流入到我们的数据库中,数据库表示,怎么受伤的总是我。。。

所以对于缓存雪崩的两种场景,我们有不同的解决方案

1.Redis服务器不可用时

如果是Redis服务器整个不可用了,我们可以考虑对Redis服务器进行主从搭配,或者集群,并且使用哨兵进行监控,使得当前Redis服务器不可用能有其他服务器及时顶住。

提一嘴 Redis的哨兵监控是会不间断的向主服务器发送检测数据,一旦发现主服务器挂了,立刻安排小弟上位,做新的服务器。

2.Redis的Key同一时间大量失效。

那这不就简单了嘛 我们可以设置不同的时效时间,不要让大家一起挂掉就好啦

或者,我们干脆不设置过期时间,所有Key都是永久存在的!!(强烈不建议)

三、Redis分片集群

最后,讲一下Redis分片集群相关的知识吧。

呃,这一段由于我自己了解的也不多,能力有限,就自己讲一下自己的心得和了解,如果有错误的地方,还往各位道友帮我指正,感激不尽!!!

我们都知道,把数据全部放在一台服务器上是很不安全的,万一服务器挂掉了,且不说数据有流失的风险,我们整个服务都会无法进行,所以多服务器的集群部署,可以使我们的后端服务更加安全

那么我们都知道,Redis的节点一共16384个,我们搭建了集群环境后,应该如何分配节点呢。

哈希取余法

哈希取余法,顾名思义,就是我们通过key值进行hash函数的运算,然后对我们集群环境中Redis服务器的数量进行取余,然后判断这个数据改放到那个服务器中,这样是最简单暴力的方法,但是他也是最不好用的办法。因为当我们的服务器增加或者减少后,我们所有的数据都要进行重新的运算和分配,这是一笔巨大的开销,我们不用它!!

一致性哈希算法

一致性哈希算法的原理就是,我们把哈希空间(原本是一个数组的样子)我们把他的头尾相连,形成一个哈希环。

然后,我们服务器的节点就根据哈希函数的运算分布在整个环之上(不均匀的分布喔),然后在进行数据的存储的时候,数据通过哈希函数的运算,找到在哈希环上的位置,然后顺时针绕环走,碰到的第一个服务器,就是它存储的服务器了。

一致性哈希环相比哈希取余法好在,即使我们服务器有增加或者减少,影响的只是它相邻两个服务器的数据,恩,不用那么大动干戈地让全世界人都知道啦。

那如果我还是觉得这样不好,移动起来麻烦,再加上服务器不能均匀分布,造成很多服务器挤在一起,别的服务器孤零零一个人在角落怎么办!!

少年你要求真多啊,不过我们还是有办法滴,办法来自于Redis 3.0引入的哈希槽(slot)。

哈希槽分区法

哈希槽是什么东东嘞,用简单通俗一点的语言来讲,哈希槽就是在我们的Redis服务器之上,多了个盒子,数据是放在这个盒子里的,而不是放在服务器中的,盒子会通过配置文件地址将数据的地址映射到服务器上,所以呀,Redis服务器里面相当于没有这个数据,有的只是这个数据的地址。
 

那可就好办了,我们可以通过自己的所求所需,我们自己来为集群环境中的Redis服务器设置插槽的大小,数据要进来,我们对他进行哈希函数的取余运算,知道它要去到哪个槽后,我们把它放进去就行了。而如果要增加服务器或者减少服务器,我们只需要来转移哈希槽给其它的服务器,就可以完成数据的转移,是不是方便很多了嘞,嘿嘿。


总结

本篇文章重点讲了Redis的持久化操作,以及Redis在实际使用中可能会碰到的问题以及解决方案。最后我们还了解了一丢丢集群分片的相关知识。还是那句话,有错误,请不吝赐教,我很开心看到不同的见解,因为我本身就是个小菜鸟,我希望获取更多的知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值