本篇提供Redis在分别作为缓存和数据库的时候的一些配置细节,应该了解的知识
使用Redis作为缓存
作为缓存和作为数据库的区别
- 缓存中的数据一般是热数据;数据库中的数据是全量数据,数据库中的数据重要程度远超缓存中的数据
- 缓存中的数据的存储时间远远低于数据库中的数据,缓存中的数据有很多甚至不会去做持久化
- 缓存中的数据访问的代价远远小于数据库中的数据
决定缓存中数据的生命周期的方式
通过业务逻辑决定:
典型的就是通过业务逻辑决定就是依靠时间决定,例如我们系统缓存中只存储前一天的信息,那么一条记录过了一天之后就会被我们的系统自动删除,清理出缓存区。
通过业务运转决定:
典型的就是使用访问频繁的内容替换访问不频繁的数据,也就是俗称的使用热数据替换冷数据
Redis缓存的数据回收策略
我们可以在 /etc/redis/6379.conf的配置文件中更改Redis的内存大小,当Redis使用的内存空间超过内存空间限制的时候,Redis就会启动空间回收策略,尝试回收一些空间
Redis的回收策略一共有下列几种
Redis数据过期的小细节
当给Redis的某个键设置过期时间时,再次访问这个键是不会重置其过期时间的
当你覆盖某个已经被设置过期时间的key时,这个key的过期时间会被直接删除,也就是说不会再次过期了
使用Redis作为数据库
使用Redis作为数据库时要注意的点
- Redis一般不作为数据库,但是如果想要使用Redis作为数据库的话,Redis就需要重视数据库都必须重视的点——数据的持久化
- 作为缓存时,Redis中的数据是可以允许丢失和少量不一致性的,如果作为数据库的话,这些细节就必须重视起来
- 一般来说,Redis数据库做持久化可以有两种方式
- 将整个数据库直接备份,想要回滚的时候就可以直接将备份数据库直接读出来
- 记录日志,想要回滚的时候就按照日志内容执行命令
Redis单机持久化方案之RDB
RDB简单介绍
RDB其实就是Redis DB,其执行的原理就是将某一个时刻的Redis数据库直接备份下来放在硬盘中以此达到Redis中数据的持久化
直接复制数据库将要面临的问题
假如说我现在面临这样的一个情况——我正在通过RDB方式备份Redis数据库内容,但是我一边备份的同时Redis数据库也正在被使用,我们在备份数据的时候不可能是一瞬间就完成的,会持续一段时间,例如50s,假如我在备份的时候还对数据库进行了改变,那么这个时候我记录的就不是某一时刻备份,而是某个时间段的备份,这就是时点混乱错误
RDB的改进
这种严重的错误会导致RDB在很多场景下根本无法使用,于是Redis就使用了copy on write技术
当Redis要进行RDB备份的时候,Redis会创建一个子进程,这个子进程会 fork() Redis中的数据,所谓的fork其实就是将指针复制一下,然后监视这个指针,一旦这个指针指向的内容要发生变化前,就先将变化前的内容复制出来,放在另外一个地方,然后子进程中的指针就指向这个新的地址,最后再将原地址中的内容改变。这就是大名鼎鼎的 cop(copy on write)
注:copy on write是linux内核提供的,这就是linux中的 父子进程之间的改变是相互隔离的,redis只是在进行RDB的时候
RDB的使用方式
人工调用
- 直接在命令行中使用 ‘save’ 命令,这样就可以直接复制数据库,不使用cop技术
- 一般在需要关机维护服务器的时候使用,发起save命令然后关机维护,这种情况用的非常少
- 直接在命令行中使用 ‘bgsave’命令,这样就可以使用cop技术来对数据库进行备份
- 直接在命令行中使用 ‘save’ 命令,这样就可以直接复制数据库,不使用cop技术
在配置文件中配置某些情况下调用
人工难免会出现问题,计算机在定时执行这种事情上的靠谱程度要高不少,这里我们就可以在配置文件中编写
在配置文件中编写的时候要注意,配置文件中写的是 save ,但是其实调用的是bgsave,这是redis的一个小问题
如果想要关闭RDB,只需要把这些save内容全部删掉即可,从这里也可以发现,redis默认是开启RDB的
RDB持久化方案的弊端
- RDB不支持拉链——即每一次备份得到的数据都会将以前的副本删除,这需要运维人员将每一次备份得到的数据手动保存到特定地点
- RDB丢失的数据会多一些,两个备份时点之间的数据容易丢失,例如我已经在9点钟备份了一份数据了,我准备在10点钟继续备份一份数据,可是就在9:59分,我的redis挂机了,非常恐怖的事情就发生了,我的数据库丢失了1h的数据量
Redis单机持久化方案之AOF
AOF简单介绍
AOF,即 append only file 就是通过日志恢复,把数据库的每一笔操作都写到日志中,恢复的时候就可以通过执行日志中的记录来进行恢复
AOF的弊端
假如现在有一个场景,我们有一个redis运行了10年,期间这个redis永远在做一件事情:创建key,删除key——永远在创建一个key,然后再删除这个key。然后redis突然挂了,这个时候需要恢复redis,那么这个redis就要恢复5年的时间(这个时间已经非常快了,最差的情况需要10年恢复)。但是我们大家都知道,这个redis其实一直在创建和删除,如果是RDB的持久化方案,那么恢复时间会非常短。
AOF弊端解决方法
- 面对redis做了很多无用操作的这种情况,我们就可以给日志瘦身,redis可以把日志中的一些命令相互抵消,比如一个key创建,然后删除,这种命令就会被抵消
Redis单机持久化方案之RDB和AOF混合
- 方案诞生的来源
- 现行的RDB和AOF都有其s自己的缺陷,RDB速度快,但是有丢失过多数据的风险;AOF的风险小但是会有可能带来恢复时间过长的问题。redis 4.0以后redis的持久化方案默认是使用的RDB和AOF混合
- 方案原理
- 在持久化的时候,首先会进行一次RDB,将RDB的数据库写入AOF文件中,然后后续的一些指令也会通过append的方式添加到AOF文件里面去
- 当Redis数据库在恢复的时候,就可以先读取AOF文件中的RDB数据,然后再继续通过AOF文件后面的一些后续指令继续恢复数据库
探讨Redis作为数据库的一些细节
Redis持久化的IO操作
Redis作为数据库是需要进行持久化的,那么在持久化的时候我们就需要进行磁盘的IO操作,IO操作都是要经过Linux内核的,这些都会影响到redis性能,所以redis提供了三种对于日志记录的等级
always
每当redis执行一条操作,就将这条操作写入到磁盘中
everysec
Redis在执行记录后会将日志记录在一个buffer里面,每秒钟将这个buffer flush一下,将它放入到磁盘中
no
Redis自己不管理flush,完全交由操作系统来管理,什么时候操作系统认为需要flush一下就会将buffer flush一下,写入磁盘
Redis作为数据库的单机持久化方案我们已经讲过了,这个时候我们再回首起点,谈谈Redis作为数据库的那些事
Redis无疑是可以胜任数据库的,但是我们要回到Redis的本质上去,redis的本质特点就是快!我们作为架构师,选择redis的目的也是非常简单的,就是要快!所以我们不能为了技术而技术,不能为了跟风就盲目地将redis作为我们的数据库,redis在作为数据库的时候会触发大量的磁盘IO,这回将redis这个内存级别的中间件被拉低成为半内存,半磁盘级别的应用,是否有点得不偿失?使用一个技术就要把它的特点发挥出来,让它在合适的位置工作,Redis最适合的还是作为缓存,不用强求它作为数据库