Redis精要

一、什么是缓存击穿、缓存穿透、缓存雪崩?

缓存穿透 【针对大量非法访问的请求,缓存中没有,直接访问DB】

缓存穿透指的查询缓存和数据库中都不存在的数据,这样每次请求直接打到数据库,就好像缓存不存在 一样。 对于系统A,假设一秒 5000 个请求,结果其中 4000 个请求是黑客发出的恶意攻击。 黑客发出的那 4000 个攻击,缓存中查不到,每次你去数据库里查,也查不到。 举个栗子。 数据库 id 是从 1 开始的,结果黑客发过来的请求 id 全部都是负数。 这样的话,缓存中不会有,请求每次都“绕过缓存”,直接查询数据库。 这种恶意攻击场景的缓存穿透就会直接把数据库给打死。

缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。 缓存穿透可能会使后端存储负载加大,如果发现大量存储层空命中,可能就是出现了缓存穿透问题。 缓存穿透可能有两种原因:

1. 自身业务代码问题 2. 恶意攻击,爬虫造成空命中。

缓存穿透解决办法:

①对空值缓存:如果一个查询数据为空(不管数据是否存在),都对该空结果进行缓存,其过期时间会 设置非常短。

②采用布隆过滤器:布隆过滤器可以判断元素是否存在集合中,他的优点是空间效率和查询时间都比一 般算法快,缺点是有一定的误识别率和删除困难。

③设置可以访问名单:使用bitmaps类型定义一个可以访问名单,名单id作为bitmaps的偏移量,每次 访问时与bitmaps中的id进行比较,如果访问id不在bitmaps中,则进行拦截,不给其访问。

④进行实时监控:对于redis缓存中命中率急速下降时,迅速排查访问对象和访问数据,将其设置为黑名单。

缓存空值/默认值 一种方式是在数据库不命中之后,把一个空对象或者默认值保存到缓存,之后再访问这个数据,就会从 缓存中获取,这样就保护了数据库。

缓存空值有两大问题: 1. 空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间(如果是攻击,问题更严 重),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除。 2. 缓存层和存储层的数据会有一段时间窗口的不一致,可能会对业务有一定影响。例如过期时间设置 为5分钟,如果此时存储层添加了这个数据,那此段时间就会出现缓存层和存储层数据的不一致。 这时候可以利用消息队列或者其它异步方式清理缓存中的空对象。

布隆过滤器 除了缓存空对象,我们还可以在存储和缓存之前,加一个布隆过滤器,做一层过滤。 布隆过滤器里会保存数据是否存在,如果判断数据不不能再,就不会访问存储。

缓存击穿【针对极少数并发量很高的key,缓存过期了,直接请求DB】

一个并发访问量比较大的key在某个时间过期,导致所有的请求直接打在DB上。 具体来是,就是说某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况, 当这个 key 在失效的瞬间,大量的请求就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一 个洞。 结果是: 请求会直接访问数据库,并回设到缓存中,高并发访问数据库会导致数据库崩溃。

缓存击穿解决方案: 

(1)预先设置热门数据: 在redis高峰访问时期,提前设置热门数据到缓存中,或适当延长缓存中key过期时间。

(2)实时调整: 实时监控哪些数据热门,实时调整key过期时间。

(3)对于热点key设置永不过期。

(4)加锁更新 ⽐如请求查询A,发现缓存中没有,对A这个key加锁,同时去数据库查询数据,写⼊缓存,再返回给⽤ 户,这样后⾯的请求就可以从缓存中拿到数据了。

缓存雪崩【针对大面积缓存同时间段失效,大面积同时访问DB】

某⼀时刻发⽣⼤规模的缓存失效的情况,例如缓存服务宕机、大量key在同一时间过期,这样的后果就 是⼤量的请求进来直接打到DB上,db无响应,最后可能导致整个系统的崩溃,称为雪崩。 对于系统 A,假设每天高峰期每秒 5000 个请求,本来缓存在高峰期可以扛住每秒 4000 个请求, 但是缓存机器意外发生了: 缓存全盘宕机,缓存挂了, 大量key在同一时间过期 此时 1 秒 5000 个请求全部落数据库,数据库必然扛不住,它会报一下警,然后db无响应,最后导致整 个系统的崩溃。 此时,如果没有采用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被 新的流量给打死了。

缓存雪崩解决方案:

缓存雪崩是三大缓存问题里最严重的一种,我们来看看怎么预防和处理。

提高缓存可用性

      1. 集群部署:通过集群来提升缓存的可用性,可以利用Redis本身的Redis Cluster或者第三方集群方 案如Codis等。

      2. 多级缓存:设置多级缓存,设置一级缓存本地 guava 缓存,第一级缓存失效的基础上再访问二级 缓存 redis,每一级缓存的失效时间都不同。

过期时间

      1. 均匀过期:为了避免大量的缓存在同一时间过期,可以把不同的 key 过期时间随机生成,避免过 期时间太过集中。

      2. 热点数据永不过期。

熔断降级 1. 服务熔断:当缓存服务器宕机或超时响应时,为了防止整个系统出现雪崩,可以使用hystrix 类似 的熔断,暂时停止业务服务访问db, 或者其他被依赖的服务,避免 MySQL 被打死。 2. 服务降级:当出现大量缓存失效,而且处在高并发高负荷的情况下,在业务系统内部暂时舍弃对一 些非核心的接口和数据的请求,而直接返回一个提前准备好的 fallback(退路)错误处理信息。

RedisCluster

Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。 Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。

RedisCluster介绍:

自动将数据进行分片,每个 master 上放一部分数据 提供内置的高可用支持,部分 master 不可用时,还是可以继续工作的 .

在 Redis cluster 架构下,每个 Redis 要放开两个端口号,比如一个是 6379,另外一个就是 加1w 的端 口号,比如 16379。 16379 端口号是用来进行节点间通信的,也就是 cluster bus 的东西,cluster bus 的通信,用来进行故 障检测、配置更新、故障转移授权。cluster bus 用了另外一种二进制的协议, gossip 协议,用于节 点间进行高效的数据交换,占用更少的网络带宽和处理时间。

redis在3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储 不同的数据。 cluster模式为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受 限于单机,可受益于分布式集群高扩展性。 RedisCluster 是 Redis 的亲儿子,它是 Redis 作者自己提供的 Redis 集群化方案。 相对于 Codis 的不同,它是去中心化的,如图所示,该集群有三个 Redis 节点组成, 每个节点负责整 个集群的一部分数据,每个节点负责的数据多少可能不一样。这三个节点相 互连接组成一个对等的集 群,它们之间通过一种特殊的二进制协议相互交互集群信息

如上图,官方推荐,集群部署至少要 3 台以上的master节点,最好使用 3 主 3 从六个节点的模式。 Redis Cluster 将所有数据划分为 16384 的 slots,它比 Codis 的 1024 个槽划分得更为精细,每个节点 负责其中一部分槽位。槽位的信息存储于每个节点中,它不像 Codis,它不 需要另外的分布式存储来存 储节点槽位信息。 Redis Cluster是一种服务器Sharding技术(分片和路由都是在服务端实现),采用多主多从,每一个分区 都是由一个Redis主机和多个从机组成,片区和片区之间是相互平行的。 Redis Cluster集群采用了P2P的模式,完全去中心化。

三主三从的RedisCluster集群

Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。 集群的每个节点负责一部分hash槽,如图中slots所示。 为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模 型,每个节点都会有1-n个从节点。 例如master-A节点不可用了,集群便会选举slave-A节点作为新的主节点继续服务。

集群创建

Redis集群一般由多个节点组成,节点数量至少为6个才能保证组成完整高可用的集群。 每个节点需要开启配置cluster-enabled yes,让Redis运行在集群模式下。 建议为集群内所有节点统一目录,一般划分三个目录:conf、data、log,分别存放配置、数据和日志 相关文件。 把6个节点配置统一放在conf目录下,集群相关配置如下:

# 节点端口
port 6379
# 开启集群模式
cluster-enabled yes
# 节点超时时间,单位毫秒
cluster-node-timeout 15000
# 集群内部配置文件
cluster-config-file "nodes-6379.conf"

集群模式的Redis除了原有的配置文件之外又加了一份集群配置文件。 当集群内节点信息发生变化,如添加节点、节点下线、故障转移等。 第一次启动时如果没有集群配置文件,它会自动创建一份,文件名称采用cluster-config-file参数项控 制,建议采用node-{port}.conf格式定义,通过使用端口号区分不同节点,防止同一机器下多个节点彼 此覆盖,造成集群信息异常。 如果启动时存在集群配置文件,节点会使用配置文件内容初始化集群信息。启动过程如图所示。

节点握手 Redis集群一般由多个节点组成,节点数量至少为6个才能保证组成完整高可用的集群。 节点握手是指一批运行在集群模式下的节点通过Gossip协议彼此通信,达到感知对方的过程。 节点握手是集群彼此通信的第一步,由客户端发起命令:cluster meet{ip}{port},如图所示。

 图中执行的命令是:cluster meet127.0.0.16380让节点6379和6380节点进行握手通信。cluster meet 命令是一个异步命令,执行之后立刻返回。内部发起与目标节点进行握手通信,如图所示。 1)节点6379本地创建6380节点信息对象,并发送meet消息。 2)节点6380接受到meet消息后,保存6379节点信息并回复pong消息。 3)之后节点6379和6380彼此定期通过ping/pong消息进行正常的节点通信。 这里的meet、ping、pong消息是Gossip协议通信的载体,之后的节点通信部分做进一步介绍,它的主 要作用是节点彼此交换状态数据信息。6379和6380节点通过meet命令彼此建立通信之后,集群结构如 图所示。对节点6379和6380分别执行cluster nodes命令,可以看到它们彼此已经感知到对方的存在。

分配槽(slot) Redis集群把所有的数据映射到16384个槽中。 每个节点对应若干个槽,只有当节点分配了槽,才能响应和这些槽关联的键命令。通过 cluster addslots命令为节点分配槽。

虚拟槽分片的映射步骤:

1.把16384槽按照节点数量进行平均分配,由节点进行管理

2.对每个key按照CRC16规则进行hash运算

3.把hash结果对16383进行取余

4.把余数发送给Redis节点

5.节点接收到数据,验证是否在自己管理的槽编号的范围 如果在自己管理的槽编号范围内,则把数据保存到数据槽中,然后返回执行结果 如果在自己管理的槽编号范围外,则会把数据发送给正确的节点,由正确的节点来把数据保存在对 应的槽中。

虚拟槽分布方式中,由于每个节点管理一部分数据槽,数据保存到数据槽中。 当节点扩容或者缩容时,对数据槽进行重新分配迁移即可,数据不会丢失。

虚拟槽分片特点: 虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数 集合中,整数定义为槽(slot)。槽是集群内数据管理和迁移的基本单位。 槽的范围一般远远大于节点数,比如Redis Cluster槽范围是0~16383。 采用大范围槽的主要目的是为了方便数据拆分和集群扩展,每个节点会负责一定数量的槽。 Redis虚拟槽分区的优点: 解耦数据和节点之间的关系,简化了节点扩容和收缩难度。 节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据。 支持节点、槽、键之间的映射查询,用于数据路由,在线伸缩等场景。 无论数据规模大,还是小,Redis虚拟槽分区各个节点的负载,都会比较均衡 。而一致性哈希在大 批量的数据场景下负载更加均衡,但是在数据规模小的场景下,会出现单位时间内某个节点完全空 闲的情况出现。

Redis集群提供了灵活的节点扩容和收缩方案,可以在不影响集群对外服务的情况下,为集群添加节点 进行扩容也可以下线部分节点进行缩容。

其实,集群扩容和缩容的关键点,就在于槽和节点的对应关系,扩容和缩容就是将一部分 槽 和 数据 迁 移给新节点。 例如下面一个集群,每个节点对应若干个槽,每个槽对应一定的数据,如果希望加入1个节点希望实现 集群扩容时,需要通过相关命令把一部分槽和内容迁移给新节点。

缩容也是类似,先把槽和数据迁移到其它节点,再把对应的节点下线。 

集群节点间通信:

集群通信原理

集群元数据的维护有两种方式:集中式、Gossip 协议。Redis cluster 节点间采用 gossip 协议进行通 信。 集中式是将集群元数据(节点信息、故障等等)几种存储在某个节点上。集中式元数据集中存储的一个 典型代表,就是大数据领域的 storm 。它是分布式的大数据实时计算引擎,是集中式的元数据存储的 结构,底层基于 zookeeper(分布式协调的中间件)对所有元数据进行存储维护。

Redis 维护集群元数据采用另一个方式, gossip 协议,所有节点都持有一份元数据,不同的节点如果 出现了元数据的变更,就不断将元数据发送给其它的节点,让其它节点也进行元数据的变更。

Redis 维护集群元数据采用另一个方式, gossip 协议,所有节点都持有一份元数据,不同的节点如果 出现了元数据的变更,就不断将元数据发送给其它的节点,让其它节点也进行元数据的变更。

集中式:

好处在于,元数据的读取和更新,时效性非常好,一旦元数据出现了变更,就立即更新到集中 式的存储中,其它节点读取的时候就可以感知到;不好在于,所有的元数据的更新压力全部集中在一个 地方,可能会导致元数据的存储有压力。

gossip去中心化:

好处在于,元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续打到所有节点上 去更新,降低了压力;不好在于,元数据的更新有延时,可能导致集群中的一些操作会有一些滞后。 10000 端口:每个节点都有一个专门用于节点间通信的端口,就是自己提供服务的端口号 +10000,比如 7001,那么用于节点间通信的就是 17001 端口。每个节点每隔一段时间都会往另 外几个节点发送 ping 消息,同时其它几个节点接收到 ping 之后返回 pong 。 交换的信息:信息包括故障信息,节点的增加和删除,hash slot 信息等等。

gossip协议:

gossip 协议包含多种消息,包含 ping , pong , meet , fail 等等。 meet:某个节点发送 meet 给新加入的节点,让新节点加入集群中,然后新节点就会开始与其它 节点进行通信。

其实内部就是发送了一个 gossip meet 消息给新加入的节点,通知那个节点去加入我们的集群。 ping:每个节点都会频繁给其它节点发送 ping,其中包含自己的状态还有自己维护的集群元数 据,互相通过 ping 交换元数据。

pong:返回 ping 和 meeet,包含自己的状态和其它信息,也用于信息广播和更新。

fail:某个节点判断另一个节点 fail 之后,就发送 fail 给其它节点,通知其它节点说,某个节点宕机啦。

ping信息原理:

ping 消息深入 ping 时要携带一些元数据,如果很频繁,可能会加重网络负担。 每个节点每秒会执行 10 次 ping,每次会选择 5 个最久没有通信的其它节点。当然如果发现某个节点通 信延时达到了 cluster_node_timeout / 2 ,那么立即发送 ping,避免数据交换延时过长,落后的时 间太长了。比如说,两个节点之间都 10 分钟没有交换数据了,那么整个集群处于严重的元数据不一致 的情况,就会有问题。所以 cluster_node_timeout 可以调节,如果调得比较大,那么会降低 ping 的频率。 每次 ping,会带上自己节点的信息,还有就是带上 1/10 其它节点的信息,发送出去,进行交换。至少 包含 3 个其它节点的信息,最多包含 总节点数减 2 个其它节点的信息。

三、Redis内存

Redis 内存不足有这么几种处理方式:

修改配置文件 redis.conf 的 maxmemory 参数,增加 Redis 可用内存 也可以通过命令set maxmemory动态设置内存上限. 

修改内存淘汰策略,及时释放内存空间. 

使用 Redis 集群模式,进行横向扩容,扩容节点数目.

四、Redis大Key问题

BigKey产生的背景

1、redis数据结构使用不恰当 将Redis用在并不适合其能力的场景,造成Key的value过大,如使用String类型的Key存放大体积二进制 文件型数据。

2、未及时清理垃圾数据 没有对无效数据进行定期清理,造成如HASH类型Key中的成员持续不断的增加。即一直往value塞数 据,却没有删除机制,value只会越来越大。

3、对业务预估不准确 业务上线前规划设计考虑不足没有对Key中的成员进行合理的拆分,造成个别Key中的成员数量过多。

Redis使用过程中,有时候会出现大key的情况

单个简单的key存储的value很大,size超过10KB

hash, set,zset,list 中存储过多的元素(以万为单位)

Big Key定义

Big Key就是某个key对应的value很大,占用的redis空间很大,本质上是大value问 题。 key往往是程序可以自行设置的,value往往不受程序控制,因此可能导致value很大。 redis中这些Big Key对应的value值很大,在序列化/反序列化过程中花费的时间很大,因此当我们操作 Big Key时,通常比较耗时,这就可能导致redis发生阻塞,从而降低redis性能。 BigKey指以Key的大小和Key中成员的数量来综合判定,用几个实际的例子对大Key的特征进行描述: Key本身的数据量过大:一个String类型的Key,它的值为5MB Key中的成员数过多:一个ZSET类型的Key,它的成员数量为10000个 Key中成员的数据量过大:一个Hash类型的Key,它的成员数量虽然只有1000个但这些成员的 Value值总大小为100MB。

大key会造成什么问题呢?

1、阻塞请求 Big Key对应的value较大,我们对其进行读写的时候,需要耗费较长的时间,这样就可能阻塞后续的请 求处理。Redis的核心线程是单线程,单线程中请求任务的处理是串行的,前面的任务完不成,后面的 任务就处理不了。

2、内存增大 读取Big Key耗费的内存比正常Key会有所增大,如果不断变大,可能会引发OOM(内存溢出),或达 到redis的最大内存maxmemory设置值引发写阻塞或重要Key被逐出。

3、阻塞网络 读取单value较大时会占用服务器网卡较多带宽,自身变慢的同时可能会影响该服务器上的其他Redis实 例或者应用。

4、影响主从同步、主从切换 删除一个大Key造成主库较长时间的阻塞并引发同步中断或主从切换。

解决Big Key问题

无非就是减小key对应的value值的大小,也就是对于String数据结构的话,减少存 储的字符串的长度;对于List、Hash、Set、ZSet数据结构则是减少集合中元素的个数。

1、对大Key进行拆分 将一个Big Key拆分为多个key-value这样的小Key,并确保每个key的成员数量或者大小在合理范围内, 然后再进行存储,通过get不同的key或者使用mget批量获取。

2、对大Key进行清理 对Redis中的大Key进行清理,从Redis中删除此类数据。 Redis自4.0起提供了UNLINK命令,该命令能够以非阻塞的方式缓慢逐步的清理传入的Key, 通过UNLINK,你可以安全的删除大Key甚至特大Key。

3、监控Redis的内存、网络带宽、超时等指标 通过监控系统并设置合理的Redis内存报警阈值来提醒我们此时可能有大Key正在产生,如:Redis内存 使用率超过70%,Redis内存1小时内增长率超过20%等。

4、定期清理失效数据 如果某个Key有业务不断以增量方式写入大量的数据,并且忽略了其时效性,这样会导致大量的失效数 据堆积。 可以通过定时任务的方式,对失效数据进行清理。

5、压缩value 使用序列化、压缩算法将key的大小控制在合理范围内,但是需要注意序列化、反序列化都会带来一定 的消耗。 如果压缩后,value还是很大,那么可以进一步对key进行拆分。

如何查找BigKey

Redis4.0 及以上版本提供了--Bigkeys, --hotkeys 命令,可以分析出实例中每种数据结构的 top 1 的 Bigkey,同时给出了每种数据类型的键值个数以及平均大小。

查看bigkey:redis-cli -a 登录密码 --bigkeys

查看hotkey:redis-cli -a 登录密码 --hotkeys

通过公司自研或者云平台查找Key.

五、Redis缓存预热

所谓缓存预热,就是提前把数据库里的数据刷到缓存里,通常有这些方法:

1、直接写个缓存刷新页面或者接口,上线时手动操作

2、数据量不大,可以在项目启动的时候自动进行加载

3、定时任务刷新缓存.

六、Redis过期数据如何删除

Redis主要有2种过期数据回收策略:

惰性删除 惰性删除指的是当我们查询key的时候才对key进⾏检测,如果已经达到过期时间,则删除。显然,他有 ⼀个缺点就是如果这些过期的key没有被访问,那么他就⼀直⽆法被删除,⽽且⼀直占⽤内存。

定期删除 定期删除指的是Redis每隔⼀段时间对数据库做⼀次检查,删除⾥⾯的过期key。由于不可能对所有key 去做轮询来删除,所以Redis会每次随机取⼀些key去做检查和删除。 

七、Redis内存淘汰策略

当 Redis 内存使用达到最大内存限制时,如果继续进行写入操作会导致 Redis 服务崩溃。因此,为了保证 Redis 服务的稳定性,Redis 在内存使用达到最大限制时采取一系列措施,如内存淘汰、警告等。

Redis 内存淘汰策略主要有如下:

(1)noeviction
不执行任何的淘汰策略,直接返回错误信息。这种方式可能导致内存使用过多而导致 Redis 崩溃。

(2)allkeys-lru
从所有的键中选取最近最少使用的数据淘汰。这种方式通常可以保留热点数据,但是可能会出现内存碎片,导致内存浪费。

(3)allkeys-lfu
从所有的键中选取访问频率最少的数据进行淘汰。这种方式适用于处理访问分布相对均匀的数据。

(4)volatile-lru
只从设定了过期时间(ttl)的键中选取最近最少使用的数据淘汰。这种方式适用于缓存等使用场景。

(5)volatile-lfu
只从设定了过期时间(ttl)的键中选取访问频率最少的数据进行淘汰。

(6)volatile-ttl
只从设定了过期时间(ttl)的键中选取即将过期的数据进行淘汰。这种方式适用于缓存等使用场景。

样例设置参数

maxmemory 2gb
maxmemory-policy allkeys-lru

可以从系统的容忍度、缓存数据的重要性、内存的使用状况。

各种淘汰策略简单说明如下:

1 noeviction(默认):不淘汰任何key,内存满时不写入新的key。
2 volatile-ttl:对设置了TTL的key,比较key的剩余TTL值,值越小越先被淘汰
3 allkeys-random:对所有key进行随机淘汰
4 volatile-random:对设置了TTL的key进行随机淘汰
5 allkeys-lru:对所有key基于LRU算法进行淘汰
6 volatile-lru:对设置了TTL的key基于LRU算法进行淘汰
7 allkeys-lfu:对全体key给予LFRU算法进行淘汰
8 volatile-lfu:对设置了TTL的key基于LFU算法进行淘汰

注:
TTL( time to live):键值对的过期时间
LRU(Least Recently Used):最近最少使用,用当前时间剪去最后一次访问时间,值越大越先被删除,
例:key1在3s前访问,key2在5s前访问,那么是删除的时key2
LFU(Least Frequently Used):最少频率使用,统计每个key的访问频率,值越小越先被删除
例:key1在5s内访问了5次,key2在5s内访问了10次,key1被删除

八、Redis的内存碎片

Redis 内存碎片产生比较常见的 2 个原因:

1、Redis 存储数据的时候向操作系统申请的内存空间可能会大于数据实际需要的存储空间

2、频繁修改 Redis 中的数据也会产生内存碎片。

当 Redis 中的某个数据删除时,Redis 通常不会轻易释放内存给操作系统。

另外,Redis 可以使用多种内存分配器来分配内存( libc、jemalloc、tcmalloc),默认使用 jemalloc[1],而 jemalloc 按照一系列固定的大小(8 字节、16 字节、32 字节……)来分配内存的。jemalloc 划分的内存单元如下图所示:

                        

当程序申请的内存最接近某个固定值时,jemalloc 会给它分配相应大小的空间,就比如说程序需要申请 17 字节的内存,jemalloc 会直接给它分配 32 字节的内存,这样会导致有 15 字节内存的浪费。不过,jemalloc 专门针对内存碎片问题做了优化,一般不会存在过度碎片化的问题。

3、如何查看内存碎片

使用info memory命令

Redis 内存碎片率的计算公式:mem_fragmentation_ratio (内存碎片率)= used_memory_rss (操作系统实际分配给 Redis 的物理内存空间大小)/ used_memory(Redis 内存分配器为了存储数据实际申请使用的内存空间大小)

也就是说,mem_fragmentation_ratio (内存碎片率)的值越大代表内存碎片率越严重。

一定不要误认为used_memory_rss 减去 used_memory值就是内存碎片的大小!!!这不仅包括内存碎片,还包括其他进程开销,以及共享库、堆栈等的开销。

通常情况下,我们认为 mem_fragmentation_ratio > 1.5 的话才需要清理内存碎片。mem_fragmentation_ratio > 1.5 意味着你使用 Redis 存储实际大小 2G 的数据需要使用大于 3G 的内存。

直接通过 config set 命令将 activedefrag 配置项设置为 yes 即可

config set activedefrag yes

具体什么时候清理需要通过下面两个参数控制:

# 内存碎片占用空间达到 500mb 的时候开始清理
config set active-defrag-ignore-bytes 500mb
# 内存碎片率大于 1.5 的时候开始清理
config set active-defrag-threshold-lower 50

通过 Redis 自动内存碎片清理机制可能会对 Redis 的性能产生影响,我们可以通过下面两个参数来减少对 Redis 性能的影响:

# 内存碎片清理所占用 CPU 时间的比例不低于 20%
config set active-defrag-cycle-min 20
# 内存碎片清理所占用 CPU 时间的比例不高于 50%
config set active-defrag-cycle-max 50

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

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

相关文章

JVM-GC-常用调优命令和GC参数

定位问题常用命令 top:查看内存/CPU占用情况top -Hp pid: 查看进程内线程情况jsp:查看java进程情况jstack 线程pid:查看进程内线程信息,一般查看线程状态,判断是否死锁。重点观察:WAITING、BLOCKED的线程,另外查看wait…

全面的WAS存储权限管理方案,了解一下

WAS存储权限管理通常指的是对Windows Azure Storage(WAS)的存储设备进行权限控制和管理。在企业中,随着数据量的飞速增长,对存储设备的安全性、效率和成本的关注也日益增加。有效的WAS存储权限管理可以确保数据的安全性&#xff0…

UV胶带和UV胶水的应用场景有哪些不同吗?

UV胶带和UV胶水的应用场景有哪些不同吗? UV胶带和UV胶水的应用场景确实存在不同之处,以下是详细的比较和归纳: 一:按使用场景来看: UV胶带的应用场景: 包装行业:UV胶带在包装行业中常用于食品包装、药…

深圳比创达电子|EMC与EMI一站式解决方案:源头到终端的全面防护

随着电子技术的飞速发展,电磁兼容性(EMC)和电磁干扰(EMI)问题日益成为产品研发和生产的关键因素。为了帮助企业更好地应对这些挑战。 一、EMC与EMI的基本概述 电磁兼容性(EMC)是指设备或系统在…

【Linux】ss 命令使用详解

目录 一、ss命令介绍 二、ss命令格式和使用 1、命令格式 2、ss命令的常用选项 3、命令的常见用法 3.1 找出打开套接字/端口应用程序 3.2 检查系统的监听套接字 3.3 显示所有状态为established的SMTP连接 3.4 查看建立的 TCP 连接 3.5 通过 -r 选项解析 IP 和端口号 …

12通道温振信号采集卡

12 通道智能数据采集器,以下简称 SG-Vib-S12。 SG-Vib-S12 旨在帮助用户对工业生产中的设备健康状况进行监测与诊断, 降低因设备故障对生产过程产生的影响。SG-Vib-S12 输入同时兼容 IEP、ICP 两 线制、三线制(振温一体)传感器&…

【html】如何利用hbuilderX 开发一个自己的app并安装在手机上运行

引言: 相信大家都非常想开发一款自己的apk,手机应用程序,今天就教大家,如何用hbuilderX 开发一个自己的app并安装在手机上运行。 步骤讲解: 打开hbuilderX ,选择新建项目 2.选择5app,想一个名字&#x…

js三元图的画法

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>三元图</title></head> <body>&l…

爬虫超详细介绍

爬虫&#xff08;Spider&#xff09;是一种自动化程序&#xff0c;用于在互联网上获取信息。 其工作原理主要可以分为以下几个步骤&#xff1a; 发起请求&#xff1a; 爬虫首先需要向目标网站发起HTTP请求&#xff0c;以获取网页的内容。这个请求可以包含一些额外的信息&…

使用 Java 构建和消费 RESTful 服务的基本方法

REST&#xff08;Representational State Transfer&#xff09;是一种架构风格&#xff0c;它基于Web标准和HTTP协议&#xff0c;常用于构建网络服务。使用Java构建和消费RESTful服务需要掌握一些基本概念和技术。 一、RESTful服务的基本概念 1. REST架构风格 REST架构风格的…

NGINX_二十 nginx 监控

二十 nginx 监控 1 nginx的基础监控 进程监控端口监控 注意&#xff1a; 这两个是必须要加在zabbix监控&#xff0c;加触发器有问题及时告警。 web 服务器 nginx 以其高性能与抗并发能力越来越多的被用户使用 作为一款服务器产品&#xff0c;其运行状态是运维密切关注的&a…

【机器学习 复习】第3章 K-近邻算法

一、概念 1.K-近邻算法&#xff1a;也叫KNN 分类 算法&#xff0c;其中的N是 邻近邻居NearestNeighbor的首字母。 &#xff08;1&#xff09;其中K是特征值&#xff0c;就是选择离某个预测的值&#xff08;例如预测的是苹果&#xff0c;就找个苹果&#xff09;最近的几个值&am…

项目六 OpenStack虚拟机实例管理

任务一 理解OpenStack计算服务 1.1 •什么是Nova • Nova是OpenStack中的计算服务项目 &#xff0c;计算虚拟机实例生命周期的所有活动都由 Nova 管理 。 • Nova 提供统一的计算资源 服务。 • Nova 需要下列 OpenStack 服务的 支持。 Keystone &#xff1a;为所有的 OpenSt…

单商户社区团购卖菜卖水果商城自提点商城系统小程序源码

打造便捷团购新体验 &#x1f34e; 引言&#xff1a;社区团购的崛起 近年来&#xff0c;社区团购以其独特的优势&#xff0c;迅速崛起并受到广大消费者的喜爱。它不仅能够提供物美价廉的商品&#xff0c;还能让居民们享受到更加便捷的购物体验。而单商户社区团购系统小程序&am…

详解 HBase 的架构和基本原理

一、基本架构 StoreFile&#xff1a;保存实际数据的物理文件&#xff0c;StoreFile 以 HFile 的格式 (KV) 存储在 HDFS 上。每个 Store 会有一个或多个 StoreFile&#xff08;HFile&#xff09;&#xff0c;数据在每个 StoreFile 中都是有序的MemStore&#xff1a;写缓存&#…

【YOLOv5/v7改进系列】引入特征融合网络——ASFYOLO

一、导言 ASF-YOLO结合空间和尺度特征以实现精确且快速的细胞实例分割。在YOLO分割框架的基础上&#xff0c;通过引入尺度序列特征融合(SSFF)模块来增强网络的多尺度信息提取能力&#xff0c;并利用三重特征编码器(TFE)模块融合不同尺度的特征图以增加细节信息。此外&#xff…

信息打点web篇----web后端源码专项收集

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 专栏描述&#xff1a;因为第一遍过信息收集的时候&#xff0c;没怎么把收集做回事 导致后来在实战中&#xff0c;遭遇资产获取少&#xff0c;可渗透点少的痛苦&#xff0c;如今决定 从头来过&#xff0c;全面全方位…

手把手教你实现条纹结构光三维重建(3)——相机投影仪标定

我们都知道&#xff0c;投影仪其实就是个反向相机&#xff0c;如果我们了解双目标定的原理&#xff0c;那么相机和投影仪的标定就不难&#xff0c;关键是我们怎么得到投影仪在图像特征点&#xff08;比如棋盘格角点&#xff09;上的像素位置。 投影仪也类似于一个cmos&#xf…

WebSocket实现消息实时通知

参考文档&#xff1a;万字长文&#xff0c;一篇吃透WebSocket&#xff1a;概念、原理、易错常识、动手实践、WebSocket 教程 1 背景 有一个需求&#xff0c;需要实现实时通信的功能&#xff0c;如果有新消息&#xff0c;后端会主动发送请求告知前端有新消息&#xff0c;需要前…

Matlab基础语法:变量和数据类型,基本运算,矩阵和向量,常用函数,脚本文件

目录 一、变量和数据类型 二、基本运算 三、矩阵和向量 四、常用函数 五、脚本文件 六、总结 一、变量和数据类型 Matlab 支持多种数据类型&#xff0c;包括数值类型、字符类型和逻辑类型。掌握这些基本的变量和数据类型&#xff0c;是我们进行数学建模和计算的基础。 数…