Redis初步学习整理——第五节Redis配置文件、RDB、AOF、Redis订阅发布

前言

上几节学习完了Redis的常规操作,这节就深入学习一下Redis的配置文件、RDB、AOF、Redis订阅发布内容了,共同加油!

一、redis.conf 配置文件参数

Redis配置文件涉及到的参数很多,如果英文很好的话,配置文件中都有相应的案例,所以不难理解,但是对于我这种英语起步阶段的话,还是需要对一些重点的参数进行一下整理的

# Note on units: when memory size is needed, it is possible to specify
# it in the usual form of 1k 5GB 4M and so forth:
#
# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes
#
# units are case insensitive so 1GB 1Gb 1gB are all the same.
# 这个提示了在配置文件中的单位
################################## INCLUDES ###################################

# Include one or more other config files here.  This is useful if you
# have a standard template that goes to all Redis servers but also need
# to customize a few per-server settings.  Include files can include
# other files, so use this wisely.
#
# Note that option "include" won't be rewritten by command "CONFIG REWRITE"
# from admin or Redis Sentinel. Since Redis always uses the last processed
# line as value of a configuration directive, you'd better put includes
# at the beginning of this file to avoid overwriting config change at runtime.
#
# If instead you are interested in using includes to override configuration
# options, it is better to use include as the last line.
#
# include /path/to/local.conf
# include /path/to/other.conf
# 提示了如何引入其他的配置文件
# 网络
bind * # 绑定可以访问的主机ip,默认是bind 127.0.0.1,只有本机可以访问
protected-mode no # 是否开启保护模式,通常和bind配合使用
port 6379  # 设置端口号
# 通用配置
daemonize yes # 是否后台启动redis,默认 no,则随着linux连接关闭而停止redis服务
loglevel notice # redus日志级别,分为debug、verbose 、notice、warning 
pidfile "/var/run/redis_6379.pid" # 后台运行时需要制定的pid文件
logfile "" # 日志文件位置署名
databases 16  # Redis数据库最大数量
always-show-logo yes # 启动时是否显示Redislogo
# 持久化配置
save 900 1  # 持久化规则,900秒的时间内Redis只要发生了一次的变化,就会进行持久化
save 300 10
save 60 10000
stop-writes-on-bgsave-error no  # 当持久化出错后,是否继续工作
rdbcompression yes # 是否压缩, yes的话会消耗一部分cpu资源,但是会减少硬盘资源
rdbchecksum yes # 保存rdb文件时,进行错误检查校验
dbfilename "backup.db" # 保存rdb的文件名
dir "/opt/redis/6.0.9" # 保存位置
# 客户端限制
maxclients 10000  # 最大可以连接的客户端数量
# 内存配置
maxmemory <bytes>  # 最大可用的内存
maxmemory-policy noeviction  # 内存达到上限后的处理策略,一共六种策略
# 1、volatile-lru:只对设置了过期时间的key进行LRU(默认值) 
# 2、allkeys-lru : 删除lru算法的key   
# 3、volatile-random:随机删除即将过期key   
# 4、allkeys-random:随机删除   
# 5、volatile-ttl : 删除即将过期的   
# 6、noeviction : 永不过期,返回错误

# APPEND ONLY MODE配置
appendonly no  # 默认不开启aof模式,默认使用rdb模式进行持久化,在多数情况下,rdb也够用的
appendfilename "appendonly.aof" # 持久化文件的名字
appendfsync everysec 
# everysec:每秒一次 sync,但是可能会丢失这一秒的数据
# no: 不同sync,这个时候操作系统同步数据,速度最快
# everysec:每次修改都会 sync,损失性能

二、持久化

Redis是一种内存数据库,遇到特殊情况就会丢失数据,这种情况下持久化就很有必要了,Redis也提供了两种持久化机制,分别是RDB(Redis Database) 和 AOF(Apend Only File)

1. RDB

Redis 默认的持久化机制就是RDB,一般情况下RDB持久化也足够了。
当然我查看了网上资料,也有一种说法,当只需要Redis作为一个缓冲时,可以关闭持久化机制,这样可以节省更多的性能;当需要Redis做持久化时,将RDB和AOF都打开,这样就可以最大程度的保证数据的完整性。
当然这些都是业务的处理方案而已,具体情况具体分析即可,还是聊一下RDB,RDB以快照的方式将Redis内存数据库中的数据保存下来,就是将当前数据库内的数据转换成二进制文件“dump.rdb”,保存当前的配置目录下,如果原目录下已经存在“dump.rdb”,那么就直接替换掉。
触发RDB快照保存的一共有三种方式,分别是save、bgsave、自动化保存

(1)save

该命令执行期间会阻塞Redis的运行,也就是当执行save命令时,其他客户端不可以再对Redis进行操作,运行流程如下图:
Redis初步学习整理——第五节Redis配置文件、RDB、AOF、Redis订阅发布_第1张图片
这个命令当Redis数据库中数据较多时,会导致sava执行时间过长,其他Client无法得到响应,所以在实际生产中也是不可取的

(2)bgsave

这个命令和save命令类似,都是保存快照,但是有所不同的是,当执行bgsave命令时,会先创建一个子进程,使用子进程来保存快照,这样的话,就不会因为保存快照而影响其他Client的访问了,流程如下图
Redis初步学习整理——第五节Redis配置文件、RDB、AOF、Redis订阅发布_第2张图片
这个简单的流程图,可以看出来当Redis接受到bgsave命令时,先fork一个子进程来保存快照,fork的时候其实是阻塞了其他client访问的,但是这个流程是很快的,之后就可以正常访问了。一般情况下,主动保存都会使用bgsave命令的

(3)自动化保存机制

自动化保存机制,说到这里,就不得不提刚刚的配置文件讲解了,就是在配置文件Redis.conf中的SNAPSHOTTING这个位置来设置RDB的配置的
1)save
这里是用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。比如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。
2)stop-writes-on-bgsave-error
默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。如果Redis重启了,那么又可以重新开始接收数据了
3)rdbcompression
默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储(会占用一定的CPU资源)
4)rdbchecksum
默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
5)dbfilename
设置快照的文件名,默认是 dump.rdb(一般没必要修改)
6)dir
置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名(一般没必要修改)。

(4)优缺点分析

优点:

  • RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
  • 生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
  • RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

缺点:

  • RDB快照是一次全量备份,存储的是内存数据的二进制序列化形式,存储上非常紧凑。当进行快照持久化时,会开启一个子进程专门负责快照持久化,子进程会拥有父进程的内存数据,父进程修改内存子进程不会反应出来,所以在快照持久化期间修改的数据不会被保存,可能丢失数据
(5)RDB补充

除了sava、bgsave两种命令会触发快照,flushall和shutdown都会触发快照操作

2. AOF

AOF(Append Only FIle),这个和RDB完全不同,RDB是全量保存数据,而AOF是追加修改数据的命令,这个AOF更像一个操作日志,AOF正常的操作流程如下图:
Redis初步学习整理——第五节Redis配置文件、RDB、AOF、Redis订阅发布_第3张图片
当开启Redis的AOF持久化机制的时候,客户端发送到的每一条修改指令都会被Redis服务记录到AOF文件中,刚刚忘记说了,AOF持久化机制是默认关闭的,这个是需要在配置文件中手动开启,开启方式如下

appendonly yes # 开启AOF持久化机制
appendfilename "appendonly.aof" # 指定AOF文件名(一般不需要修改)
appendfsync everysec # 指定追加触发条件  always:每收到一条修改指令时追加;everysec :每秒追加一次;no:从不追加
auto-aof-rewrite-min-size 64mb # 当追加的AOF文件超过了64MB时进行重写,一般情况下设置为3GB

(1) 重写机制
AOF的机制也带来了一个问题,AOF是一个不断追加记录数据的过程,这也导致了AOF文件越来越大,这样就很不好管理,所以Redis提供了一个重写机制,当AOF文件达到我们配置的一个阈值时,自动进行重写(当然也可以通过命令手动重写:bgrewriteaof),当进行重写时,Redis会生成一个临时文件用来存储Redis中的数据,然后fork出一个子进程来进行重写操作,如下图
Redis初步学习整理——第五节Redis配置文件、RDB、AOF、Redis订阅发布_第4张图片

突然发现写的比较好的文章,那就借图一张,当然了,这样的话,也会造成一些问题,如fork出的进程肯定会占用一定的内存,然后因为子进程使用的是克隆主进程的临时文件,所以会造成一定的数据不对等,也就是说当子进程进行重写的时候,主进程的数据有了更新,那么这部分数据是没有进行重写的,那么这个时候发生了宕机或者断电,是很容易造成数据丢失的

3. 补充

在实际使用中,不需要更改太多的配置文件,只需要根据需要进行个性化的修改就可以了,大多数的配置使用默认的就很合理了
如果业务中需要Redis做持久化,那么同时启动RDB和AOF,或许效果更多一些

三、Redis订阅发布

首先,说一下订阅发布并不是Redis的强项,Redis只是提供了一个简单的发布订阅的功能,要说这块功能做得好的,要是消息中间件,等一下整理完Redis的话,我估计会再整理一下Rabbitmq!
Redis的订阅发布很简单,一共涉及了五个命令
Redis初步学习整理——第五节Redis配置文件、RDB、AOF、Redis订阅发布_第5张图片
截取自菜鸟
我理解的是,订阅者可以订阅一个固定的频道,也可以订阅一个给定模式的频道,有差区别呢,其实就是给定模式的频道,是订阅一个范围的频道,比如china.*,那么不管是china.city还是china.chengshi,都是被它订阅的
发布者对某个特定的频道进行消息推送
下面看一下例子
订阅消息

127.0.0.1:6379> subscribe cainiao helloword # 订阅频道
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "cainiao"
3) (integer) 1  # 订阅了cainiao这个频道
1) "subscribe"
2) "helloword"
3) (integer) 2  # 订阅了helloword频道
1) "message" # 收到消息
2) "cainiao" # cainiao频道收到消息
3) "helloword!" # 消息内容

发布者

127.0.0.1:6379> publish cainiao helloword! # 向cainiao这个频道发布helloword! 
(integer) 1

模式订阅的话,和这个类似,不过有一个通配符*,意味着匹配任意字符的意思
订阅者

127.0.0.1:6379> psubscribe china.*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "china.*"
3) (integer) 1
1) "pmessage"
2) "china.*"
3) "china.1"
4) "1"
1) "pmessage"
2) "china.*"
3) "china.2"
4) "2

发布者

127.0.0.1:6379> publish china.1 1
(integer) 1
127.0.0.1:6379> publish china.2 2
(integer) 1

至于发布订阅的相关原理,应该是Redis在内部存储了一个字典表或者是一个链表,以chanel作为key,所有订阅这个channel的client作为键,当发布者发送信息到channel时,将消息转发给所有订阅的client
有一篇博客讲的还可以,可以看一看订阅与发布

结语

这节就到这里,下一节最后研究一下Redis的集群部署、主从复制、哨兵模式、雪崩和缓存穿透,望路过大佬指点

你可能感兴趣的:(数据库,redis)