使用Wireshark分析Redis通信 - 图1

说明

  1. 对于Wireshark的使用我这里不会阐述,具体可以google一下;
  2. 本章内容会对redis的set, mset 请求进行分析;

    实战

    1. SET

    1. set("set_key","set_value");
    2. set("set_key2","set_value2");
    观察抓取的数据,如下:
    使用Wireshark分析Redis通信 - 图2
  • 红框区域:SYNTCP三次握手建立连接的;
  • 黄框区域:PSH是发送数据,ACK是响应;
  • 绿色区域:FIN表示关闭连接;

我们这里只分析发送数据(即黄框区域的数据);
上面的set命令请求了两次,我们可以想象一下这个过程: 客户端发送数据 -> 服务端 (PSH)服务端收到数据,发送回执 -> 客户端 (ACK)服务端发送数据 -> 客户端 (PSH)客户端收到数据,发送回执 -> 服务端 (ACK) 是不是这样呢,我们看下抓取的数据
使用Wireshark分析Redis通信 - 图3
看起来是像我们上面说的那样,但怎么下面还有一遍这个步骤(下面还有PSH和ACK),我们可以先看下发送的数据是什么样的
使用Wireshark分析Redis通信 - 图4使用Wireshark分析Redis通信 - 图5
从上图中可以看到,客户端请求了两次(即发送了两次数据),服务端也响应了两次(即也是发送了两次数据),所以上面的 1,2,3,4步骤会有两遍,我们再观察一下发送的数据格式: *3 表示3个参数$3 第一个参数的长度SET 第一个参数的值 (要执行的Command = set)$7 第二个参数的长度set_key 第二个参数的值 (key)$9 第三个参数的长度set_value 第三个参数的值 (value)+OK 执行结果 那你如果还不敢肯定,咱们继续看
使用Wireshark分析Redis通信 - 图6使用Wireshark分析Redis通信 - 图7
从图中可以确认我们上面说的就是对的。

2. MSET

mset相比于set而言可以一次发送多个key,value(即一次发送多个命令),我们再抓取数据看一下
使用Wireshark分析Redis通信 - 图8
根据上面说的,我们可以发现客户端确实只发送了一次请求,服务端也发送了一下(响应数据),具体的请求内容如下:
使用Wireshark分析Redis通信 - 图9
由此可以说明 mset比多次set减少了请求,缩短了时间。
如果想看其他命令是怎么通信的,可以照此方法抓取一下数据就一目了然了。
补充:
我通过Wireshark 分析了Redis pipeline命令,发现客户端Jedis和Lettuce是不一样的(spring data redisTemplate 底层是使用的Lettuce)。
区别:
Jedis 使用pipeline,客户端发送多个命令时会放到客户端缓冲区(此时并没有真实发送),最后发送一个请求(包含多个命令)给服务端,服务端是逐条执行命令,然后统一把每条执行结果放到一个Response中返回给客户端;
Lettuce 使用pipeline发送命令,因为底层是使用Netty,每条命令执行时,直接异步发送(并非是合并所有命令一起发送)。

过滤TCP连接与[SYN], [SYN, ACK],[FIN]

  1. (tcp.flags==0x12) and not tcp.analysis.initial_rtt
  2. (tcp.port==6379 or tcp.port==6380) &&(tcp.flags.fin==1)

tcp.flags=0x12“查找 SYN/ACK 数据包(您也可以使用”tcp.flags.syn==1 or (tcp.flags.syn==1 and tcp.flags.ack==1)“,或者,如果您想要 SYNSYN/ACK,则使用”tcp.flags.syn==1 or (tcp.flags.syn==1 and tcp.flags.ack==1)“。
诀窍是使用”not tcp.analysis.initial_rtt“,因为这将检查 Wireshark 是否计算了对话的初始往返时间 - 只有握手完成后,它才会这样做。因此,如果缺少字段,并且看到 SYN/ACK,则有半打开连接(假设 SYN 存在)。请注意,筛选器没有检查实际的 iRTT 值,它将与双相等的操作员(例如”tcp.analysis.initial_rtt==0.12345“)进行检查,但如果该字段存在的话。
image.png

原文链接

https://zhuanlan.zhihu.com/p/145932152