Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。有字符串,链表,集 合和有序集合。支持在服务器端计算集合的并,交和补集(difference)等,还支持多种排序功能。所以Redis也可以被看成是一个数据结构服务 器。
Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。
第一种方法filesnapshotting:默认redis是会以快照的形式将数据持久化到磁盘的(一个二进 制文件,dump.rdb,这个文件名字可以指定),在配置文件中的格式是:save N M表示在N秒之内,redis至少发生M次修改则redis抓快照到磁盘。当然我们也可以手动执行save或者bgsave(异步)做快照。
工作原理简单介绍一下:当redis需要做持久化时,redis会fork一个子进程;子进程将数据写到磁盘上一个临时RDB文件中;当子进程完成写临时文件后,将原来的RDB替换掉,这样的好处就是可以copy-on-write
还有一种持久化方法是Append-only:filesnapshotting方法在redis异常死掉时, 最近的数据会丢失(丢失数据的多少视你save策略的配置),所以这是它最大的缺点,当业务量很大时,丢失的数据是很多的。Append-only方法可 以做到全部数据不丢失,但redis的性能就要差些。AOF就可以做到全程持久化,只需要在配置文件中开启(默认是no),appendonly yes开启AOF之后,redis每执行一个修改数据的命令,都会把它添加到aof文件中,当redis重启时,将会读取AOF文件进行“重放”以恢复到 redis关闭前的最后时刻。
LOG Rewriting随着修改数据的执行AOF文件会越来越大,其中很多内容记录某一个key的变化情况。因此redis有了一种比较有意思的特性:在后台重建AOF文件,而不会影响client端操作。在任何时候执行BGREWRITEAOF命令,都会把当前内存中最短序列的命令写到磁盘,这些命令可以完全构建当前的数据情况,而不会存在多余的变化情况(比如状态变化,计数器变化等),缩小的AOF文件的大小。所以当使用AOF时,redis推荐同时使用BGREWRITEAOF。
AOF文件刷新的方式,有三种,参考配置参数appendfsync :appendfsync always每提交一个修改命令都调用fsync刷新到AOF文件,非常非常慢,但也非常安全;appendfsync everysec每秒钟都调用fsync刷新到AOF文件,很快,但可能会丢失一秒以内的数据;appendfsync no依靠OS进行刷新,redis不主动刷新AOF,这样最快,但安全性就差。默认并推荐每秒刷新,这样在速度和安全上都做到了兼顾。
可能由于系统原因导致了AOF损坏,redis无法再加载这个AOF,可以按照下面步骤来修复:首先做一个AOF文件的备份,复制到其他地方;修复原始AOF文件,执行:$ redis-check-aof –fix ;可以通过diff –u命令来查看修复前后文件不一致的地方;重启redis服务。
LOG Rewrite的工作原理:同样用到了copy-on-write:首先redis会fork一个子进程;子进程将最新的AOF写入一个临时文件;父进程 增量的把内存中的最新执行的修改写入(这时仍写入旧的AOF,rewrite如果失败也是安全的);当子进程完成rewrite临时文件后,父进程会收到 一个信号,并把之前内存中增量的修改写入临时文件末尾;这时redis将旧AOF文件重命名,临时文件重命名,开始向新的AOF中写入。
最后,为以防万一(机器坏掉或磁盘坏掉),记得定期把使用 filesnapshotting 或 Append-only 生成的*rdb *.aof文件备份到远程机器上。我是用crontab每半小时SCP一次。我没有使用redis的主从功能 ,因为半小时备份一次应该是可以了,而且我觉得有如果做主从有点浪费机器。这个最终还是看应用来定了。
========================
数据持久化通俗讲就是把数据保存到磁盘上,保证不会因为断电等因素丢失数据。
redis 需要经常将内存中的数据同步到磁盘来保证持久化。redis支持两种持久化方式,一种是 Snapshotting(快照)也是默认方式,另一种是Append-only file(缩写aof)的方式。先介绍下这两种dump方式再讲讲自己遇到的一些现象和想法,前面的内容是从网上整理出来的。
Snapshotting
快照是默认的持久化方式。这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久 化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照,下面是默认的快照保存配置
save 900 1 #900秒内如果超过1个key被修改,则发起快照保存
save 300 10 #300秒内容如超过10个key被修改,则发起快照保存
save 60 10000
下面介绍详细的快照保存过程
1.redis调用fork,现在有了子进程和父进程。
2. 父进程继续处理client请求,子进程负责将内存内容写入到临时文件。由于os的写时复制机制(copy on write)父子进程会共享相同的物理页面,当父进程处理写请求时os会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程的地址空间内的数 据是fork时刻整个数据库的一个快照。
3.当子进程将快照写入临时文件完毕后,用临时文件替换原来的快照文件,然后子进程退出。
client 也可以使用save或者bgsave命令通知redis做一次快照持久化。save操作是在主线程中保存快照的,由于redis是用一个主线程来处理所有 client的请求,这种方式会阻塞所有client请求。所以不推荐使用。另一点需要注意的是,每次快照持久化都是将内存数据完整写入到磁盘一次,并不 是增量的只同步脏数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能。
另外由于快照方式是在一定间隔时间做一次的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用aof持久化方式。下面介绍
Append-only file
aof 比快照方式有更好的持久化性,是由于在使用aof持久化方式时,redis会将每一个收到的写命令都通过write函数追加到文件中(默认是 appendonly.aof)。当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。当然由于os会在内核中缓存 write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。不过我们可以通过配置文件告诉redis我们想要 通过fsync函数强制os写入到磁盘的时机。有三种方式如下(默认是:每秒fsync一次)
appendonly yes //启用aof持久化方式
# appendfsync always //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
# appendfsync no //完全依赖os,性能最好,持久化没保证
aof 的方式也同时带来了另一个问题。持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条set test 100就够了。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。收到此命令redis将使用与快照类似的方式将内存中的数据 以命令的方式保存到临时文件中,最后替换原来的文件。具体过程如下
1. redis调用fork ,现在有父子两个进程
2. 子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
3.父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
4.当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
5.现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。
需要注意到是重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
运维上的想法
其实快照和aof一样,都使用了Copy-on-write技术。多次试验发现每次做数据dump的时候,内存都会扩大一倍(关于这个问题可以参考我去年写的redis的内存陷阱,很多人用redis做为缓存,数据量小,dump耗时非常短暂,所以不太容易发现),这个时候会有三种情况:
一:物理内存足以满足,这个时候dump非常快,性能最好
二:物理内存+虚拟内存可以满足,这个时候dump速度会比较慢,磁盘swap繁忙,服务性能也会下降。所幸的是经过一段比较长的时候数据dump完成了,然后内存恢复正常。这个情况系统稳定性差。
三: 物理内存+虚拟内存不能满足,这个时候dump一直死着,时间久了机器挂掉。这个情况就是灾难!
如果数据要做持久化又想保证稳定性,建议留空一半的物理内存。如果觉得无法接受还是有办法,下面讲:
快照和aof虽然都使用Copy-on-write,但有个不同点,快照你无法预测redis什么时候做dump,aof可以通过bgrewriteaof命令控制dump的时机。
根据这点我可以在一个服务器上开启多个redis节点(利用多CPU),使用aof的持久化方式。
例 如在24G内存的服务器上开启3个节点,每天用bgrewriteaof定期重新整理数据,每个节点dump的时间都不一样,这 样理论上每个节点可以消耗6G内存,一共使用18G内存,另外6G内存在单个节点dump时用到,内存一下多利用了6G! 当然节点开的越多内存的利用率也越高。如果带宽不是问题,节点数建议 = CPU数。
我的应用里为了保证高性能,数据没有做dump,也没有用aof。因为不做dump发生的故障远远低于做dump的时候,即使数据丢失了,自动修复脚本可以马上数据恢复。毕竟对海量数据redis只能做数据分片,那么落到每个节点上的数据量也不会很多。
redis的虚拟内存建议也不要用,用redis本来就是为了达到变态的性能,虚拟内存、aof看起来都有些鸡肋。
现在还离不开redis,因为它的mget是现在所有db里性能最好的,以前也考虑过用tokyocabinet hash方式做mget,性能不给力。直接用redis,基本上单个redis节点mget可以达到10W/s
纠错
之前说过redis做数据dump的时候内容会扩大一倍,后来我又做了些测试,发现有些地方说的不对。
top 命令并不是反映真实的内存占用情况,在top里尽管fork出来的子进程占了和父进程一样的内存,但是当做dump的时候没有写操作,实际使 用的是同一份内存的数据。当有写操作的时候内存才会真实的扩大(具体是不是真实的扩大一倍不确定,可能数据是按照页分片的),这才是真正的Copy- on-write。
基于这点在做数据持久化会更加灵活。
相关推荐
本文将详细介绍这两种持久化方式的原理、配置方法及其各自的优缺点。 #### RDB 持久化 RDB 持久化是一种将 Redis 在内存中的数据库记录定期 dump 到磁盘上的机制。这种方式通过创建数据库快照来实现数据的持久化。...
首先概述了Redis的基本特点及其内存数据存储方式,接着分别讲解了RDB和AOF两种持久化方案的原理、流程、优劣势以及相关配置。文中还涉及了混合持久化模式和主从复制的基本原理。通过对持久化机制的深入解析,帮助...
本文主要介绍了 Redis 的两种持久化机制:RDB(Redis Database Backup file)和 AOF(Append Only File),重点讲解了 RDB 的工作原理与实现。 RDB 是 Redis 数据库的一种快照备份,它将当前内存中的数据库状态保存...
Redis 提供了两种持久化方式:RDB 和 AOF。 * RDB 持久化:将 Redis 的数据快照保存到磁盘上,可以通过 SAVE 或 BGSAVE 命令触发。 * AOF 持久化:将 Redis 的每条命令记录到日志文件中,可以通过 BGREWRITEAOF ...
为了在系统崩溃或意外停机后能够恢复数据,Redis提供了两种持久化机制:RDB(Redis Database Backup)和AOF(Append Only File)。这两种机制各有优缺点,可以根据实际需求进行选择或结合使用。 **RDB持久化**: ...
Redis提供了两种持久化方式:RDB(Redis Database)和AOF(Append Only File)。 RDB持久化 RDB是一种快照持久化方式,它可以将Redis数据库的快照保存到硬盘中。RDB的工作原理是将Redis数据库的快照保存到硬盘中...
内容概要:本文详细介绍了Redis的持久化策略,特别是RDB(Redis Database Backup)和AOF(Append Only File)两种主要的持久化方法。RDB通过在某个时间点创建数据集的快照来实现数据持久化,其优点包括数据恢复快、...
本文将深入探讨 Redis 的两种持久化方式——RDB(Redis Database)和 AOF(Append Only File),并分析各自的优缺点。 #### 二、RDB 模式详解 **1. 基本概念** RDB 是 Redis 提供的一种基于时间点快照的持久化...
- **持久化**:Redis支持RDB和AOF两种持久化方式,确保数据在服务器重启后不丢失。RDB是定期生成快照,AOF记录每次写操作日志。 - **复制**:Redis支持主从复制,可以构建高可用的分布式系统,提高服务的容错性。 ...
##### 2.1 RDB 持久化原理 RDB 持久化是一种定期快照的方式,它会在特定的时间点将内存中的数据集生成一份完整的拷贝,并将这份拷贝保存到磁盘上。具体实现方式通常是通过Redis的`bgsave`命令来完成,该命令会fork...
Redis 提供两种持久化机制:RDB 快照和 AOF 日志。RDB 在特定条件下自动保存内存数据到磁盘,恢复速度快但可能丢失部分数据;AOF 记录每次写操作,恢复精度高,但可能导致恢复速度较慢。针对内存不足的情况,Redis ...
本文将详细介绍 RDB 和 AOF 两种持久化方案,包括操作方法和持久化的实现原理。 正文 Redis 是一个基于 K-V 存储的数据库服务器,下面先介绍 Redis 数据库的内部构造以及 K-V 的存储形式,有助于我
2. **持久化**:Redis提供了两种持久化方式:RDB(快照)和AOF(Append Only File)。RDB是在特定时间点生成数据的快照,而AOF记录所有写操作日志,确保即使在服务器重启后也能恢复数据。 3. **复制**:Redis支持...
2. **持久化**:Redis提供了两种持久化方式,RDB(Snapshotting)和AOF(Append Only File)。RDB是在特定时间点生成数据库的快照,而AOF记录每次写操作的日志,重启时重放日志恢复数据。 3. **复制**:Redis支持...
为防止数据丢失,它支持持久化,主要有两种方式:RDB(定期保存数据库快照)和AOF(Append Only File,记录每次写操作日志)。 3. 主从复制:Redis支持主从复制,通过复制机制,可以创建多个副本,提高读取性能和...
redis持久法的方式主要为两种:快照(rdb);写日志(aof); rdb原理 rdb实现持久化主要是将当前进程中的数据生成快照保存到硬盘上,在重启的时候读取硬盘上的数据(如果同时配置了aof,将会先执行aof策略,因为...
持久化:支持RDB和AOF两种持久化方式。 多种数据结构:支持字符串、哈希表、列表、集合、有序集合等多种数据结构。 原子性:所有操作都是原子性的,保证数据的一致性。 Redis与其他数据库的区别 Redis是内存数据库,...
4. **Redis持久化**:为了防止数据丢失,Redis提供了两种持久化方式:RDB(快照)和AOF(Append Only File)。这两种方式的原理、优缺点和应用场景会在书中进行深入解析。 5. **Redis复制**:通过主从复制,可以...