当前位置:   article > 正文

redis性能监控与调优

redis性能监控与调优

本篇不详写prometheus、grafana的搭建,需要可以翻阅linux监控篇
在这里插入图片描述

redis优势

  • 性能极高性能极高-Redis能读的速度是110000次/s,写的速度是81000次/s 。
  • 丰富的数据类型-Redis支持二进制案例的Strings, Lists, Hashes, Sets 及Ordered Sets 数据类型操作。
  • 原子-Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  • 丰富的特性- Redis还支持publish/subscribe,通知, key过期等等特性。

1、redis安装

#requirepass:redis密码
docker run --name redistest -p 6379:6379 -d redis --requirepass"02cabc11b36ef001"
  • 1
  • 2

2、redis压测

docker exec -it redistest bash
  • 1
#性能命令 10万次请求 并发50
redis-benchmark -n 100000 -q
  • 1
  • 2

在这里插入图片描述
常用的5种数据结构
在这里插入图片描述
客户端
在这里插入图片描述
命令行模式

#登录redis,-a 带密码
redis-cli -a 02afbc26a84dd058
  • 1
  • 2

在这里插入图片描述

3、线上监控 Prometheus+grafana

redis_exporter

  • Prometheus对redis进行数据采集,需要在redis所在服务安装redis_exporter
docker run -d --name redis_exporter -p 9121:9121 oliver006/redis_exporter --redis.addr redis://192.168.9.61:6379 --redis.password '02cabc11b36ef001'
  • 1
http://ip:9121/metrics
  • 1

Prometheus.yml配置文件:

- job_name: "redis"
scrape_interval: 5s
static_configs:
- targets: ['192.168.9.31:9121']
  • 1
  • 2
  • 3
  • 4

grafana:模板 763

https://grafana.com/grafana/dashboards/
在这里插入图片描述

设置最大内存

一般推荐Redis设置内存为最大物理内存的四分之三(不超过75%)

查看redis容器内存限制

dokcer stats redis
  • 1

在这里插入图片描述

查看、设置redis内存

 config get maxmemory
 config set maxmemory 2GB
  • 1
  • 2

在这里插入图片描述

4、redis慢查询

1、慢查询日志的两个配置项

1、slowlog-log-slower-than:Redis 慢查询日志的时间阈值,单位微妙,默认 10000 微秒( 10毫秒 )

config get slowlog-log-slower-than
  • 1

在这里插入图片描述
2、config get slowlog-max-len:慢查询日志长度,最小值为零。默认 128

config get slowlog-max-len
  • 1

在这里插入图片描述

参数修改

在这里插入图片描述

2、慢查询获取

#SLOWLOG GET N 命令来读取慢日志,查询最近的 N 条记录
slowlog get 10
  • 1
  • 2

5、redis.conf配置文件

挂载

docker run -v /usr/local/conf:/usr/local/etc/redis --name myredis redis redisserver /usr/local/etc/redis/redis.conf

配置项说明

Save :同步数据的RDB策略
在这里插入图片描述
在这里插入图片描述

6、Jmeter_redis

1、jmeter安装插件:Redis Data Set

在这里插入图片描述

2、配置元件

在这里插入图片描述

Beanshell

import redis.clients.jedis.Jedis;
import org.apache.commons.lang3.StringUtils;

String host = "${ip}"; //服务器地址
int port = ${port}; //端口号 不要加引号
String password = "02afbc26a84dd058"; //redis密码
int index = 0; //redis db 用的是哪个redis库
String key = "zhangsan"; //key值
Jedis jedis = new Jedis(host, port);
if(StringUtils.isNotBlank(password)){
  jedis.auth(password);
}
jedis.select(index);
String redisGetResult = jedis.get(key);
jedis.close();
vars.put("mytest",redisGetResult); //将key值保存为变量
# 缓存问题
## 1、缓存穿透
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2573387533f24b14bbfc2b0e4cf89284.png)
## 2、缓存雪崩
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/bdb3423198f049f6ae69be4402557adc.png)
## 3、缓存击穿
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3c25b61482424a85b537077785742b9c.png)
# redis命令行
## 1、redis-server: 用于启动Redis 的工具
```bash
docker run --name redistest -p 6379:6379 -d redis --requirepass "02afbc26a84dd058"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
docker run --privileged=true -v /usr/local/redisconfig:/usr/local/etc/redis -p 6379:6379 --name myredis -d redis redis-server /usr/local/etc/redis/redis.conf
  • 1

2、redis-benchmark: 用于检测Redis在本机的运行效率

#性能命令 10万次请求 并发50
redis-benchmark -n 100000 -q -a 02afbc26a84dd058
  • 1
  • 2

7、缓存问题

1、缓存穿透

在这里插入图片描述

2、缓存雪崩

在这里插入图片描述

3、缓存击穿

在这里插入图片描述

8、redis命令行

1、redis-server: 用于启动Redis 的工具

docker run --name redistest -p 6379:6379 -d redis --requirepass "02afbc26a84dd058"
  • 1
docker run --privileged=true -v /usr/local/redisconfig:/usr/local/etc/redis -p 6379:6379 --name myredis -d redis redis-server /usr/local/etc/redis/redis.conf
  • 1

2、redis-benchmark: 用于检测Redis在本机的运行效率

#性能命令 10万次请求 并发50
redis-benchmark -n 100000 -q -a 02afbc26a84dd058
  • 1
  • 2

3、redis-cli: Redis 命令行工具

redis-cli -a 02afbc26a84dd058
redis-cli -v
  • 1
  • 2

4、恢复测试

参考操作

#rdb和aof是redis服务中持久化功能的两种形式
redis-check-aof: 修复AOF持久化文件
redis-check-rdb: 修复RDB 持久化文件
  • 1
  • 2
  • 3

9、redis调优策略

#将外部的redis.conf挂载到内部路径,redis-server启动运行redis.conf
docker run --privileged=true -v /usr/local/redisconfig:/usr/local/etc/redis -p
6379:6379 --name myredis -d redis redis-server /usr/local/etc/redis/redis.conf
  • 1
  • 2
  • 3

redis服务端:

1、限制redis内存大小

  • 需要使用maxmemory来设置Redis的最大内存,例如 maxmemory 1GB
  • 在64位操作系统中,Redis的内存大小是没有限制的,因为maxmemory配置项是被注释掉的,这样就会导致在Redis内存不足时,Redis会使用磁盘作为其虚拟内存,而当操作系统将Redis所用的内存分配至磁盘时,将会阻塞Redis进程,到处Redis出现延迟,从而影响Redis的整体性能,因此我们要限制Redis的内存大小为一个固定的值,并且该值不能大于服务器的内存(75%)。当Redis的运行达到此值时会触发内部的淘汰策略,从而将内存回收。
#maxmemory设置
config get maxmemory
  • 1
  • 2

2、淘汰策略

Redis4.0之后有8种淘汰策略:
在这里插入图片描述
在redis.conf文件中设置maxmemory-policy项

3、内存碎片率问题

  • redis 释放的内存可能是不连续的。 这种不连续的内存可能不会再被使用,空闲但无法使用的就是内存碎片。
  • 内存碎片无法完全避免,只能降低碎片率。 redis 内存碎片虽然不会影响 redis
  • 性能,但是会增加内存消耗,当内存空间不够时候,会影响redis性能,或者不必要的内存浪费。
查看命令
info memory 
  • 1

在这里插入图片描述

Redis 相关参数
  • used_memory: Redis 已使用的内存大小,单位 Byte
  • used_memory_human: Redis 已使用的内存大小,单位 Mb
  • used_memory_rss:操作系统实际分配给 Redis 的物理内存空间,单位 Byte
  • used_memory_rss_human:操作系统实际分配给 Redis 的物理内存空间,单位 Mb
  • mem_fragmentation_ratio: Redis 当前的碎片率(减去 1 表示内存碎片比例)
  • mem_fragmentation_ratio: Redis 当前的碎片率(减去 1 表示内存碎片比例)

内存碎片率 = 已分配的内存 / 实际使用的内存
mem_fragmentation_ratio = used_memory_rss / used_memory

  • 1 < mem_fragmentation_ratio <= 1.5 经验值一般保持在 1~1.5 之间是最合理的

  • mem_fragmentation_ratio > 1.5 这表明内存碎片率已经超过了 50%。一般情况下,这个时候就应该采取一些措施来降低内存碎片率了

1、为避免内存碎片率过大的问题, Redis 4.0-RC3 版本开始支持自动整理 Redis 内存碎片

# 1、登录 Redis 集群
192.169.5.107:7001> config get activedefrag
1) "activedefrag"
2) "no"# 3、开启 Redis 自动内存碎片整理机制
192.169.5.107:7001> config set activedefrag yes
OK# 4、设置内存碎片清理所占用 CPU 时间的比例不高于 75%
192.169.5.107:7001> config set active-defrag-cycle-max 75
OK# 5、设置内存碎片清理所占用 CPU 时间的比例不低于 25%
192.169.5.107:7001> config set active-defrag-cycle-min 25
OK# 6、设置启动活动碎片整理的最小碎片百分比,内存碎片率大于 0.05 的时候开始清理
192.169.5.107:7001> config set active-defrag-threshold-lower 5
OK# 7、设置内存碎片超过 100%,尽最大清理
192.169.5.107:7001> config set active-defrag-threshold-upper 100
OK# 8、设置内存碎片的字节数达到256M时开始清
192.169.5.107:7001> config set active-defrag-ignore-bytes 268435456
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2、重启redis

4、优化耗时命令

我们可以使用slowlog功能,找出最耗时的Redis命令进行优化,以提升Redis的运行速度,慢查询有两个重要的配置项:

  • slowlog-log-slower-than:用于设置慢查询的评定时间,也就是说执行时间超过改时间的命
    令,将会被当成慢查询记录在日志中,它的执行时间是微秒
  • slowlog-max-len:用来配置慢查询日志的最大记录数

5、优化持久化策略

Redis的持久化策略有RDB(高,丢数据)AOF混合持久化方式(4.0之后新增),由于RDB和AOF各有利弊,RDB可能会造成一定的数据丢失,AOF由于文件较大,会影响Redis的启动速度,因此如果是Redis4.0及以上版本,可以直接使用混合持久化方式。

同样,如果在业务中,Redis不需要持久化数据库时,可以关闭持久化,这样可以有效地提升Redis的运行速度,不会出现间歇性卡顿的问题。

参考文章

redis客户端:(开发建议)

1、设置键值的过期时间

我们应该根据实际的业务情况,对键值对设置合理的过期时间,这样Redis会自动的清楚过期的键值对,从而达到节省内存占用的效果,可以避免键值对过多的堆积,频繁触发内存淘汰策略。

Redis有四个命令可以设置键的存活时间或过期时间:

  • expire:用于设置key还剩余多少秒过期
  • pexpire:用于设置key还有多少毫秒过期
  • expireat:用于设置key的过期时间(到期的具体秒数时间戳)
  • pexpireat:用于设置key的过期时间(到期的具体毫秒时间戳)
127.0.0.1:6388> set d1 va
OK
127.0.0.1:6388> set d2 va
OK
127.0.0.1:6388> set d3 va
OK
127.0.0.1:6388> set d4 va
OK
127.0.0.1:6388> expire d1 100
(integer) 1
127.0.0.1:6388> pexpire d2 100000
(integer) 1
127.0.0.1:6388> ttl d1
(integer) 83
127.0.0.1:6388> ttl d2
(integer) 91
127.0.0.1:6388> expireat d3 1612363856
(integer) 1
127.0.0.1:6388> ttl d3
(integer) 87127.0.0.1:6388> pexpireat d4 1612364096000
(integer) 1
127.0.0.1:6388> ttl d4
(integer) 112
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

2、禁用长耗时的查询命令

Redis绝大多数的读写命令的时间复杂度都是在O(1)到O(N)之间,其中O(1)就可以放心使用,但是O(N)就要当心了,因为N表示不确定性,数据越大,查询的速度就会越慢,因为Redis只用一个线程来做数据查询,如果这些指令非常耗时,就会造成Redis的阻塞,那么就会造成大量的延时。

要避免O(N)类的命令对Redis性能造成的影响,就要从以下几个方面进行改造:
1、禁止使用key * 命令;
2、避免一次查询所有成员,要使用 scan 命令进行分批的、游标式的遍历
3、通过机制严格空指Hset、Set、Scorted Set 等数据结构的大小
4、将排序、并集、交集等操作放在客户端执行,以减少Redis服务器的运行压力
5、删除一个大的数据时,可能会需要很长的时间,所以建议用异步删除的方式unlink,他会启动一个新的线程来删除目标数据,而不是阻塞Redis主线程。

3、避免大量数据同时失效

Redis过期Key的删除使用的是贪心策略,其会在一秒内进行10次扫描(该配置可以在redis.conf文件中配置,默认配置是 hz 10),redis会随机抽取20个key,删除这20个key中过期的key,如果过期的key比重超过25%,则重复执行该流程,直到比重低于25%为止。

那么如果在同一时期如果存在大量的key一起过期,就会导致Redis多次循环持续扫描删除过期key,直到被删除的数据足够多(redis的过期数据不再很密集,随机抽取低于25%),才会停止,在此过程中,由于循环和删除的原因,会导致Redis的独写出现明显的卡顿,卡顿的另一种原因是内存管理器需要频繁回收内存,因此也会消耗一定的CPU。

为了避免因为这种情况导致的卡顿现象,我们要预防大量的key在同一时刻一起过期,简单的解决方案就是在过期时间的基础上加一个指定范围的随机数。

4、使用 Pipeline 批量操作数据

Pipeline(管道技术)是客户端提供的一种批处理技术,用于一次处理多个Redis命令,从而提高整个交互的性能。

5、使用连接池

在客户端的使用上,我们尽量使用Pipeline技术外,还需要尽量使用Redis连接池,而不是频繁的创建、销毁Redis连接,这样就可以减少网络传输次数和减少非必要的调用命令。

#服务器默认1w够用
CONFIG GET maxclients
  • 1
  • 2

6、缓存命中率问题

参考文章

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/514198
推荐阅读
相关标签
  

闽ICP备14008679号