目录标题
- Redis
- 1. NoSQL简介
- 2. Redis
- 1、简介:
- 2、特点:
- 3、安装
- 4、启动
- 5、关闭
- 6、Redis客户端
- 7、Redis基本知识
- 8、Redis 的 5 种数据结构
- 9、Redis的常用操作命令
- 9.1、Key 的操作命令
- 9.2、字符串类型(string)
- 9.3、列表(List)
- 9.4、集合类型(set)
- 9.5、哈希类型(hash)
- 9.6、有序集合类型(Zset)
- 10、Redis 的配置文件
- 10.1、redis.conf 存放位置
- 10.2、Redis 的网络相关配置
- 10.3、Redis 的常规配置
- 10.4、**Redis** **的安全配置**
- 10.5、Redis 的 RDB 配置
- 10.6、Redis AOF 配置
- 11、Redis 的持久化
- 11.1、RDB
- 11.2、AOF
- 12、Redis的事务
- 12.1、Redis的事务
- 12.2、Redis事务的常用命令
- 12.3、Redis事务小结
- 13、Redis消息的发布与订阅(了解)
- 13.1、Redis发布订阅
- 13.2、Redis发布订阅示意图
- 13.3、Redis发布订阅的常用命令
- 14、Redis的主从复制
- 14.1、主从复制
- 14.2、一主二从
- 14.2.1、一主二从原理
- 14.2.2、一主二从搭建
- 14.3、复制原理
- 14.3.1、全量复制
- 14.4、哨兵模式
- 14.4.1、哨兵模式原理
- 14.4.2、哨兵模式搭建
- 14.4.3、哨兵模式搭建(配置文件模式)
- 14.5、小结
- 14.5.1、操作:
- 14.5.2、缺点
- 15、Jedis操作Redis
- 15.1、Jedis简介
- 15.2、Jedis操作Redis
- 15.2.1、Jedis 操作 key
- 15.2.2、Jedis 操作字符串(string)类型数据
- 15.2.3、Jedis 操作列表(list)类型数据
- 15.2.4、Jedis 操作哈希(hash)类型数据
- 15.2.5、Jedis 操作集合(set)类型数据
- 15.2.6、Jedis 操作有序集合(zset)类型数据
- 15.2.7、Jedis 操作事务
- 3. Redis分布式缓存
- 缓存的用途
- Redis介绍
Redis
1. NoSQL简介
- 关系型数据库有Oracle、DB2、MySQL、Microsoft SQL Server、Microsoft Access;
- 常见的非关系型数据库有:1、mongodb;2、cassandra;3、redis;4、hbase;5、neo4j;其中mongodb是非常著名的NoSQL数据库,它是一个面向文档的开源数据库。
Redis操作的是key-value
NoSQL 数据库的一个显著特点就是去掉了关系数据库的关系型特性,数据之间一旦没有关系,使得扩展性、读写性能都大大提高。
2. Redis
1、简介:
- Remote Dictionary Server(远程字典服务器),是一个用 C 语言编写的、开源的、基于内存运行并支持持久化的、
高性能的 NoSQL 数据库。也是当前热门的 NoSQL 数据库之一。
适合存储频繁访问,数据量较小的数据。
2、特点:
- 支持数据持久化
- Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
- 支持多种数据结构
- Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。
- 支持数据备份
- Redis 支持数据的备份,即 master-slave 模式的数据备份。
3、安装
- 下载 redis压缩包——》上传linux ——》解压到/opt目录 ——》进入目录,执行make命令编译(没有gcc,先安装gcc,命令:yum -y install gcc,再进行清理工作:make distclean,再执行make命令编译),执行make install安装redis。
4、启动
- 前台启动 redis-server
- 后台启动 redis-server &
- 配置文件启动 redis-server redis.conf &
5、关闭
- redis-cli shutdown
- kill pid(进程号)
6、Redis客户端
- 启动Redis客户端
- 直连(默认ip127.0.0.1,端口6379):redis-cli
- 指定IP和端口连接redis:redis-cli -h 127.0.0.1 -p 6379
- 退出客户端:exit或quit
7、Redis基本知识
- 查看redis度武器的统计信息:info
- 语法:info [section]
- redis默认使用16个库,从0到15。在redis.conf文件中database 16。
- redis 中各个库不能自定义命名,只能用序号表示。
- 切换库命令:select db
- 默认0,使用其它,select 库的序号
- 查看当前数据库中 key 的数目:dbsize
- 查看当前数据库中有哪些 key:keys *
- 清空当前库:flushdb
- 清空所有数据库:flushall
- config get * 获得 redis 的所有配置值
- config get parameter:获取运行中 Redis 服务器的配置参数
- config get databases:获取数据库个数
- config get port:获取端口号
8、Redis 的 5 种数据结构
- 字符串类型 string
- 单key:单value
- 列表类型 list
- 单key:多有序value
- 集合类型 set
- 单key:多无序value
- 哈希类型 hash
- 单key:对象(属性:值)
- 有序集合类型 zset (sorted set)
- 单key:多有序value
9、Redis的常用操作命令
9.1、Key 的操作命令
- keys pattern
- 查找所有符合模式 pattern 的 key, pattern 可以使用通配符
- exists key [key…]
- 判断 key 是否存在
- 存在 key 返回 1,其他返回 0。使用多个 key,返回存在的 key 的数量
- move key db
- 移动 key 到指定的数据库,移动的 key 在原库被删除。
- ttl key
- 查看 key 的剩余生存时间(ttl: time to live),以秒为单位。
- -1 :没有设置 key 的生存时间, key 永不过期。
-2:key 不存在
- expire key seconds
- 设置 key 的生存时间,超过时间,key 自动删除。单位是秒。
- type key
- 查看 key 所存储值的数据类型
- 返回值:none (key 不存在)
string (字符串)
list (列表)
set (集合)
zset (有序集)
hash (哈希表)
- rename key newkey
- 将 key 改为名 newkey
- del key [key…]
- 删除存在的 key,不存在的 key 忽略。
9.2、字符串类型(string)
字符串类型是 Redis 中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据,序列化后的数据,JSON 化的对象甚至是一张图片。
字符串类型的数据操作总的思想是通过 key 操作 value,key 是数据标识,value 是我们感兴趣的业务数据。
- key1 value1
- key2 value2
- set key value
- 将字符串值 value 设置到 key 中
- get key
- 获取 key 中设置的字符串值
- key 存在,返回 key 对应的 value;key 不存在,返回 nil
- append key value
- 如果 key 存在,则将 value 追加到 key 原来旧值的末尾;如果 key 不存在,则将 key 设置值为 value。
- 返回值:追加字符串之后的总长度(字符个数)
- strlen key
- 返回 key 所储存的字符串值的长度
- incr key
- 将 key 中储存的数字值加 1,如果 key 不存在,则 key 的值先被初始化为 0 再执行 incr 操作。
- decr key
- 将 key 中储存的数字值减 1,如果 key 不存在,则么 key 的值先被初始化为 0 再执行 decr 操作
- incrby key offset
- 将 key 所储存的值加上增量值,如果 key 不存在,则 key 的值先被初始化为 0 再执行 INCRBY 命令。
- decrby key offset
- 将 key 所储存的值减去减量值,如果 key 不存在,则 key 的值先被初始化为 0 再执行 DECRBY 命令。
- getrange key startIndex endIndex
- 获取 key 中字符串值从 startIndex 开始到 endIndex 结束的子字符串,包括 startIndex 和 endIndex。
- setrange key offsetIndex value
- 用 value 覆盖 key 的存储的值从 offset 开始
- setex key seconds value
- 设置key的值,并将 key 的生存时间设为 seconds (以秒为单位) ,如果key已经存在,将覆盖旧值。
- setnx key value
- setnx 是 set if not exists 的简写,如果 key 不存在,则 set 值,存在则不设置值。
- mset key value [key value…]
- 同时设置一个或多个 key-value 对
- mget key [key …]
- 获取所有(一个或多个)给定 key 的值
- msetnx key value[key value…]
- 同时设置一个或多个 key-value 对,如果有一个 key 是存在的,则设置不成功。
9.3、列表(List)
Redis 列表是简单的字符串列表,按照插入顺序排序,左边(头部)、右边(尾部)或者中间都可以添加元素。链表的操作无论是头或者尾效率都极高,但是如果对中间元素进行操作,那效率会大大降低了。
列表类型的数据操作总的思想是通过 key 和下标操作 value,key 是数据标识,下标是数据在列表中的位置,value是我们感兴趣的业务数据。
- key1 v1, v2, v3, …
- key2 v1, v2, v3, …
- lpush key value [value…]
- 将一个或多个值 value 插入到列表 key 的最左边(表头),各个 value 值依次插入到表头位置。
- 返回值:插入之后的列表的长度。
- rpush key value [value…]
- 将一个或多个值 value 插入到列表 key 的最右边(表尾),各个 value 值按依次插入到表尾。
- lrange key startIndex endIndex
- 获取列表 key 中指定下标区间内的元素,下标从 0 开始,到列表长度-1;下标也可以是负数,表示列表从后往前取,-1 表示倒数第一个元素,-2 表示倒数第二个元素,以此类推;startIndex 和 endIndex 超出范围不会报错。返回值:获取到的元素列表。
- lpop key
- 移除并返回列表 key 头部第一个元素,即列表左侧的第一个元素。
- rpop key
- 移除并返回列表 key 尾部第一个元素,即列表右侧的第一个元素。
- lindex key index
- 获取列表 key 中下标为指定 index 的元素,列表元素不删除,只是查询。0 表示列表的第一个元素
- key 存在时,返回指定元素的值;Key 不存在时,返回 nil。
- llen key
- 获取列表 key 的长度
- lrem key count value
- 根据参数 count 的值,移除列表中与参数 value 相等的元素
- count >0 ,从列表的左侧向右开始移除;
count < 0 从列表的尾部开始移除;
count = 0 移除表中所有与 value 相等的值。
- ltrim key startIndex endIndex
- 截取 key 的指定下标区间的元素,并且赋值给 key。下标从 0 开始,一直到列表长度-1。
- lset key index value
- 将列表 key 下标为 index 的元素的值设置为 value。
- linsert key before/after pivot value
- 将值 value 插入到列表 key 当中位于值 pivot 之前或之后的位置。key 不存在或者 pivot 不在列表中,不执行任何操作。
- 返回值:命令执行成功,返回新列表的长度。没有找到 pivot 返回 -1, key 不存在返回 0。
9.4、集合类型(set)
Redis 的 Set 是 string 类型的无序不重复集合。
集合类型的数据操作总的思想是通过 key 确定集合,key 是集合标识,元素没有下标,只有直接操作业务数据和数据的个数。
- key1
- v2
- v1
- …(无序不重复)
- key2
- v1
- v2
- …(无序不重复)
- sadd key member [member…]
- 功能:将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略,不会再加入。
返回值:加入到集合的新元素的个数(不包括被忽略的元素)。
- smembers key
- 功能:获取集合 key 中的所有成员元素,不存在的 key 视为空集合。
返回值:返回指定集合的所有元素集合,不存在的 key,返回空集合。
- sismember key member
- 功能:判断 member 元素是否是集合 key 的元素
返回值:member 是集合成员返回 1,其他返回 0 。
- scard key
- 功能:获取集合里面的元素个数
返回值:数字,key 的元素个数。其他情况返回 0 。
- srem key member [member…]
- 功能:移除集合中一个或多个元素,不存在的元素被忽略。
返回值:数字,成功移除的元素个数,不包括被忽略的元素。
- srandmember key[count]
- 功能:只提供 key,随机返回集合中一个元素,元素不删除,依然在集合中; 提供了 count 时,count 正数, 返回包含 count 个数元素的集合,集合元素各不重复。count 是负数,返回一个 count 绝对值的长度的集合,集合中元素可能会重复多次。
返回值:一个元素或者多个元素的集合
- spop key[count]
- 功能:随机从集合中删除一个或 count 个元素。
返回值:被删除的元素,key 不存在或空集合返回 nil。
- smove src dest member
- 功能:将 member 元素从 src 集合移动到 dest 集合,member 不存在,smove 不执行操作,返回 0,如果 dest 存 在 member,则仅从 src 中删除 member。
返回值:成功返回 1 ,其他返回 0 。
- sdiff key key [key…]
- 功能:返回指定集合的差集,以第一个集合为准进行比较,即第一个集合中有但在其它任何集合中都没有的元素组成的集合。
返回值:返回第一个集合中有而后边集合中都没有的元素组成的集合,如果第一个集合中的元素在后边集合中都有则返回空集合。
- sinter key key [key…]
- 功能:返回指定集合的交集,即指定的所有集合中都有的元素组成的集合。
返回值:交集元素组成的集合,如果没有则返回空集合。
- sunion key key [key…]
- 功能:返回指定集合的并集,即指定的所有集合元素组成的大集合,如果元素有重复,则保留一个。
返回值:返回所有集合元素组成的大集合,如果所有 key 都不存在,返回空集合。
9.5、哈希类型(hash)
Redis 的 hash 是一个 string 类型的 key 和 value 的映射表,这里的 value 是一系列的键值对,hash 特别适合用于存储对象。
哈希类型的数据操作总的思想是通过 key 和 field 操作 value,key 是数据标识,field 是域,value 是我们感兴趣的业务数据。
- key1
- field1 value1
- field2 value2
- key2
- field1 value1
- field2 value2
- hset key field value [field value …]
- 功能:将键值对 field-value 设置到哈希列表 key 中,如果 key 不存在,则新建哈希列表,然后执行赋值,如果 key下的 field 已经存在,则 value 值覆盖。
返回值:返回设置成功的键值对个数。
- hget key field
- 功能:获取哈希表 key 中给定域 field 的值。
返回值:field 域的值,如果 key 不存在或者 field 不存在返回 nil。
- hmset key field value [field value…]
- 功能:同时将多个 field-value (域-值)设置到哈希表 key 中,此命令会覆盖已经存在的 field,hash 表 key 不存在,创建空的 hash 表,再执行 hmset。
返回值:设置成功返回 ok,如果失败返回一个错误
- hmget key field [field…]
- 功能:获取哈希表 key 中一个或多个给定域的值
返回值:返回和 field 顺序对应的值,如果 field 不存在,返回 nil。
- hgetall key
- 功能:获取哈希表 key 中所有的域和值
返回值:以列表形式返回 hash 中域和域的值,key 不存在,返回空 hash。
- hdel key field [field…]
- 功能:删除哈希表 key 中的一个或多个指定域 field,不存在 field 直接忽略。
返回值:成功删除的 field 的数量。
- hlen key
- 功能:获取哈希表key中域field的个数
返回值:数值,field的个数。key不存在返回0。
- hexists key field
- 功能:查看哈希表 key 中,给定域 field 是否存在
返回值:如果 field 存在,返回 1,其他返回 0。
- hkeys key
- 功能:查看哈希表 key 中的所有 field 域列表
返回值:包含所有 field 的列表,key 不存在返回空列表
- hvals key
- 功能:返回哈希表 中所有域的值列表
返回值:包含哈希表所有域值的列表,key 不存在返回空列表。
- hincrby key field int
- 功能:给哈希表 key 中的 field 域增加 int
返回值:返回增加之后的 field 域的值
- hincrbyfloat key field float
- 功能:给哈希表 key 中的 field 域增加 float
返回值:返回增加之后的 field 域的值
- hsetnx key field value
- 功能:将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在的时候才设置,否则不设置。
返回值:设值成功返回 1,其他返回 0。
9.6、有序集合类型(Zset)
Redis 有序集合zset和集合set一样也是string类型元素的集合,且不允许重复的成员。
不同的是 zset 的每个元素都会关联一个分数(分数可以重复),redis 通过分数来为集合中的成员进行从小到大的排序。
- key1
- v1
- v2
- …(有序不重复)
- key2
- v1
- v2
- …(有序不重复)
- zadd key score member [score member…]
- 功能:将一个或多个 member 元素及其 score 值加入到有序集合 key 中,如果 member 存在集合中,则覆盖原来的值;score 可以是整数或浮点数.
返回值:数字,新添加的元素个数.
- zrange key startIndex endIndex [WITHSCORES]
- 功能:查询有序集合,指定区间的内的元素。集合成员按 score 值从小到大来排序;startIndex 和 endIndex 都是从0 开始表示第一个元素,1 表示第二个元素,以此类推; startIndex 和 endIndex 都可以取负数,表示从后往前取,-1 表示倒数第一个元素;WITHSCORES 选项让 score 和 value 一同返回。
返回值:指定区间的成员组成的集合。
- zrangebyscore key min max [WITHSCORES ] [LIMIT offset count]
- 功能:获取有序集 key 中,所有 score 值介于 min 和 max 之间(包括 min 和 max)的成员,有序成员是按递增(从小到大)排序;
使用符号”(“ 表示包括 min 但不包括 max;
withscores 显示 score 和 value;
limit 用来限制返回结果的数量和区间,在结果集中从第 offset 个开始,取 count 个。
返回值:指定区间的集合数据
- zrem key member [member…]
- 功能:删除有序集合 key 中的一个或多个成员,不存在的成员被忽略。
返回值:被成功删除的成员数量,不包括被忽略的成员。
- zcard key
- 作用:获取有序集 key 的元素成员的个数。
返回值:key 存在,返回集合元素的个数; key 不存在,返回 0。
- zcount key min max
- 功能:返回有序集 key 中, score 值在 min 和 max 之间(包括 score 值等于 min 或 max )的成员的数量。
返回值:指定有序集合中分数在指定区间内的元素数量。
- zrank key member
- 功能:获取有序集 key 中成员 member 的排名,有序集成员按 score 值从小到大顺序排列,从 0 开始排名,score最小的是 0 。
返回值:指定元素在有序集合中的排名;如果指定元素不存在,返回 nil。
- zscore key member
- 功能:获取有序集合 key 中元素 member 的分数。
返回值:返回指定有序集合元素的分数。
- zrevrank key member
- 功能:获取有序集 key 中成员 member 的排名,有序集成员按 score 值从大到小顺序排列,从 0 开始排名,score最大的是 0 。
返回值:指定元素在有序集合中的排名;如果指定元素不存在,返回 nil。
- zrevrange key startIndex endIndex [WITHSCORES]
- 功能:查询有序集合,指定区间的内的元素。集合成员按 score 值从大到小来排序;startIndex 和 endIndex 都是从0 开始表示第一个元素,1 表示第二个元素,以此类推; startIndex 和 endIndex 都可以取负数,表示从后往前取,-1 表示倒数第一个元素;WITHSCORES 选项让 score 和 value 一同返回。
返回值:指定区间的成员组成的集合。
- zrevrangebyscore key max min [WITHSCORES ] [LIMIT offset count]
- 功能:获取有序集 key 中,所有 score 值介于 max 和 min 之间(包括 max 和 min)的成员,有序成员是按递减(从大到小)排序;
使用符号”(“ 表示不包括 min 和 max;
withscores 显示 score 和 value;
limit 用来限制返回结果的数量和区间,在结果集中从第 offset 个开始,取 count 个。
返回值:指定区间的集合数据
10、Redis 的配置文件
10.1、redis.conf 存放位置
Redis 的安装根目录下(/opt/redis-5.0.2),Redis 在启动时会加载这个配置文件,在运行时按照配置进行工作。 这个文件有时候我们会拿出来,单独存放在某一个位置,启动的时候必须明确指定使用哪个配置文件,此文件才会生效。
10.2、Redis 的网络相关配置
- bind:绑定 IP 地址,其它机器可以通过此 IP 访问 Redis,默认绑定 127.0.0.1,也可以修改为本机的 IP 地址。
- port:配置 Redis 占用的端口,默认是 6379。
- tcp-keepalive:TCP 连接保活策略,可以通过 tcp-keepalive 配置项来进行设置,单位为秒,假如设置为 60 秒,则 server 端会每 60 秒向连接空闲的客户端发起一次 ACK 请求,以检查客户端是否已经挂掉,对于无响应的客户端则会关闭其连接。如果设置为 0,则不会进行保活检测。
10.3、Redis 的常规配置
- loglevel:日志级别,开发阶段可以设置成 debug,生产阶段通常设置为 notice 或者 warning.
- logfile:指定日志文件名,如果不指定,Redis 只进行标准输出。要保证日志文件所在的目录必须存在,文件可以不存在。还要在 redis 启动时指定所使用的配置文件,否则配置不起作用。
- databases:配置 Redis 数据库的个数,默认是 16 个。
10.4、Redis 的安全配置
- requirepass:配置 Redis 的访问密码。默认不配置密码,即访问不需要密码验证。此配置项需要在protected-mode=yes 时起作用。使用密码登录客户端:redis-cli -h ip -p 6379 -a pwd
10.5、Redis 的 RDB 配置
- save :配置复合的快照触发条件,即 Redis 在 seconds 秒内 key 改变 changes 次,Redis 把快照内的数据保存到磁盘中一次。默认的策略是:
- 1 分钟内改变了 1 万次
- 或者 5 分钟内改变了 10 次
- 或者 15 分钟内改变了 1 次
如果要禁用 Redis 的持久化功能,则把所有的 save 配置都注释掉。
- stop-writes-on-bgsave-error:当 bgsave 快照操作出错时停止写数据到磁盘,这样能保证内存数据和磁盘数据的一致性,但如果不在乎这种一致性,要在 bgsave 快照操作出错时继续写操作,这里需要配置为 no。
- rdbcompression:设置对于存储到磁盘中的快照是否进行压缩,设置为 yes 时,Redis 会采用 LZF 算法进行压缩;如果不想消耗 CPU 进行压缩的话,可以设置为 no,关闭此功能。
- rdbchecksum:在存储快照以后,还可以让 Redis 使用 CRC64 算法来进行数据校验,但这样会消耗一定的性能,如果系统比较在意性能的提升,可以设置为 no,关闭此功能。
- dbfilename:Redis 持久化数据生成的文件名,默认是 dump.rdb,也可以自己配置。
- dir:Redis 持久化数据生成文件保存的目录,默认是./即 redis 的启动目录,也可以自己配置。
10.6、Redis AOF 配置
- appendonly:配置是否开启 AOF,yes 表示开启,no 表示关闭。默认是 no。
- appendfilename:AOF 保存文件名
- appendfsync:AOF 异步持久化策略
- always:同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差但数据完整性比较好(慢,安全)
- everysec:出厂默认推荐,每秒异步记录一次(默认值)
- no:不即时同步,由操作系统决定何时同步。
- no-appendfsync-on-rewrite:重写时是否可以运用 appendsync,默认 no,可以保证数据的安全性。
- auto-aof-rewrite-percentage:设置重写的基准百分比
- auto-aof-rewrite-min-size:设置重写的基准值
11、Redis 的持久化
redis 是内存数据库,它把数据存储在内存中,这样在加快读取速度的同时也对数据安全性产生了新的问题,即当 redis 所在服务器发生宕机后,redis 数据库里的所有数据将会全部丢失。为了解决这个问题,redis 提供了持久化功能——RDB 和 AOF(Append Only File)。
11.1、RDB
RDB(Redis DataBase)是 Redis 默认的持久化方案。在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中。即在指定目录下生成一个 dump.rdb 文件。Redis 重启会通过加载 dump.rdb 文件来恢复数据。
- RDB原理
- Redis会复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程,来进行持久化。
- 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。
- 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
- RDB 保存的文件
- RDB保存的文件是dump.rdb文件,位置保存在Redis的启动目录。Redis每次同步数据到磁盘都会生成一个dump.rdb文件,新的 dump.rdb 会覆盖旧的 dump.rdb 文件。
- 配置RDB持久化策略
- 在 redis.conf 的快照配置中,配置 RDB 保存的策略。
- 在客户端执行 FLUSHDB 或者 FLUSHALL 或者 SHUTDOWN 时,也会把快照中的数据保存到 dump.rdb,只不过这种操作已经把数据清空了,保存的也是空文件,没有意义。
- 手动保存RDB快照
- save 命令执行一个同步保存操作,将当前 Redis 实例的所有数据快照(snapshot)以 RDB 文件的形式保存到硬盘。
- 由于 save 指令会阻塞所有客户端,所以保存数据库的任务通常由 BGSAVE 命令异步地执行,而 save 作为保存数据的最后手段来使用,当负责保存数据的后台子进程不幸出现问题时使用。
- RDB 数据恢复
- 通过脚本将 Redis 产生的 dump.rdb 文件备份(cp dump.rdb dump_bak.rdb),每次启动 Redis 前,把备份的 dump.rdb文件替换到 Redis 相应的目录(在 redis.conf 中配置的 dir 目录)下,Redis 启动时会加载 dump.rdb 文件,并且把数据
读到内存中。
- RDB小结
- Redis默认开启RDB持久化方式,适合大规模的数据恢复,但它的数据一致性和完整性较差。
11.2、AOF
AOF(Append Only File),Redis 默认不开启。它的出现是为了弥补RDB的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
- AOF原理
- Redis以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据。
- redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
- AOF保存的文件
- AOF保存的文件是appendonly.aof文件,位置保存在Redis的启动目录。如果开启了AOF,Redis每次记录写操作都会往appendonly.aof文件追加新的日志内容。
- 配置AOF持久化策略
- 在redis.conf的“APPEND ONLY MODE”配置模块中,配置AOF保存策略。
- AOF数据恢复
- 通过脚本将Redis产生的appendonly.aof文件备份(cp appendonly.aof appendonly_bak.aof),每次启动Redis前,把备份的appendonly.aof文件替换到Redis相应的目录(在redis.conf中配的的dir目录)下,只要开启AOF的功能,Redis每次启动,会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
- 但在实际开发中,可能因为某些原因导致 appendonly.aof 文件格式异常,从而导致数据还原失败,可以通过命令redis-check-aof --fix appendonly.aof 进行修复 。会把出现异常的部分往后所有写操作日志去掉。
- AOF的重写
- AOF采用文件追加方式,文件会越来越大,为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。
- AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
- Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。当然,也可以在配置文件中进行配置。
- AOF小结
- Redis需要手动开启AOF持久化方式,AOF的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。
- 关于Redis持久化的使用:若只打算用Redis做缓存,可以关闭持久化。若打算使用Redis的持久化,建议RDB和AOF都开启。其实RDB更适合做数据的备份,留一后手。AOF出问题了,还有RDB。
- AOF和RDB模式可以同时启用,并不冲突。如果AOF是可用的,那Redis启动时将自动加载AOF,这个文件能够提供更好的持久化保障。
12、Redis的事务
Redis的事务允许在一次单独的步骤中执行一组命令,并能够保证将一个事务中的所有命令序列化,然后按顺序执行;在一个Redis事务中,Redis要么执行其中的所有命令,要么什么都不执行。即Redis的事务要能够保证序列化和原子性。
12.1、Redis的事务
12.2、Redis事务的常用命令
- multi
- 功能:用于标记事务块的开始。Redis 会将后续的命令逐个放入队列中,然后才能使用 EXEC 命令原子化地执行这个命令序列。
返回值:开启成功返回 OK
- exec
- 功能:在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态。如果在把命令压入队列的过程中报错,则整个队列中的命令都不会执行,执行结果报错;
如果在压队列的过程中正常,在执行队列中某一个命令报错,则只会影响本条命令的执行结果,其它命令正常运行;
当使用 WATCH 命令时,只有当受监控的键没有被修改时,EXEC 命令才会执行事务中的命令;而一旦执行了 exec 命令,之前加的所有 watch 监控全部取消。 - 返回值:这个命令的返回值是一个数组,其中的每个元素分别是原子化事务中的每个命令的返回值。
- discard
- 功能:清除所有先前在一个事务中放入队列的命令,并且结束事务。
如果使用了 WATCH 命令,那么 DISCARD 命令就会将当前连接监控的所有键取消监控。 - 返回值:清除成功,返回 OK。
- watch key [key …]
- 功能:当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的。如果被监控的 key 值在本事务外有修改时,则本事务所有指令都不会被执行。Watch 命令相当于关系型数据库中的乐观锁。
- 返回值:监控成功,返回 OK。
- unwatch
- 功能:清除所有先前为一个事务监控的键。
如果在 watch 命令之后你调用了 EXEC 或 DISCARD 命令,那么就不需要手动调用 UNWATCH 命令。 - 返回值:清除成功,返回 OK。
12.3、Redis事务小结
- 单独的隔离操作:
- 事务中的所有命令都会序列化、顺序地执行。事务在执行过程中,不会被其它客户端发来的命令请求所打断,除非使用 watch 命令监控某些键。
- 不保证事务的原子性:
- redis 同一个事务中如果一条命令执行失败,其后的命令仍然可能会被执行,redis 的事务没有回滚。Redis 已经在系统内部进行功能简化,这样可以确保更快的运行速度,因为 Redis 不需要事务回滚的能力
13、Redis消息的发布与订阅(了解)
13.1、Redis发布订阅
- Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。Redis客户端可以订阅任意数量的频道。
13.2、Redis发布订阅示意图
- 图一:消息订阅者(client2、client5和client1)订阅频道channel1:
- 图二:消息发布者发布消息到频道channel1,会被发送到三个订阅者:
13.3、Redis发布订阅的常用命令
- subscribe channel [channel…]
- 功能:订阅一个或多个频道的信息
- 返回值:订阅的消息
- publish chanel message
- 功能:将信息发送到指定的频道。
- 返回值:数字。接收到消息订阅者的数量。
- psubscribe pattern [pattern]
- 功能:订阅一个或多个符合给定模式的频道。模式以 * 作为通配符,例如:news.* 匹配所有以 news. 开头的频道。
- 返回值:订阅的信息。
14、Redis的主从复制
14.1、主从复制
- 主机数据更新后,根据配置和策略,自动同步到从机。master/slave机制,Master以写为主,Slave以读为主。
14.2、一主二从
14.2.1、一主二从原理
- 配从(库)不配主(库)
- 配从(库):slaveof 主库IP 主库端口
- 主写从读、读写分离
- 从连前后同
- 主断从待命、从断重新连
14.2.2、一主二从搭建
- 一台服务器模拟三台主机:
- 第一步:将redis.conf 拷贝三份,名字分别是,redis6379.conf,redis6380.conf,redis6381.conf
- 第二步:修改三个文件的port端口,pid文件名,日志文件名,rdb文件名
如:
port 6379
pidfile /var/run/redis_6379.pid
logfile “6379.log”
dbfilename dump6379.rdb - 第三步:分别打开三个窗口模拟三台服务器,开启redis服务。
- 查询主从信息:info replication
- 写操作6379:
- 设置主从关系:
- 在6380和6381主机上分别执行命令:slaveof 127.0.0.1 6379
- 另一种方式,就是修改6380和6381的配置文件,在最后加上:
- 全量复制:在6380和6381分别执行命令 get k1
- 增量复制:6379执行命令:set k2 v2。然后6380端口和6381端口,分别执行命令:get k2
- 主写从读、读写分离:在6380和6381上执行写操作:set k3 v3
- 主机宕机:6379执行指令shutdown,并查看6380和6381的redis信息,从机原地待命。
- 主机宕机后恢复:重启6379,并且执行写命令set k4 v4;6380和6381上分别执行get k4
主机重启后,一切正常。 - 从机宕机:6380执行指令shutdown,并查看6379和6381的redis信息
- 从机宕机后恢复:重启6380,并查看6380、6379和6381的redis信息
注意:从机跟master断开联系,必须重新连接,除非写进配置文件 - 从机恢复连接主机前,主机写操作:6379执行写命令 set k5 v5,6380和6381分别执行命令 get k5
- 从机恢复连接主机,6380执行命令:slaveof 127.0.0.1 6379,并且执行命令:get k5
- 从机上位:
- 第一步:主机宕机,6379执行命令:shutdown
- 第二步:6380断开主从关系,执行命令:slaveof no one
- 第三步:重新搭建主从,6381执行命令:info replication,SLAVEOF 127.0.0.1 6380
- 第四步:之前主机恢复,重启6379的Redis服务,并执行命令:info replication
在6379主机宕机后,6380从机断开主从关系,6381开始还在原地待命;后来6380从机上位,6381投靠6380,6379主机即使回来但它已是孤寡老人,空头司令。 - 15、天堂变地狱:6379执行命令saveof 127.0.0.1 6381,并在6379和6381执行info replication
一台主机配多台从机,一台从机再配多台从机,从而实现了庞大的集群架构。同时也减少了一台主机的压力,缺点是增加了服务器间的延迟。
14.3、复制原理
14.3.1、全量复制
- slave启动成功连接到master后会发送一个sync命令;Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步;slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
- 只要是重新连接master,一次完全同步(全量复制)将被自动执行。
14.3.2、增量复制
- Master将新的所有收集到的修改命令依次传给slave,完成同步。
14.4、哨兵模式
14.4.1、哨兵模式原理
- 从机上位的自动版。
- Redis 提供了哨兵的命令,哨兵命令是一个独立的进程,哨兵通过发送命令,来监控主从服务器的运行状态,如果检测到 master 故障了根据投票数自动将某一个 slave 转换 master,然后通过消息订阅模式通知其它slave,让它们切换主机。
- 然而,一个哨兵进程对 Redis 服务器进行监控,可能会出现问题,为此,我们可以使用多哨兵进行监控。
14.4.2、哨兵模式搭建
- 1—7 步跟 14.2.2 一主二从搭建一样:一台服务器模拟三台主机、查询主从信息、写操作 6379、设置主从关系、全量复制、增量复制、主写从读、读写分离。
- 创建 redis_sentinel.conf 文件,并编辑里边的内容:sentinel monitor dc-redis 127.0.0.1 6379 1,表示:指定监控主机的 ip 地址,port 端口,得到哨兵的投票数(当哨兵投票数大于或者等于此数时切换主从关系)。
- 新开窗口,启动哨兵:redis-sentinel /opt/redis-5.0.2/redis_sentinel.conf
- 主机宕机:
- 等待从机投票,在 sentinel 窗口中查看打印信息。
- 查看 6380 和 6381 的 redis 信息:
- 原主机恢复,启动 6379:
14.4.3、哨兵模式搭建(配置文件模式)
- 1—7 步跟 14.2.2 一主二从搭建一样:一台服务器模拟三台主机、查询主从信息、写操作 6379、设置主从关系、全量复制、增量复制、主写从读、读写分离。
- 复制三份 redis_ sentinel.conf 文件为 redis_sentinel26379.conf、redis_sentinel26380.conf、redis_sentinel 26381.conf,
并修改内容:
端口分别修改为 26379、26380、26381
哨兵监控策略都修改为:
sentinel monitor mymaster 192.168.235.128 6379 2,表示:指定监控主机的 ip 地址,port 端口,得票数多 于 2 时表示需要切换主从关系。
如果设置密码了,都还需要设置密码:
sentinel auth-pass mymaster 123456 - 新开三个窗口,启动哨兵:./redis-sentinel …/myconfs/sentinel26379.conf
- 主机宕机:
- 等待从机投票,在 sentinel 窗口中查看打印信息。
- 查看 6380 和 6381 的 redis 信息:
- 原主机恢复
14.5、小结
14.5.1、操作:
- 查看主从复制关系命令:info replication
- 设置主从关系命令:slaveof 主机 ip 主机 port
- 开启哨兵模式命令:./redis-sentinel sentinel.conf
- 主从复制原则:开始是全量复制,之后是增量复制
- 哨兵模式三大任务:监控,提醒,自动故障迁移
14.5.2、缺点
- Redis 的主从复制最大的缺点就是延迟,主机负责写,从机负责备份,这个过程有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,从机器数量的增加也会使这个问题更加严重。
15、Jedis操作Redis
15.1、Jedis简介
- 使用 Redis 官方推荐的 Jedis,在 java 应用中操作 Redis。Jedis 几乎涵盖了 Redis 的所有命令。操作 Redis 的命令在Jedis 中以方法的形式出现。
15.2、Jedis操作Redis
15.2.1、Jedis 操作 key
15.2.2、Jedis 操作字符串(string)类型数据
15.2.3、Jedis 操作列表(list)类型数据
15.2.4、Jedis 操作哈希(hash)类型数据
15.2.5、Jedis 操作集合(set)类型数据
15.2.6、Jedis 操作有序集合(zset)类型数据
15.2.7、Jedis 操作事务
3. Redis分布式缓存
缓存的用途
- 表数据量大,查多写少,用来提高查询效率
- 临时数据,跨线程使用,不需要持久化
- 分布式锁、ElasticSearch等…
Redis介绍
Remote Dictionary Server (远程字典服务):
- 效率高,c语言编写,单线程纯内存操作,最大QPS达到读11w和写 8w
- 内存存储、可持久化(RDB/AOF)
- 丰富的数据结构(string/hash/list/set/zset 以及 bitmap/hyperloglog/geo)
- 自带定时器、计数器功能,能方便的解决某些业务需求
框架在Redis的基础上,搭配使用了高性能的本地缓存 Caffeine 组成 Redis+Caffeine 的二级缓存,并接入Spring-cache,对开发人员使用无影响的前提下,进一步提升系统响应速度和缓存服务的容错能力。