etcd server

etcd server启动的流程

Posted by Liangjf on March 30, 2020

etcd server启动的流程

【github.com/coreos/etcd@v3.3.18+incompatible/embed/etcd.go:93】

1、检查配置
2、创建Etcd实例
3、开始监听节点node
4、开始监听客户端client
5、根据wal日志初始化作为集群成员
6、获取PeerURLsMap(peerUrl 与 etcd name对应的map)以及cluster token
7、生成new etcdServer所需的的ServerConfig结构体
8、创建EtcdServer实例,初始化EtcdServer
	1、分配内存空间
	2、检查是否有data数据目录
	3、检查是否有快照目录
	4、根据数据目录data是否有预写日志haveWAL和node状态是否是NewCluster的不同,调用不同函数创建raft node
	5、初始化作为server的状态
	6、初始化集群leader状态
	7、实例化EtcdServer对象,作为提供服务方,包含了raft node
	8、初始化租期lessor,设置定时租期
	9、初始化多版本并发控制mvcc
	10、启动http处理handler,等待peer的连接
9、进入主循环(e.Server.Start()-->(s *EtcdServer) run()),等待处理etcd事件
	1、初始化
		1、从raft storage中获取快照,通过snapshot恢复store中完整状态
		2、创建fifo调度队列FIFOScheduler
		3、raft初始化响应事件处理raftReadyHandler(更新leader状态updateLeadership,更新commit index updateCommittedIndex)
		4、启动raftNode,s.r.start(rh)
		5、初始化etcdProcess参数,包括任期Term,commit日志下标Index等参数值
	2、进入for循环等待处理各种etcd事件
		1、case ap := <-s.r.apply()。当写事务已经被集群中超过半数的raft node确认过并且保存到WAL日志后,raftNode会触发apply()事件,进而执行applyAll方法进行处理。applyAll方法中会执行真正的写操作修改Etcd数据库内容
			1、s.r.apply()
			2、s.applyAll(&ep, &ap)
			3、s.applyEntries(ep, apply)
			4、s.apply(ents, &ep.confState)
			5、s.applyEntryNormal(&e)
			6、s.w.Trigger(req.ID, s.applyV2Request(req))
				func (s *EtcdServer) applyV2Request(r *RequestV2) Response {
					switch r.Method {
					case "POST":
						return s.applyV2.Post(r)
					case "PUT":
						return s.applyV2.Put(r)
					case "DELETE":
						return s.applyV2.Delete(r)
					case "QGET":
						return s.applyV2.QGet(r)
					case "SYNC":
						return s.applyV2.Sync(r)
					default:
						return Response{Err: ErrUnknownMethod}
					}
				}