这篇文章是上篇文章的继续,上篇文章其实是整个server启动过程中非常小的一部分,文章最后有一个整体流程图,感兴趣的话可以点开进行查看。
TiKV源码略读-Config - 技术文章 / 原理解读 - AskTUG
这次我们的代码略读会基于v4.0.8这个分支开展阅读工作,当阅读完本次代码之后,TiKV就真正运行起来了。TiKV服务启动流程相关的代码肯定拥有更多的逻辑细节,我们会适当忽略一些细节,以便集中在重要的几个模块逻辑上,避免过多的细节迷失方向。
主线流程:
和上一篇一样,TiKV启动主要流程我们还是用镂空的图示代表,每一步都会展开讲解。
初始步骤:
初始步骤主要配置日志系统和环境变量检查,没有太多技术细节,也不是我们重点关注的部分,所以我们先跳过。
初始化配置:
这部分的流程其实包含了上一篇文章内容,都是配置信息的读取,检查和对应的设置,不是主要的逻辑代码,所以有几块内容留着空白,等后续再补充。
网络端口冲突检测:
网络地址和端口冲突检测其实非常简单,就是把配置中的地址和端口检查一下可不可用,代码量也不大,直接过。
初始化文件系统:
这段代码主要在store_path下新建了一个LOCK的文件,应该是用来记录和管理锁相关的信息。然后会检查现有的rocksdb文件是否正常,可用磁盘空间是否充足。
初始化Yet another thread pool:
这里调用了一个外部线程池管理库,代码就3行,看着只是配置了prometheus的监控,貌似没有更多实际的代码逻辑。从github项目文件看,也是一个在完善中的库。我们先对yatp有个初步的认识,等具体到项目中再看有没有其他地方用到yatp。
初始化加密:
通过配置文件初始化DataKeyManager,代码就一行,很简单。配置的时候会有几个参数需要注意,一个是加密方法EncryptionMethod,包括了明文,AES128,AES192,AES256;还有一个是Master Key,可以通过明文,文件,access-key和secret-key三种方式配置。
初始化raw engine v5.0:
这部分代码是分支换成了master后梳理的内容,当时感觉有点怪,但很明显这部分代码不属于4.0版本,从最近的新分支可以看到这部分代码是5.0的功能。
从代码逻辑上看,这部分代码可以通过config配置,设置当前节点使用本地rocksdb还是raft版本的engine,似乎有大的功能计划,也可能是打算之后废弃init_engines部分的代码,这两部分代码有比较大的重叠部分。
而且raftengine也拉出去变成了一个新的项目库,核心代码会有比较大的变化,很期待。
初始化engines:
TiKV启动流程里的核心代码,第一部分会初始化两个engine:
- raft_engine存储在raftdb_path目录内,应该是给raft保存信息用的;
- kv_engine存储在DEFAULT_ROCKSDB_SUB_DIR目录内,是rocksdb所在的地方。
这两个engine会组合在一起保存在engine::Engines里。之后会再初始化一个RaftKV的engine,这个engine的参数不是本地目录,而是一个raft router,可以猜测应该是node之间通信的engine。
初始化GC:
官网只有TiDB的GC相关文档,并没有过多关于TiKV的GC相关的内容。从代码中大致可以看出TiKV的GC可能是用来处理锁的相关事务,这里的悬念我们暂时搁置一下,会在后续文章中详细探究。
初始化servers:
那个红色的框其实和这部分代码关系不大,所以被我移到初始化config的代码块里了,5.0之后这个红框就没有了。
这里根据前面几步初始化的配置,生成了snap manager和raft storage两个管理对象,再生成了server这个对象。
server和SSTimporter,split_check_worker又一起参与到node.start方法中,这时候服务器开始作为tikv分布式系统中的一个节点开始启动,包括启动raft store,连通PD并注册,一些后端的worker开始schedule工作,rocksdb准备工作也开始执行了。
到这步结束,tikv单一节点内部的准备工作都已经完成,就等外部数据请求接入开始工作了。
注册services:
这里主要注册了import,debug,diagnostic,deadlock,backup,cdc等一系列gRPC服务,这些服务会在下一步启动TiKV时候一一执行。
启动TiKV:
这里是启动的最后一步,首先执行上一步注册的services,然后开始运行snap worker,并开始监听gRPC端口,最后输出“TiKV is ready to serve”的日志,标志TiKV正式启动成功!
之后还有一些监控指标的配置和等待结束信号的代码,这里就不细细描述了,有兴趣的小伙伴可以直接翻阅tikv的代码,相信剩下的部分应该不是难事。