Redis基础操作与持久化

目录

引言

一、Reids工具与数据类型

(一)Reids工具

(二)Redis数据类型

1.String(字符串)

2.Hash(哈希)

3.List(列表)

4.Set(集合)

5.sorted set(有序集合)

二、基本命令

(一)字符串命令

1.set与get指令

2.getset指令

3.mset与mget指令

4.setnx指令

5.strlen指令

(二)哈希命令

1.hmset指令

2.hmget指令

3.Hdel指令

(三)列表命令

1.rpush指令

2.lrange指令

3.lpush指令

4.lindex指令

(四)集合命令

1.sadd与smembers指令

2.srem与smove指令

(五)有序集合命令

1.zadd指令

2.zrem指令

(六)其它命令

三、持久化

(一)redis持久化方式

1.RDB(Redis DataBase)方式

2.AOF (Append Only File) 持久化

(二)持久化过程

1..RDB持久化过程

2.AOF持久化过程

(三)开启持久化

1.开启RDB持久化

2.开启AOF持久化

(四)RDB与AOF的优缺点

1.RDB持久化方式的优点与缺点

2.AOF持久化方式的优点与缺点

四、性能管理

(一)内存碎片

(二)Redis内存碎片率

(三)Redis内存使用率

(四)Redis内部Key回收策略

总结


引言

Redis作为一种流行的内存数据存储系统,以其出色的性能、丰富的数据结构和持久化机制,被广泛应用于缓存、队列、计数器、排行榜等多种场景

一、Reids工具与数据类型

(一)Reids工具

Redis安装完毕后,会在安装目录的bin目录下生成几个工具文件

[root@localhost opt]#ll /usr/local/redis/bin/
总用量 32788
-rwxr-xr-x. 1 root root 4367640 4月   1 17:25 redis-benchmark
-rwxr-xr-x. 1 root root 8127288 4月   1 17:25 redis-check-aof
-rwxr-xr-x. 1 root root 8127288 4月   1 17:25 redis-check-rdb
-rwxr-xr-x. 1 root root 4808824 4月   1 17:25 redis-cli
lrwxrwxrwx. 1 root root      12 4月   1 17:25 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 8127288 4月   1 17:25 redis-serverredis-benchmark
#基准测试工具,用于模拟多个客户端同时对Redis服务器执行读写操作,
#以此来测试Redis服务器在各种场景下的性能表现。redis-check-aof
#持久化文件检查工具。在Redis使用AOF持久化时,这个工具可以帮助检查AOF文件是
#否损坏或存在一致性问题,并在必要时对其进行修复。redis-check-rdb
#RDB持久化文件检查工具。它可以检测RDB文件是否损坏,并在可能的情况下尝试修复。redis-cli
#redis-cli是Redis的命令行客户端,你可以通过它直接与Redis服务器进行交互,
#执行命令、查看数据、进行调试等工作。redis-sentinel
#高可用性解决方案之一,它负责监控Redis服务器实例的状态,并在主服务器发生故障时
#自动进行故障转移,确保服务的持续可用。redis-server
#执行程序,通过启动它来运行Redis数据库服务。
#通过配置文件(如redis.conf)来设置服务器的各种参数,而后通过此命令启动服务供客户端连接

(二)Redis数据类型

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

1.String(字符串)

string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。

string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。

string类型是Redis最基本的数据类型,一个键最大能存储512MB。

存储方式:字符串数据类型的基本存储方式为:键-值

2.Hash(哈希)

Redis hash 是一个键值对集合。

Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。

存储方式:哈希表的数据的基本存储方式为:键--字段--值

一个键可以对应多个字段与值:key  filed1 value1 filed2 value2....

3.List(列表)

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。

存储方式为:键--有序的值队列 。  key_name value0 value1....

4.Set(集合)

Redis的Set是string类型的无序集合。

集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)

存储方式:键--无序的不重复的成员。 key_name stringX stringY....

5.sorted set(有序集合)

Redis sorted set又称zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

zset的成员是唯一的,但分数(score)却可以重复。

存储方式:键-按分数排序的不重复的成员 。 key-scorel:stringX, score2:stringY...

二、基本命令

(一)字符串命令

命令描述
Setnx只有在 key 不存在时设置 key 的值。
Getrange返回 key 中字符串值的子字符
Mset  同时设置一个或多个 key-value 对。
Setex  将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。
SET设置指定 key 的值
Get获取指定 key 的值。
Getbit对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
Setbit对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
Decr将 key 中储存的数字值减一。
Decrbykey 所储存的值减去给定的减量值(decrement) 。
Strlen返回 key 所储存的字符串值的长度。
Msetnx同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
Incrby将 key 所储存的值加上给定的增量值(increment) 。
Incrbyfloat将 key 所储存的值加上给定的浮点增量值(increment) 。
Setrange用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。
Psetex

这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX

命令那样,以秒为单位。

Append如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。
Getset将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
Mget获取所有(一个或多个)给定 key 的值。
Incr

将 key 中储存的数字值增一。

1.set与get指令

设定键值:set key_name value

获取键值:get key_name value

2.getset指令

getset指令用于赋予已存在的键新的值,并显示该键之前的值

基本语法为:getset key_name new_value

3.mset与mget指令

使用mset命令,可以同时为多个键指定值

基本语法为:mset key_name1  value1 key_name2 value2.....

使用mget命令,可以同时获取多个键的值

基本语法为:mget key_name1 key_name2.....

4.setnx指令

只有在key不存在时设置 key 的值。防止误将本来存在的键以及对应的值进行覆盖,造成数据丢失

5.strlen指令

该指令用于返回key所储存的字符串值的长度。

基本语法为:strlen key_name

(二)哈希命令

哈希列表的命令操作语法与字符串命令基本一致

命令描述
Hmset同时将多个field-value(域-值)对设置到哈希表key中。
Hmget获取所有给定字段的值
Hset将哈希表key中字段field的值设为value。旧版本使用,较新版本与Hmset合并
Hgetall获取在哈希表中指定key的所有字段和值
Hget获取存储在哈希表中指定字段的值/td>
Hexists查看哈希表key中,指定的字段是否存在。
Hincrby为哈希表key中的指定字段的整数值加上增量increment。
Hlen获取哈希表中字段的数量
Hdel删除一个或多个哈希表字段
Hvals获取哈希表中所有值
Hincrbyfloat为哈希表key中的指定字段的浮点数值加上增量increment。
Hkeys获取所有哈希表中的字段
Hsetnx只有在字段field不存在时,设置哈希表字段的值。

1.hmset指令

hmset 命令用于为哈希表中的字段赋值 。

如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。

如果字段已经存在于哈希表中,旧值将被覆盖。

基本语法为:hmest key_name filed1 value1 filed2 value2.....

2.hmget指令

hmget指令用来获取指定哈希表中给定字段的值

基本语法为hmget key_name filed1 [filed2....]

3.Hdel指令

删除哈希表中一个或多个字段

基本语法为:hdel key_name filed [filed....]

(三)列表命令

命令描述
Lindex通过索引获取列表中的元素
Rpush在列表中添加一个或多个值
Lrange获取列表指定范围内的元素
Rpoplpush移除列表的最后一个元素,并将该元素添加到另一个列表并返回
Blpop

移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹

出元素为止。

Brpop

移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可

弹出元素为止。

Brpoplpush

从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元

素会阻塞列表直到等待超时或发现可弹出元素为止。

Lrem移除列表元素
Llen获取列表长度
Ltrim

对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内

的元素都将被删除。

Lpop移出并获取列表的第一个元素
Lpushx将一个或多个值插入到已存在的列表头部
Linsert在列表的元素前或者后插入元素
Rpop移除并获取列表最后一个元素
Lset通过索引设置列表元素的值
Lpush将一个或多个值插入到列表头部
Rpushx为已存在的列表添加值

1.rpush指令

在列表中添加一个或多个值

基本语法为:rpush key_name value0 value1....

2.lrange指令

获取列表指定范围内的元素

基本语法为:lrange key_name start stop

3.lpush指令

将一个或多个值插入到列表头部

基本语法为:lpush key_name value0 value1....

4.lindex指令

通过索引获取列表中的元素

基本语法为:lindex key_name 

(四)集合命令

命令描述
Sunion返回所有给定集合的并集
Scard获取集合的成员数
Srandmember返回集合中一个或多个随机数
Smembers返回集合中的所有成员
Sinter返回给定所有集合的交集
Srem移除集合中一个或多个成员
Smove将 member 元素从 source 集合移动到 destination 集合
Sadd向集合添加一个或多个成员
Sismember判断 member 元素是否是集合 key 的成员
Sdiffstore返回给定所有集合的差集并存储在 destination 中
Sdiff返回给定所有集合的差集
Sscan迭代集合中的元素
Sinterstore返回给定所有集合的交集并存储在 destination 中
Sunionstore所有给定集合的并集存储在 destination 集合中
Spop移除并返回集合中的一个随机元素

1.sadd与smembers指令

sadd指令用于向集合添加多个成员

基本语法为:sadd key_name member [member ...]

smembers指令用于返回集合中的所有成员

基本语法为:smembers key_name

2.srem与smove指令

srem指令移除集合中一个或多个成员

基本语法为:srem key_name member [member ...]

smove指令用于将 member 元素从 source 集合移动到 destination 集合

基本语法为:smove source destination member

(五)有序集合命令

命令描述
Zrevrank

返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序

序号从0开始,0为第一名

Zlexcount在有序集合中计算指定字典区间内成员数量
Zunionstore计算给定的一个或多个有序集的并集,并存储在新的 key 中
Zremrangebyrank移除有序集合中给定的排名区间的所有成员
Zcard获取有序集合的成员数
Zrem移除有序集合中的一个或多个成员
Zinterstore计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
Zrank返回有序集合中指定成员的索引
Zincrby有序集合中对指定成员的分数加上增量 increment
Zrangebyscore通过分数返回有序集合指定区间内的成员
Zrangebylex通过字典区间返回有序集合的成员
Zscore返回有序集中,成员的分数值
Zremrangebyscore移除有序集合中给定的分数区间的所有成员
Zscan迭代有序集合中的元素(包括元素成员和元素分值)
Zrevrangebyscore返回有序集中指定分数区间内的成员,分数从高到低排序
Zremrangebylex移除有序集合中给定的字典区间的所有成员
Zrevrange返回有序集中指定区间内的成员,通过索引,分数从高到底
Zrange通过索引区间返回有序集合成指定区间内的成员
Zcount计算在有序集合中指定区间分数的成员数
Zadd向有序集合添加一个或多个成员,或者更新已存在成员的分数

1.zadd指令

向有序集合添加一个或多个成员,或者更新已存在成员的分数

基本语法为:zadd key [NX|XX] [CH] [INCR] score member [score member ...]
 

NX:仅当成员不存在时添加成员XX:仅当成员存在时修改成员CH(changed):返回变更的成员数量
*默认返回新增的成员数量incr:累加分数
*选择incr时,只能操作一个分数-成员对score member:分数及成员名称

修改分数,使用incr选项

ch选项进行判断

2.zrem指令

zrem指令用于移除一个或多个成员

(六)其它命令

在redis当中还有许多其它的命令类型,如键(key) 命令、连接命令、 服务器命令、事务命令、 脚本命令等。

命令描述
Flushdb清空当前数据库的所有键。
Flushall清空所有数据库的所有键。
Dbsize返回当前数据库中键的数目。
Type返回 key 所储存的值的类型。
Rename修改 key 的名称
Renamenx仅当 newkey 不存在时,将 key 改名为 newkey 。
Keys查找所有符合给定模式( pattern)的 key 。
DEL该命令用于在 key 存在时删除 key。
Move将当前数据库的 key 移动到给定的数据库 db 当中。
select切换库

本文只讲解了一些命令的基本使用方法,更详细的使用方法,可以参考官方文档的

官方文档:Commands | Redis

中文文档:redis命令手册

三、持久化

持久化是redis当中一个非常重要的功能,因为redis是一个基于内存的数据库,如果没有持久化,一旦关机或者重启,之前所有的数据都会丢失,这对一个数据库来说是非常致命的,持久化就是为解决这个问题而诞生了

(一)redis持久化方式

1.RDB(Redis DataBase)方式

RDB 是 Redis 默认的持久化方式,通过定期将内存中的数据以二进制的形式保存到磁盘上的RDB文件中,实现数据的持久化。这个过程可以通过Redis服务器自动触发(例如通过save配置指令设置触发条件),也可以手动执行(通过bgrewriteaof命令)。

RDB 文件是经过压缩的二进制文件,便于备份和恢复,同时加载速度快,但可能会丢失最后一次触发快照后到Redis宕机之间这段时间的数据。

2.AOF (Append Only File) 持久化

AOF 持久化则是将每一次对Redis服务器的写操作以Redis协议的格式追加到一个单独的日志文件(也就是AOF文件)中。相比RDB,AOF提供了更高的数据安全性,因为它的持久化粒度更细,理论上可以达到每一笔写操作都不会丢失的程度。

AOF 文件随着时间推移会不断增大,Redis 提供了AOF重写机制(bgrewriteaof命令触发),用来压缩AOF文件,去掉无效的命令和合并连续的写操作。

AOF模式可以配置不同的同步策略,包括“每条命令都同步”、“每秒同步一次”和“在写入后至少等待指定数量的写操作再同步”。

(二)持久化过程

1..RDB持久化过程

1.1 触发RDB持久化

RDB持久化可以通过配置文件中的save指令自动触发,例如当满足一定条件(如过去5分钟内有10个key发生变化)时,Redis会自动执行一次快照操作。也可以通过手动执行SAVE或BGSAVE命令触发。SAVE命令会阻塞Redis服务器直到RDB文件创建完成,而BGSAVE命令会在后台异步执行持久化操作。

1. 2 父进程fork子进程

触发RDB持久化后,父进程会fork一个子进程,这个过程中父进程是阻塞的,不能接受其它的客户端命令

1.3 fork子进程完成

子进程负责将内存中的数据以二进制格式写入到RDB文件中,而主进程继续处理客户端请求。

1.4 子进程生成RDB文件

子进程将数据库中的数据转换为一系列序列化格式的键值对,然后写入磁盘文件。写入完成后,原来的RDB文件(如果存在)会被新的RDB文件替换。

1.5 子进程向父进程发送信号

子进程发送信号给父进程表示完成,父进程更新统计信息
 

2.AOF持久化过程

AOF持久化过程主要包括三个方面,命令追加、文件写入与文件同步、文件重写。

2.1 命令追加

每次客户端发送的写命令在Redis服务器中执行完成后,都会被以Redis协议格式追加到AOF缓冲区,而后统一写入到磁盘当中。主要是为了防止每次写命令都直接继续如磁盘,导致磁盘IO负载过高。造成瓶颈

2.2 文件写入与文件同步

启用AOF持久化后,Redis会将所有的写命令追加到AOF文件的末尾,可以配置不同的同步策略(always、everysec、no)来平衡数据安全性和性能。根据配置的同步策略,Redis会在命令执行完成后立即(always)、每秒(ecerysec)或在操作系统缓冲区满时(no)将命令刷入磁盘。

appendfsync always

设置为 always 表示每次Redis接收到写命令后,都会调用操作系统提供的 fsync() 或类似函数强制将AOF缓冲区的内容同步到磁盘中。这种方式能够确保每个写命令都立即被持久化,因此在Redis服务器崩溃的情况下,数据丢失的可能性最小。但是,频繁的同步操作会显著降低Redis的性能,因为它涉及到磁盘I/O操作,而磁盘I/O通常比内存操作要慢得多。

appendfsync everysec

这是Redis AOF的默认设置。在这种模式下,Redis会在每一秒结束时(大约每秒)将AOF缓冲区的内容同步到磁盘。这意味着在最坏情况下,如果Redis在同步后立即崩溃,可能会丢失这一秒内的写操作数据。然而,这种策略在保证数据相对安全的同时,也能保持较好的性能表现。

appendfsync no

当设置为 no 时,Redis不会主动调用同步操作,而是依赖操作系统的缓存策略来决定何时将AOF缓冲区内容刷到磁盘。这种配置下,Redis的写性能将会是最高的,因为它减少了与磁盘交互的频率。然而,这也意味着在服务器突然断电或无预警关机的情况下,可能丢失大量未写入磁盘的数据,因此数据安全性极低。

总结来说,appendfsync 的不同设置允许用户在数据安全性和性能之间进行权衡选择。在实际应用中,大多数场景推荐使用 appendfsync everysec 来达到较好的折衷效果。对于极度关注数据安全的应用,可以选择 appendfsync always,但在牺牲性能的前提下;而对于对性能要求极高且能接受一定数据丢失风险的应用,则可考虑 appendfsync no。

2.3 AOF重写

① 随着AOF文件的持续增长,Redis提供了AOF重写功能(可通过bgrewriteaof命令触发)来压缩AOF文件。

②Redis父进程首先判断当前是否存在正在执行bgsave/bgrewriteaof的子进程,如果存在则bgrewriteaof命令直接返回,如果存在 bgsave命令则等bgsave执行完成后再执行。父进程执行fork操作创建子进程,这个过程中父进程是阻塞的。

③父进程fork后,bgrewriteaof命令返回信息并不再阻塞父进程。而后将所有的命令写入缓冲区,而后根据同步方式追加到AOF文件的末尾,同时命令也进入重写缓冲区

④ 子进程首先生成新的AOF文件,而后向父进程发送信号,更新统计信息

⑤重写缓冲区会遍历内存中的数据构建最小化且有效的命令集合,将这些命令写入新的AOF文件。

新的AOF文件创建完成后,Redis会原子地用新的AOF文件替换旧文件。

重写的作用

将过期的数据不再写入文件,最后一条错误语句不写入

无效的命令不在写入,比如创建set  key value,在后面又执行了del key。这样创建又删除的操作将自动被忽略

将多条命令合并,比如将sadd key_set value1, sadd key_set value2, saddkey_set value3,合并成sadd key_set value1 value2 value3

(三)开启持久化

1.开启RDB持久化

需要修改/etc/redis/6379.conf配置文件

save 900 1
#这是Redis的RDB快照保存策略,表示如果在过去的900秒(15分钟)内,至少有1个key的数据发生
#变化,Redis就会自动触发一次持久化操作,将当前内存中的数据生成一份RDB文件保存在磁盘上。save 300 10
#在过去的300秒(5分钟)内,至少有10个key的数据发生变化,Redis也将触发RDB持久化。save 60 10000
#在过去的60秒内,有10000个key的数据发生变化,Redis会执行RDB持久化。rdbcompression yes
#这个配置项表示在生成RDB文件时启用压缩功能,以减小RDB文件的体积,从而节省存储空间。
#启用压缩会影响RDB文件的生成速度和恢复速度,但通常压缩率较高,总体上利大于弊。dbfilename dump.rdb
#设置RDB文件的名称为dump.rdb。当Redis执行RDB持久化时,生成的文件会以这个名字存储。dir /var/lib/redis/6379
#设置RDB文件和AOF文件(如果开启的话)的存放目录为/var/lib/redis/6379。
#当Redis需要保存或加载持久化文件时,会在这个目录下查找相应文件。

2.开启AOF持久化

appendonly yes
#这行配置表示启用Redis的AOF持久化方式。appendfilename "appendonly.aof"
#设置AOF文件的名称为"appendonly.aof"。每次Redis执行写操作时,都会同步更新这个文件。# appendfsync always
appendfsync everysec
# appendfsync no
#选择同步策略aof-load-truncated yes
#是否忽略最后一条可能存在问题的指令
#表示当Redis启动时发现AOF文件已被截断或者损坏(非正常关闭导致),依然尝试加载该文件
#并继续运行,而不是直接报错退出。这对于应对一些意外情况非常有用,因为即使AOF文件不完
#整,也有可能部分恢复之前的数据状态

(四)RDB与AOF的优缺点

1.RDB持久化方式的优点与缺点

1.1 优点

性能优异:RDB持久化在生成快照时会对主线程进行fork操作创建一个子进程,子进程完成数据持久化工作,不会阻塞主线程处理客户端请求,故对Redis服务性能影响较小。

数据恢复快:RDB文件是二进制格式的,紧凑且易于加载,Redis在重启时可以直接读取RDB文件恢复数据,速度较快。

易于备份与迁移:RDB文件可以方便地用于备份或迁移到其他Redis服务器,而且由于文件体积相对较小,传输和存储成本较低。

1.2 缺点

数据安全性略低:在发生故障时,最后一次持久化和故障之间的时间段内的数据可能丢失。如果RDB文件生成周期较长,潜在的数据丢失风险就越大。

资源消耗:虽然fork操作在现代操作系统中代价相对较小,但对于大容量数据的Redis实例,fork操作仍可能引起暂时的性能下降和较大的内存开销。

不适合大型在线更新场景:如果应用中有大量的写入操作,且需要非常严格的实时持久化保证,RDB可能不是最佳选择,因为RDB是以周期性快照方式进行持久化的。

2.AOF持久化方式的优点与缺点

2.1 优点

数据安全性高:AOF持久化以命令追加的方式记录,可以设置不同的同步策略(如appendfsync everysec),接近于实时持久化,大大降低了数据丢失的可能性。

容错性强:即便AOF文件损坏,Redis提供了redis-check-aof工具进行修复,可以从中找回大部分数据。

重写功能:缩小文件体积,减少磁盘的空间占用,优化存储效率,提示性能。

精确恢复:AOF记录了所有写操作,因此在Redis重启时可以按照写入命令的顺序逐条执行,精确恢复数据状态。

2.2 缺点

性能损耗:根据不同的同步策略,AOF可能需要频繁地将命令写入硬盘,尤其在always同步策略下,对性能影响较大。

文件体积增长较快:随着写操作的增多,AOF文件会逐渐变大,尽管Redis提供了AOF重写功能(bgrewriteaof)来压缩文件,但仍然需要一定的存储空间。

恢复速度相对较慢:AOF文件在Redis重启时需要逐条执行命令来恢复数据,相比于直接加载RDB文件,恢复速度较慢。

四、性能管理

首先了解一下什么是内存碎片

(一)内存碎片

内存碎片(Memory Fragmentation)是指在计算机内存管理中,由于分配和回收内存空间而导致的无法连续使用的内存区域。内存碎片分为两类:

内部碎片(Internal Fragmentation): 当内存分配器为一个程序分配内存时,分配的内存块可能会大于程序实际需要的空间。例如,分配器可能按照固定大小或者页大小分配内存,即使请求的内存小于分配单位大小,也会分配一个完整的单位。这部分分配给程序但未被使用的内存空间就是内部碎片。内部碎片不可用于分配给其他程序,即使它在物理上是可用的。

外部碎片(External Fragmentation): 随着程序的运行和内存的分配与回收,内存中可能会形成许多小的、不连续的空闲区域,虽然这些区域的总和足以满足一个大的内存请求,但由于它们彼此不连续,所以不能被分配给需要大块连续内存空间的程序。这些无法合并使用的空闲区域构成了外部碎片。

内存碎片的存在会降低内存利用率,尤其是在连续内存分配策略中,严重的内存碎片可能导致即使还有足够的内存总量,也无法分配给新的请求,这在资源有限的系统中尤为不利。现代内存管理系统通常会采用各种策略来减少或避免内存碎片,如动态内存分配算法、分页系统和垃圾回收机制等。

(二)Redis内存碎片率

内存碎片率是衡量Redis内存利用率的一个关键指标,表示Redis在分配和回收内存过程中未使用的内存空间与已使用内存之间的比例。公式通常定义为 mem_fragmentation_ratio = used_memory_rss / used_memory,

其中

used_memory_rss 是Redis进程在操作系统层面所占用的实际物理内存大小。

used_memory 是Redis为了存储数据所分配的内存总量。

碎片率较高意味着Redis分配了大量的内存但并未完全有效利用,可能是由于Redis在分配内存时倾向于分配整块空间,当存储的数据大小变化时,原有的内存块未被完全填满,形成了碎片。长期的碎片积累可能导致Redis内存效率低下,甚至在达到最大内存限制(maxmemory 设置)时因内存不足引发 OOM 错误

跟踪内存碎片率对理解Redis实例的资源性能是非常重要的:
内存碎片率稍大于1是合理的,这个值表示内存碎片率比较低,也说明 Redis 没有发生内存交换

内存碎片率超过1.5,说明Redis消耗了实际需要物理内存的150%,其中50%是内存碎片率。需要在redis-cli工具上输入shutdown save 命令,让 Redis 数据库执行保存操作并关闭 Redis 服务,再重启服务器。

内存碎片率低于1的,说明Redis内存分配超出了物理内存,操作系统正在进行内存交换。需要增加可用物理内存或减少 Redis 内存占用。

(三)Redis内存使用率

内存使用率是指Redis已经使用的内存占总内存(或分配给Redis的最大内存)的比例。虽然Redis本身并不直接显示内存使用率这个百分比,但我们可以通过计算得出大致的使用情况。例如,如果你知道Redis实例的最大可用内存(即maxmemory设定值),则内存使用率可近似表示为 used_memory / maxmemory * 100%

可以使用 info memor命令查看内存使用情况

redis实例的内存使用率超过可用最大内存,操作系统将开始进行内存与swap空间交换

避免内存交换发生的方法:

针对缓存数据大小选择安装 Redis 实例

尽可能的使用Hash数据结构存储

设置key的过期时间

(四)Redis内部Key回收策略

为了管理内存资源并防止内存溢出,Redis提供了多种数据淘汰策略( eviction policies ),当内存达到maxmemory限制时,Redis会根据选择的策略自动删除部分Key以释放内存空间

开启key回收,取消配置文件(通常为/etc/redis/6379.conf)中598行的注释,开启key回收

volatile-lru:仅针对设置了过期时间(TTL)的Key,按照最近最少使用(LRU)算法剔除最久未访问的Key。

allkeys-lru:对所有Key均采用LRU算法剔除。

volatile-ttl:剔除即将过期的Key中,剩余生存时间(TTL)最短的Key。

noeviction:不主动删除任何Key,但在尝试写入新的数据时,如果内存已满,则拒绝执行会导致内存增长的命令。

volatile-random 和 allkeys-random:随机剔除具有过期时间或所有Key中的某个Key。

除了上述策略外,管理员还可以通过手动执行 DEL 或 KEYS 指令配合 UNLINK (非阻塞版本的删除指令)来删除特定Key,以减少内存占用。

总结

在生产环境中,redis是一个处理大批量数据的一个好帮手,与此同时,也需要注意数据的完整性,比如提取大批量的日志信息,可以使用redis

本章的重点内容

1.持久化

理解持久化的过程,需要熟练掌握持久化的操作过程,以及数据流向,可以很好的处理持久化的文件,保存数据,保证数据的完整性。

2.Key回收策略

了解key回收的策略,根据情况,选择不同的回收策略,释放内存空间,提高redis性能。

更多的详细解释,可以查看redis的官网进行查看

redis官方文档:Redis | The Real-time Data Platform

redis中文网:Redis中文网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/802569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实践笔记-linux内核版本升级(centos7)

linux内核版本升级 1.查看当前内核版本信息2.采用yum方式进行版本升级2.1导入仓库源2.2选择 ML 或 LT 版本安装2.3设置内核启动 3.删除旧版本内核 1.查看当前内核版本信息 #查看操作系统版本 cat /etc/redhat-release #查看系统内核 uname -r2.采用yum方式进行版本升级 2.1导…

白色磨砂质感html5页源码

白色磨砂质感html5页源码,简约的基础上加上了团队成员,自动打字特效音乐播放器存活时间 源码下载 https://www.qqmu.com/2980.html

vscode的源码插件GitHub Repositories

打铁还需自身硬,需要不断提升自我,提升自我的一种方式就是看源码,站在更高的维度去理解底层原理,以便以后更好的开发和解决问题,由于源码一个动不动就是几个G甚至十几个G,如果一个个源码下载下来&#xff0…

数字图像处理项目——基于BCNN和迁移学习的鸟类图像细粒度分类(论文/代码)

完整的论文代码见文章末尾 以下为核心内容 摘要 本文采用了ResNet50、VGG19、InceptionV3和Xception等四种不同的深度神经网络模型,并应用于鸟类图像的细粒度分类问题中,以探究其在该任务上的性能表现。 其中,本文使用了BCNN(B…

查分约束学习

问题模型&#xff1a; 有n个变量&#xff1a;&#xff0c;有m个约束条件 令差分数组&#xff0c;可以知道如果x1x2<q&#xff0c;那么与j和i-1有关联 由画图可知&#xff0c;如果有在i-1至j建立的有向图中跑最短路&#xff0c;那么dis[n]即为最小的约束变量 另外&#x…

Chrome浏览器如何跟踪新开标签的网络请求?

在测试一个东西的时候&#xff0c;它虽然是a链接&#xff0c;但是&#xff0c;是由前端在js里写跳转的。我又必须要知道它的跳转链接&#xff0c;只能用截屏的方式来捕捉浏览器的地址栏链接 打开浏览器控制台(F12)点击红色箭头打钩为弹出式窗口自动打开DevTools 英文版调试参…

华大单片机新建工程步骤

1.新建文件夹&#xff0c;比如00_LED 2.拷贝 hc32f460_ddl_Rev2.2.0\driver 到 00_LED 3.拷贝 hc32f460_ddl_Rev2.2.0\mcu\common 到 00_LED 4.拷贝 hc32f460_ddl_Rev2.2.0\example\ev_hc32f460_lqfp100_v2\gpio\gpio_output\source 到 00_LED 5.拷贝 hc32f460_ddl_Rev2.2.…

933.最近的请求次数

题目&#xff1a;写一个 RecentCounter 类来计算特定时间范围内最近的请求。 请你实现 RecentCounter 类&#xff1a; RecentCounter() 初始化计数器&#xff0c;请求数为 0 。int ping(int t) 在时间 t 添加一个新请求&#xff0c;其中 t 表示以毫秒为单位的某个时间&#x…

HarmonyOS 开发-使用SideBarContainer侧边栏淡入淡出动效实现案例

介绍 在2in1或平板上&#xff0c;群聊侧边栏是一种较为常用的功能&#xff0c;虽然HarmonyOS已经具备了基本的动效&#xff0c;但是部分情况下开发者可能有定制侧边栏动效的需求&#xff0c;本例主要介绍了如何基于显式动画实现侧边栏的淡入淡出动效。 效果图预览 使用说明&a…

​泛微文书定人事档案一体化管理,覆盖人事管理全过程,人事档案全量归档

人事档案是个人身份、学历、资历等方面的证据&#xff0c;与个人工资待遇、社会劳动保障、组织关系紧密挂钩&#xff0c;具有法律效力。应注重收集和鉴别、整理工作&#xff0c;提升人事档案利用率。 企业应依据国家有关人事档案管理规定&#xff0c;制定企业人事档案管理办法&…

【吊打面试官系列】Java高并发篇 - 什么是线程组,为什么在 Java 中不推荐使用?

大家好&#xff0c;我是锋哥。今天分享关于 【什么是线程组&#xff0c;为什么在 Java 中不推荐使用&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 什么是线程组&#xff0c;为什么在 Java 中不推荐使用&#xff1f; ThreadGroup 类&#xff0c;可以把线程归属…

领鸡蛋游戏养鸡游戏淘宝客源码广告联盟

用户中心 用户信息&#xff1a;显示用户名、头像、鸡蛋数量、足迹等基本信息。我的足迹&#xff1a;展示用户的饲料获取记录明细&#xff0c;包括来源、数量和时间。我的好友&#xff1a;展示邀请的好友列表&#xff0c;支持好友间互动&#xff0c;如串门、偷取/赠送饲料&#…

wait 和 notify

由于线程之间是抢占式执行的, 因此线程之间执行的先后顺序难以预知。但是实际开发中有时候我们可以通过一些 api 让线程主动阻塞&#xff0c;从而控制多个线程之间的执行先后顺序. 完成这些操作就需要用到 wait&#xff0c;notify / notifyAll 注意: wait, notify, notifyAll…

Google Play上架:2024年4月份政策更新改动

4月份政策更新改动 关于恶意软件新增伪装软件新增间谍软件关于移动垃圾软件详细定义关于不当内容暴力极端主义关于设备和网络滥用金融服务关于恶意软件 我们将更新恶意软件政策,阐明伪装软件是一种恶意软件。伪装软件是一种利用多种规避技术向用户提供不一致或虚假功能的应用…

如何让MacOS「终端」走代理

在 MacOS 操作系统中&#xff0c;默认情况下&#xff0c;终端命令行不会通过代理进行网络连接。这导致在应用软件研发过程中&#xff0c;许多需要通过命令行下载安装的软件或依赖包无法成功安装。经常出现Failed to connect to xxx port 443 after 75329 ms: Couldnt connect t…

html写一个登录注册页面

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>注册登录界面Ⅰ</title><link rel"stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.mi…

基于SpringBoot+vue的在线商城系统+论文+免费远程调试

基于SpringBootvue的在线商城系统034(含源码 数据库文档免费送&#xff09; 开发系统:Windows10 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springb…

苹果电脑(Mac)怎么清理 itunes 备份?

苹果电脑用户广泛利用 iTunes 应用程序对 iPhone 或 iPad进行定期备份&#xff0c;以确保珍贵的数据安全无虞。然而&#xff0c;随着备份历史的增长&#xff0c;它们会在磁盘上积累大量空间&#xff0c;尤其当您频繁为多台设备备份时&#xff0c;存储资源可能会迅速消耗殆尽。为…

第46期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

基于SpringBoot+Vue+Mysql的图书管理系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…