Redis单线程、持久化、主从、哨兵的理解与实验

理解redis的单线程

redis的单线程是指对网络IO和键值对的读写由一个线程来执行,但 Redis 的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的

单线程为什么执行得那么快

基于内存,所有的运算都是内存级别的运算,而且单线程避免了多线程的切换性能损耗问题

正因为 Redis 是单线程,所以要小心使用 Redis 指令,对于那些耗时的指令(比如keys),要谨慎使用,一不小心就可能会导致 Redis 卡顿

那么单线程如何处理那么多的客户端并发连接?

Redis的IO多路复用:redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器

info命令

redis在运行时,可以通过info来查看运行信息,包括:

  • Server:可以查看redis版本,操作系统,gcc版本,进程id,tcp端口号,服务器启动以来经过的秒数和天数,可执行进程以及配置文件
  • Clients:连接数,阻塞的客户端,最长的输出列表和最大输入缓存
  • Memory:内存总量(字节),可读的方式显示内存总量,内存消耗峰值(字节),操作系统分配的内存总量rss(一般大于uesd),当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片,可以通过 mem_fragmentation_ratio 的值看出
  • Persistence:持久化信息
  • Stats:通用统计数据
  • Replication:主从复制相关信息
  • CPU:CPU使用情况
  • Cluster:集群信息
  • KeySpace:键值对统计数量信息

持久化

RDB

关闭RDB只需要将配置文件中所有的save保存策略注释掉即可

手动执行命令生成RDB快照,进入redis客户端执行命令save或bgsave可以生成dump.rdb文件,每次命令执行都会将所有redis内存快照到一个新的rdb文件里,并覆盖原有rdb快照文件

在生成dump.edb文件时,由两种方式:save和bgsave,默认是使用的bgsave,这两种方式最大的区别就是bgsave不会阻塞当前的redis命令,并且采用写时复制(COW)进行同步

写时复制(COW)

其作用就是redis正在做持久化的时候,若有新的redis命令到达,并且生成结果集,这个结果集不但会保存在内存中,而且会立马复制到dump.rdb文件中,这就是COW

实现原理:bgsave 子进程是由主线程fork生成的,可以共享主线程的所有内存数据。bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。此时,如果主线程对这些数据也都是读操作,那么,主线程和 bgsave 子进程相互不影响。但是,如果主线程要修改一块数据,那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据

RDB的缺点:会严格按照配置文件的规则和手动进行数据持久化,如果突然断电,那么内存中的数据将直接丢失

AOF

为了避免RDB持久化方式在断电时造成数据丢失,redis还提供了AOF这种持久化方式

将修改的每一条指令记录进文件appendonly.aof中(先写入os cache,每隔一段时间fsync到磁盘)

在这里插入图片描述

触发AOF的规则

# appendfsync always   每次修改就进行一次AOF
appendfsync everysec   # 每秒钟就进行一次AOF,redis默认
# appendfsync no       不进行AOF
AOF重写

AOF会定期根据内存的最新数据生成aof文件

为什么要设置重写?因为redis在恢复数据时,根据aof中记录的数据一条一条的执行,这样的效率太低。

举个例子:某个key被修改了很多次,那么正常情况下会有很多个修改的语句,如果一条一条去执行的话,做的是无用功。那还不如直接存储key现在的值呢,这样会大大提高效率

同样在配置文件中配置重写规则

# auto‐aof‐rewrite‐min‐size 64mb  //aof文件至少要达到64M才会自动重写,文件如果太小恢复速度本来就很快,重写意义不大
# auto‐aof‐rewrite‐percentage 100 //aof文件自上一次重写后文件大小增长了100%则再触发重写

当然,还可以手动重写,执行命令bgrewriteaof即可

实现原理:redis会fork出一个子进程去做重写(bgsave命令类似),不会影响正常命令处理

混合持久化

RDB和AOF各有有缺点,如果只用RDB,那么恢复的速度会非常块,但是数据可能会丢失;如果只使用AOF,虽然安全性很高,但太影响性能。

所以,Redis 4.0 以后,有一种新的方式——混合持久化(RDB和AOF的结合体),这种方式是基于AOF的,因此在使用时要确保AOF开启

工作原理:在做AOF时,会先把内存中已有的数据用RDB做快照处理,在保存的过程中,会有新的命令产生结果集,新的结果集就用AOF保存,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。在 Redis 重启的时候,先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的AOF 全量文件重放,因此重启效率得到大大提升

Redis数据备份策略

  • 写crontab定时调度脚本,每小时都copy一份rdb或aof的备份到一个目录中去,仅仅保留最近48
    小时的备份

  • 每天都保留一份当日的数据备份到一个目录中去,可以保留最近1个月的备份

  • 每次copy备份的时候,都把太旧的备份给删了

  • 每天晚上将当前机器上的备份复制一份到其他机器上,以防机器损坏

主从架构,读写分离

在高并发场景下,如果用一台redis机器,读和写会导致压力过大,影响性能,并且一旦宕机,就会影响用户使用。

可以配置主机和从机,实现读写分离,在主机执行写操作,从机执行读操作

如何配置从机:

  1. 复制一份配置文件
  2. 配置跟随哪个主机
replicaof 127.0.0.1 6379 # 从本机6379的redis实例复制数据,也就是把这个端口下的redis当成主机
replica‐read‐only yes # 配置从节点只读
  1. 启动从机

注意:Redis 5.0之前使用slaveof,而不是replicaof

搭建主从机器

在电脑上模拟一下,假设

我的主机:127.0.0.1 6379

从机1:127.0.0.1 6380

从机2:127.0.0.1 6381

配置文件后,启动三个服务:

在这里插入图片描述
打开客户端连接一下:
在这里插入图片描述
6380也连一下
在这里插入图片描述

6381就不贴图出来了。。

在主机6379里面,我设定一个值:name “yuqingming”

在这里插入图片描述

到从机6380去取

在这里插入图片描述

但是在6380写数据是不行的

在这里插入图片描述

成功模拟简单的主从架构,实现读写分离,减轻主机压力

主从是如何实现数据同步的

两种方式:全量和部分

全量复制

过程如下
在这里插入图片描述

全量复制上是在,从机刚开始启动,或者从机宕机很久之后启动进行的,如果从机宕机不久,那么使用部分复制(节省消耗)

部分复制(断点续传)

master会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master和它所有的slave都维护了复制的数据下标offset和master的进程id,因此,当网络连接断开后,slave会请求master继续进行未完成的复制,从所记录的数据下标开始。如果master进程id变化了,或者从节点数据下标offset太旧,已经不在master的缓存队列里了,那么将会进行一次全量复制。

在这里插入图片描述

主从复制风暴

如果主机有很多从机,显然这样同步主机的压力会比较大,会产生主从复制风暴

解决方法:让部分从节点与从节点(与主节点同步的从机)同步数据

哨兵架构

哨兵的作用:监控redis节点,如果主机宕机了,会在从机里面投票选出新的主机,不用人工手动再去配置

工作流程

  1. 客户端连接哨兵(刚开始不会直接和master通信),找到redis集群的master
  2. 客户端往后直接和master通信,不通过哨兵
  3. 如果master宕机了,哨兵会第一时间感知到,选出新的master之后再通知客户端
  4. 客户端拿到新的主机id,再去和新master通信,不通过哨兵

redis的client端实现了订阅功能,订阅哨兵发布的节点变动消息

搭建架构

哨兵也需要开放一个单独的端口,是一个独立的进程

  1. 首先复制sentinel.conf文件

  2. 修改配置,port,

sentinel monitor mymaster 127.0.0.1 6379 2 # mymaster这个名字随便取,客户端访问时用
# 上一条语句中最后的2是一个数字,表示当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 +1),过半数,master才算真正失效

我配置了三个哨兵

  • 127.0.0.1 26379
  • 127.0.0.1 26380
  • 127.0.0.1 26381
  1. 启动哨兵
    在这里插入图片描述

在主机6379执行一下info命令,可以看到整个架构是完整的,6379为主机,6380和6381为从机

在这里插入图片描述

经测试,主从架构读写分离没问题

现在我把6379主机kill一下,可以看到新的主机产生了

在这里插入图片描述

在6380执行一下info

在这里插入图片描述

主机重新启动后的角色

如果刚才kill的主机重新再启动,那么它会是什么角色呢?

实践一下就知道了~

启动一波6379 redis-server conf/redis6379.conf

进入6379客户端执行一下info

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值