2019独角兽企业重金招聘Python工程师标准>>>

问题描述

在基于 packetbeat 分析 redis 协议时发现,在某些情况下,基于 request-response 关联出的 transaction 信息是错误的,示例如下:

responsetime(947201 microseconds) ==>    No.<1>
----
{"@timestamp":"2016-12-29T07:21:24.657Z","beat":{"hostname":"xg-mesos-39","name":"xg-mesos-39","version":"6.0.0-alpha1"},"bytes_in":14,"bytes_out":40,"client_ip":"10.0.242.43","client_port":7125,"client_proc":"","client_server":"","ip":"10.0.246.114","method":"PING","port":48877,"proc":"","query":"PING","redis":{"return_value":"[REPLCONF, ACK, 5372098]"},"resource":"","responsetime":947201,"server":"","status":"OK","type":"redis"}

从上述信息可以明显看出,当前 transaction 中关联的 request 为 PING 命令,response 为 [REPLCONF, ACK, 5372098] 命令;

注意:因为 transaction 的构建是基于 TCP 连接的,因此不会出现将不同 TCP 连接上的请求应答错乱匹配的问题;

问题原因

上面错误在于,将 PING[REPLCONF, ACK, 5372098] 进行了关联,而这两者明显不是对应关系;

通过梳理 Redis 协议相关资料可以知道:

  • PING 的使用

    1. [客户端-服务器] 使用客户端向 Redis 服务器发送一个 PING ,如果服务器运作正常的话,会返回一个 PONG 。通常用于测试与服务器的连接是否仍然生效,或者用于测量延迟值;

    2. [Sentinel] 在默认情况下,Sentinel 会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其他 Sentinel 在内)发送 PING 命令,并通过实例返回的 PING 命令回复(有效回复为 +PONG/-LOADING/-MASTERDOWN)来判断实例是否在线(主观下线状态检测);

    3. [主从复制] 当从服务器成为主服务器的客户端后,做的第一件事就是向主服务器发送一个 PING 命令;两个作用:a) 检查套接字的读写状态是否正常;b) 检查主服务器能否正常处理命令请求;只有从服务器在规定时间内读取到主服务器返回的 PONG 才算成功;

    4. [主从复制] Slaves 以预定义的周期向 server 发送 PING;该周期通过 repl_ping_slave_period 选项进行配置,默认为 10 秒; The original replication protocol was vulnerable to network/Internet outages where the master detects the outage and closes the connection, but the slave does not. The slave thinks the connection is still open and the master simply has no updates to send (low traffic or no traffic). So the slave never disconnects and re-connects to restart the replication. I know this very well. I have some v2.0.x Redis instances that replicate across 3,000 miles and once or twice a month this problem occurs. Adding PING to the replication protocol solved that. The slave now detects the connection problem when the PING replies stop coming from the master. The slave can close its end of the connection and re-connect again.

    5. [集群] 集群里的每个节点默认每隔一秒钟就会从已知节点列表中随机选出五个节点,然后对这五个节点中最长时间没有发送过 PING 消息的节点发送 PING 消息,以此来检测被选中的节点是否在线;除此之外,如果节点 A 最后一次收到节点 B 发送的 PONG 消息的时间,距离当前时间已经超过了节点 A 的 cluster-node-timeout 选项设置时长的一半,那么节点 A 也会向节点 B 发送 PING 消息,这可以防止节点 A 因为长时间没有随机选中节点 B 作为 PING 消息的发送对象,而导致对节点 B 的信息更新滞后;

  • [REPLCONF, ACK, <replication_offset>] 的使用

    在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送该命令;该命令的作用为:a) 检测主从服务器的网络连接状态;b) 辅助实现 min-slaves 选项;c) 检测命令丢失;

具体抓包数据如下

*3
$8
REPLCONF
$3
ACK
$11
81234009046
*3
$8
REPLCONF
$3
ACK
$11
81234009046
*3
$8
REPLCONF
$3
ACK
$11
81234009046
*3
$8
REPLCONF
$3
ACK
$11
81234009046
*3
$8
REPLCONF
$3
ACK
$11
81234009046
*3
$8
REPLCONF
$3
ACK
$11
81234009046
*3
$8
REPLCONF
$3
ACK
$11
81234009046
*3
$8
REPLCONF
$3
ACK
$11
81234009046
*3
$8
REPLCONF
$3
ACK
$11
81234009046
*1
$4
PING
*3
$8
REPLCONF
$3
ACK
$11
81234009060

可以看到,在一个 10s 的抓包周期中,出现了 10 个 [REPLCONF, ACK, xxxx] 和 1 个 PING ;可以确定,该 PING 为基于 repl_ping_slave_period 选项的保活 PING ;

解决办法

可以确认的是,出现 [REPLCONF, ACK, xxx] 命令的连接一定是 master 和 slave 进行通信的连接;因此,一种简单的解决办法就是针对该命令进行过滤,从而避免 transaction 的构建中出现 [REPLCONF, ACK, xxx],但这种方式可能会导致统计数据输出时,多出一些 unmatched 的内容;一种高级的解决办法就是在检测出该命令后,直接将该命令属于的 TCP 流彻底剔除;

转载于:https://my.oschina.net/moooofly/blog/849634

【原创】packetbeat 之“request-response 错误关联”问题相关推荐

  1. 【错误记录】Android Studio 配置 GitHub 报错 ( Can‘t login using given credentials: Request response: 401 Una )

    文章目录 一.报错信息 二.解决方案 一.报错信息 使用账号密码配置 , 出现如下错误 ; Can't login using given credentials: Request response: ...

  2. 3.request response

    rr的介绍 request是代表请求,response是响应 执行流程: 1.浏览器发送请求 2.服务器接受请求,创建两个对象,将请求信息封装给request,将两个对象发送给对应的servlet 3 ...

  3. request.getRequestDispatcher().forward(request,response)和response.sendRedirect()的区别

    在进行web开发时,跳转是最常见的,今天在这里来学习下2种跳转: 第一种是request.getRequestDispatcher().forward(request,response): 1.属于转 ...

  4. JavaWeb - Request Response

    Request & Response 1,Request和Response的概述 为什么运行项目后默认打开index.html - 是因为 tomcat 配置文件中事先配好了 ==Reques ...

  5. chain.doFilter(request,response)详解

    过滤器的生命周期一般都要经过下面三个阶段: 初始化 当容器第一次加载该过滤器时,init() 方法将被调用.该类在这个方法中包含了一个指向 Filter Config 对象的引用. 过滤 过滤器的大多 ...

  6. Filter若不写chain.doFilter(request,response)原Servlet路径代码不会被执行

    为什么80%的码农都做不了架构师?>>>    Filter如果不写chain.dofilter(request,response) 那么对应的Servlet URL 是不会执行的. ...

  7. 【Servlet】Request/Response/Cookie/Session中常用方法

    #1.Request package com.tcb.servlet;import java.io.IOException; import javax.servlet.ServletException ...

  8. Request 对象 错误 'ASP 0104 : 80004005' 解决方法

    在windows server 2003下携带多个附件或者较大的附件进行发送时系统报错: Request 对象 错误 'ASP 0104 : 80004005' 不允许操作 /inc/config.a ...

  9. request,response传入线程值会变为null

    request,response传入Thread线程值会变为null Exception in thread "Thread-21" java.lang.NullPointerEx ...

  10. chain.doFilter(request,response)含义

    过滤器的生命周期一般都要经过下面三个阶段: 初始化 当容器第一次加载该过滤器时,init() 方法将被调用.该类在这个方法中包含了一个指向 Filter Config 对象的引用.我们的过滤器实际上并 ...

最新文章

  1. matlab反馈模型,—倒立摆状态反馈系统的建模及matlab仿真.docx
  2. [Java,MVC] Eclipse下搭建Spring MVC
  3. [补档]暑假集训D5总结
  4. Jenkins+maven(testng)项目(本地项目配置)
  5. 近些年CPU的性能是不是快到天花板了?
  6. 【安卓笔记】—— 页面导航 Navigation(2)
  7. ojdbc6报红以及nested exception is org.hibernate.service.spi.ServiceException: 已解决
  8. 2021爱分析·智慧城市厂商全景报告
  9. 突破运营商 QoS 封锁,WireGuard 真有“一套”!
  10. Vue高频面试问题(含答案),面试官直呼好家伙~
  11. #使用SAS进行变量筛选、模型诊断、多元线性回归分析 #
  12. 微信网页扫码登录的实现(两种方式)
  13. 常州abb机器人编程_最新ABB机器人编程程序解析
  14. 【软件定义汽车】【场景篇】AR-HUD
  15. Linux内核中的Watchdog
  16. Python | 凸多边形间重叠面积计算
  17. 用水泥混凝土摊铺机进行作业时该做到的日常养护工作
  18. OpenGL ES for Android 绘制旋转的地球
  19. 【C语言进阶】带你深度剖析那些常见的字符函数(一)
  20. 微信公众号官方文档入口

热门文章

  1. IDEA配置git环境
  2. Linux 文件属性和权限详解
  3. fork练习、从进程角度考虑堆区内存申请与释放的有关问题
  4. php签名墙代码,我们是一家人(签名墙)
  5. 介绍Android 与 GPhone的书籍
  6. # # # 正则
  7. CodeForces 940E
  8. 找新朋友(欧拉函数)
  9. destoon代码从头到尾捋一遍
  10. 九度oj 题目1537:买卖股票