Redis-04(Redis.conf以及持久化发布和订阅)

Redis.conf

容量单位不区分大小写

可以使用多个include组合多个配置
image

网络配置

image

日志

# 日志
# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably) 生产环境
# warning (only very important / critical messages are logged)
loglevel notice
logfile "" # 日志的文件位置名
databases 16 # 数据库的数量,默认是 16 个数据库
always-show-logo yes # 是否总是显示LOGO

日志输出级别

debug
verbose
notice
waring

持久化操作(RDB AOF)--->讲持久的时候细说

# 如果900s内,如果至少有一个1 key进行了修改,我们及进行持久化操作
save 900 1
# 如果300s内,如果至少10 key进行了修改,我们及进行持久化操作
save 300 10
# 如果60s内,如果至少10000 key进行了修改,我们及进行持久化操作
save 60 10000
# 我们之后学习持久化,会自己定义这个测试!
stop-writes-on-bgsave-error yes # 持久化如果出错,是否还需要继续工作!
rdbcompression yes # 是否压缩 rdb 文件,需要消耗一些cpu资源!
rdbchecksum yes # 保存rdb文件的时候,进行错误的检查校验!
dir ./ # rdb 文件保存的目录!

SECURITY安全

可以在这里设置redis的密码,默认没有密码

127.0.0.1:6379> ping
PONG
127.0.0.1:6379> config get requirepass # 获取redis的密码
1) "requirepass"
2) ""
127.0.0.1:6379> config set requirepass "123456" # 设置redis的密码
OK

# 发现所有的命令都没有权限了
127.0.0.1:6379> config get requirepass 
(error) NOAUTH Authentication required.
127.0.0.1:6379> ping
(error) NOAUTH Authentication required.
127.0.0.1:6379> auth 123456 # 使用密码进行登录!
OK
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "123456"

限制CLIENTS(客户端连接相关)

maxclients 10000 # 设置能连接上redis的最大客户端的数量
maxmemory <bytes> # redis 配置最大的内存容量
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 模式 aof配置

appendonly no # 默认是不开启aof模式的,默认是使用rdb方式持久化的,在大部分所有的情况下,
rdb完全够用!
appendfilename "appendonly.aof" # 持久化的文件的名字
# appendfsync always # 每次修改都会 sync。消耗性能
appendfsync everysec # 每秒执行一次 sync,可能会丢失这1s的数据!
# appendfsync no # 不执行 sync,这个时候操作系统自己同步数据,速度最快!

Redis持久化---RDB

面试工作的重点
Redis是内存型的数据库,如果不将内存中的数据保存到磁盘中,那么一旦服务器出现了问题,服务器中的数据库状态也可能会消失,所以Redis提供了持久化功能

什么是RDB

在指定的时间间隔后,(save中定义的).将内存中的数据集写入数据库中;在恢复的时候,可以直接读取快照文件,进行数据恢复;在默认情况下,Redis将数据库快照保存在dump.rdb的二进制文件中.文件名字可以在配置文件中自定义

在指定的时间间隔将内存中的数据集写入磁盘,也就是Snapshot快照,它恢复是将快照文件直接读到内存中.
redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化结束了,再将这个临时文件替换上次持久化好的文件.整个过程中,主进程时不进行任何IO操作的.
这就确保了极高的性能,如需进行大规模的恢复,且对于数据恢复的完整性要求不是非常敏感,那么rdb方式就要比aof方式更加高效.
rdb的缺点是最后一次持久化后的数据可能丢失.
我们默认的就是rdb,一般情况下不需要修改配置,生产环境会将文件进行备份
rdb保存的文件是dump.rdb都是我们的配置文件中快照中进行配置的

工作原理

image

在进行RDB的时候,redis的主线程是不会做id操作的,主线程会fork一个子线程来完成该操作

  • redis在调用forks.同时拥有父进程和子进程
  • 子进程将数据集写到一个临时的RDB文件中
  • 当子进程完成对新的RDB文件的写入时,Redis又用新的RDB文件替换原来的RDB文件,并删除旧的RDB文件
    这种工作方式使得Redis可以从写时复制机制中获益(因为是使用子进程进行,而父进程依然可以接收来自客户端的请求)

触发机制

  • save的规则满足的情况下,会自动触发rdb原则
  • 执行flushall命令,也会触发我们的rdb原则
  • 退出redis,也会自动产生rdb文件
    save

使用save时候,会立刻对当前内存中的数据进行持久化,但是会阻塞,也就是不接受其他操作了;
由于save是同步命令,会占用Redis的主进程,若Redis数据非常多的时候,save命令会执行的速度非常慢,阻塞所有的客户端请求
示意图

image

flushall

flushall命令也会触发持久化;

满足配置条件中的触发条件

可以通过配置文件对Redis进行设置,让它在N秒内数据集至少有M个改动这一个条件满足时,自动进行数据集的保存操作
image

save 900 1如果900秒的时间内至少1个key进行了修改,就进行持久化
save 300 10如果300s内对10个key进行了修改...
...
image

bgsave
是异步进行的,进行持久化的时候,redis还可以继续响应客户端请求
image

bgsave 和 save 的对比
image

如果恢复rdb文件

  1. 只需要将rdb文件放在我们启动redis的目录就可以了(也就是有redis-saver和redis-cli),redis启动的时候会自动检查然后恢复其中的数据
  2. 查看需要存在的位置使用指令config get dir(需要在进入client之后)

优缺点

优点

  1. 适合大规模的数据恢复
  2. 对数据的完整性要求不高

缺点

  1. 需要一定的时间间隔进行操作,如果redis宕机了,这个最后一次修改的数据就没有了
  2. fork进程的时候,会占用一定的内容空间

Redis持久化---AOF

append only file
将我们所有的命令都记录下来,类似于history这个命令,恢复的时候全部执行一边
image
以日志的形式来记录每个写的操作,将Redis执行过的所有指令记录下来,只许追加文件但是不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将指令从前到后执行一次以完成数据的恢复工作

什么是AOF

  • 快照功能(RDB)并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、以及未保存到快照中的那些数据。 从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。
    appendonly no yes则表示启用AOF
    默认是不开启的,我们需要手动配置,然后重启redis,就可以生效了!
    如果这个aof文件有错位,这时候redis是启动不起来的,我需要修改这个aof文件
    redis给我们提供了一个工具redis-check-aof --fix

优缺点

优点

  • 每次修改都会同步,文件的完整性会更好
  • 每秒同步一次,可能会丢失一点点数据
  • 从不同步的话效率最高

缺点

  • 相对于数据文件来说,aof远大于rdb,修复的速度比rdb慢
  • aof运行效率也比rdb慢,所以我们的redis默认是rdb来持久化

AOF RDB扩展

  1. RDB 持久化方式能够在指定的时间间隔内对你的数据进行快照存储
  2. AOF 持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以Redis 协议追加保存每次写的操作到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
  3. 只做缓存,如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化
  4. 同时开启两种持久化方式
  • 在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
  • RDB 的数据不实时,同时使用两者时服务器重启也只会找AOF文件,那要不要只使用AOF呢?建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的Bug,留着作为一个万一的手段。
  1. 性能建议
  • 因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留 save 900 1 这条规则。
  • 如果Enable AOF ,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了,代价一是带来了持续的IO,二是AOF rewrite 的最后将 rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上,默认超过原大小100%大小重写可以改到适当的数值。
  • 如果不Enable AOF ,仅靠 Master-Slave Repllcation 实现高可用性也可以,能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave 同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master/Slave 中的 RDB文件,载入较新的那个,微博就是这种架构。

如何选择使用哪种持久化方式?

  • 一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
  • 如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
  • 有很多用户都只使用 AOF 持久化, 但并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要

Redis发布和订阅

Redis 发布订阅是一种消息通信模式,类似于微信的公众号,发送者发送消息,订阅者接收消息.
Redis客户端可以订阅任意数量的频道.
image
有新的消息会通过publish命令来发送给频道的channel1,然后这个消息就会被推送到订阅的三个客户端也就是client
image

命令

  • psubscribe pattern [pattern]订阅一个或者多个符合给定模式的频道
  • punsubscribe patten [pattern]退订一个或者多个符合给定模式的频道
  • pubshb subcommand查看订阅与发布的系统状态
  • publish channel订阅给定的一个或者多个频道
  • unsubscribe channel退订一个或者频道
----------------------------订阅端---------------------------
127.0.0.1:6379> SUBSCRIBE sakura # 订阅sakura频道
Reading messages... (press Ctrl-C to quit) # 等待接收消息
1) "subscribe" # 订阅成功的消息
2) "sakura"
3) (integer) 1
1) "message" # 接收到来自sakura频道的消息 "hello world"
2) "sakura"
3) "hello world"
1) "message" # 接收到来自sakura频道的消息 "hello i am sakura"
2) "sakura"
3) "hello i am sakura"
---------------------消息发布端-----------------------

127.0.0.1:6379> PUBLISH sakura "hello world" # 发布消息到sakura频道
(integer) 1

127.0.0.1:6379> PUBLISH sakura "hello i am sakura" # 发布消息
(integer) 1


-------------------查看活跃的频道---------------------

127.0.0.1:6379> PUBSUB channels
"sakura"

原理

Redis是通过C实现的,通过Redis源码里的pubsub.c文件,了解发布和订阅机制的底层实现,籍此加深对Redis的理解
Redis是通过publish subscribe pubscribe 等命令来实现发布和订阅功能的,要想更好的实现消息功能需要使用消息队列RabbitMQ
每个Redis的服务器进程中都维持着一个表示服务器状态的redis.h/redisServer结构,结构的pubsub_channels属性是一个字典,这个字典就用月保存订阅频道的信息,其中,字典的键为正在被订阅的频道,而字典的值则是一个链表,链表中保存了所有订阅这个频道的客户端
image
客户端订阅,就被链接到对应频道的链表的尾部,退订则是将客户端的节点从链表中移除

  • 缺点:
  1. 如果一个客户端订阅了频道,但自己读取的消息速度不够快的话,那么不断积压的消息会使redis输出的缓冲区的体积变得越来越大,这可能使得redis本身的速度变慢,甚至直接崩溃
  2. 这个数据可靠性有关,如果在订阅方断线,那么它将会丢失所有在短线期间发布的消息
  • 应用:
  1. 消息订阅:公众号订阅,微博关注等等(使用消息队列来进行实现RabbitMQ)
  2. 多人聊天室的实现
posted @ 2021-10-12 11:50  1_f  阅读(28)  评论(0)    收藏  举报