一、Redis在Linux环境下的安装及配置
(一)基于Center OS7安装Redis
? 下载安装包 wget http://download.redis.io/releases/redis-?.?.?.tar.gz ? 解压 tar –xvf 文件名.tar.gz ? 编译 make ? 安装 make install [destdir=/目录]
(二)Redis基础环境设置
? 创建软链接: ln -s 原始目录名 快速访问目录名 ? 创建配置文件管理目录 mkdir conf mkdir config ? 创建数据文件管理目录 mkdir data
(三)Redis服务启动
? 默认配置启动 redis-server redis-server –-port 6379 redis-server –-port 6380 …… ? 指定配置文件启动 redis-server redis.conf redis-server redis-6379.conf redis-server redis-6380.conf …… redis-server conf/redis-6379.conf redis-server config/redis-6380.conf ……
(四)Redis客户端连接
1、默认连接 redis-cli 2、 连接指定服务器 redis-cli -h 127.0.0.1 redis-cli –port 6379 redis-cli -h 127.0.0.1 –port 6379
(五)Redis服务端配置
? 基本配置 1、daemonize yes:以守护进程方式启动,使用本启动方式,redis将以服务的形式存在,日志将不再打印到命令窗口中 2、port 6***:设定当前服务启动端口号 3、dir “/自定义目录/redis/data“:设定当前服务文件保存位置,包含日志文件、持久化文件(后面详细讲解)等 4、logfile "6*.log“**:设定日志文件名,便于查阅
二、持久化
(一)概念
什么是持久化 利用永久性存储介质(硬盘)将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化。 为什么要进行持久化 防止数据的意外丢失,确保数据安全性 持久化过程保存什么 Redis中存储的数据格式是二进制数据 如:  保存方案一(快照)也叫RDB ? 将当前数据状态进行保存,以快照形式,存储数据结果,存储格式简单,关注点在数据 保存方式二(保存过程)也叫AOF ? 将数据的操作过程进行保存,日志形式,存储操作过程,存储格式复杂,关注点在数据的操作过程 
(二)RDB
1、保存数据的条件(谁,什么时间,干什么事情)
命令执行 ? 谁:redis操作者(用户) ? 什么时间:即时(随时进行) ? 干什么事情:保存数据
2、RDB持久化操作的 save指令
命令:save 作用:手动执行一次保存操作 (每保存一次,都会去生成一个.rdb的文件,用来保存当前的快照信息)
3、save指令相关配置(配置 .conf文件)
? dbfilename dump.rdb 说明:设置本地数据库文件名,默认值为 dump.rdb 经验:通常设置为dump-端口号.rdb ? dir 说明:设置存储.rdb文件的路径 经验:通常设置成存储空间较大的目录中,目录名称data ? rdbcompression yes 说明:设置存储至本地数据库时是否压缩数据,默认为 yes,采用 LZF 压缩 经验:通常默认为开启状态,如果设置为no,可以节省 CPU 运行时间,但会使存储的文件变大(巨大) ? rdbchecksum yes 说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行 经验:通常默认为开启状态,如果设置为no,可以节约读写性过程约10%时间消耗,但是存储一定的数据损坏风险 完整版 
4、save指令工作原理

注意:save指令的执行会阻塞当前Redis服务器,直到当前RDB过程完成为止,有可能会造成长时间阻塞,线上环境不建议使用。
5、数据量过大,单线程执行方式造成效率过低如何处理?
后台执行 ? 谁:redis操作者(用户)发起指令;redis服务器控制指令执行 ? 什么时间:即时(发起);合理的时间(执行) ? 干什么事情:保存数据
6、RDB启动方式 —— bgsave指令
? 命令:bgsave ? 作用:手动启动后台保存操作,但不是立即执行
7、bgsave指令工作原理
 注意: bgsave命令是针对save阻塞问题做的优化。Redis内部所有涉及到RDB操作都采用bgsave的方式,save命令可以放弃使用。
8、bgsave指令相关配置
? dbfilename dump.rdb 说明:设置本地数据库文件名,默认值为 dump.rdb 经验:通常设置为dump-端口号.rdb ? dir 说明:设置存储.rdb文件的路径 经验:通常设置成存储空间较大的目录中,目录名称data ? rdbcompression yes 说明:设置存储至本地数据库时是否压缩数据,默认为 yes,采用 LZF 压缩 经验:通常默认为开启状态,如果设置为no,可以节省 CPU 运行时间,但会使存储的文件变大(巨大) ? rdbchecksum yes 说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行 经验:通常默认为开启状态,如果设置为no,可以节约读写性过程约10%时间消耗,但是存储一定的数据损坏风险 ? stop-writes-on-bgsave-error yes 说明:后台存储过程中如果出现错误现象,是否停止保存操作 经验:通常默认为开启状态
9、反复执行保存指令,忘记了怎么办?不知道数据产生了多少变化,何时保存?
自动执行 ? 谁:redis服务器发起指令(基于条件) ? 什么时间:满足条件 ? 干什么事情:保存数据
10、RDB启动方式 ——save配置
? 配置 save second changes ? 作用 满足限定时间范围内key的变化数量达到指定数量即进行持久化 ? 参数 second:监控时间范围 changes:监控key的变化量 ? 位置 在conf文件中进行配置 ? 范例 save 900 1 save 300 10 save 60 10000 conf完整版: 
11、RDB启动方式 ——save配置原理
 注意: save配置要根据实际业务情况进行设置,频度过高或过低都会出现性能问题,结果可能是灾难性的 save配置中对于second与changes设置通常具有互补对应关系(一大一小),尽量不要设置成包含性关系 save配置启动后执行的是bgsave操作
12、RDB三种启动方式对比

13、rdb特殊启动形式
? 全量复制 在主从复制中详细讲解 ? 服务器运行过程中重启:debug reload ? 关闭服务器时指定保存数据:shutdown save
默认情况下执行shutdown命令时,自动执行 bgsave(如果没有开启AOF持久化功能)
14、RDB的优缺点
RDB优点: ? RDB是一个紧凑压缩的二进制文件,存储效率较高 ? RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景 ? RDB恢复数据的速度要比AOF快很多 ? 应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复 Rdb缺点: ? RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据 ? bgsave指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能 ? Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象
三、AOF
1、RDB存储的弊端
? 存储数据量较大,效率较低 基于快照思想,每次读写都是全部数据,当数据量巨大时,效率非常低 ? 大数据量下的IO性能较低 ? 基于fork创建子进程,内存产生额外消耗 ? 宕机带来的数据丢失风险 解决思路 ? 不写全数据,仅记录部分数据 ? 降低区分数据是否改变的难度,改记录数据为记录操作过程 ? 对所有操作均进行记录,排除丢失数据的风险
2、AOF概念
? AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令 达到恢复数据的目的。与RDB相比可以简单描述为改记录数据为记录数据产生的过程 ? AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式
3、AOF写数据过程

当客户端发送出一条指令到服务器时,服务器接收到这条指令,但是它并没有马上记录。而是放到了一个零时区域(AOF写命令的缓存区),到了一定阶段后,将命令同步到aof文件中
4、AOF写数据的三种策略(appendfsync)
? always(每次:来一个指令存一次) 每次写入操作均同步到AOF文件中,数据零误差,性能较低不建议使用。 ? everysec(每秒:每一秒去存一次) 每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高,性能较高 在系统突然宕机的情况下丢失1秒内的数据,建议使用,也是默认配置 ? no(系统控制) 由操作系统控制每次同步到AOF文件的周期,整体过程不可控
5、AOF功能开启(配置xxx.conf文件)
? 配置:appendonly yes|no 默认为no ? 作用:是否开启AOF持久化功能,默认为不开启状态 ? 配置:appendfsync always|everysec|no 默认为always ? 作用:AOF写数据策略 AOF的其他配置 ? 配置:appendfilename filename ? 作用AOF持久化文件名,默认文件名未appendonly.aof,建议配置为appendonly-端口号.aof ? 配置:dir ? 作用:AOF持久化文件保存路径,与RDB持久化文件保持一致即可 完整版 
6、AOF写数据遇到的问题
如果连续执行如下指令该如何处理:  如果连续执行如上指令,则可以将set合并为最后一个,将incr合并为3,因为set只有最后一个生效了,执行三次incr相当于执行了一次set num 3,所以AOP就提供的这样的功能—重写
7、AOF重写
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制压缩文件体积。AOF文件重写是将Redis进程内的数据转化为写命令同步到新AOF文件的过程。简单说就是将对同一个数据的若干个条命令执行结 果转化成最终结果数据对应的指令进行记录。
8、AOF重写作用
? 降低磁盘占用量,提高磁盘利用率 ? 提高持久化效率,降低持久化写时间,提高IO性能 ? 降低数据恢复用时,提高数据恢复效率
9、AOF重写规则
? 进程内已超时的数据不再写入文件 ? 忽略无效指令,重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令 如del key1、 hdel key2、srem key3、set key4 111、set key4 222等 ? 对同一数据的多条写命令合并为一条命令 如lpush list1 a、lpush list1 b、 lpush list1 c 可以转化为:lpush list1 a b c。 为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等类型,每条指令最多写入64个元素
10、AOF重写方式
? 手动重写:bgrewriteaof 在set后输入bgrewriteaof重写
11、AOF手动重写 —— bgrewriteaof指令工作原理
 background saving started是bgsave返回的消息 Background append only file rewriting started 是bgrewriteaof返回的消息
12、AOF自动重写方式
AOF自动重写方式: auto-aof-rewrite-min-size size 自动aop自动重写的大小设置 auto-aof-rewrite-percentage percent 自动重写的百分比 设置 ? 自动重写触发比对参数( 运行指令info Persistence获取具体信息 ) aof_current_size 标识aof缓冲中已经有的大小 aof_base_size 基础大小  条件1:aof_current_size>auto-aof-rewrite-min-size:标识当前的大小大配置的自动重写的大小时重写 条件2:已有的大小减去基础大小然后除以基础大小的百分比大于或等于配置的自动重写的百分比是重写 查看redis的所有运行属性值的指令:info
13、AOF工作流程

always:指令进来后进入主进程,然后执行set的同时启动fork,再将信息写入到aof文件中 everysec:指令进来后进入主进程,后执行set的同时启动fork,再将信息装入到aof的缓存区中,等到达到时间后写入aof文件中
14、AOF重写流程

15、RDB与AOF区别

16、RDB与AOF的选择之惑
对数据非常敏感,建议使用默认的AOF持久化方案 ? AOF持久化策略使用everysecond,每秒钟fsync一次。该策略redis仍可以保持很好的处理性能,当出现问题时,最多丢失0-1秒内的数据。 ? 注意:由于AOF文件存储体积较大,且恢复速度较慢 数据呈现阶段有效性,建议使用RDB持久化方案 ? 数据可以良好的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且恢复速度较快,阶段点数据恢复通常采用RDB方案 ? 注意:利用RDB实现紧凑的数据持久化会使Redis降的很低,慎重总结: 综合比对 ? RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊 ? 如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF ? 如能承受数分钟以内的数据丢失,且追求大数据集的恢复速度,选用RDB ? 灾难恢复选用RDB ? 双保险策略,同时开启 RDB 和 AOF,重启后,Redis优先使用 AOF 来恢复数据,降低丢失数据的量
17、持久化应用场景
? Tips 1:redis用于控制数据库表主键id,为数据库表主键提供生成策略,保障数据库表的主键唯一性 因为:从redis中获取可能会不连续,出现错误 ? Tips 3:redis应用于各种结构型和非结构型高热度数据访问加速 因为:从数据中获取和从Redis中获取没区别 ? Tips 4:redis 应用于购物车数据存储设计 因为:redis中的数据和数据库中的一样 ? Tips 5:redis 应用于抢购,限购类、限量发放优惠卷、激活码等业务的数据存储设计 因为:可能出现断电等问题,像这些 快速存储快速消失的数据用 ? Tips 6:redis 应用于具有操作先后顺序的数据控制 因为:有些数据可能是数据库中没有存储的 ? Tips 7:redis 应用于最新消息展示 ? Tips 9:redis 应用于同类信息的关联搜索,二度关联搜索,深度关联搜索 ? Tips 12:redis 应用于基于黑名单与白名单设定的服务控制 如果黑名单是临时性的就可以考虑用 ? Tips 13:redis 应用于计数器组合排序功能对应的排名 ? Tips 15:redis 应用于即时任务/消息队列执行管理 有更好的解决方案 ? Tips 16:redis 应用于按次结算的服务控制
四、事务
(一)什么是事务
Redis执行指令过程中,多条连续执行的指令被干扰,打断,插队? redis事务就是一个命令执行的队列,将一系列预定义命令包装成一个整体(一个队列)。当执行时,一次性,按照添加顺序依次执行,中间不会被打断或者干扰。 一个队列中,一次性、顺序性、排他性的执行一系列命令
(二)事务的基本操作
? 开启事务:multi ? 作用:设定事务的开启位置,此指令执行后,后续的所有指令均加入到事务中 ? 执行事务:exec ? 作用:设定事务的结束位置,同时执行事务。与multi成对出现,成对使用 ? 取消事务:discard ? 作用:终止当前事务的定义,发生在multi之后,exec之前 (在事务定义过程中发现出了问题时用)
注意:加入事务的命令暂时进入到任务队列中,并没有立即执行,只有执行exec命令才开始执行
(三)事务的工作流程

(四)事务的注意事项
1、定义事务的过程中,命令格式输入错误怎么办
? 语法错误:指命令书写格式有误 ? 处理结果:如果定义的事务中所包含的命令存在语法错误,整体事务中所有命令均不会执行。包括那些语法正确的命令。
2、定义事务的过程中,命令执行出现错误怎么办?
? 运行错误:指命令格式正确,但是无法正确的执行。例如对list进行incr操作 ? 处理结果:能够正确运行的命令会执行,运行错误的命令不会被执行 注意:已经执行完毕的命令对应的数据不会自动回滚,需要程序员自己在代码中实现回滚。
(五)手动进行事务回滚
? 记录 操作过程中被影响的数据之前的状态 单数据:string 多数据:hash、list、set、zset ? 设置指令恢复所有的被修改的项 单数据:直接set(注意周边属性,例如时效) 多数据:修改对应值或整体克隆复制
(六)基于特定条件的事务执行—锁
业务场景1 天猫双11热卖过程中,对已经售罄的货物追加补货,4个业务员都有权限进行补货。补货的操作可能是一系列的操作,牵扯到多个连续操作,如何保障不会重复操作? 业务分析 ? 多个客户端有可能同时操作同一组数据,并且该数据一旦被操作修改后,将不适用于继续操作 ? 在操作之前锁定要操作的数据,一旦发生变化,终止当前操作 解决方案 ? 对 key 添加监视锁,在执行exec前如果key发生了变化,终止事务执行:watch key1 [key2……] ? 取消对所有 key 的监视:unwatch Tips 18: ? redis 应用基于状态控制的批量任务执行
(七)基于特定条件的事务执行—分布式锁
业务场景 天猫双11热卖过程中,对已经售罄的货物追加补货,且补货完成。客户购买热情高涨,3秒内将所有商品购买完毕。本次补货已经将库存全部清空,如何避免最后一件商品不被多人同时购买?【超卖问题】 业务分析 ? 使用watch监控一个key有没有改变已经不能解决问题,此处要监控的是具体数据 ? 虽然redis是单线程的,但是多个客户端对同一数据同时进行操作时,如何避免不被同时修改? 解决方案 ? 使用 setnx 设置一个公共锁:setnx lock-key value 例:如果key为name 则设置为setnx lock-name 1/-1/true value值可以随便设置
利用setnx命令的返回值特征,有值则返回设置失败,无值则返回设置成功 ? 对于返回设置成功的,拥有控制权,进行下一步的具体业务操作 ? 对于返回设置失败的,不具有控制权,排队或等待 操作完毕通过del操作释放锁,被人才能访问 注意:上述解决方案是一种设计概念,依赖规范保障,具有风险性 Tips 19: ? redis 应用基于分布式锁对应的场景控制
(八)基于特定条件的事务执行——分布式锁改良
业务场景 依赖分布式锁的机制,某个用户操作时对应客户端宕机,且此时已经获取到锁。如何解决? 业务分析 ? 由于锁操作由用户控制加锁解锁,必定会存在加锁后未解锁的风险 ? 需要解锁操作不能仅依赖用户控制,系统级别要给出对应的保底处理方案 解决方案 ? 使用 expire 为锁key添加时间限定,到时不释放,放弃锁 expire lock-key second pexpire lock-key milliseconds
由于操作通常都是微秒或毫秒级,因此该锁定时间不宜设置过大。具体时间需要业务测试后确认。 ? 例如:持有锁的操作最长执行时间127ms,最短执行时间7ms。 ? 测试百万次最长执行时间对应命令的最大耗时,测试百万次网络延迟平均耗时 ? 锁时间设定推荐:最大耗时120%+平均网络延迟110% ? 如果业务最大耗时<<网络平均延迟,通常为2个数量级,取其中单个耗时较长即可
常用指令
查看redis进程:ps -ef | grep redis- 杀死进程:kill -s 9 端口号 启动redis服务:redis-server conf/redisxxxx.conf 删除文件:rm -rf 文件名 查看文件内容:cat 文件名 查看redis的所有运行属性值:info
|