Redis笔记

一、Redis为什么这么快
   1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存 中,类似于HashMap,HashMap 的优势就是查找和操作的时间
   复杂度都是O(1);
   2、数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计 的;
   3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,
   不存在加锁释放锁 操作,没有因为可能出现死锁而导致的性能消耗;
   4、使用多路 I/O 复用模型,非阻塞 IO;
   5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协 议不一样,Redis直接自己构建了VM机制 ,因为一般的系统调用
   系统函数的话,会浪费一定的时间去移动和请求;  
二、Redis 的持久化机制是什么?各自的优缺点?
RDB:是Redis DataBase缩写快照

RDB是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保 存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来 定义快照的周期。

优点:

1、只有一个文件 dump.rdb,方便持久化。
2、容灾性好,一个文件可以保存到安全的磁盘。
3、性能大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能
4、相对于数据集大时,比 AOF 的启动效率更高。

缺点:

1、数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发 生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候)
2、AOF(Append-only file)持久化方式: 是指所有的命令行记录以 redis 命 令请 求协议的格式完全持久化存储)保存为 aof 文件。

AOF:持久化

AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录 到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。 当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。

优点:

数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一 次 命令操作就记录到 aof 文件中一次。
通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-checkaof 工具解决数据一致性问题。
AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命 令 进行合并重写),可以删除其中的某些命令(比如误操作的 flushall))

缺点:

AOF 文件比 RDB 文件大,且恢复速度慢。
数据集大的时候,比 rdb 启动效率低。

三、Redis的内存淘汰策略有哪些

Redis的内存淘汰策略是指在Redis的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。
全局的键空间选择性移除
1、noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
2、allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除 近 少使用的key。(这个是最常用的)
3、allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。设置过期时间的键空间选择性移除
4、volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除 近 少使用的key。
5、volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
6、volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。
总结
Redis的内存淘汰策略的选取并不会影响过期的key的处理。内存淘汰策略用于处理内存不足时的需要申请额外空间的数据;过期策略用于处理过期的缓存数据。

四、Redis事务支持隔离性吗

Redis 是单进程程序,并且它保证在执行事务时,不会对事务进行中断,事务可以运行直到执行完所有事务队列中的命令为止。因此,Redis 的事务是总是带有隔离性的。

五、Redis事务保证原子性吗,支持回滚吗

Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。

六、redis、 zk 分布式锁的?二者区别

Redis:setNx获得锁,获取不到则加锁,expire释放锁
zk:①.客户端对某个方法加锁时,在 zk 上的与该方法对应的指定节点的目录下,生成一个唯一的瞬时有序节点 node1;②.客户端获取该路径下所有已经创建的子节点,如果发现自己创建的 node1 的序号是最小的,就认为这个客户端获得了锁。③、.如果发现 node1 不是最小的,则监听比自己创建节点序号小的最大的节点,进入等待。④.获取锁后,处理完逻辑,删除自己创建的 node1 即可。区别:zk 性能差一些,开销大,实现简单。

七、Redis 集群方案应该怎么做?都有哪些方案?

①.redis主从方案:一个master可以拥有多个slave;多个slave链接同一个master,也可以链接其它slave;主从复制不会阻塞master,在同步数据时,master可以继续处理client请求.;
slave 配置为slave-read-only on需要升级为主节点或者写入配置文件中, 而不能在默认slave情况下直接设置master与slave断开后会检测心跳, 从新建立连接.;可以直接copy DUMP文件从新重启master,在Master为空以后,slave同步数据会抹掉全部数据
②.redis cluster方案:Redis Cluster是一种服务器Sharding技术,3.0版本开始正式提供
③.codis集群方案:Codis是目前用的比较多的一种方案,Codis在高可用方面做的比较好

八、怎么理解 Redis 事务?

事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行,事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

九、缓存穿透、缓存击穿、缓存雪崩
缓存穿透:一般的缓存系统,都是按照 key 去缓存查询,如果不存在对应的 value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的 key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

解决方案:①、对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该 key 对应的数据 insert 了之后清理缓存。②、对一定不存在的 key 进行过滤。可以把所有的可能存在的 key 放到一个大的 Bitmap 中,查询时通过该 bitmap 过滤。

缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

解决方案:①、在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个 key 只允许一个线程查询数据和写缓存,其他线程等待。②、做二级缓存, A1 为原始缓存, A2 为拷贝缓存, A1 失效时,可以访问 A2, A1 缓存失效时间设置为短期, A2 设置为长期③、不同的 key,设置不同的过期时间,让缓存失效的时间点尽量均匀

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。和缓存雪崩不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案
1.设置热点数据永远不过期。
2.加互斥锁,互斥锁缓存预热
缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
解决方案
直接写个缓存刷新页面,上线时手工操作一下;数据量不大,可以在项目启动的时候自动进行加载;定时刷新缓存;

十、为什么Redis是单线程的

1)不需要各种锁的性能消耗
Redis的数据结构并不全是简单的Key-Value,还有list,hash等复杂的结构,这些结构有可能会进行很细粒度的操作,比如在很长的列表后面添加一个元素,在hash当中添加或者删除一个对象。这些操作可能就需要加非常多的锁,导致的结果是同步开销大大增加。总之,在单线程的情况下,就不用去考虑各种锁的问题,不存在加锁、释放锁操作,没有因为可能出现死锁而导致的性能消耗。
2)单线程多进程集群方案
单线程的威力实际上非常强大,单核cpu效率也非常高,多线程自然是可以比单线程有更高的性能上限,但是在今天的计算环境中,即使是单机多线程的上限也往往不能满足需要了,需要进一步摸索的是多服务器集群化的方案,这些方案中多线程的技术照样是用不上的。所以“单线程、多进程的集群”不失为一个时髦的解决方案。
3)CPU消耗
采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU。
但是如果CPU成为Redis瓶颈,或者不想让服务器其他CUP核闲置,那怎么办?可以考虑多起几个Redis进程,Redis是key-value数据库,不是关系数据库,数据之间没有约束。只要客户端分清哪些key放在哪个Redis进程上就可以了。

十一、IO多路复用技术

redis 采用网络IO多路复用技术,来保证在多连接的时候系统的高吞吐量。
多路-指的是多个socket网络连接,复用-指的是复用一个线程。多路复用主要有三种技术:select,poll,epoll。epoll是最新的、也是目前最好的多路复用技术。
采用多路I/O复用技术:其一,可以让单个线程高效处理多个连接请求(尽量减少网络IO的时间消耗)。其二,Redis在内存中操作数据的速度非常快(内存里的操作不会成为这里的性能瓶颈)。主要以上两点造就了Redis具有很高的吞吐量。

十二、热点key解决方案
服务端缓存方案

首先 Client 会将请求发送至 Server 上,而 Server 又是一个多线程的服务,本地就具有一个基于 Cache LRU 策略的缓存空间。当 Server 本身就拥堵时,Server 不会将请求进一步发送给 DB 而是直接返回,只有当 Server 本身畅通时才会将 Client 请求发送至 DB,并且将该数据重新写入到缓存中。此时就完成了缓存的访问跟重建。
但该方案也存在以下问题:
• 缓存失效,多线程构建缓存问题。
• 缓存丢失,缓存构建问题。
• 脏读问题。

使用 Memcache、Redis 方案

该方案通过在客户端单独部署缓存的方式来解决热点 Key 问题。
使用过程中 Client 首先访问服务层,再对同一主机上的缓存层进行访问。
该种解决方案具有就近访问、速度快、没有带宽限制的优点,但是同时也存在以下问题:
• 内存资源浪费。
• 脏读问题。

使用本地缓存方案

使用本地缓存则存在以下问题:
• 需要提前获知热点。
• 缓存容量有限。
• 不一致性时间增长。
• 热点 Key 遗漏。

热点数据解决方案

该方案通过主动发现热点并对其进行存储来解决热点 Key 的问题。
首先 Client 也会访问 SLB,并且通过 SLB 将各种请求分发至 Proxy 中,Proxy 会按照基于路由的方式将请求转发至后端的 Redis 中。
在热点 key 的解决上是采用在服务端增加缓存的方式进行。
具体来说就是在 Proxy 上增加本地缓存,本地缓存采用 LRU 算法来缓存热点数据,后端 db 节点增加热点数据计算模块来返回热点数据。
Proxy 架构的主要有以下优点:
• Proxy 本地缓存热点,读能力可水平扩展。
• DB 节点定时计算热点数据集合。
• DB 反馈 Proxy 热点数据。
• 对客户端完全透明,不需做任何兼容。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

软软的铲屎官

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值