前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[Stream Load 超时问题排查1] - 源码排查定位- timeout by txn manager

[Stream Load 超时问题排查1] - 源码排查定位- timeout by txn manager

作者头像
小伟
发布2022-07-24 09:37:08
1K0
发布2022-07-24 09:37:08
举报
文章被收录于专栏:魔都程序缘魔都程序缘

问题现象

doris 现象: timeout by txn manager

nginx现象

代码语言:javascript
复制
<html>
<head><title>504 Gateway Time-out</title></head>
<body bgcolor="white">
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx</center>
</body>
</html>

问题分层怀疑、定位

在分层定位问题前需要先知道Doris的整体部署结构, 方便定位问题. 部署结构如下:

由错误信息可以做如下猜测:

  1. nginx本身在请求超时时间是60s, 小于doris本身的超时时间
  2. doris本身的超时时间是60s
  3. 用户指定了超时时间是60s
  4. Load Blance (LB)本身超时时间是60s

通过排查,

  • 首先否定4. 原因: “timeout by txn manager”是doris任务执行时间太长被主动结束了. 和LB没关系
  • 其次check nginx各种超时配置后, 否定1
  • check doris配置后, 否定2, 默认是Config.stream_load_default_timeout_second, 应该为300s

具体朝3的方向分析

问题分析

  1. 查看Doris Stream Load报错详情后, 可以看到Prepare Time和Finish Time相差60s
  2. 翻看Doris源码, 确认 “timeout by txn manager”报错位置: 源码位置. 确认是Doris会定时检查哪些导入事物超时了, 超时后主动停止该任务. 通过翻看DatabaseTransactionMgr.java代码,最后可以知道是TransactionState.java中timeout参数控制超时时间.默认是Config.stream_load_default_timeout_second, 该配置默认300秒. 但是本次超时是60秒, 说明timeout参数沟通TransactionState.java的构造函数被重置了.
  3. 确认isTimeout数来源: 查找TransactionState构造函数的依赖关系, 可以找到如下代码截图: 按照标号顺序看:

说明: FrontendServiceImpl.java是fe提供的RPC服务接口. 提供库、表、事物等的基本操作服务.

到这里貌似就知道地方RPC请求了loadTxnBegin()方法, 什么地方调用的不清楚. 是broker ? be ? 猜测是be

回头再看看stream load在Fe中的处理过程.

stream load我们知道是http请求, 从源码包中我们查到到如下代码

翻看代码, 通古注册的url可以知道stream load是LoadAction.java这个类处理的. 请求是如何被转到这里处理的, 下回再分解.

代码语言:javascript
复制
 public static void registerAction(ActionController controller) throws IllegalArgException {
        ExecuteEnv execEnv = ExecuteEnv.getInstance();
        LoadAction action = new LoadAction(controller, execEnv);
        controller.registerHandler(HttpMethod.PUT,
                                   "/api/{" + DB_KEY + "}/{" + TABLE_KEY + "}/_load", action);

        controller.registerHandler(HttpMethod.PUT,
                                   "/api/{" + DB_KEY + "}/{" + TABLE_KEY + "}/_stream_load",
                                   new LoadAction(controller, execEnv, true));
    }
代码语言:javascript
复制

executeWithoutPassword()这个方法是当有stream load请求到fe时, 请求会被转发到这个方法处理, 代码核心如下:

代码语言:javascript
复制
TNetworkAddress redirectAddr;
if (!isStreamLoad && !Strings.isNullOrEmpty(request.getSingleParameter(SUB_LABEL_NAME_PARAM))) {
    ...
} else {
    ...
    redirectAddr = new TNetworkAddress(backend.getHost(), backend.getHttpPort());
}

LOG.info("redirect load action to destination={}, stream: {}, db: {}, tbl: {}, label: {}",
        redirectAddr.toString(), isStreamLoad, dbName, tableName, label);
redirectTo(request, response, redirectAddr);


这个核心代码逻辑比较简单, fe会把stream load的请求redirect到一个be节点处理, 这个be节点称为Coordinator节点. 这个be节点会负责和fe通信生成导入执行计划, 处理导入事物等. 下面我们再细说.

那我们看看be是如何处理fe转发过来的stream load请求的.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 魔都程序缘 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题现象
  • nginx现象
  • 问题分层怀疑、定位
  • 问题分析
  • 回头再看看stream load在Fe中的处理过程.
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档