一、Redis运行原理
redis服务器对命令的处理都是单线程的,但是I/O层面却面向多个客户端并发地提供服务,并发到内部单线程的转化通过多路复用框架来实现。redis命令从发送到执行经理以下四个过程
- 发送命令
- 命令排队
- 命令执行
- 结果返回
二、redis执行协议
对redis请求进行抓包,查看抓包内容
1、执行抓包命令
2、查看抓包内容
redis协议位于TCP层之上,即客户端和redis实例保持双工的连接,交互的都是序列化后的协议数据
RESP协议
Redis 服务器与客户端通过RESP(REdis Serialization Protocol)协议通信。
RESP 底层采用的是TCP 的连接方式,通过tcp 进行数据传输,然后根据解析规则解析相应信息,完成交互。
我们可以测试下,首先运行一个serverSocket 监听6379,来接收redis 客户端的请求信息。实现如下
1、建立socket连接监听6379端口,用于接收请求并输出
/** * /** * <p>模拟redis</p> * * @author DK * @version V1.0 */ public class SimulatedRedis { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(6379); Socket rec = server.accept(); byte[] result = new byte[2048]; rec.getInputStream().read(result); System.out.println(new String(result)); } }
2、使用jedis客户度端请求本地6379端口
/** * /** * <p>模拟redis</p> * * @author DK * @version V1.0 */ public class SimulatedRedisClient { public static void main(String[] args) throws IOException { Jedis jedis = new Jedis("127.0.0.1", 6379); jedis.set("user:2", "9999"); jedis.close(); } }
打印输出
发现和抓包内容一致
每个字段标示含义为:
*3 表示有几组数据
$ 3 表示set长度为3
Set 命令
$6 表示key长度为6
User:2 key
$1 表示value长度为1
2 value
主要以下特点:从上述实例中发现,redis使用resp协议的好处为容易实现,解析快,人类可读,并且传输在TCP层,可以减少不必要的信息传输
模拟resp协议进行redis写入
/** * /** * <p>模拟redis</p> * * @author DK * @version V1.0 */ public class RespRedis { public static void main(String[] args) { SocketAddress addr = new InetSocketAddress("10.1.253.188", 6379); Socket sk = new Socket(); try { sk.connect(addr); OutputStream out = sk.getOutputStream(); StringBuffer sb = new StringBuffer(); sb.append("*3\r\n"); sb.append("$3\r\n"); sb.append("SET\r\n"); sb.append("$6\r\n"); sb.append("user:0\r\n"); sb.append("$5\r\n"); sb.append("11111\r\n"); System.out.println(sb.toString()); byte[] b = sb.toString().getBytes(); out.write(b); out.flush(); } catch (IOException e) { e.printStackTrace(); } } }
三、redis性能测试
Redis慢查询分析
mysql一样:当执行时间超过极大值时,会将发生时间 耗时 命令记录
redis命令生命周期:发送 排队 执行 返回,慢查询只统计第3个执行步骤的时间
Redis慢查询极值设置
一般有两种方式,默认时间为10ms
1、命令方式
config set slowlog-log-slower-than 10000 //10毫秒
使用config set完后,若想将配置持久化保存到redis.conf,要执行config rewrite
2、配置文件修改
redis.conf修改:找到slowlog-log-slower-than 10000 ,修改保存即可
注意:slowlog-log-slower-than =0记录所有命令 -1命令都不记录
慢查询原理
慢查询记录也是存在队列里的,slow-max-len 存放的记录最大条数,
比如设置的slow-max-len=10,当有第11条慢查询命令插入时,队列的第一条命令
就会出列,第11条入列到慢查询队列中, 可以config set动态设置,
也可以修改redis.conf完成配置
慢查询命令
获取队列里慢查询的命令:slowlog get
获取慢查询列表当前的长度:slowlog len //以上只有1条慢查询,返回1;
1),对慢查询列表清理(重置):slowlog reset //再查slowlog len 此时返回0 清空;
2),对于线上slow-max-len配置的建议:线上可加大slow-max-len的值,记录慢查询存长命令时redis会做截断,不会占用大量内存,线上可设置1000以上
3),对于线上slowlog-log-slower-than配置的建议:默认为10毫秒,根据redis并发量来调整,对于高并发比建议为1毫秒
4),慢查询是先进先出的队列,访问日志记录出列丢失,需定期执行slowlog get,将结果存储到其它设备中(如mysql)
1、redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 10000
100个并发连接,10000个请求,检测服务器性能