开源分布式数据库PolarDB-X源码解读——PolarDB-X源码解读(二):CN启动流程

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: 开源分布式数据库PolarDB-X源码解读——PolarDB-X源码解读(二):CN启动流程

本文主要讲解PolarDB-X的CN节点(polardbx-sql)的启动过程包括参数加载、元信息加载等过程并对启动过程中设计的模块做简单的介绍。  


CN Server层的代码主要包含在polardbx-server模块中,main函数位于TddlLauncher


主逻辑入口在CobarServer.init()方法中。


CN启动分为以下几个流程:


1.CobarServer对象的创建


该类是单例,可以通过CobarServer.getInstance()获取。


2.参数加载


路径:TddlLauncher.main() -> CobarServer.new() -> CobarConfig.new() -> CobarConfig.initCobarConfig() -> ServerLoader.load()


CN的参数均为key-value的形式。


ServerLoader.load()中,CN主要从以下位置读取参数:


 server.properties文件,其默认位置在classpath的根目录中,所以一般使

 用           IDE          进         行            开          发          时 ,     加          载          的         是

polardbx-server\src\main\resources\server.properties文件


String conf = 
System.getProperty("server.conf","classpath:server.properties");


 Java运行参数中


例如java...-DserverPort=8527


 环境变量中


serverProps.putAll(System.getProperties());
serverProps.putAll(System.getenv());


以上参数来源中,server.properties的优先级最低,环境变量中的优先级最高,当包含同名参数时,高优先级的参数来源会覆盖低优先级的参数来源。


加载的参数,会保存在SystemConfig中,该类为单例,可以通过CobarServer.getInstance().getConfig().getSystem()获取。


3.从MetaDB读取元数据,并初始化实例级的系统组件


路径:

TddlLauncher.main()->CobarServer.new()->CobarConfig.new()->CobarConfig.initCobarConfig()->ServerLoader.load()->ServerLoader.initPolarDbXComponents()


1)初始化元数据库的连接池


MetaDbDataSource.initMetaDbDataSource


会使用SystemConfig中存储的MetaDB的地址、端口、用户名、密码、库名等信息,建立与MetaDB的连接。


MetaDbDataSource
            .initMetaDbDataSource(this.system.getMetaDbAddr(), this.system.getMetaDbName(),
                this.system.getMetaDbProp(),
                this.system.getMetaDbUser(),
                this.system.getMetaDbPasswd());


MetaDbDataSource是一个单例,实现了JDBC的程序中可以使用MetaDbDataSource.getInstance().getConnection()获取与MetaDB的连接(实现了JDBC接口),并使用该连对MetaDB进行访问。


2)对系统表进行创建或者升级


SchemaChangeManager.getInstance().handle();


polardbx-gms\src\main\resources\ddl\中保存了系统表的表结构,并且使用alter语句记录了每一次版本的变更。SchemaChangeManager在初始化时,会检测当前每个系统表的表结构版本,如果版本较老,会依次使用这些语句对alter语句进行更新。


3)读取实例ID信息


ServerInstIdManager.getInstance();


一个PolarDB-X集群也称为一个实例,在MetaDB中有一个唯一的实例ID。同时,PolarDB-X实例有主实例与只读实例两种模式。当存在只读实例时,必然存在一个主实例。该步骤从MetaDB中读取实例ID,如果当前实例为只读实例,则还会读取其主实例的实例ID。  


4)MetaDbConfigManager


先简单介绍下这个东西是干啥的。


我们存在MetaDB中的配置信息,如果发生变化,CN需要能感知到这个变化。例如,某个表增加了一个列。作为CN,如何能感知到这个变化呢?


一个比较简单的思路是对元数据做轮询,各几秒查一次。但如果让每个模块都去做这样的事情,会有个比较大的问题是对MetaDB的访问压力会很大。


MetaDbConfigManager对此作了封装,作了一个统一的轮询机制。但由于每个模块元数据表的格式千变万化,所以MetaDbConfigManager并不是直接轮询每个模块的元数据表,而是轮询config_listener这张表。这张表的几个关键列是data_id、op_version、gmt_modified。


我们可以为每个data_id在代码中注册一个listener,当MetaDbConfigManager轮询到data_id的op_version发生变化的时,会回调这个listener,一般情况下,各模块实现的listener会按需要再读取对应的元数据表。


例如,d1.t1表在config_listener中有一行记录:


polardbx.meta.table.d1.t1


往t1表中增加了一个列,我们会修改MetaDB中的columns表,同时,我们会修改config_listener表中 polardbx.meta.table.d1.t1这行记录的op_version,进行+1的操作。


几秒钟后,MetaDbConfigManager会轮询到这行记录的op_version列发生了变化,会回调表结构管理模块的listener(类:TableMetaListener),该listener会重新加载d1.t1表的元数据。


在启动时,CN会初始化MetaDbConfigManager用于做轮询的线程和定时任务。


5)MetaDbInstConfigManager


初始化实例级的配置项,这里的配置项类似于MySQL中的System Variables,例如SQL的内存大小限制之类的。该阶段会从MetaDB的inst_config表中加载所有的配置项并保存在内存中。


并且会注册对应的listener,这样当inst_config表发生变化的时候,会回调MetaDbInstConfigManager的listener。  


6)ConnPoolConfigManager


这个是用来存连接池(CN与DN之间的连接池)相关的配置项的(其实它用到的配置MetaDbInstConfigManager中都有),也是从inst_config中读取。


7)StorageHaManager


这个比较重要。


目前每一组DN(这里的组指一个Paxos组)内选举的结果是存储在该组DN自己的系统表中,并不会写到MetaDB中。因此CN需要有机制去从DN的系统表中探测各节点的角色。


StorageHaManager会从storage_info表中读取所有的DN节点的连接信息,并且内部会有轮询的线程去检测角色信息。当DN发生HA的时候,StorageHaManager会探测到这个变化,并感知到最新的Leader等角色。


8)初始化系统库


initSystemDbIfNeed初始化information_schema和polardbx等几个系统库。


4.创建线程池


路径:CobarServer.new()


几个主要的线程池的创建:


 managerExecutor,负责Manager端口的请求。

 killExecutor,专门用来执行kill指令

 serverExecutor,各种SQL都是由这个线程池执行


5.CobarServer.init


路径:TddlLauncher.main()->CobarServer.init()  


1)逻辑库(TDataSource)的初始化


入口在GmsAppLoader.initDbUserPrivsInfo,类里的“App”指的就是一个逻辑库。这里会加载每个逻辑库的用户权限信息以及最重要的TDataSouce。


TDataSource在CN中与逻辑库一一对应。它是每个逻辑库执行SQL的入口。TDatSource的初始化逻辑在MatrixConfigHolder.init中,包含了以下内容:


 初始化拓扑,例如这个库包含了哪些DN,并初始化与这些DN之间的连接池

 (TopologyHandler.initPolarDbXTopology


 获取每个DN的信息,包括版本,特性的支持程度等

StorageInfoManager.init


 初始化分片的路由信息(mode='drds',TddlRuleManager.init

 mode='auto',PartitionInfoManager.init


 初始化表管理器(有哪些表、每个表有哪些列哪些索引等)(GmsTableMetaManager.init


 初始化事务管理器(transactionManager.init()


 创建Plan Cache(PlanCache planCache = new PlanCache(schemaName);


 启动DDL任务引擎(ddlEngineInit()


 统计信息管理器的初始化(StatisticManager.init


 SPM的初始化(PlanManager.init


2)GmsClusterLoader.loadPolarDbXCluster


加载集群信息,例如集群中有哪些CN节点等。初始化CclService,这个是用来做SQL限流的。


3)warmup


CN的SQL函数目前是反射机制进行加载的,这里主要作用是加载下所有的函数。


6.网络层的初始化


该步骤结束后,服务端口便会打开,该CN进程就能开始对外提供服务了。  


CN在这一步会启动Server端口与Manager端口两个端口。  


Server端口对应MySQL的3306端口,是提供给前端应用使用的。


Manager端口用于内部的管理使用,例如,SHOW PROCEESSLIST指令需要收集所有CN的执行情况,就会使用该端口进行收集。


1)NIOProcessor


processors = new NIOProcessor[system.getProcessors()];
for (int i = 0; i < processors.length; i++) {
      processors[i] = new NIOProcessor(i, "Processor" + i,this.serverExecutor);
processors[i].startup();
}


CN网络层处理请求的入口是NIOProcessor,每个NIOProcessor有读写两个线程。这里会来启动NIOProcessor的W与R线程。


2)NIOAcceptor


CN网络层用来处理连接建立请求的是NIOAcceptor,NIOAcceptor的new过程中,会打开端口进行监听:  


public NIOAcceptor(String name, int port, FrontendConnectionFactory factory, boolean online) throws IOException {
        super.setName(name);
        ...
            this.selector = Selector.open();
            this.serverChannel = ServerSocketChannel.open();
            this.serverChannel.socket().bind(new InetSocketAddress(port), 65535);
        ...
    }


同时,NIOAcceptor也是一个线程,会处理连接建立的请求。当连接建立后,NIOAcceptor.accept方法会将连接绑定到一个NIOProcessor上,由NIOProcessor继续处理该连接上后续的读写请求。


可以看出,对于服务端口来说,NIOAcceptor只有一个,NIOProcessor的数目则一般和CPU核数保持一致。


3)MPP Server的启动


CN作为MPP集群中的一个,还需要启动端口来进行CN之间的通信。


startMppServer会进行MPP服务的启动。  


4)CDC服务的启动


CobarServer.tryStartCdcManager会进行CDC的启动。


7:结语


至此,CN就启动完成了。这个过程包含了CN中绝大多数组件,鉴于篇幅原因,没有完整介绍每个组件的作用。如果你对这些组件中的哪一个感兴趣,欢迎留言给我们,我们会在后续的文章中,对一些关键的组件做进一步详细的介绍。  

相关实践学习
快速体验PolarDB开源数据库
本实验环境已内置PostgreSQL数据库以及PolarDB开源数据库:PolarDB PostgreSQL版和PolarDB分布式版,支持一键拉起使用,方便各位开发者学习使用。
相关文章
|
7天前
|
消息中间件 监控 数据可视化
Apache Airflow 开源最顶级的分布式工作流平台
Apache Airflow 是一个用于创作、调度和监控工作流的平台,通过将工作流定义为代码,实现更好的可维护性和协作性。Airflow 使用有向无环图(DAG)定义任务,支持动态生成、扩展和优雅的管道设计。其丰富的命令行工具和用户界面使得任务管理和监控更加便捷。适用于静态和缓慢变化的工作流,常用于数据处理。
Apache Airflow 开源最顶级的分布式工作流平台
|
12天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,并与使用 RPM 包安装进行了对比
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,并与使用 RPM 包安装进行了对比。通过具体案例,读者可以了解如何准备环境、下载源码、编译安装、配置服务及登录 MySQL。编译源码安装虽然复杂,但提供了更高的定制性和灵活性,适用于需要高度定制的场景。
44 3
|
12天前
|
PHP 数据库 数据安全/隐私保护
布谷直播源码部署服务器关于数据库配置的详细说明
布谷直播系统源码搭建部署时数据库配置明细!
|
15天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
59 2
|
1月前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置服务等,并与使用 RPM 包安装进行了对比,帮助读者根据需求选择合适的方法。编译源码安装虽然复杂,但提供了更高的定制性和灵活性。
218 2
|
2月前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
本文介绍了一个基于Spring Boot和Vue.js实现的在线考试系统。随着在线教育的发展,在线考试系统的重要性日益凸显。该系统不仅能提高教学效率,减轻教师负担,还为学生提供了灵活便捷的考试方式。技术栈包括Spring Boot、Vue.js、Element-UI等,支持多种角色登录,具备考试管理、题库管理、成绩查询等功能。系统采用前后端分离架构,具备高性能和扩展性,未来可进一步优化并引入AI技术提升智能化水平。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的在线考试系统(含教程&源码&数据库数据)
|
1月前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤
【10月更文挑战第7天】本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据自身需求选择合适的方法。
53 3
|
1月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
40 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
29天前
|
关系型数据库 MySQL 分布式数据库
零基础教你用云数据库PolarDB搭建企业网站,完成就送桌面收纳桶!
零基础教你用云数据库PolarDB搭建企业网站,完成就送桌面收纳桶,邀请好友完成更有机会获得​小米Watch S3、小米体重称​等诸多好礼!
零基础教你用云数据库PolarDB搭建企业网站,完成就送桌面收纳桶!
|
2月前
|
关系型数据库 MySQL Serverless
探索PolarDB MySQL版:Serverless数据库的灵活性与性能
本文介绍了个人开发者对阿里云PolarDB MySQL版,特别是其Serverless特性的详细评测体验。评测涵盖了产品初体验、性能观测、Serverless特性深度评测及成本效益分析等方面。尽管试用过程中遇到一些小问题,但总体而言,PolarDB MySQL版表现出色,提供了高性能、高可用性和灵活的资源管理,是个人开发者和企业用户的优秀选择。

热门文章

最新文章

相关产品

  • 云原生数据库 PolarDB