[Doris核心原理] -- FE启动过程原理分析3 -- 初始化Catalog

170人浏览 / 0人评论

本文承接上一篇[Doris核心原理] -- FE启动过程原理分析2 -- 启动类PaloFe.java.
从上一篇中, 我们了解了Doris Fe启动类的运行过程, 本篇主要讲解Doris Fe启动时是如何初始化Catalog.java这个类的.
Catalog.java是Doris Fe的一个核心类, 主要负责以下功能(包括但不限于)

  • 元数据初始化、管理等
  • Load任务管理、清理等
  • Export任务管理、清理等
  • 事物清理
  • Editlog重放管理
  • Fe角色变更管理
  • 回收站任务管理
  • broker管理器
  • 资源管理器
  • 授权管理
  • 分桶数据统计管理
  • 动态分区任务管理

启动类PaloFe.java是通过调用下面的代码进行初始化的.

// init catalog and wait it be ready
Catalog.getCurrentCatalog().initialize(args);
Catalog.getCurrentCatalog().waitForReady();

接下来, 我们主要讲解Catalog.getCurrentCatalog().initialize(args)的初始化过程.

  1. 初始化配置的元数据目录信息. 元数据目录需要事先创建, 如果不创建启动会报错, 然后进程退出. bdb目录、image目录如果不存在则会创建.

    • 元数据目录, 默认是$DORIS_HOME/doris-meta
    • bdb数据目录. 默认是$DORIS_HOME/doris-meta/bdb
    • image目录. image是doris定时将bdb数据全部打包做成一个image保存, 以便在Fe之间同步元数据和Fe自身元数据恢复使用. 默认目录$DORIS_HOME/doris-meta/image
  2. 处理当前Fe启动时的host、port, 启动时设置的helper节点地址

  3. 初始化插件管理器

    • 初始化插件目录, 不存在则会自动创建
    • 初始化Doris自带的插件, 目前自动审计日志插件, 会将全部的sql语句记录在审计日志中. 插件可以自己实现, 然后通过命令安装, 安装文档: 插件安装文档
  4. 初始化审计日志处理器. 审计日志处理器实在AuditEventProcessor.java中实现的, 代码结构如下:

    public class AuditEventProcessor {
        private static final Logger LOG = LogManager.getLogger(AuditEventProcessor.class);
        private static final long UPDATE_PLUGIN_INTERVAL_MS = 60 * 1000; // 1min
        private PluginMgr pluginMgr;
        private List<Plugin> auditPlugins;
        private long lastUpdateTime = 0;
        private BlockingQueue<AuditEvent> eventQueue = Queues.newLinkedBlockingDeque(10000);
        private Thread workerThread;
    
        private volatile boolean isStopped = false;
    
        public AuditEventProcessor(PluginMgr pluginMgr) {
        }
    
        public void start() {
        }
    
        public void stop() {
        }
    
        public void handleAuditEvent(AuditEvent auditEvent) {  
        }
    
        public class Worker implements Runnable {
        }
      }
    

    下面我们介绍这段代码中的核心字段和方法.

    • UPDATE_PLUGIN_INTERVAL_MS, 定时更新插件的周期, 默认是1min. 因为有可能Doris在运行时安装和卸载插件, 所以需要定时更新
    • pluginMgr, 插件管理器, 这个类中实现了插件的安装、卸载等
    • auditPlugins, 当前扫描后全部的插件
    • eventQueue, 如果有新的查询, jdbc协议层会调用handleAuditEvent将审计事件传递过来, 保存在这个队列中
    • workerThread, 审计日志分发线程, 负责将eventQueue中的审计事件分发给全部的审计插件处理
    • Worker类, 这个类实现了Runnable接口, 是workerThread线程运行的对象, 插件扫描、分发都在这里执行. 具体代码可自行参考源码, 这里不列出.
  5. 初始化当前Fe的角色、版本. 实现方式是: getClusterIdAndRole().

    • 处理角色文件, 角色文件中保存了当前这个节点是什么角色, 目前角色只有两种: follower和observer.
    • 处理版本文件, 版本文件中保存了当前节点归属的集群id、集群token 这里会根据角色文件、版本文件关系决定是否从helper节点中拉取image数据. 也就是新启动了一个follower的非master节点, 此时需要从master同步image信息, image中包含了全部的元数据信息. 这个方法个人感觉代码结构比较混乱, 有待apache孵化优化.
  6. 初始化editLog, 并加载image和回放editLog日志. 代码如下:

    this.editLog = new EditLog(nodeName);
    loadImage(this.imageDir); // load image file
    editLog.open(); // open bdb env
    this.globalTransactionMgr.setEditLog(editLog);
    this.idGenerator.setEditLog(editLog);
    
    • editLog, 有点类似mysql的binlog, 通过记录和回放可以还原元数据信息.
    • image信息是doris通过checkpoint机制定时打包的全部bdb数据, 帮助Fe可以从异常中恢复数据.
  7. 清理load、export任务的元信息.

    createLabelCleaner();
    

Fe默认不会全部的load、export任务信息都保存, 比如load任务信息默认保存3天, 然后就内存删除了, 由于没有落盘, 删除后将永远不可见.

  1. 清理过期的事物信息. 事物包含创建库、表, drop库表,load数据等, 都是一个事物, 要么成功要么失败. 但是Doris不会允许一个事物无限期的执行, 比如stream load默认600s超时,
    createTxnCleaner();
    
  2. 初始化Fe角色变化监听器. Fe的角色选举是通过bdb来实现的, 当bdb发现有新加节点或者有新节点下线后, 会重新选举新的master Fe节点, 选成功后通过状态变化通知其他Fe节点.
    该监听器就是监听当前Fe角色变化的, 一旦角色变化则立即做出角色改变. 比如转化为master后, 调用transferToMaster()方法, 启动一系列的master后台线程服务, 代码上继承MasterDaemon.java类的都是. transferToMaster()的核心功能如下:
  • 暂停回放的editlog的线程, 只有非master才会回放editlog同步元数据
  • 重新回放全部大于当前元数据id的的元数据, 并且记录元数据版本
  • 启动全部的master后台服务, 比如:
    • Checkpoint任务
    • 心跳
    • Load Checked. 这里比较复杂, 以后再详细讲解
    • backup处理器
    • 回收站任务
  • 启动fe通用后台服务
    • tablet统计服务
    • load、export任务清理服务
    • Elasticsearch状态存储服务
    • 域名解析服务

在这些步骤执行完成后, 会Doris Fe启动类会调用Catalog.getCurrentCatalog().waitForReady()方法, 直到本地的editlog都回放完成后, 再继续执行之后的逻辑.

下一篇将主要介绍Fe中的三个服务: Qe服务、Fe服务、Http服务, 分别为Fe提供了jdbc协议接入、thrift RPC接入、Http接入和监控.

全部评论