文章目录
Redis性能
一、Redis慢查询
1.1 记录慢查询
- 与mysql一样,当执行时间超过阈值,会将发生时间,耗时和命令记录下来;
- redis命令生命周期:发送->排队->执行->返回,慢查询只统计第3个执行步骤的时间;
1.2 阈值
设置: config set slowlog-log-slower-than 10000 //10 ms
查询: config get slowlog-log-slower-than 10000 //默认10 ms
(使用config set完后,若想将配置持久化保存到redis.conf,要执行config rewrite )
- 如果设置为0则会记录所有命令,-1则不记录任何命令
1.3 慢查询原理
- 慢查询记录也是存在队列里的,slow-max-len表示存放的记录最大条数,比如设置的slow-max-len=10,当有第11条慢查询命令插入时,队列的第一条命令就会出列,第11条入列到慢查询队列中,可config set动态设置,也可以修改
redis.conf完成配置(线上环境建议1000)
1.4 慢查询分析
- 获取慢查询命令:slowlog get
- 获取慢查询队列长度:slowlog len
- 清理慢查询队列:slowlog reset
- 生产环境建议10ms,并发高的建议1ms
- 慢查询是FIFO队列,建议定期保存到其他组件,如mysql
二、redis内存检测
2.1 检测内存使用量
//每秒输出内存使用量,输100次
redis-cli -r 100 -i 1 info |grep used_memory_human
2.2 redis-server详解
//检测操作系统能否提供1G内存给redis, 常用于测试,
//想快速占满机器内存做极端条件的测试,可使用这个指令
redis-server --test-memory 1024
三、并发测试
3.1 redis-benchmark详解
- redis-benchmark是并发测试工具
//100个并发连接,100000个请求,检测指定服务器性能
redis-benchmark -h x.x.x.x -p port -c 100 -n 100000
// 测试存取大小为100字节的数据包的性能
redis-benchmark -h x.x.x.x -p port -q -d 100
// 只测试 set,lpush操作的性能
redis-benchmark -t set,lpush -n 100000 -q
//只测试某些数值存取的性能
redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')"
PS:上述命令会输出每秒支持的请求个数,或者命令的时延,比如90%时延,95%时延,99%时延
四、Pipeline
4.1 Pipeline优点
-
使用Pipeline将一组命令批量发送,然后排队执行,不需要逐条发送,降低时延,节约带宽。客户端与服务端的网络延迟越大,性能体能越明显;
-
pipeline不是原子性的,只是把多个命令一起发送到服务端执行,最好不要太多命令否则数据量过大且容易阻塞
-
Pipleline和原生批量命令的区别(mset,mget)
Pipleline | 原生批量命令 |
---|---|
非原子 | 原子操作 |
客户端和服务端一起实现 | 服务端实现 |
其实是多个命令一次发送到服务端执行 | 是一个命令,一个命令中带多个key |
4.1 Pipeline使用建议
组装的命令不要过多,避免数据了太大,造成客户端等待过久,甚至网络阻塞
将大量命令组装成多个小的Pipeline执行
4.2 Pipeline使用示例
public class MyPipeline {
public static final String REDIS_HOST = "127.0.0.1";
public static final String REDIS_PASSWORD = "Intellifusion@20190108";
public static final int REDIS_PORT = 6379;
public static Jedis jedis = new Jedis(REDIS_HOST);
// static {
// jedis.auth(REDIS_PASSWORD);
// }
public static void main(String[] args) throws InterruptedException, IOException {
//1.获取一个Pipeline
Pipeline pipelined = jedis.pipelined();
//2.设置命令到Pipeline
pipelined.set("player1", "Duncan");
pipelined.set("player2", "James");
pipelined.set("player3", "Kobe");
pipelined.get("player1");
pipelined.get("player2");
pipelined.get("player3");
//3.执行并获取结果
List<Object> returnAll = pipelined.syncAndReturnAll();
for (Object result : returnAll) {
System.out.println(result);
}
}
}
输出(执行后对应的值被设置到redis中。):
OK
OK
OK
Duncan
James
Kobe