redis跟memcached类似,都是内存数据库,不过redis支持数据持久化,也就是说redis可以将内存中的数据同步到磁盘来持久化,以确保redis 的数据安全。不过持久化这块可能比较容易产生误解,下面聊聊这块。
Redis持久化是如何工作的?
什么是持久化?简单来讲就是将数据放到断电后数据不会丢失的设备中,也就是我们通常理解的硬盘上。
1. 数据库写操作的5个过程
首先我们来看一下数据库在进行写操作时到底做了哪些事,主要有下面五个过程:
2. 故障分析
写操作大致有上面5个流程,当数据库系统故障时,这时候系统内核还是完好的。那么此时只要我们执行完了第3步,那么数据就是安全的,因为后续操作系统会来完成后面几步,保证数据最终会落到磁盘上。当系统断电时,这时候上面5项中提到的所有缓存都会失效,并且数据库和操作系统都会停止工作。所以只有当数据在完成第5步后,才能保证在断电后数据不丢失。
【补充】这里可能有几个疑问:
对于***个问题,通常数据库层面会进行全面控制。
而对第二个问题,操作系统有其默认的策略,但是我们也可以通过POSIX API提供的fsync系列命令强制操作系统将数据从内核区写到磁盘控制器上。
对于第三个问题,看起来数据库已经无法触及,但实际上,大多数情况下磁盘缓存是被设置关闭的,或者是只开启为读缓存,也就是说写操作不会进行缓存,直接写到磁盘。建议的做法是仅仅当你的磁盘设备有备用电池时才开启写缓存。
3. 数据损坏
所谓数据损坏,就是数据无法恢复,上面我们讲的都是如何保证数据是确实写到磁盘上去,但是写到磁盘上可能并不意味着数据不会损坏。比如我们可能一次写请求会进行两次不同的写操作,当意外发生时,可能会导致一次写操作安全完成,但是另一次还没有进行。如果数据库的数据文件结构组织不合理,可能就会导致数据完全不能恢复的状况出现。
三种解决策略:
那么,redis又针对持久化提供了什么方式呢?
redis持久化的两种方式
redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File)。
RDB,简而言之,就是将存储的数据快照的方式存储到磁盘上,
AOF,则是将redis执行过的所有写指令记录下来,通过write函数追加到AOF文件的末尾。在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。
RDB机制
1. 概念
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照,下面是默认的快照保存配置
- save 900 1 #900秒内如果超过1个key被修改,则发起快照保存
- save 300 10 #300秒内容如超过10个key被修改,则发起快照保存
- save 60 10000
2. RDB文件保存过程
client 也可以使用save或者bgsave命令通知redis做一次快照持久化。save操作是在主线程中保存快照的,由于redis是用一个主线程来处理所有 client的请求,这种方式会阻塞所有client请求。所以不推荐使用。
另一点需要注意的是,每次快照持久化都是将内存数据完整写入到磁盘一次,并不是增量的只同步脏数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能。
3. 优势
4. 劣势
AOF
1. 概念
redis会将每一个收到的写命令都通过write函数追加到文件中(默认是 appendonly.aof)。
当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。当然由于os会在内核中缓存 write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。
可以通过配置文件告诉redis通过fsync函数强制os写入到磁盘的时机。有三种方式如下(默认是:每秒fsync一次)
- appendonly yes //启用aof持久化方式
- # appendfsync always //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
- appendfsync everysec //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
- # appendfsync no //完全依赖os,性能***,持久化没保证
2. AOF文件保存过程
aof 的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。
为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis将使用与快照类似的方式将内存中的数据 以命令的方式保存到临时文件中,***替换原来的文件。具体过程如下:
需要注意到是重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
3. 优势
4. 劣势
总结
对于我们应该选择RDB还是AOF,取决于具体的应用场景,官方的建议是两个同时使用。这样可以提供更可靠的持久化方案。其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。
如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache一样。
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,...
新买电脑和硬盘的玩家已经习惯了用T作为容量单位,原先的G也就看不上眼了,不过...
redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快...
伟大的领导者们知道,如何让合作伙伴也取得成果和让自己取得成果一样重要。在这...
基于内存的Redis应该是目前各种web开发业务中最为常用的key-value数据库了,我们...
如今,新冠性病毒的防控工作已经得到初步成果,新增和死亡病例在大幅减少,预计...
[中国,深圳,2020年5月28日] 今天,华为面向全球发布全新一代海量数据存储Ocean...
韩国kt机房介绍: 韩国KT服务器是韩国KT集团下的数据中心,位于韩国首尔通信大楼内...
世界已经从4G进入5G时代。随着5G建设在全球如火如荼地铺展,5G在金融、医疗、交...
很多情况下基于wcf的复杂均衡都首选zookeeper,这样可以拥有更好的控制粒度,但z...