适用于如下场景:
对数据高并发处理
对大数据高效率存储和访问
对数据高可用及高扩展
Redis是NoSQL数据库的一种Redis是以KV方式存储数据库
特点:非关系,分布,开源,可扩展,高速内存操作。
适合运行在廉价的pc服务器上分布式处理海量数据
Redis是一个开源的,先进的kv存储方式的数据库,通常叫数据结构服务器,键可以包含字符串strings,哈希hashes,lists链表,集合sets,有序集合sorted sets/zsets,这些数据类型支持push,pop,add,move及集合等操作,支持各种不同方式排序,为了提供性能,数据都在内存中,为了数据可靠根据需要周期更新数据到磁盘或日志记录文件。
待续:
一:SNAPSHOTTING(快照方式 -》二进制文件)
①定时生成快照
②定量生成快照
观察redis的配置文件中的SNAPSHOTTING设置模块的设置信息,我们可以发现
上图已经对save命令的意思做出了解释,现在我再来说一下,意思就是:
save 900 1 每900秒(15分钟)至少一次键值变更时被触发;
##当snapshot时出现错误无法继续时,是否阻塞客户端“变更操作”,“错误”可能因为磁盘已满/磁盘故障/OS级别异常等
stop-writes-on-bgsave-error yes
rdbcompression
RDB文件过大时,是可以压缩的,Redis默认开启压缩,当然也可以通过配置rdbcompression参数来禁用压缩
压缩和不压缩的优缺点:
压缩:
优点:减少磁盘存储空间
缺点:消耗CPU资源
不压缩:
优点:不消耗CPU资源
缺点:占用磁盘空间多
如何选择? 那就需要看需求、看服务器资源情况了。
RDB的快照过程:
1.redis 调用 fork,现在有了子进程和父进程。
2. 父进程继续处理 client 请求,子进程负责将内存内容写入到临时文件。由于 os 的实时复制机制( copy on write)父子进程会共享相同的物理页面,当父进程处理写请求时 os 会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程地址空间内的数据是 fork时刻整个数据库的一个快照。
3.当子进程将快照写入临时文件完毕后,用临时文件替换原来的快照文件,然后子进程退出。client 也可以使用 save 或者 bgsave 命令通知 redis 做一次快照持久化。 save 操作是在主线程中保存快照的,由于 redis 是用一个主线程来处理所有 client 的请求,这种方式会阻塞所有client 请求。所以不推荐使用。另一点需要注意的是,每次快照持久化都是将内存数据完整写入到磁盘一次,并不是增量的只同步变更数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘 io 操作,可能会严重影响性能。
手动快照:
如果没有触发自动快照,可以对redis进行手动快照操作,SAVE和BGSAVE都可以执行手动快照,两个命令的区别是前者是由主进程进行快照操作,会阻塞其他请求;而后者是通过fork子进程进行快照操作。
注意:
由于redis使用fork来复制一份当前进程,那么子进程就会占有和主进程一样的内存资源,比如说主进程8G内存,那么在备份的时候必须保证有16G内存,要不然会启用虚拟内存,性能非常差。
工作原理
写时复制(copy-on-write/COW)技术:
写入时复制(Copy-on-write)是一个被使用在程式设计领域的最佳化策略。其基础的观念是,如果有多个呼叫者(callers)同时要求相同资源,他们会共同取得相同的指标指向相同的资源,直到某个呼叫者(caller)尝试修改资源时,系统才会真正复制一个副本(private copy)给该呼叫者,以避免被修改的资源被直接察觉到,这过程对其他的呼叫只都是通透的(transparently)。此作法主要的优点是如果呼叫者并没有修改该资源,就不会有副本(private copy)被建立。
二:APPEND ONLY MODE(aof类似于预写日志)
①后台执行
②边服务边备份
Redis AOF是类似于log的机制,每次写操作都会写到硬盘上,当系统崩溃时,可以通过AOF来恢复数据。每个带有写操作的命令被Redis服务器端收到运行时,该命令都会被记录到AOF文件上。由于只是一个append到文件操作,所以写到硬盘上的操作往往非常快。
其实Redis oaf机制包括了两件事,rewrite和AOF。rewrite类似于普通数据库管理系统日志恢复点,当AOF文件随着写命令的运行膨胀时,当文件大小触碰到临界时,rewrite会被运行。
rewrite会像replication一样,fork出一个子进程,创建一个临时文件,遍历数据库,将每个key、value对输出到临时文件。输出格式就是Redis的命令,但是为了减小文件大小,会将多个key、value对集合起来用一条命令表达。在rewrite期间的写操作会保存在内存的rewrite buffer中,rewrite成功后这些操作也会复制到临时文件中,在最后临时文件会代替AOF文件。
以上在AOF打开的情况下,如果AOF是关闭的,那么rewrite操作可以通过bgrewriteaof命令来进行。
Redis Bgrewriteaof 命令用于异步执行一个 AOF(AppendOnly File) 文件重写操作。重写会创建一个当前 AOF 文件的体积优化版本。
即使 Bgrewriteaof 执行失败,也不会有任何数据丢失,因为旧的 AOF 文件在 Bgrewriteaof 成功之前不会被修改。
注意:从 Redis 2.4 开始, AOF 重写由 Redis 自行触发, BGREWRITEAOF 仅仅用于手动触发重写操作。
为了避免aof文件过大,我们会周期性的做bgrewriteaof来重整aof文件。以前我们会额外的配置crontab在业务低峰期执行这个命令,这额外的增加一个workaroud的脚本任务在大集群里是很糟糕的,不易检查,出错无法即时发现。
于是这个自动bgrewriteaof功能被直接加到redis的内部。首先对于aof文件,server对象添加一个字段来记录aof文件的大小server.appendonly_current_size,每次aof发生变化都会维护这个字段。
bgrewriteaof完毕或者实例启动载入aof数据后也会调用aofUpdateCurrentSize这个函数维护这个字段,同时会记录下此时的aof文件的大小server.auto_aofrewrite_base_size作为基准值,用于接下来判断aof增长率。
有了当前值和基准值我们就可以判断aof文件的增长情况。另外还需要配置两个参数来判断是否需要自动触发bgrewriteaof。
auto-aof-rewrite-percentage:aof文件的大小超过基准百分之多少后触发bgrewriteaof。默认这个值设置为100,意味着当前aof是基准大小的两倍的时候触发bgrewriteaof。把它设置为0可以禁用自动触发的功能。
auto-aof-rewrite-min-size: 当前aof文件大于多少字节后才触发。避免在aof较小的时候无谓行为。默认大小为64mb。
两个参数都是可以在conf里静态配置,或者通过config set来动态修改的。
appendonly 是否开启aof缓存机制
appendfilename aof文件的名称
appendfsync 的三种执行方式:
always 每次都调用,比如安全,但速度最慢;
everysec 每秒同步,这也是默认方式;
no 不调用fsync,由操作系统决定何时同步,比如快的模式;
no-appendfsync-on-rewrite no
如上面所说到的bgrewriteaof机制,在一个子进程中进行aof的重写,从而不阻塞主进程对其余命令的处理,同时解决了aof文件过大问题。现在问题出现了,同时在执行bgrewriteaof操作和主进程写aof文件的操作,两者都会操作磁盘,而bgrewriteaof往往会涉及大量磁盘操作,这样就会造成主进程在写aof文件的时候出现阻塞的情形,现在no-appendfsync-on-rewrite参数出场了。如果该参数设置为no,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题。如果设置为yes呢?这就相当于将appendfsync设置为no,这说明并没有执行磁盘操作,只是写入了缓冲区,因此这样并不会造成阻塞(因为没有竞争磁盘),但是如果这个时候redis挂掉,就会丢失数据。丢失多少数据呢?在linux的操作系统的默认设置下,最多会丢失30s的数据。
因此,如果应用系统无法忍受延迟,而可以容忍少量的数据丢失,则设置为yes。如果应用系统无法忍受数据丢失,则设置为no。
写数据的流程:
AOF和RDB各有优缺点,这是有它们各自的特点所决定:
- 1) AOF更加安全,可以将数据更加及时的同步到文件中,但是AOF需要较多的磁盘IO开支,AOF文件尺寸较大,文件内容恢复数度相对较慢。
*2) snapshot,安全性较差,它是“正常时期”数据备份以及master-slave数据同步的最佳手段,文件尺寸较小,恢复数度较快。
可以通过配置文件来指定它们中的一种,或者同时使用它们(不建议同时使用),或者全部禁用,在架构良好的环境中,master通常使用AOF,slave使用snapshot,主要原因是master需要首先确保数据完整性,它作为数据备份的第一选择;slave提供只读服务(目前slave只能提供读取服务),它的主要目的就是快速响应客户端read请求;但是如果你的redis运行在网络稳定性差/物理环境糟糕情况下,建议你master和slave均采取AOF,这个在master和slave角色切换时,可以减少“人工数据备份”/“人工引导数据恢复”的时间成本;如果你的环境一切非常良好,且服务需要接收密集性的write操作,那么建议master采取snapshot,而slave采用AOF。
Redis数据恢复
当redis服务器挂掉时,重启时将按以下优先级恢复数据到内存种:
1. 如果只配置了AOF,重启时加载AOF文件恢复数据.
2. 如果同时配置了RBD和AOF,启动时只加载AOF文件恢复数据.
3. 如果只配置了RDB,启动时将加载dump文件恢复数据.
这是我在redis使用中,所遇到的一些问题,以及解决方案:
①Redis低版本无法向前兼容高版本RDB文件
问题的:在模拟redis集群中主redis kill掉之后且没有开启redis aof追加模式的情况下,去读取从redis的rdb快照文件,来恢复数据
主redis:redis_version:2.8.17
从服务器:redis_version:3.2.8
造成影响就是主redis无法启动了。
解决方案就是:删除掉主redis上的rdb文件就可以了。
②redis 安全模式所造成的:
但是那样会接到redis安全模式的报错:
解决方案:设置密码,或者远程连接的ip
默认最大连接数为10000,一旦达到最大限制,redis将关闭所有的新连接,并发送一个“max number of clients reached”的错误。