集群组件异常重试机制
集群组件异常重试机制¶
MPP数据库处理用户请求的过程¶
在一个MPP数据库中,参与数据查询的数据库组件包括Coordinator和Executor。在包含多个Coordinator和多个Executor的集群环境下,用户的数据库操作请求的执行过程大致如下:
-
在执行DDL语句时,接收用户请求的Coordinator节点负责权限和语法检查,之后把DDL语句分发给其他的Coordinator和Executor,待所有Coordinator和Executor都执行完该DDL后,返回给接收用户请求的Coordinator,该Coordinator返回最终结果给客户端。Coordinator与其他Coordinator、Coordinator与Executor执行通过指令传输通道进行通信。
-
在执行查询语句时,接收用户请求的Coordinator节点负责协调查询计划、元数据管理和查询优化,而Executor节点负责存储数据和执行查询操作。这些节点之间需要进行通信以协调其工作。如下是执行查询语句时Coordinator与Executor之间通信的一般流程:
- 初始化阶段:在启动时,Coordinator节点会加载元数据信息,包括数据库的结构、表信息、分布式数据布局等。
- 查询计划分发:当一个查询被提交到MPP时,Coordinator节点会根据查询优化器生成一个查询计划。然后,Coordinator会将查询计划分解成适合分段节点处理的片段,并将这些片段分发到相应的Executor节点。
- 并行执行:每个Executor节点独立地执行其分配的查询片段。这可能涉及扫描本地存储的数据、执行计算等操作。Executor节点之间可能需要通过网络进行数据交换,以支持并行执行。
- 数据交换:在执行查询过程中,如果某些操作需要从一个Executor节点获取另一个Executor节点上的数据,数据交换就会发生。这可能涉及到将数据通过网络传输从一个Executor节点发送到另一个Executor节点。
- 结果汇总:在Executor节点完成其分配的操作后,结果会被发送回Coordinator节点,以便在Coordinator节点上进行汇总和组合。
- 查询完成和结果返回:一旦Coordinator节点接收到所有Executor节点的结果,并对其进行汇总和组合,它将生成最终的查询结果并将其返回给客户端。
执行查询的过程中,Coordinator节点与Executor节点之间的通信主要通过网络协议实现,包括指令通信(包括查询计划分发)和数据通信。
下面两个图,是Coordinator与Executor之间的指令通信和数据通信示意图:
通过语句重试机制消除组件异常对用户请求的影响¶
用户的请求需要多个Coordinator和Executor参与,如果组件间的网络互联发生异常,或者个别组件宕机,或者运维需要降级主节点提升备节点等,都会造成用户请求的执行失败。语句重试机制在用户直接连接的Coordinator内实现。当这个Coordinator在与其他组件交互时,发现其他组件异常,不立刻报错给用户,而是内部尝试重新执行用户的请求。通过重试,如果其他组件在重试的窗口期内恢复了正常,则视为用户请求执行成功,返回用户正常执行的结果。
语句重试机制是由用户直接连接的Coordinator发起的,当它检查到有其他组件发生了可以重试的错误时,会进行语句重试。这个检查组件错误的时间点主要有如下几个:
- Coordinator与其他Coordinator或Executor建立连接来分发指令或分发执行计划时,如果与其他Coordinator或Executor建立连接失败,会重试建立连接的操作。
- Coordinator发送两阶段事务提交命令给其他Coordinator或Executor时发生错误,会重新发送该两阶段命令。
- Coordinator在等待其他Coordinator或Executor执行结束,而其他的Coordinator或Executor返回了执行异常的错误信息,导致当前语句执行失败。如果这个执行异常的错误信息是由于互联的网络错误引起的;或者是其他的Coordinator与Executor收到了shutdown信号引起的;或者其他的Coordinator或Executor上有其它进程宕机引起的。则会触发重试。
对于最后一种情况,如果当前执行出错的语句是没有开启事务的单条查询,则重试时只会重新执行本条语句。如果当前执行出错的语句在一个事务内,则重试时会先中止当前的事务,并从事务的开始语句开始执行,直到重试完之前出错的语句,把结果返回给用户,然后等待用户的进一步输入。执行重试时,发起重试的Coordinator会重新建立与其他Coordinator和Executor的连接。重试前创建的临时表在新建立的连接上是不存在的,所以如果重试语句访问之前的临时表,会报错该临时表不存在。
如果Coordinator在重试最后一种错误,ps -aux
查看其seaboxsql的后端进程,会有RETRY
字样进行提示。例如RETRY SELECT
即在重试一个SELECT语句。
语句重试机制涉及的控制参数¶
如下的GUC参考控制重试机制的行为:
- sc_execute_error_retry_count
- 可重试错误发生后,最大的重试次数,每次重试之间会有10秒钟的时间间隔。
-
默认值5, 有效值[0, 65536]
-
sc_gang_creation_retry_count
- Coordinator与其他Coordinator和Executor建立连接时报错,重试的次数
-
默认值20,有效值[0, 128]
-
dtx_phase2_retry_second
- 两阶段事务提交阶段出错时重试的时间,单位为秒
-
默认值600, 有效值[0, INT_MAX]
-
max_retry_cached_entries
- 如果开启了事务,事务内每条语句都会缓存到重试语句的列表中,这个参数控制这个重试列表的长度
- 默认值102400, 有效值[1, 1024000]
另外,对于进行节点替换等操作的场景,希望长时间进行重试,不再受上面的重试次数的限制,可以通过utility模式连上coordinator执行 select sc_force_retry_ic_error(true);
来设置强制重试而不计次数。这个函数执行后对所有现有的连接都会立刻生效。当节点替换操作执行完,通过utility模式连接Coordinator,执行 select sc_force_retry_ic_error(false);
来退出强制重试的模式。