Redis知识点总价

1 redis的数据结构

2 redis的线程模型

1) Redis 采用单线程为什么还这么快

之所以 Redis 采用单线程(网络 I/O 和执行命令)那么快,有如下几个原因:

Redis 的大部分操作都在内存中完成,并且采用了高效的数据结构,因此 Redis 瓶颈可能是机器的内存或者网络带宽,而并非 CPU,既然 CPU 不是瓶颈,那么自然就采用单线程的解决方案了;
Redis 采用单线程模型可以避免了多线程之间的竞争,省去了多线程切换带来的时间和性能上的开销,而且也不会导致死锁问题。(CPU并不是制约Redis性能表现的瓶颈所在,更多情况下是受到内存大小和网络I/O的限制,所以 Redis 核心网络模型使用单线程并没有什么问题,如果你想要使用服务的多核CPU,可以在一台服务器上启动多个节点或者采用分片集群的方式。)
Redis 采用了 I/O 多路复用机制处理大量的客户端 Socket 请求,IO 多路复用机制是指一个线程处理多个 IO 流,就是我们经常听到的 select/epoll 机制。简单来说,在 Redis 只运行单线程的情况下,该机制允许内核中,同时存在多个监听 Socket 和已连接 Socket。内核会一直监听这些 Socket 上的连接请求或数据请求。一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的效果

2)Redis 6.0 之后为什么引入了多线程

Redis 的主要工作大体分为两部分 1)网络 I/O  2)执行命令,一直是单线程模型,

在 Redis 6.0 版本之后,也采用了多个 I/O 线程来处理网络请求,这是因为随着网络硬件的性能提升,Redis 的性能瓶颈有时会出现在网络 I/O 的处理上。所以为了提高网络 I/O 的并行度,Redis 6.0 对于网络 I/O 采用多线程来处理。但是对于命令的执行,Redis 仍然使用单线程来处理,所以大家不要误解 Redis 有多线程同时执行命令。

结论:6.0的多线程部分是1)网络IO的处理上,对于执行命令上依然是单线程。

3 redis的持久化方式

Redis 如何实现数据不丢失


AOF日志:每执行一条写操作命令,就把该命令以追加的方式写入到一个文件里;
RDB快照:将某一时刻的内存数据,以二进制的方式写入磁盘;
混合持久化方式:Redis 4.0 新增的方式,集成了 AOF 和 RBD 的优点;

Redis 的 AOF(Append-Only File)是一种持久化方式,它记录了 Redis 服务器接收到的写操作命令,在服务器重启时,可以通过重新执行 AOF 文件中的命令来恢复数据。

 AOF 持久化的特点和工作原理

  1. 日志追加:Redis 将接收到的写命令以追加的方式记录到 AOF 文件中,新的命令会不断追加到文件末尾。

  2. 可读性:AOF 文件是一个文本文件,易于读取和理解。它记录了 Redis 服务器接收到的每个写命令。

  3. 数据恢复:当 Redis 服务器重新启动时,它会重新执行 AOF 文件中的命令,从而恢复数据到重启前的状态。

  4. 同步方式:Redis 提供了不同的 AOF 同步策略,包括 always、everysec 和 no。always 表示每次写操作都会同步到 AOF 文件,everysec 表示每秒同步一次,而 no 表示不主动同步,由操作系统来处理。

  5. 重写机制:Redis 提供了 AOF 重写机制,可以对 AOF 文件进行重写,去除冗余的命令,从而减小文件大小。AOF 重写是在后台进行的,不会阻塞服务器的正常运行。

  6. 复制和传输:AOF 文件可以被复制到其他 Redis 服务器上,用于数据备份和迁移。

AOF 日志是在主进程中执行 ,重写 AOF 日志是在子进程中进行。

重写过程中,主进程依然可以正常处理命令,那问题来了,重写 AOF 日志过程中,如果主进程修改了已经存在 key-value,那么会发生写时复制,此时这个 key-value 数据在子进程的内存数据就跟主进程的内存数据不一致了,这时要怎么办呢?

为了解决这种数据不一致问题,Redis 设置了一个 AOF 重写缓冲区,这个缓冲区在创建 bgrewriteaof 子进程之后开始使用。

在重写 AOF 期间,当 Redis 执行完一个写命令之后,它会同时将这个写命令写入到 「AOF 缓冲区」和 「AOF 重写缓冲区」

RDB持久化的特点和工作原理

因为 AOF 日志记录的是操作命令,不是实际的数据,所以用 AOF 方法做故障恢复时,需要全量把日志都执行一遍,一旦 AOF 日志非常多,势必会造成 Redis 的恢复操作缓慢。 为了解决这个问题,Redis 增加了 RDB 快照,Redis 的快照是全量快照,也就是说每次执行快照,都是把内存中的「所有数据」都记录到磁盘中。所以执行快照是一个比较重的操作,如果频率太频繁,可能会对 Redis 性能产生影响。如果频率太低,服务器故障时,丢失的数据会更多。

 RDB生成方式:

1)在「主线程」里执行:执行 save命令,由于和执行操作命令在同一个线程,所以如果写入 RDB 文件的时间太长,会阻塞主线程

2)会创建一个子进程来生成 RDB 文件:执行 bgsave 命令,会创建一个子进程来生成 RDB 文件,这样可以避免主线程的阻塞

 执行机制:配置文件里配置隔多少时间修改多少次会触发

RDB 在执行快照的时候,数据能修改吗


可以的,执行 bgsave 过程中,Redis 依然可以继续处理操作命令的,也就是数据是能被修改的,关键的技术就在于写时复制技术(Copy-On-Write, COW)。

执行 bgsave 命令的时候,会通过 fork() 创建子进程,此时子进程和父进程是共享同一片内存数据的,因为创建子进程的时候,会复制父进程的页表,但是页表指向的物理内存还是一个,此时如果主线程执行读操作,则主线程和 bgsave 子进程互相不影响。如果主线程执行写操作,则被修改的数据会复制一份副本,然后 bgsave 子进程会把该副本数据写入 RDB 文件,在这个过程中,主线程仍然可以直接修改原来的数据。

 混合持久化:  


优点:混合持久化结合了 RDB 和 AOF 持久化的优点,开头为 RDB 的格式,使得 Redis 可以更快的启动,同时结合 AOF 的优点,有减低了大量数据丢失的风险。
缺点:AOF 文件中添加了 RDB 格式的内容,使得 AOF 文件的可读性变得很差;
兼容性差,如果开启混合持久化,那么此混合持久化 AOF 文件,就不能用在 Redis 4.0 之前版本了。

4 redis的内存淘汰策略

内存淘汰策略是解决内存过大的问题,当 Redis 的运行内存超过最大运行内存时,就会触发内存淘汰策略

5 redis的过期删除策略

Redis 使用的过期删除策略是「惰性删除+定期删除」,删除的对象是已过期的 key。

惰性删除:不主动删除,被访问的时候检查是否到期,到期了就删除,会使得一直不被访问的数据一直存在占用内存

定期删除:

Redis会将设置了过期时间的key放在一个独立的字典中,定时遍历这个字典来删除过期的key,遍历策略如下:

1)每秒进行10次过期扫描,每次从过期字典中随机选出20个key
2)删除20个key中已经过期的key
3)如果过期key的比例超过1/4,则进行步骤一
4)每次扫描时间的上限默认不超过25ms,避免线程卡死

因为Redis中过期的key是由主线程删除的,为了不阻塞用户的请求,所以删除过期key的时候是少量多次

6 redis的雪崩、击穿和穿透

 雪崩:是指在某一时刻缓存中的存储的数据同时大量地失效,而且这些数据都是经常被访问的数据(比如热点文章,热门商品等),这样就会导致大量的请求都会落到数据库上,造成数据库的压力瞬间增大,从而导致服务器宕机,形成一种“雪崩”效应。

击穿:
        是指某个热点数据在缓存中失效了,而且这个数据也是经常被访问的数据,这样就会导致大量的请求都会落到数据库上,造成数据库的压力瞬间增大,从而导致服务器宕机。

解决缓存击穿的方法有很多,其中一种比较常见的方法是采用“互斥锁”和“逻辑过期时间”两种手段来解决。

互斥锁
        是指在查询数据库时,如果发现缓存中的数据已经失效,那么就先获取一个互斥锁,然后再去查询数据库,这样一来,只有一个线程去访问数据库,将查询到的数据同步到缓存当中,其他线程就直接从缓存中获取了,就可以避免大量的请求都会落到数据库上。

缓存穿透:
        是指恶意的请求,会故意查询数据库不存在的数据,而这些数据在Redis缓存中也不存在,这样就会导致大量的请求都会落到数据库上,造成数据库的压力瞬间增大,从而导致服务器宕机。

解决缓存穿透的方法有很多,其中一种比较常见的方法是采用“缓存空对象”和“BloomFilter(布隆过滤器)”两种手段来解决。

缓存空对象
        是指在查询数据库时,如果发现查询的数据不存在,那么就将这个空对象也缓存起来,这样一来,下次再查询这个不存在的数据时,就可以直接在缓存中获取到空对象,而不需要去数据库中查询。

BloomFilter(布隆过滤器)

逻辑过期时间
        是指在查询数据库时,如果发现缓存中的数据已经失效,那么就先将数据库中的数据缓存起来,但是不将这个数据的过期时间设置为实际的过期时间,而是将过期时间设置为一个较短的时间,这样一来,就可以避免缓存中的数据一直都是“冷”数据。

7 redis的高可用

实现 高可用 的技术主要包括 持久化复制哨兵 和 集群,持久化上面已经提到主要是RDB和AOF,复制,哨兵和集群是redis部署的模式,来提高服务的高可用。

redis常见部署方式

主从复制:

提高读性能,实现数据冗余。一旦 主节点宕机从节点 晋升成 主节点,同时需要修改 应用方 的 主节点地址,还需要命令所有 从节点 去 复制 新的主节点,整个过程需要 人工干预

哨兵机制:

1)监控(PING)  2)通知 (订阅/发布)  3)自动故障转移(选主/半数以上)

主观下线

客观下线

集群的数据分片

Redis Cluster 方案采用哈希槽(Hash Slot),来处理数据和节点之间的映射关系。在 Redis Cluster 方案中,一个切片集群共有 16384 个哈希槽,这些哈希槽类似于数据分区,每个键值对都会根据它的 key,被映射到一个哈希槽中,具体执行过程分为两大步

这些哈希槽怎么被映射到具体的 Redis 节点上的呢?有两种方案:

  • 平均分配: 在使用 cluster create 命令创建 Redis 集群时,Redis 会自动把所有哈希槽平均分布到集群节点上。比如集群中有 9 个节点,则每个节点上槽的个数为 16384/9 个。
  • 手动分配: 可以使用 cluster meet 命令手动建立节点间的连接,组成集群,再使用 cluster addslots 命令,指定每个节点上的哈希槽个数。

相关知识拓扑图:

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值