Redis是一个高性能的key-value数据库,是由 Salvatore Sanfilippo 用C语言开发的一款开源的、高性能的键值对存储数据库,它采用 BSD 协议,为了适应不同场景下的存储需求,提供了多种键值数据类型。
支持的键值数据类型有字符串、列表、有序集合、散列及集合等。正是因为它有如此丰富的数据类型的支持,才会有庞大的用户群体。
内置复制、Lua 脚本、LRU 收回、事务及不同级别磁盘持久化功能,同时通过 Redis Sentinel 实现高可用,通过 Redis Cluster 提供自动分区等相关功能。
Redis 是一款功能强大、支持多语言多种数据类型的数据库,它具有许多优秀的特性,可以实现消息订阅发布、Lua 脚本、数据库事务、Pipeline(管道,即当指令达到一定数量后,客户端才会执行)。同时 Redis 是单线程的,它不依赖外部库,它的所有操作都是原子性的,使用简单,
具体如下:
哈希、集合、位图(多用于活跃用户数等的统计)、HyperLogLog(超小内存唯一值计数,由于只有 12KB,因而是有一定误差范围的)、GEO(地理信息定位)。
官方给出的数据是,Redis 能读的速度是 110 000次/s,写的速度是 81 000次/s。之所以有这么快的读/写速度,是因为这些数据都存储在内存中。
Redis 的持久化也就是备份数据,它每隔一段时间就将内存中的数据保存在磁盘中,在重启的时候会再次加载到内存中,从而实现数据持久化。Redis 的持久化方式是 RDB 和 AOF。
通常来看,数据放在内存中是不安全,一旦发生断电或者故障,重要的数据可能会丢失。因此Redis提供了两种持久化方式:RDB和AOF,这两种方式可以将数据保存到硬盘中,这样就保证了数据的持久化。
Redis提供了复制功能,实现多个相同数据的Redis副本。
复制功能是分布式Redis的基础。
2.8版本正式提供了高可用实现Redis Sentinel ,它能保证Redis节点的故障发现和故障自动转移。
3.0版本正式提供了分布式实现Redis Cluster ,它是是Redis真正的分布式实现,提供了高可用,读写和容量的扩展性。
它师最基本的类型,可以理解为Memcached一模一样的类型,一个key对应一个value
常用命令:set、get、decr、incr、mget等
一个键最大能存储 512MB
// 批量设置
> mset key1 value1 key2 value2
// 批量获取
> mget key1 key2
// 获取长度
> strlen key
// 字符串追加内容
> append key xxx
// 获取指定区间的字符
> getrange key 0 5
// 整数值递增 (递增指定的值)
> incr intkey (incrby intkey 10)
// 当key 存在时将覆盖
> SETEX key seconds value
// 将 key 的值设为 value ,当且仅当 key 不存在。
> SETNX key value
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
常用命令:lpush、rpush、lpop、rpop、lrange等
列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)
// 将一个或多个值 value 插入到列表 key 的表头
> LPUSH key value [value ...]
// 将一个或多个值 value 插入到列表 key 的表尾(最右边)。
> RPUSH key value [value ...]
// 移除并返回列表 key 的头元素。
> LPOP key
// 移除并返回列表 key 的尾元素。
> RPOP key
// BLPOP 是列表的阻塞式(blocking)弹出原语。
> BLPOP key [key ...] timeout
// BRPOP 是列表的阻塞式(blocking)弹出原语。
> BRPOP key [key ...] timeout
// 获取指点位置元素
> LINDEX key index
Redis 的 Set 是 string 类型的无序集合
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)
常用命令:sadd、spop、smembers、sunion等
Set可包含的最大元素数量是4294967295
// 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
> SADD key member [member ...]
// 返回集合 key 中的所有成员。
> SMEMBERS key
// 返回集合 key 的基数(集合中元素的数量)。
> SCARD key
// 如果命令执行时,只提供了 key 参数,那么返回集合中的一个随机元素。
> SRANDMEMBER key [count]
// 移除并返回集合中的一个随机元素。
> SPOP key
// 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。
> SREM key member [member ...]
// 判断 member 元素是否集合 key 的成员。
> SISMEMBER key member
// 获取前一个集合有而后面1个集合没有的
> sdiff huihuiset huihuiset1
// 获取交集
> sinter huihuiset huihuiset1
// 获取并集
> sunion huihuiset huihuiset1
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序
常用命令:zadd、zrange、zrem、zcard等
zset的成员是唯一的,但分数(score)却可以重复
//将一个或多个 member 元素及其 score 值加入到有序集 key 当中。
> ZADD key score member [[score member] [score member] ...]
// 返回有序集 key 中,指定区间内的成员。其中成员的位置按 score 值递增(从小到大)来排序
> ZRANGE key start stop [WITHSCORES]
// 返回有序集 key 中,指定区间内的成员。其中成员的位置按 score 值递减(从大到小)来排列。
> ZREVRANGE key start stop [WITHSCORES]
// 返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。
> ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
// 移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。
> ZREM key member [member ...]
// 返回有序集 key 的基数。
> ZCARD key
// 为有序集 key 的成员 member 的 score 值加上增量 increment 。
> ZINCRBY key increment member
// 返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。
> ZCOUNT key min max
// 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。
> ZRANK key member
Redis hash 是一个键名对集合
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象
常用命令:hget、hset、hgetall等
每个 hash 可以存储 232 -1 键值对(40多亿)
// 将哈希表 key 中的域 field 的值设为 value 。
> HSET key field value
// 返回哈希表 key 中给定域 field 的值。
> HGET key field
// 返回哈希表 key 中的所有域。
> HKEYS key
// 返回哈希表 key 中所有域的值。
> HVALS key
// 为哈希表 key 中的域 field 的值加上增量 increment 。
> HINCRBY key field increment
// 查看哈希表 key 中,给定域 field 是否存在。
> HEXISTS key field
1.geospatial将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。
这些数据将会存储到sorted set这样的目的是为了方便使用GEORADIUS或者GEORADIUSBYMEMBER命令对数据进行半径查询等操作。
2.sorted set使用一种称为Geohash的技术进行填充。经度和纬度的位是交错的,以形成一个独特的52位整数。
sorted set的double score可以代表一个52位的整数,而不会失去精度。(有兴趣的同学可以学习一下Geohash技术,使用二分法构建唯一的二进制串)
3.有效的经度是-180度到180度
有效的纬度是-85.05112878度到85.05112878度
命令 | 功能 | 描述 |
---|---|---|
geoadd | 添加地理位置 | 往key中添加地理位置的坐标(经度、纬度、位置名称) |
geopos | 查询经纬度 | 返回指定成员的经纬度参数 |
geodist | 查询距离 | 返回指定2个成员之间的直线距离(默认单位:米) |
georadius | 附近的人 | 指定经纬度为中心,返回该中心指定半径内的成员 |
georadiusbymember | 附近的人 | 等同georadius,上述是指定经纬度,这个是指定成员附近的人 |
geohash | 地理位置坐标 | 返回Redis GEO 的地理位置的坐标 |
m 表示单位为米[默认值]
km 表示单位为千米
mi 表示单位为英里
ft 表示单位为英尺
geoadd key longitude latitude member [longitude …]
geoadd {key} {longitude} {latitude} {member} [longitude latitude member…]
// 添加北京(经纬度)、上海(经纬度)的位置到名为mycity的key中
127.0.0.1:6379> geoadd mycity 116.40 39.9 beijing 121.47 31.23 shanghai
(integer) 2
// 底层是zset存储方式,可以直接用zrange查询索引区间的所有成员
127.0.0.1:6379> zrange mycity 0 -1
1) "beijing"
2) "tianjin"
geopos key member1 member2…
geopos {key} {member} [member…]
// 底层是zset存储方式,可以直接用zrange查询索引区间的所有成员
127.0.0.1:6379> zrange mycity 0 -1
1) "beijing"
2) "shanghai"
// 查询上海、北京、成都的经度纬度
127.0.0.1:6379> geopos mycity beijing shanghai tianjin
1) 1) "116.39999896287918091"
2) "39.90000009167092543"
2) 1) "121.47000163793563843"
2) "31.22999903975783553"
3) (nil) # 不存在mycity中的城市位置,则返回nil
geodist key member1 member2… [m|km|ft|mi 单位可选]
geodist {key} {member1} {member2} [m|km|ft|mi ]
// 指定单位的参数 unit 必须是以下单位的其中一个
// 返回上海到北京的直线距离,单位为:km千米
127.0.0.1:6379> geodist mycity beijing shanghai km
"1067.3788"
// 返回北京到天津的直线距离,成都在mycity中不存在,返回nil
127.0.0.1:6379> geodist mycity beijing tianjin
(nil)
georadius key longitude latitude radius [m|km|ft|mi 单位可选]
georadius {key} {longitude} {latitude} radius m|km|ft|mi
# 返回经度120,纬度30 的周边500千米内的成员
127.0.0.1:6379> georadius mycity 120 30 500 km
1) "nanchang"
2) "hangzhou"
3) "shanghai"
4) "nanjing"
# 100千米内的成员
127.0.0.1:6379> georadius mycity 120 30 100 km
1) "hangzhou"
# 200千米内的成员
127.0.0.1:6379> georadius mycity 120 30 200 km
1) "hangzhou"
2) "shanghai"
# 200千米内的成员名称、120,30与该成员位置的直线距离数、经纬度参数
127.0.0.1:6379> georadius mycity 120 30 200 km withdist withcoord
1) 1) "hangzhou"
2) "30.8146" # 直线距离
3) 1) "120.1600000262260437"
2) "30.2400003229490224"
2) 1) "shanghai"
2) "196.2512"
3) 1) "121.47000163793563843"
2) "31.22999903975783553"
# 返回1个 200千米内的成员名称 (count num 指定显示num个)
127.0.0.1:6379> georadius mycity 120 30 200 km count 1
1) "hangzhou"
georadiusbymember key longitude latitude radius [m|km|ft|mi]
# 返回上海的周边300千米内的成员名称
127.0.0.1:6379> georadiusbymember mycity shanghai 300 km
1) "hangzhou"
2) "shanghai"
3) "nanjing"
# 200千米内的成员名称
127.0.0.1:6379> georadiusbymember mycity shanghai 200 km
1) "hangzhou"
2) "shanghai"
# 返回上海的周边200千米内的成员名称、经纬度参数
127.0.0.1:6379> georadiusbymember mycity shanghai 200 km withcoord
1) 1) "hangzhou"
2) 1) "120.1600000262260437"
2) "30.2400003229490224"
2) 1) "shanghai"
2) 1) "121.47000163793563843"
2) "31.22999903975783553"
geohash key member1 member2…
# 返回上海、北京、杭州的坐标hash
127.0.0.1:6379> geohash mycity shanghai beijing hangzhou
1) "wtw3sj5zbj0"
2) "wx4fbxxfke0"
3) "wtmkn31bfb0"
hyperloglog 是用来做基数统计的,其优点是:输入的提及无论多么大,hyperloglog使用的空间总是固定的12KB ,利用12KB,它可以计算2^64个不同元素的基数!非常节省空间!但缺点是估算的值,可能存在误差
这个结构可以非常省内存的去统计各种计数,比如注册 IP 数、每日访问 IP 数的页面实时UV、在线用户数,共同好友数等。
Redis HyperLogLog 是一种基数算法,可以用于估计一个集合中的元素数量。Redis HyperLog 的特点如:
Redis HyperLogLog 是一种基数算法,可以用于估计一个集合中的元素数量。
Redis HyperLogLog 的误差率很小,通常在 0.81% 左右。
Redis HyperLogLog 的空间占用很小,通常只需要几 KB 的空间。
# 添加指定元素到 HyperLogLog 中
# PFADD key [element [element ...]]
127.0.0.1:6379> PFADD mykey1 a b c d e f g h i j
(integer) 1
# 返回给定 HyperLogLog 的基数估算值。
# PFCOUNT key [key ...]
127.0.0.1:6379> PFCOUNT mykey1
(integer) 10
# 将多个 HyperLogLog 合并为一个 HyperLogLog
# PFMERGE destkey sourcekey [sourcekey ...]
127.0.0.1:6379> PFADD mykey2 i j z x c v b n m
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2
(integer) 9
127.0.0.1:6379> PFMERGE mykey3 mykey1 mykey2
OK
127.0.0.1:6379> PFCOUNT mykey3
(integer) 15
Redis提供的Bitmaps这个“数据结构”可以实现对位的操作。Bitmaps本身不是一种数据结构,实际上就是字符串,但是它可以对字符串的位进行操作。
Bitmap 即位图数据结构,都是操作二进制位来进行记录,只有0 和 1 两个状态。
比如:统计用户信息,活跃,不活跃! 登录,未登录! 打卡,不打卡! 两个状态的,都可以使用
可以把Bitmaps想象成一个以位为单位数组,数组中的每个单元只能存0或者1,数组的下标在bitmaps中叫做偏移量。单个bitmaps的最大长度是512MB,即2^32个比特位。
1.设置Bitmaps中某个偏移量的值(0或1)
setbit key offset value
2.获取Bitmaps中某个偏移量的值
getbit key offset
3.统计字符串从start字节到end字节比特值为1的数量
bitcount key [start end]
4.对多个Bitmaps的and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存在destkey中
bitop and(or/not/xor) destkey [key1 key2 ...]
127.0.0.1:6379> SETBIT sign:Bob:202201 1 1 # 设置 这里的 1|0 是二进制
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 2 1
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 3 0
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 4 1
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 5 1
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 6 1
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 7 1
(integer) 0
127.0.0.1:6379> GETBIT sign:Bob:202201 2 # 获取某天状态
(integer) 1
127.0.0.1:6379> BITCOUNT sign:Bob:202201 # 统计 位 1 的数量
(integer) 6
对指定key按位进行交、并、非、异或操作,并把结果保存到destKey中
127.0.0.1:6379> SETBIT sign:Bob:202201 1 1 # 设置 这里的 1|0 是二进制
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 2 1
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 3 0
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 4 1
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 5 1
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 6 1
(integer) 0
127.0.0.1:6379> SETBIT sign:Bob:202201 7 1
(integer) 0
127.0.0.1:6379> GETBIT sign:Bob:202201 2 # 获取某天状态
(integer) 1
127.0.0.1:6379> BITCOUNT sign:Bob:202201 # 统计 位 1 的数量
(integer) 6
事务
// 1. multi命令开启事务,exec命令提交事务
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK
// 2. 组队的过程中可以通过discard来放弃组队。
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> set k4 v4
QUEUED
127.0.0.1:6379(TX)> discard
OK
缓存已过期了,请求直奔数据库。
查DB后同步Redis、Canal同步
大量的热点Key过期(Redis 宕机),请求全部打到DB,导致数据库极大压力飙升甚至宕机。
过期时间添加随机值、接口限流
查询不存在的数据(一般为恶意请求),请求直奔数据库,缓存系统形同虚设,对数据库产生很大压力从而影响正常服务。
布隆过滤器、设置缺省值
主从复制是高可用Redis的基础,哨兵和cluster都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。
优势:
缺陷:故障恢复无法自动化,写操作无法负载均衡,存储能力受到单机的限制。
主从复制模式就是,部署多台redis节点,其中只有一台节点是主节点(master),其他的节点都是从节点(slave),也叫备份节点(replica)。只有master节点提供数据的事务性操作(增删改),slave节点只提供读操作。所有slave节点的数据都是从master节点同步过来的。
哨兵模式即为反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。
缺陷:故障恢复无法自动化,写操作无法负载均衡,存储能力受到单机的限制。
通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案
主节点负责读写请求和集群信息的维护,从节点只进行主节点数据和状态信息的复制
数据分区(或称数据分片)是集群最核心的功能(分布式)
集群将数据分散到多个节点,一方面突破了 Redis 单机内存大小的限制,存储容量大大增加,另一方面每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力
Redis 单机内存大小受限问题,例如,如果单机内存太大,bgsave 和 bgrewriteaof 的 fork 操作可能导致主进程阻塞,主从环境下主机切换时可能导致从节点长时间无法提供服务,全量复制阶段主节点的复制缓冲区可能溢出
集群支持主从复制(模式)和主节点的自动故障转移(与哨兵类似),当任意节点发送故障时,集群仍然可以对外提供服务
Redis 集群引入了哈希槽的概念,有 16384 个哈希槽(编号 0~16383)
集群的每个节点负责一部分哈希槽,每个 Key 通过 CRC16 校验后对 16384 取余来决定放置哪个哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作
Redis是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题Redis供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失
两种持久化方式:快照(RDB文件)和追加式文件(AOF文件),下面分别为大家介绍两种方式的原理。
Redis中的RDB持久化方式,采用了写时复制技术(copy on write)和fork子进程。
RDB是Redis用来进行持久化的一种方式,是把当前内存中的数据集快照写入磁盘,也就是 Snapshot 快照(数据库中所有键值对数据),它可以手动执行,也可以在redis.conf配置文件中配置,定时执行,恢复时是将快照文件直接读到内存里。
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,在用这个临时文件替换上次持久化好的文件.
整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能
如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效.
save:这里是用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。比如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave(这个命令下面会介绍,手动触发RDB持久化的命令)
当然如果你只是用Redis的缓存功能,不需要持久化,那么你可以注释掉所有的 save 行来停用保存功能。可以直接一个空字符串来实现停用:save “”
save 900 1 900s检查一次,至少有1个key被修改就触发
save 300 10 300s检查一次,至少有10个key被修改就触发
save 60 10000 60s检查一次,至少有10000个key被修改
默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。如果Redis重启了,那么又可以重新开始接收数据了
默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。
默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
设置快照的文件名,默认是 dump.rdb
设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。默认是和当前配置文件保存在同一目录。
也就是说通过在配置文件中配置的 save 方式,当实际操作满足该配置形式时就会进行 RDB 持久化,将当前的内存快照保存在 dir 配置的目录中,文件名由配置的 dbfilename 决定。
该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。
显然该命令对于内存比较大的实例会造成长时间阻塞,这是致命的缺陷,为了解决此问题,Redis提供了第二种方式。
执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。
基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。
ps:执行执行 flushall 命令,也会产生dump.rdb文件,但里面是空的,无意义
任何组件在正常关闭的时候,都会去完成应该完成的事。比如Mysql 中的Redolog持久化,正常关闭的时候也会去持久化。
数据清空指令会触发RDB操作,并且是触发一个空的RDB文件,所以, 如果在没有开启其他的持久化的时候,flushall是可以删库跑路的,在生产环境慎用。
将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可,redis就会自动加载文件数据至内存了。Redis 服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。
获取 redis 的安装目录可以使用 config get dir 命令
有些情况下,我们只想利用Redis的缓存功能,并不像使用 Redis 的持久化功能,那么这时候我们最好停掉 RDB 持久化。可以通过上面讲的在配置文件 redis.conf 中,可以注释掉所有的 save 行来停用保存功能或者直接一个空字符串来实现停用:save “”
也可以通过命令:
redis-cli config set save " "
1.RDB是一个非常紧凑(compact)的文件,它保存了redis 在某个时间点上的数据集。这种文件非常适合用于进行备份和灾难恢复。
2.生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
3.RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
以日志的形式来记录每个写的操作,将Redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
Always,同步写回:每个写命令执行完,立马同步地将日志写回磁盘;
Everysec,每秒写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘;
No,操作系统控制的写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。
配置项 | 写回时机 | 优点 | 缺点 |
---|---|---|---|
Always | 同步写回 | 可靠性高,数据基本不会丢失 | 每个写命令都要落盘,性能影响较大 |
Everysec | 每秒写回 | 性能适中 | 宕机时丢失1秒内的数据 |
No | 操作系统控制的写回 | 性能好 | 宕机时丢失数据较多 |
base:表示基础AOF,一般由子进程重写产生,该文件最多只有一个。
incr:表示增量AOF,一般会在AOFRW开始执行时被创建,该文件可有多个。
history:表示历史AOF,由base和incr变化而来,每次AOFRW成功完成时,本次AOFRW之前对应的base和incr都会变成history,history类型的AOF会被redis自动删除
AOF相对RDB更加安全,一般不会有数据的丢失或者很少,官方推荐同时开启AOF和RDB。
如果系统是愿意牺牲一些性能,换取更高的缓存一致性(AOF)
或者是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(RDB)。
Redis允许同时开启AOF和RDB,既保证了数据安全又使得进行备份等操作十分容易。此时重新启动Redis后Redis会使用AOF文件来恢复数据,因为AOF方式的持久化可能丢失的数据更少。
AOF也有不同的触发方案,这里简要描述以下三种触发方案:
always:每次发生数据修改就会立即记录到磁盘文件中,这种方案的完整性好但是IO开销很大,性能较差;
everysec:在每一秒中进行同步,速度有所提升。但是如果在一秒内宕机的话可能失去这一秒内的数据;
no:默认配置,即不使用 AOF 持久化方案。
可以在redis.config中进行配置,appendonly no改换为yes,再通过注释或解注释appendfsync配置需要的方案
应用场景:做纯粹的高并发高性能缓存服务器时
关闭RDB:save “”
关闭AOF:appendonly no
同时关闭RDB+AOF,但在RDB+AOF都禁用的情况下,仍然可以使用save/bgsave命令生成rdb文件,仍可以使用bgrewriteaof命令生成aof文件