Redis

Redis 相对于 Memcache 等其他的缓存产品,有一个比较明显的优势就是 Redis 不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。接下来我们要介绍 Redis 的另外一大优势——持久化。

由于 Redis 是一个内存数据库,所谓内存数据库,就是将数据库中的内容保存在内存中,这与传统的MySQL,Oracle等关系型数据库直接将内容保存到硬盘中相比,内存数据库的读写效率比传统数据库要快的多(内存的读写效率远远大于硬盘的读写效率)。但是保存在内存中也随之带来了一个缺点,一旦断电或者宕机,那么内存数据库中的数据将会全部丢失。

为了解决这个缺点,Redis提供了将内存数据持久化到硬盘,以及用持久化文件来恢复数据库数据的功能。Redis 支持两种形式的持久化,一种是RDB快照(snapshotting),另外一种是AOF(append-only-file)。

Redis常见的面试题其实就是关于数据持久化部分,分为RDB和AOF两种方式。

RDB

RDB是Redis用来进行持久化的一种方式,是把当前内存中的数据集快照写入磁盘,也就是 Snapshot 快照(数据库中所有键值对数据)。恢复时是将快照文件直接读到内存里。

RDB 有两种触发方式:自动触发和手动触发。自动触发可在conf配置文件中找到
在这里插入图片描述
save命令:什么时候将内存中的数据保存到硬盘,但是会阻塞当前Redis服务器,直到RDB过程完成为止
bgsave命令:Redis会在后台执行该命令,也就是还可以响应客户端请求,具体操作是Redis进程fork(创建)子进程RDB过程由子进程完成并结束,主进程不需要进行任何磁盘IO操作。阻塞就只在fork过程,不过一般时间很短。

save 900 1:表示900 秒内如果至少有 1 个 key 的值变化,则保存
save 300 10:表示300 秒内如果至少有 10 个 key 的值变化,则保存
save 60 10000:表示60 秒内如果至少有 10000 个 key 的值变化,则保存

RDB优缺点

优点:保存了Redis在某一个时间点的数据集,非常适用备份和灾难恢复,生成RDB文件主进程会fork子进程来处理保存工作,主进程不需要进行任何IO操作
缺点:这种保存操作无法做到实时性持久化,因为bgsave每次都需要fork一个子进程出来,内存中的数据会被克隆一份出来,因此会占用内存并由于频繁调用影响性能
同时由于是间隔一段时间做一次备份所以如果redis意外崩掉了那么最后一次快照后的修改后的数据将会丢失(对数据完整性要求不高)

AOF

https://www.cnblogs.com/ysocean/p/9114267.html
RDB通过保存数据库键值对,而AOF通过保存redis服务器所执行的写命令

conf文件第600多行
①、appendonly:默认值为no,也就是说redis 默认使用的是rdb方式持久化,如果想要开启 AOF 持久化方式,需要将 appendonly 修改为 yes。

②、appendfilename :aof文件名,默认是"appendonly.aof"

③、appendfsync:aof持久化策略的配置;

no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快,但是不太安全;

always表示每次写入都执行fsync,以保证数据同步到磁盘,效率很低;

everysec表示每秒执行一次fsync,可能会导致丢失这1s数据。通常选择 everysec ,兼顾安全性和效率。

④、no-appendfsync-on-rewrite:在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。如果对延迟要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择。 设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。Linux的默认fsync策略是30秒。可能丢失30秒数据。默认值为no。

⑤、auto-aof-rewrite-percentage:默认值为100。aof自动重写配置,当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候,Redis能够调用bgrewriteaof对日志文件进行重写。当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程。

⑥、auto-aof-rewrite-min-size:64mb。设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写。

⑦、aof-load-truncated:aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存。重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项,出现这种现象 redis宕机或者异常终止不会造成尾部不完整现象,可以选择让redis退出,或者导入尽可能多的数据。如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。如果是no,用户必须手动redis-check-aof修复AOF文件才可以。默认值为 yes。

重启 Redis 之后就会进行 AOF 文件的载入。
异常修复命令:redis-check-aof --fix 进行修复

AOF重写:aof持久化是将一条条的命令写入aof文件所以aof文件会越来越庞大,占用内存和恢复数据集速度越来越慢,因此redis增加了重写机制,通过对aof文件的内容压缩,只保留可以恢复数据的最小指令集,也就是直接读取服务器的键值对并用一条命令去代替之前记录这个键值对的多条命令,生成新的aof文件后再去代替原aof文件,重写机制也是在子进程中进行防止redis长时间无法执行命令,在重写过程中生成的新命令将会放在redis重写缓冲区,当子进程完成重写后会发送信号给父进程,父进程调用函数将重写缓冲区的内容都写到新aof文件中,
优点

①、AOF 持久化的方法提供了多种的同步频率,即使使用默认的同步频率每秒同步一次,Redis 最多也就丢失 1 秒的数据而已。

②、AOF 文件使用 Redis 命令追加的形式来构造,因此,即使 Redis 只能向 AOF 文件写入命令的片断,使用 redis-check-aof 工具也很容易修正 AOF 文件。

③、AOF 文件的格式可读性较强,这也为使用者提供了更灵活的处理方式。例如,如果我们不小心错用了 FLUSHALL 命令,在重写还没进行时,我们可以手工将最后的 FLUSHALL 命令去掉,然后再使用 AOF 来恢复数据。

缺点

①、对于具有相同数据的的 Redis,AOF 文件通常会比 RDB 文件体积更大。

②、(虽然 AOF 提供了多种同步的频率,默认情况下,每秒同步一次的频率也具有较高的性能)。但在 Redis 的负载较高时,RDB 比 AOF 具好更好的性能保证。

③、RDB 使用快照的形式来持久化整个 Redis 数据,而 AOF 只是将每次执行的命令追加到 AOF 文件中,因此从理论上说,RDB 比 AOF 方式更健壮。官方文档也指出,AOF 的确也存在一些 BUG,这些 BUG 在 RDB 没有存在。

那么对于 AOF 和 RDB 两种持久化方式,我们应该如何选择呢?

如果可以忍受一小段时间内数据的丢失,毫无疑问使用 RDB 是最好的,定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快,而且使用 RDB 还可以避免 AOF 一些隐藏的 bug;否则就使用 AOF 重写。但是一般情况下建议不要单独使用某一种持久化机制,而是应该两种一起用,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。Redis后期官方可能都有将两种持久化方式整合为一种持久化模型。

主从复制

https://www.cnblogs.com/ysocean/p/9143118.html

线程模型

内部采用文件事件处理器,这个文件事件处理器是单线程的,所以redis才叫单线程的模型,采用IO多路复用机制,其中多路是指多个socket同时在监听,复用指的是复用同一个线程。
I/O多路复用是用来解决对多个I/O监听时,一个I/O阻塞影响其他I/O的问题,跟多线程没关系。
在这里插入图片描述
I/O多路复用模型使用了Reactor设计模式实现了这一机制。通过Reactor的方式,可以将用户线程轮询I/O操作状态的工作统一交给handle_events事件循环进行处理。用户线程注册事件处理器之后可以继续执行做其他的工作(异步),而Reactor线程负责调用内核的select函数检查socket状态。当有socket被激活时,则通知相应的用户线程(或执行用户线程的回调函数),执行handle_event进行数据读取、处理的工作。由于select函数是阻塞的,因此多路I/O复用模型也被称为异步阻塞I/O模型。注意,这里的所说的阻塞是指select函数执行时线程被阻塞,而不是指socket。一般在使用I/O多路复用模型时,socket都是设置为NONBLOCK的,不过这并不会产生影响,因为用户发起I/O请求时,数据已经到达了,用户线程一定不会被阻塞。

总结:I/O 多路复用模型是利用select、poll、epoll可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll是只轮询那些真正发出了事件的流),依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。

缓存雪崩

缓存同一时间大面积失效,那么后面的请求都会落到数据库,数据库短时间内承受了大量请求而崩掉
事前:尽量保证整个redis集群的可用性,发现机器宕机尽快补上
事后:利用redis持久化机制保存的数据尽快恢复缓存

缓存穿透

大量请求的key根本不存在缓存中,导致请求直接落到了数据库

事前:做好参数校验,一些不合法的参数请求直接抛出异常信息给客户端,比如查询条件是年龄是个负数,或邮箱格式不对

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值