以往的文章:html
2、Redis-通用指令篇
linux
Redis是C语言开发的一个高性能键值对(key -value
) 内存数据库,能够用做数据库,缓存和消息中间件等。web
特色redis
做为内存数据库,它的性能很是优秀,数据存储在内存当中,读写速度很是快,支持并发10W QPS(每秒查询次数),单进程单线程,是线程安全的,采用IO多路复用机制。数据库
丰富的数据类型,支持字符串,散列,列表,集合,有序集合等,支持数据持久化。能够将内存中数据保存在磁盘中,重启时加载。windows
主从复制,哨兵,高可用,可用做分布式锁。能够做为消息中间件使用,支持发布订阅。缓存
举个例子:
有没有试过在写文件(如写论文时用的Word
)的时候,忽然遇到断电或者是软件崩溃之类的状况,可是咱们在遇到文件崩溃的时候,软件每每有一个自动备份的机制,以至于咱们在遇到忽然断电或者软件崩溃,来不及保存的状况下提供的一个恢复的可能。
那么所谓的自动备份,自动恢复是怎么回事呢?其实就是将内存中的数据将硬盘中的数据作了一个关联,在一段时间之后,将内存中的数据保存到了硬盘上,等到万一数据丢失了,它会把硬盘的数据再读回到内存中,把数据恢复了,用这种形式来对数据起到一个保护的做用。
Redis做为一个内存数据库,数据若是丢失,会很麻烦,显然也须要这样一个机制来保存数据,须要常常同步内存中的数据到硬盘保证持久化。安全
===》因此:
持久化是将程序数据在持久状态和瞬时状态间转换的机制。通俗的讲,就是瞬时数据(好比内存中的数据,是不能永久保存的)持久化为持久数据(好比持久化至数据库中,可以长久保存)。
如:服务器
应用层:若是关闭(shutdown)你的应用而后从新启动则先前的数据依然存在。
系统层:若是关闭(shutdown)你的系统(电脑)而后从新启动则先前的数据依然存在。
可见:持久化保存的是数据
快照: 指的是在规定的时间间隔内将内存中的数据集写入到磁盘中,通俗地说就是像照相机同样,快门一闪,就能够将某一历史时刻的景象留在了照片上,不一样的是拍照的对象是数据,而不是其余画面。
因此咱们能够快速地根据快照来查找到某一历史时刻的数据信息。
利用快照来对当前数据状态结果进行保存,格式简单,关注点在数据。可是快照时间点后面的数据都会丢失。
在Redis中咱们能够每隔1分钟保存一次快照,这样就算遇到断电或者其余突发状况,咱们损失的一小部分数据影响也不大。
RDB提供了两种指令来生成RDB文件,每执行一遍,就保存一遍快照
由于 Redis 是单线程的,假定有几个客户端分别发送几条指令到服务器,实际上这几个指令发送过来是会有必定的执行顺序的,假如如今有大量执行指令(非save
)已经在这个任务序列里面,等到某客户端发送了一个 save 指令过来,开始执行RDB,一旦时间过长,就会阻塞 Redis 服务器进程,且 Redis 服务器在阻塞过程当中,不能处理任何其余命令,直到RDB文件建立过程完毕为止,才能够往下执行。这样子就影响了Redis的正常使用,因此线上环境不建议使用,有可能形成长时间阻塞,效率下降。
save // 返回 OK
save 执行的日志信息:
[4928] 09 Jun 18:04:45.165 * DB saved on disk
解决前面的单线程执行方式形成阻塞问题,引入了bgsave
这个命令,在执行这个命令的时候,服务器首先返回:Background saving started
再在空闲时间调用fork函数派生出一个子进程,而后由子进程负责建立 RDB 文件,父进程继续处理其余命令请求,子进程建立完毕后,会在日志中返回这样一个信息Background saving terminated with success
bgsave // 返回 Background saving started
bgsave 执行的日志信息:
[4928] 09 Jun 17:11:42.834 * Background saving started by pid 9480 开始 [4928] 09 Jun 17:11:43.078 # fork operation complete [4928] 09 Jun 17:11:43.080 * Background saving terminated with success 结束
注意:bgsave命令是针对save阻塞这个问题作的优化,。Redis内部全部涉及到RDB操做都采用bgsave方式进行,基本上能够不用save了
执行成功后生成的文件:
打开文件,在RDB中保存的形式为二进制,大概就是些数据头+Redis版本号+数据内容
rdb文件数据:
命令执行完成后会在下面redis.windows.conf文件(linux为redis.conf
)配置的目录下生成,默认文件名dump.rdb,咱们能够根据需求来修改配置
配置文件:
# 后台存储过程当中若是出现错误,是否中止报错操做,默认开启—— bgsave stop-writes-on-bgsave-error yes # 设置是否压缩数据,默认为YES,采用 LZF 压缩 # 不压缩能够节省时间,但存储的文件会更大 rdbcompression yes # 是否进行RDN文件格式校验,在文件读写过程都会进行 # 默认开启,若是不开启,能够节约读写过程时间,可是有数据损坏风险 rdbchecksum yes # The filename where to dump the DB # 设置本地数据库文件名,默认值为dump.rdb,一般设置成 dump-端口号.rdb dbfilename dump.rdb # The DB will be written inside this directory, with the filename specified # 设置存储.rdb文件的路径,一般设置到存储空间较大的目录中 dir ./
RDB启动方式:
手工(管理员手工执行命令备份)==》save 命令 | bgsave 命令
自动执行(Redis服务器执行命令备份)==》save second changes
在知足的second时间范围内key变化达到changes数量,即执行一次持久化,须要至少changes数量足够才执行,不然从新计时,如设置10秒内至少5个key改变执行,可是10秒过去了只有2个key改变,则从新计时,在conf文件里进行新增配置规则
save second changes
能够配置多个规则,只要知足其中一个规则就执行
注意事项:
经过配置save second changes
执行的在后台实际是bgsave操做
RDB三种方式对比:
方式 | save命令 | bgsave命令 | save配置==bgsave命令 |
---|---|---|---|
读写 | 同步(阻塞) | 异步(新进程) | 异步 |
阻塞客户端 | 是(单进程) | 否(新进程) | 否 |
额外消耗内存 | 否(没有新进程) | 是(新进程) | 是 |
启动新进程 | 否 | 是 | 是 |
RDB优势,在上面介绍过一遍了,再作一次总结
RDB缺点,在上面介绍过一遍了,再作一次总结
数据头+Redis版本号+数据内容
,可能会出现不一样版本数据格式不兼容的状况过程:
与RDB持久化经过保存数据库中的键值对来记录数据库状态不一样,AOF持久化是经过保存Redis所执行的写命令来记录数据库状态的。如:在PS或者其余工具用的比较多的——“撤回” 功能,在PS历史记录就有很好的体现,每执行一个操做,都将它的命令给记录下来,当咱们在操做失误时,能够调出历史记录去选择恢复到某一步操做的位置
在Redis中就是将命令操做步骤记录下来,当须要恢复数据的时候,将命令从新执行一遍就能够了。这种方案能够解决数据持久化的实时性(上面RDB数据快照时间点后的数据可能丢失
),在备份的时候能够不必每次都进行所有数据备份,只追加记录部分数据,并将记录的数据变为记录数据命令的过程。
当AOF功能打开时,服务器在执行命令完成以后,服务器没有直接记录到AOF文件,而是将被执行的命令写到一个临时存储的区域——AOF_BUFF缓冲区末尾,而后再将命令在必定条件下同步到AOF文件中。
AOF同步条件的三种策略(appendfsync):
AOF_FSYNC_NO :系统来控制同步到AOF文件的周期,根据空闲状况触发同步,总体过程不可控
,系统挂了,损失的数据就随缘了。。
AOF_FSYNC_EVERYSEC :每一秒钟将缓冲区命令同步保存一次到AOF文件中,数据准确仍是比较高的,且性能会较好。系统忽然挂掉,同步损失的就只有那一秒的数据
,比较推荐用
AOF_FSYNC_ALWAYS :每执行一个命令同步一次到AOF文件,0偏差,可是性能差(同时来个十几万条数据,IO消耗大量资源,大几率崩溃
)
文件配置路径:redis.windows.conf | redis.conf
注意:若是RDB和AOF同时存在,那么redis会以AOF为准,由于在一般状况下AOF文件保存的数据集要比RDB文件完整
# 默认不开启,AOF和RDB持久化能够同时启用,实际场景得根据本身需求了 #appendonly yes 的时候优先级比RDB高 appendonly no # The name of the append only file (default: "appendonly.aof") # 默认名:appendonly.aof 可加上端口号:appendonly-端口号.aof appendfilename "appendonly.aof" # If unsure, use "everysec". # 默认使用 everysec # 下面是三种同步策略 # appendfsync always appendfsync everysec # appendfsync no # 文件保存路径 dir
随着命令不断写入AOF,文件会愈来愈大,有可能会记录不少无效或重复的数据,或者是后面的把前面覆盖的数据,能够将数据进行整理合并。为了解决这个问题,Redis引入了AOF重写机制压缩文件体积,AOF文件重写是将redis进程内的数据转化为写命令同步到新AOF文件的过程,简单滴就是说对用一个数据的若干条命令执行结果转化成最终结果对应的指令进行记录。
总之重写干的就是优化AOF文件的活,减少AOF文件的体积
AOF重写做用
能够合并的指令: lpush list a lpush list b lpush list c 能够合并成为 lpush list a b c ,执行1次总比执行3次效率高 -------------------------------------------------------------------------- 无效的指令: del keya hdel keyb srem keyc 能够直接利用内存中的数据来直接生成命令,内存中没有的数据就不须要生成,这就避免了先添加-再删除两步 -------------------------------------------------------------------------- 后面的指令已经覆盖前面的: set key a set key b 能够直接利用内存中的数据来直接生成一条添加 b 命令,添加内存原本的 b 数据,这就避免了先添加a-再修改成 b 两步 -------------------------------------------------------------------------- 进程中已经超时的数据: setex key seconds values 若是数据超时了,便是此数据已被删除,无需再写到文件了,参考无效指令 --------------------------------------------------------------------------
为了不在执行命令时形成客户端输入缓冲区溢出,重写程序在处理list、 hash、set、sorted set 等类型,会先检查键所包含的元素数 量,若是元素的数量超过了redis.h的REDIS_AOF_REWRITE_ITEMS_PER_CMD = 64
常量的值,那么重写程序将使用多条命令来记录键的值,而不仅仅使用一条命令。
AOF 重写方式
bgrewriteaof // 重写
流程相似 RDB 的: bgsave 命令
AOF文件内容:
执行日志:
[4928] 09 Jun 21:28:26.356 * Background append only file rewriting started by pid 17824 [4928] 09 Jun 21:28:26.533 * AOF rewrite child asks to stop sending diffs. [4928] 09 Jun 21:28:26.633 # fork operation complete [4928] 09 Jun 21:28:26.635 * Background AOF rewrite terminated with success [4928] 09 Jun 21:28:26.637 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB) [4928] 09 Jun 21:28:26.637 * Background AOF rewrite finished successfully
# 配置文件:redis.conf | redis.windows.conf # 自动触发的条件配置 //这两个配置项的意思是,在aof文件体量超过64mb,且比上次重写后的体量增长了100%时自动触发重写。咱们能够修改这些参数达到本身的实际要求 auto-aof-rewrite-percentage 100 // 自动重写的百分比增加率,百分比达到100%才重写 auto-aof-rewrite-min-size 64mb //触发重写的最小容量,不一样版本默认值不同,缓冲区到64M才进行重写 # 自动触发对比参数 # 基础大小 aof_base_size # 当前缓冲区容量大小 aof_current_size 触发重写所需条件; 第一种:当前容量超出设置的最小容量 aof_current_size > auto-aof-rewrite-min-size 第二种:基本大小与当前大小进行比较,若是当前大小大于指定的百分比,将触发重写 (aof_current_size - aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage
看图注释:
AOF 工做流程
aways(每次都写入)非重写
everysec(每秒够后才写入)非重写
everysec(每秒够后才写入)重写
持久化方式 | RDB | AOF |
---|---|---|
占用存储空间 | 小(数据级:可配置压缩) | 大(指令级:可配置重写) |
存储速度 | 慢(每次都得所有存一次) | 快(可追加) |
恢复速度 | 快(二进制存储,直接载入内存) | 慢(要从新执行命令,文件大) |
数据安全性 | 会丢失数据(丢失快照时间点后的数据) | 依据策略决定 (可能丢失一秒的(每秒),也可能未知(系统调度)) |
资源消耗 | 高/重量级(save单进程阻塞/bgsave子进程) | 低/轻量级 (不阻塞) |
启动优先级 | 低 | 高(同时开启是AOF高) |
备份选择 | 全量备份 | 增量备份 |
每种都有利有弊,看实际需求。。。。。
对数据很是敏感,不能承受数分钟之内数据丢失——AOF
能承受数分钟之内数据丢失,追求大数据恢复速度——RDB
双保险:综合使用AOF和RDB两种持久化机制,使用AOF来保证数据不丢失,做为数据恢复的第一选择;用RDB作不一样程度的冷备,当AOF备份文件丢失或损坏不可用时,可使用RDB快照文件快速的恢复数据——RDB+AOF