Redis(二)

一、Redis持久化(RDB方式)

(一)此种方式的介绍及rdb默认触发条件的变化

A、此种方式会根据配置文件指定的时间间隔和写入频率决定是否更新磁盘上的持久化库;此种方式是将整个库直接快照(snapshotting)备份在磁盘中。

B、6和7在配置文件中rdb方式默认备份频率发生了变化

6的配置文件中如下,前一个数字代表时间间隔s ,后一个代表在该时间间隔写入操作的次数

7版本将默认备份的频率下调了;

 (二)自动触发和手动触发

自动触发

  • 在配置文件中指定自己的触发备份规则。(注意配置文件中注释不能喝配置同一行,否则报需哦)
 save 5 2 
#设置为5秒两次即可触发自动备份
  • 配置备份文件的保存路径
dir /opt/redis-7.0.11/myredis/rdbfiles    
#指定的文件夹要实际存在,redis不会帮我们创建文件夹
  • 配置备份文件的名字
dbfilename dump6379.rdb 
#默认命名为dump.rdb,这里改为加上端口号,在后期方便辨认
  • 重启redis-server,加载配置文件
redis-server /opt/redis-7.0.11/myredis/myredis.conf
  • 通过命令获取配置,检查配置(也可以通过set设置,这里省略)
127.0.0.1:6379> config get dir
1) "dir"
2) "/opt/redis-7.0.11/myredis/rdbfiles"
  • 执行五秒2次以上的命令触发快照。
127.0.0.1:6379> set k2 "you"
OK
127.0.0.1:6379> set k3 "youn"
OK
  • 快照出现在指定文件夹下
[root@quihechunshui rdbfiles]# ll
total 4
-rw-r--r-- 1 root root 109 Sep 16 17:19 dump6379.rdb

(三)自动持久rdb持久化方式注意点与备份文件的恢复。

A、当执行flushdb和flushall等敏感操作后,redis也会更新执行路径下的rdb文件,但是这个rdb文件是没有数据的,所以在执行该命令前一定要确定之前的备份文件不会被覆盖。

B、此外当我们在用户端执行shutdown命令关闭服务时,rdb文件也会更新,这个更新的rdb文件同样也是无效的。

C、由上面两条可知,我们备份文件一定不要和redis服务在同一台机器上,不然机器挂了,服务也挂了。

D、我们模拟文件备份恢复,首先要修改备份文件名字,然后执行清库命令,删除清库命令带来的空rdb文件。

备份有数据的rdb文件.加了个文件后缀,防止清库时被覆盖

cp dump6379.rdb dump6379.rdb.rdk

现在文件夹中有两个文件,分别是自己备份有数据的文件,和即将被清库命令更新的指定备份文件,然后我们执行清库命令,然后停掉redis服务(使用shutdown命令)

接着我们删除两次敏感操作产生的空备份文件,恢复备份过的有数据的备份文件,然后当我们再次启动redis服务时,就会默认读取备份文件恢复数据

[root@quihechunshui rdbfiles]# rm dump6379.rdb
rm: remove regular file 'dump6379.rdb'? y
[root@quihechunshui rdbfiles]# cp dump6379.rdb.rdk dump6379.rdb
[root@quihechunshui rdbfiles]# ll
total 8
-rw-r--r-- 1 root root 109 Sep 16 20:43 dump6379.rdb
-rw-r--r-- 1 root root 109 Sep 16 20:35 dump6379.rdb.rdk

启动服务查看数据恢复情况

[root@quihechunshui rdbfiles]# redis-server /opt/redis-7.0.11/myredis/myredis.conf
[root@quihechunshui rdbfiles]# redis-cli -a chen13515216766 -p 6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
27.0.0.1:6379> get k1
"me" #恢复成功!

C、自此我们得出经验,备份文件和redis服务不能放在一台服务器上!

手动触发

A、执行save或者bgsave,就可以手动保存rdb

B、save命令是阻塞式的,当该命令执行完毕之前,所有redis其他服务都必须等待其执行完毕,不适用于大量数据写入和写出的场景,容易导致服务崩溃

C、bgsave是异步的,当该命令被调用时,会调用linux底层的forks命令创建一个子进程,这个子进程在后台默默备份,不影响住进程redis服务的执行。

D、实例:

执行bgsave命令:

127.0.0.1:6379> bgsave 
Background saving started

执行save命令:

127.0.0.1:6379> save
OK

D、LISTSAVE命令可以获取上一次成功备份的时间戳

获取时间戳:

127.0.0.1:6379> lastsave
(integer) 1694869850

然后用lunix指令将时间戳格式化:

[root@quihechunshui ~]# date -d @1694869850
Sat Sep 16 21:10:50 CST 2023

这样我们就知道上一次成功保存是什么时候了。

(四)RDB方式的优缺点

A、优点:

  1. RDB是redis数据的一种非常紧凑的单文件时间点表示,非常适合定时备份,进行不同版本的大量数据恢复
  2. 它非常适合灾难恢复,rdb文件可以上传到数据中心保存,方便灾难恢复
  3. 避免了父进程进行磁盘io等耗时的工作,相对提升了redis的服务效率
  4. 对数据一致性的要求不高(会丢失部分数据,也可以是优点)

B、缺点:

  1. 因为每次备份RDB文件时都要依赖主进程的fork命令,同时备份占用大量io操作,很大概率会拖慢redis服务效率;此外每次创建子进程需要复制主进程数据,会导致数据膨胀两倍。
  2. 因为除手动触发外,自动触发都是有双重条件限制的,如果在上次成功执行保存命令后,服务器突然宕机,我们就会丢失上次保存之后未达到保存条件的操作所添加的数据。

(五)修复rdb文件指令

  • 当 rdb备份文件被稍微损坏,不能使用时,可以尝试使用修复指令:
[root@quihechunshui ~]# redis-check-rdb /opt/redis-7.0.11/myredis/rdbfiles/dump6379.rdb
[offset 0] Checking RDB file /opt/redis-7.0.11/myredis/rdbfiles/dump6379.rdb
[offset 27] AUX FIELD redis-ver = '7.0.11'
[offset 41] AUX FIELD redis-bits = '64'
[offset 53] AUX FIELD ctime = '1694869850'
[offset 68] AUX FIELD used-mem = '980664'
[offset 80] AUX FIELD aof-base = '0'
[offset 82] Selecting DB ID 0
[offset 109] Checksum OK
[offset 109] \o/ RDB looks OK! \o/
[info] 2 keys read
[info] 0 expires
[info] 0 already expired
[root@quihechunshui ~]# 

(六)总结会触发RDB快照的几种情况

  1. 满足配置文件指定的RDB规则
  2. 执行save或者bgsave命令
  3. 执行flushdb或者flushall等清库指令,但是产生的RDB文件是空文件,无用
  4. 指定shutdown且没有开启aof备份方式的情况下
  5. 发生主从复制时由主节点触发

(七)禁用快照与RDB优化

A、在客户端输入指令,临时将配置文件修改

127.0.0.1:6379> config set save ""
OK

B、直接修改配置文件中的save项为空串,禁用RDB

C、配置文件中还有一些配置项跟RDB有关。

stop-writes-on-bgsave-error yes
#在RDB文件写入出现错误后,是否再接收备份指令,默认为yes,保证数据完整性
rdbcompression yes
#默认开启,给配置会将备份的rdb文件进行压缩储存,消耗些许cpu
rdbchecksum yes
#默认开启,开启后每次备份rdb时都会进行CRC64算法进行数据校验,保证数据正确完整。
rdb-del-sync-files no
#此配置项用于主从复制时的rdb配置文件生成,默认为no。此配置项决定在主从复制时若没有指定持久化,就将RDB文件删除。

二、Redis的持久化(AOF方式)

(一)AOF相关理论

A、AOF是将用户的每一次写指令加入到配置文件aof中,这样就保证了RDB方式备份,突然产生断电等突发情况,导致备份时间间隔内部分数据丢失的问题;每次服务重新启动,这些aof文件中记录的写指令都会被执行一遍,这样就保证了数据不丢失

B、AOF的执行流程

C、三种写回策略

  • 修改写回策略的位置(在配置文件中寻找如下配置项)
appendfsync everysec
  • 写回策略
  1. always 每执行一次写操作,都会直接调用io操作,写入磁盘,太频繁影响性能
  2. everysec 每隔1s,将缓冲区的指令集写入磁盘,最优,默认选项。
  3. no 所有写指令都暂时放在缓冲区中,将写入磁盘交给计算机,此种方式容易导致指令丢失

(二)使用AOF

A、设置配置项

  • 开启aof支持
appendonly yes 
#默认为no
  • 指定aof文件保存基本路径
#dir /opt/redis-7.0.11/myredis/rdbfiles
#在redis6中RDB文件和AOF文件都保存在dir指定的文件夹下,但是redis7做了优化,AOF文件会在dir指定路径的基础上再加上一层文件夹(由appenddirname配置项指定)
#由上我们需要变更基本路径,一面引起歧义
dir /opt/redis-7.0.11/myredis
#这样之后RDB文件就接保存在myredis文件夹下,AOF文件直接保存在myredis文件夹下,自己另指定的自己的文件夹
  •  指定AOF文件保存专属文件夹和文件名
appenddirname "appendonlydir"
#直接使用默认文件夹名
appendfilename "appendonly.aof"
#也是直接使用默认指定的文件名
  • 值得注意的是,redis7较redis6的aof文件保存过程做了优化,aof文件结构也发生变化
  1. redis6中是直接一个aof文件,达到一定大小,生成新的AOF文件内容
  2. 在redis7中用multipart aof实现aof文件,顾名思义就是把原来的一份aof文件变成了多份共同表示。
  • redis7中aof文件有四种类型
BASE表示基础aof,它一般由子进程通过重写产生
INCR

表示增量aof,它一般会在aof重写指令执行时被创建,

该文件可以存在多个

history每次aof重写完毕,之前的base和incr文件都会变成history文件,这个文件会被redis自动删除。我们看不到
mainifest为了管理上面三种类型而引入的管理文件,这个文件会跟踪和监控上面三种类型的文件。
  •  他们的文件格式如下:

B、配置文件搞完,重新启动服务,加载配置文件,然后执行写命令,查看生成的aof文件

[root@quihechunshui appendonlydir]# ll
total 12
-rw-r--r-- 1 root root 89 Sep 17 10:41 appendonly.aof.1.base.rdb
-rw-r--r-- 1 root root 58 Sep 17 10:42 appendonly.aof.1.incr.aof
-rw-r--r-- 1 root root 88 Sep 17 10:41 appendonly.aof.manifes

(三)模拟异常,aof恢复数据

A、在客户端执行写操作,set一些值用来验证。

127.0.0.1:6379> set kme "huarong"
OK
127.0.0.1:6379> set kyou "mei"
OK

我们观察执行set命令前后的aof文件可知,写操作都被记录到incr文件中了。

B、先备份aof文件夹,然后指定flushdb模拟宕机

  • 为什么要备份aof文件夹?

因为flushdb也是写指令,也会更新aof文件,如果不备份,重启服务后还是会将flushdb命令执行,造成再次清库。

  • 备份文件夹
cp -r appendonlydir appdonlydir.bak
  • 执行清库指令flushdb
  • 删除aof文件夹和rdb文件,避免最后的清库操作和rdb恢复混淆判断,然后恢复之前备份的aof文件夹
rm -r appendonlydir
rm -r dump6379.rdb
mv appdonlydir.bak appendonlydir #恢复备份文件夹

C、重启服务,查看是否恢复数据

127.0.0.1:6379> get kme
"huarong" #数据恢复成功!

(四)aof文件的修复

A、通过上面我们知道,所有执行的命令都储存在aof的incr文件中

B、在实际生产上可能会出现宕机导致指令储存不全等情况这种情况会导致开机后,进行备份文件恢复时,aof文件损坏

C、查看aof文件结构

*2
$6
SELECT
$1
0
*3
$3
set
$3
kme
$7
huarong
*3
$3
set
$4
kyou
$3
mei

可以看到!我们的指令都被用指定方式存到了文件中

D、我们故意在后面随便加些内容,造成文件损坏,尝试重新启动服务

[root@quihechunshui myredis]# redis-server /opt/redis-7.0.11/myredis/myredis.conf
#重启貌似正常
[root@quihechunshui myredis]# redis-cli -a chen13515216766 -p 6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>  
#可见登陆尝试失败,无法连接到服务

E、修复aof文件

使用redis-check-aof --fix 命令来修复aof文件

[root@quihechunshui appendonlydir]# redis-check-aof --fix appendonly.aof.1.incr.aof
Start checking Old-Style AOF
AOF appendonly.aof.1.incr.aof format error
AOF analyzed: filename=appendonly.aof.1.incr.aof, size=109, ok_up_to=90, ok_up_to_line=20, diff=19
This will shrink the AOF appendonly.aof.1.incr.aof from 109 bytes, with 19 bytes, to 90 bytes
Continue? [y/N]: y
Successfully truncated AOF appendonly.aof.1.incr.aof

注意:一定要加--fix不然不会对文件进行更改

(五)AOF的重写机制

A、AOF的自动重写

  • 配置文件默认的重写策略如下:(意为当aof的incr文件膨胀到上次重写产生的base文件的1倍并且incr文件达到60MB大小时才会触发AOF的自动重写机制)
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

B、什么是AOF的重写

  • 当aof文件过大,aof会调用重写子进程,对aof文件进行重写,只保留恢复数据的关键指令,并且会压缩合并指令,以达到aof瘦身的目的。
  • 比如本来aof存储的命令是set k1 me   set  k1 you set k1 he   压缩之后的指令就变成了set k1 he。这样不仅减少了空间的占用,更提高了数据恢复的效率。

C、AOF的手动重写

  • 只需要执行bgrewriteaof指令即可手动调用后台重写进程进行aof文件重写。

D、实验

  • 修改自动触发重写条件,将64MB改为1K 方便进行重写并关闭aof和RDB混合策略,防止混淆视听。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 1k 
#修改触发条件
aof-use-rdb-preamble no
#默认为yes,开启,我们关闭防止rdb影响
  • 删除appendonly文件夹下的aof文件
[root@quihechunshui appendonlydir]# rm -rf *
[root@quihechunshui appendonlydir]# ll
total 0
  • 重新加载配置文件,并执行命令生成新的aof文件
[root@quihechunshui ~]# redis-cli -a chen13515216766 -p 6379 shutdown
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Could not connect to Redis at 127.0.0.1:6379: Connection refused
[root@quihechunshui ~]# redis-server /opt/redis-7.0.11/myredis/myredis.conf
[root@quihechunshui ~]# redis-cli -a chen13515216766 -p 6379 
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> set k1 me
OK



  • 触发重写之前的结构如下:
[root@quihechunshui appendonlydir]# ll
total 8
-rw-r--r-- 1 root root  0 Sep 17 15:21 appendonly.aof.1.base.aof
-rw-r--r-- 1 root root 52 Sep 17 15:22 appendonly.aof.1.incr.aof
-rw-r--r-- 1 root root 88 Sep 17 15:21 appendonly.aof.manifest
#可见base大小为0,还未被重写,incr为52,保存了我们刚刚的写操作
  • 我们不断写入大量数据让incr超过1k触发自动重写,下面展示重写后的aof文件结构
[root@quihechunshui appendonlydir]# ll
total 12
-rw-r--r-- 1 root root 131 Sep 17 15:26 appendonly.aof.2.base.aof
-rw-r--r-- 1 root root 131 Sep 17 15:26 appendonly.aof.2.incr.aof
-rw-r--r-- 1 root root  88 Sep 17 15:26 appendonly.aof.manifest
#可见重写后的文件,base文件变成了2,之前的1变成了history被清理了,这里的2.base是对1.incr文件重
#写后的指令集,重写后1.base文件也变成history被回收了。
  • 最后测试一下手动重写
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
  • 查看结构变化
[root@quihechunshui appendonlydir]# ll
total 8
-rw-r--r-- 1 root root 131 Sep 17 15:30 appendonly.aof.3.base.aof
-rw-r--r-- 1 root root   0 Sep 17 15:30 appendonly.aof.3.incr.aof
-rw-r--r-- 1 root root  88 Sep 17 15:30 appendonly.aof.manifest
#可见手动重写成功

(六)AOF重写的过程概括、AOF备份的优缺点、AOF相关配置总结

A、AOF重写的过程

  1. 重写开始前,重写子进程被调用,该进程会读取现有的aof文件,并写入到一个临时文件中
  2. 同时主进程会将新接收到的写指令积累到内存缓冲区中,还会继续写入到原有的aof文件中,这样保证了aof文件的可用性,避免在重写过程中出现意外。
  3. 当重写子进程完成工作以后,会发信号给主进程,主进程收到信号后就会将内存中缓存的写指令追加到新的aof文件中
  4. 当追加结束后,redis就会用新的aof文件来代替旧的aof文件,之后再有新的写指令,就会追加到新的aof文件中
  5. 重写aof文件的操作并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重新写了一个新的aof文件。

B、AOF备份的优缺点

  • 优点防止数据部分丢失,对误操作等处理方便(仅需要再aof文件中删除对应的指令即可)
  • 缺点:同样的数据,aof备份方式要比rdb方式占用空间更大,当数据量庞大到一定程度aof和rdb效率是一致的。

C、配置总结

apendonly no/yes是否开启aof重写支持
appendonlyfilename 指定aof文件名字
appendfsync指定aof文件同步策略
no-appendfsync-on-rewriteaof重写期间是否同步

auto-aof-rewrite-percentage

auto-aof-rewrite-min-size

共同制定了aof的自动重写触发条件

三、Redis混合持久化(AOF+RDB)(推荐)

A、如何开启混合模式支持(前提是aof rdb都已经开启了支持配置完整)

aof-use-rdb-preamble yes

#默认为yes,就开启了支持

B、aof和rdb都开启的优先级,见下图

 C、开启混合持久化支持后的优势

  • 每隔一段时间RDB会进行快照储存,在执行写命令时会持久化到aof文件中,每次aof重写被触发时,就会将最新的数据通过RDB方式储存,这样既保证了数据的一致性,又提高了数据的恢复效率,正所谓扬长避短。
  • 一句话就是aof负责增量备份,rdb负责全量备份。

四、纯缓存模式(关闭自动aof和rdb)

A、只需要将save 设置为"" 空串,append-only-file设置为no

B、这样之后,save、bgsave还可以手动调用生成rdb文件,bgrewriteaof也可以调用生成aof文件

五、Redis事务

(一)Redis事务的分析

A、Redis事务可以将多个指令放在一个事务组中,在一个事务组中的指令都会被序列化,串行化执行,在一组命令执行期间其他命令不会插入执行。

B、Redis事务跟传统数据库事务特性的比较

  1. 单独隔离操作,是单线程架构,一组事务中的多个指令在执行完之前,不能执行其他指令
  2. 没有隔离级别的概念,因为单线程,所以当事务执行完毕之前所有操作都不可能执行,所以就不会产生脏读幻读等问题,很想传统数据库隔离级别的串行化。
  3. 不保证事务的原子化,当事务中有指令失败,存在不回滚已执行成功的命令,所以不保证原子化。
  4. 具有排他性,独占进程,其他进程莫插入。

(二)Redis事务的使用

A、关于事务的命令

multi开启事务
exec事务加入队列完毕,使用此命令执行事务
discard取消事务,放弃执行事务中的所有命令
watch在开启事务之前对数据的监控,加上乐观锁保证事务的一致性
unwatch放弃对事务的监控,在事务执行之后数据都会被unwatch,断开连接亦是。

B、各种情况的举例

  • 正常开启并执行事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 "i will better!"
QUEUED
127.0.0.1:6379(TX)> set k1 "i will become better myself"
QUEUED
127.0.0.1:6379(TX)> set k2 "black apple"
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK
3) OK
  • 中途取消事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> get k1
QUEUED
127.0.0.1:6379(TX)> get k2
QUEUED
127.0.0.1:6379(TX)> discard
OK
  • 当加入事务队列的指令有错误,整个事务都不会执行
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> get k1
QUEUED
127.0.0.1:6379(TX)> get
(error) ERR wrong number of arguments for 'get' command#这里我没有指定get的健,语法都不通过,所以就加入队列错误,在后面执行事务时,前面正确的也都不会执行,事务被取消了。
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
  • 当事务运行时发现错误,仅错误语句不能执行,其他正常执行(这点跟数据库就很不同)
127.0.0.1:6379> set k3 4
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incr k3 
QUEUED
127.0.0.1:6379(TX)> incr k2 #这里我们让文本执行加一操作,肯定报错
QUEUED
127.0.0.1:6379(TX)> get k1
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 5
2) (error) ERR value is not an integer or out of range #可见仅有该条指令报错执行失败,其他命令执行正常。
3) "i will become better myself"
  • 对一个事务添加监控,在事务执行之前,有其他客户端修改加锁数据,则事务中指令都得不到执行,返回nli
127.0.0.1:6379> watch k3 #给k3加上乐观锁
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k3 9 #在事务执行之前,该条数据被其他客户端修改为19
QUEUED
127.0.0.1:6379(TX)> get k2
QUEUED
127.0.0.1:6379(TX)> exec  
(nil)    #事务执行后不经加锁的k3没有设置成功,get指令也没有得到执行。
127.0.0.1:6379> get k3
"19"

在事务执行完毕,对数据的watch就自动释放了。

六、Redis管道(pipe lining)

(一)管道出现原因及原理

A、为了解决一个问题:频繁的命令往返造成的性能瓶颈。

B、Redis采用的是客户端和服务器模型,每次指令从开始到返回都要经历下图的过程(每次等待返回都是阻塞式的,所以会影响性能)

如果每条指令都要执行上面的过程,累计起来的往返时间(Round-Trip Time)累计起来,不仅频繁占用io,大量调用redis读写方法,同时用户数据不断由用户态转向内核态,故会拖慢效率,让redis陷入性能瓶颈

C、管道的出现,实现了将多条可执行命令,一起发送到server,仅用一次rtt就可以实现多条指令往返,这就解决了性能瓶颈。(原理如下图)

(二)实际操作

 A、首先我们将要执行的命令写入一个文本文件。

我们创建一个suinter.txt文件,存入以下内容

set k3 "i will win"
get k2 "me,and,you" #这条命令是错误命令
set k4 "haha"
                                                                                                                                             

B、然后执行如下指令(运用到了lunix的管道命令)

[root@quihechunshui myredis]# cat suinter.txt | redis-cli -a chen13515216766 -p 6379 --pipe
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
All data transferred. Waiting for the last reply...
ERR wrong number of arguments for 'get' command
Last reply received from server.
errors: 1, replies: 3    #这里显示我们出错的命令和成功的命令

C、然后我们在客户端查看set值是否成功!

127.0.0.1:6379> get k4
"haha" #成功!

(三)管道跟事务的对比

管道事务
非原子性的原子性
非阻塞式阻塞式
一次发送大量命令单条命令装载队列,然后发送

(四)使用管道的注意事项

  1. 一次发送的命令不能过多,因为命令本身以及处理命令都要占用server的内存,当指令过多时,很可能直接返回队列超载等内存问题
  2. 使用pipe方式执行的命令如果有指令出错,不会影响后面正确指令的执行。 

七、pub/sub(简单实现消息收发,很多不足,了解)

A、pub/sub相关指令

psubscribe pattern [pattern...]通过执行模式订阅频道,如模糊指定频道名,同时订阅多个消息
subscribe channel [channel..]通过频道名订阅频道
publish channel [channel..]向指定频道发送消息
punsubscibe [pattern...]根据指定的频道名模式,退订多个频道
unsubscribe channel [channel ...]退订指定频道
pubsub subcommand [argument [argument]]查询订阅于发布的状态,可以查询数据及对应指令见下表

B、查询发布订阅状态的指令如下(要和上面的pubsb一起使用)

channels返回活跃频道的名称列表
numsub [channel]返回某个频道有几个订阅者
numpat统计通过pattern订阅方式的pattern数量

C、模拟消息发布订阅(三个客户端,客户端一创建频道发布信息、客户端二,以信道名订阅频道、客户端三以pattern方式订阅信道。)

  • 客户端二订阅信道
127.0.0.1:6379> subscribe cone
Reading messages... (press Ctrl-C to quit)
1) "subscribe" 
2) "cone"
3) (integer) 1 
#订阅后就处在等待状态,有消息发送到cone信道就会被接收,ctrl+c推出接收
  • 客户端三订阅
127.0.0.1:6379> psubscribe c* w?
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "c*"
3) (integer) 1
1) "psubscribe"
2) "w?"
3) (integer) 2
  • 客户端一创建频道发送消息
127.0.0.1:6379> publish cone "i am supperman!"
(integer) 2
  • 客户端发送消息后就被二和三接收到了。
#客户端三接收到的内容
3) "cone" #频道名
4) "i am supperman!" #消息内容
#客户端二接收到的内容
1) "message" #接收到的类型
2) "cone" #频道名
3) "i am supperman!" #消息内容
  • 在客户端一查看发布订阅状态
127.0.0.1:6379> pubsub channels #查询活跃频道数量
1) "cone"
127.0.0.1:6379> pubsub numsub cone #查看指定信道的订阅数,模糊订阅不算在内
1) "cone"
2) (integer) 1
127.0.0.1:6379> pubsub numpat #查询模式订阅有几个pattern,这里2,是因为客户端三用了两个patern
(integer) 2
  • 演示两种订阅方式的退订(客户端都首先ctrl+c推出)
#客户端二
127.0.0.1:6379> unsubscribe cone
1) "unsubscribe"
2) "cone"
#客户端三
127.0.0.1:6379> punsubscribe c* w?
1) "punsubscribe"
2) "c*"
3) (integer) 0

D、这种方式的劣势

  1. 没有消息持久化规则,消息放在频道里没有订阅者接收就直接丢失
  2. 没有ack机制,消息处理得不到保证
  3. 所以5.0版本之后出现了stream来弥补不足,但还是用途不广

八、Redis主从复制(一主多从)

(一)为什么要有主从复制?

  1. 此种模式多出来了几台机器可以分散职能分解redis服务压力
  2. 从机会不断同步数据,在另一方面多了一个数据备份。
  3. 多台设备,也能分摊风险,主机挂了,从机顶上,从机挂了,其他从机顶上。

(二)多台机器的不同配置

A、情况说明,正常环境是redis的主机和从机不在一台机器上,在不同的机器上ip自然也会不同,端口号可以一样。但环境有限,我们用三个配置文件设置不同的端口号,来模拟三台机器的主从复制。

B、三台机器对应三个配置文件

  • 6380从机配置文件
daemonize yes #开启后台运行模式
protected-mode no  #取消自我保护模式,其他可连
#bind 127.0.0.1 -::1 #取消自我绑定,其他机器可连
dir /opt/redis-7.0.11/myredis #指定工作空间
pidfile /var/run/redis_6380.pid #指定自己服务启动后端口号占用情况记录文件
port 6380 #指定自己的端口号
logfile "/opt/redis-7.0.11/myredis/redislog6380.log"#指定日志文件名字
requirepass "1234566380" #指定自己的密码
 masterauth "chen13515216766" #配置要从属的主机密码
 replicaof 47.94.143.83 6379 #指定要从属的主机地址和端口号
  • 从机6379配置文件
daemonize yes #开启后台运行模式
protected-mode no  #取消自我保护模式,其他可连
#bind 127.0.0.1 -::1 #取消自我绑定,其他机器可连
dir /opt/redis-7.0.11/myredis #指定工作空间
pidfile /var/run/redis_6380.pid #指定自己服务启动后端口号占用情况记录文件
port 6390 #指定自己的端口号
logfile "/opt/redis-7.0.11/myredis/redislog6390.log"#指定日志文件名字
requirepass "1234566390" #指定自己的密码
 masterauth "chen13515216766" #配置要从属的主机密码
 replicaof 47.94.143.83 6390 #指定要从属的主机地址和端口号
  • 主机配置文件少了后两个,其他就变端口号。 

(三)启动三台服务

redis-server /opt/redis-7.0.11/myredis/redis6379.conf
redis-server /opt/redis-7.0.11/myredis/redis6380.conf
redis-server /opt/redis-7.0.11/myredis/redis6390.conf

然后我们查看日志检查连接状态:

  • 两个从机日志都显示连接成功!下面随便展示其中一个。

  •  然后我们用三个客户端分别登陆登陆!

(四)关于主从可能出现的情况说明

  1. 当主机突然宕机,所有从机都会处于等待状态,直到主机归来,不会抢占主机master地位
  2. 主机可以读写,但是从机只能进行读操作,这样职能分离。
  3. 当从机宕机后,再次接入,宕机时主机写入的命令,会被一次性备份到从机,不会数据丢失。

(五)关于主从复制的命令及连接模式变化

A、主从复制的命令如下

slaveof 主机ip 主机port从新认新的主机做大哥
info repliation显示该服务的主从信息
slaveof no one使该台服务不隶属于任何其他master,自成一派。

B、使用slaveof 命令改变主机,同时改变主从模式,让6390继承6380,这样6380就有了双重身份(注意在改变之前要先将配置文件指定的主机地址和密码都注掉,不然连接转化会因为密码不对连不上)

127.0.0.1:6390> slaveof 47.94.143.83 6380
OK
127.0.0.1:6390> info replication
# Replication
role:slave   #自己的身份
master_host:47.94.143.83
master_port:6380
master_link_status:up  
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_read_repl_offset:4466
slave_repl_offset:4466
master_link_down_since_seconds:164
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:c6e9a582df0a066973b9f90019f9672bfa962a98
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:4466
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:337
repl_backlog_histlen:4130

C、只有一级master才有读和写的权限,下属的slave无论是否是其他slave的master,依然没有写权限。

D、当使用命令切换之后,依然会全量复制新主机的数据,在这之前要删除前主机数据。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值