Doris中的节点
FE
- 主要负责用户请求的接入
- 查询解析规划
- 元数据的管理
- 节点管理相关工作
BE
- 主要负责数据存储
- 查询计划的执行
broker
- 轻量无状态节点,上面封装了一层文件读写的语义
- 用于支持 Doris 读写远端存储上的文件和目录
- Broker 通过提供一个 RPC 服务端口来提供服务,是一个无状态的 Java 进程,负责为远端存储的读写操作封装一些类 POSIX 的文件操作,如 open,pread,pwrite 等等。
- 除此之外,Broker 不记录任何其他信息,所以包括远端存储的连接信息、文件信息、权限信息等等,都需要通过参数在 RPC 调用中传递给 Broker 进程,才能使得 Broker 能够正确读写文件
FE节点管理
fe的角色
Follower
- 所有 Follower 角色的 FE 节点会组成一个可选择组,类似 Paxos 一致性协议里的组概念。
- 组内会选举出一个 Follower 作为 Master
- 保证元数据写的可靠性
- 一条元数据日志需要在多数 Follower 节点写入成功,才算成功。
- 比如3个 FE ,2个写入成功才可以。这也是为什么 Follower 角色的个数需要是奇数的原因
- 不参与数据的计算,如果系统是重计算,则不考虑扩展fe
Observer
- 保证元数据读的扩展
为什么要引入obeserver?
如果只存在follower节点,那么当横向扩展的时候会带来元数据写入的压力
所以引入obeserver只读节点,其只会轮训的同步flower的元数据,但不参与选举与元数据多数写的策略
当加入多个observer的时候不会造成集群元数据写的延迟
其保证了元数据读的扩展,一般建议根据负载请求安装observer的数量
- 负载请求即高并发场景
fe启动流程
在1.2-SNAPSHOT中已经变成Env.getCurrentEnv().initialize
元数据目录结构
bdb:BDBJE的数据目录
- BDBJE:分布式嵌入式kv数据库
- Doris 元数据的元数据
Image
- Image.2858:元数据镜像文件
- ROLE:记录角色信息
- VERSION:记录集群信息
- 认证信息token
- 集群id
在fe.conf中指定元数据目录路径
FE 启动流程 – 获取节点信息和Helper信息
- Catalog.getSelfHostPort()
- IP + PORT 唯一确定一个 FE 节点
- Catalog.getHelperNode()
- sh start_fe.sh –helper ip:port
- 当在集群中启动新fe节点的时候,需要为其指定master的信息
- 新节点从Master节点拉取集群和角色信息
- HelperNode:
- 指向任一已存在的Follower
获取集群和角色信息
首节点启动
当没有指定helper的时候 isMyself()=true
- 认为自己就是fe的首节点
非首节点启动
非首节点启动会忽略本地存储的集群信息,从helperNode中拉取信息
从helper获取信息
获取自身fe的role、cluster id 、token等
如果远端节点没有ready,会在循环中等待远端节点返回的信息
进行节点认证
比对 cluster id 、token id
将源端获取的 cluster id 、token id和本地存储的 cluster id 、token id比对
如果本地没有,则直接存储
如果本地有,需要和本地比对,判断是否和上次加入的集群是同一个集群
- 比对失败就会启动失败
从helper node 节点 pull new image,进行元数据加载
加载元数据
状态监听
- Catalog.createStateListener()
FE启动流程回顾
Env.getCurrentEnv().initialize执行流程
确认元数据目录
确定是否为helper节点
如果不是,则从本地加载或创建元数据目录
如果是,则从helper node中获取集群信息,并进行节点认证
加载元数据
开启状态监听
FE 启动流程 – 节点认证
防止错误的节点加入集群
新节点的 IP:PORT 必须在元数据中显式注册。
双向认证:
Master FE只会发送心跳给已注册的FE节点,防止未注册的节点被错误加入。
新增FE会校验Master FE发送的心跳信息中的FE信息,防止接收到其他FE发送的错误心跳。
- role、cluster_id、token
认证代码:org.apache.doris.httpv2.meta.MetaService.java
均是restful api
/role?host=ip&port=9030
- 检查指定的[ip:port]是否已经注册,并返回对应的角色(Follower / Observer)
/version
- 返回 VERSION 文件
/check
- 返回 cluster_id 和 token 用于对端校验
FE ADD NODE
删除FE节点
FE节点删除流程
执行删除命令
ALTER SYSTEM DROP FOLLOWER “ip:port”
ALTER SYSTEM DROP OBSERVER “ip:port”
执行流程
接受命令节点的操作
其他FE会同步这个“删除FE节点”的元数据操作
EditLog.loadJournal()
如果发现删除的是自己,直接退出。
BE ADD NODE
ADD BE NODE 流程
注册BE节点信息
ALTER SYSTEM ADD BACKEND ”ip:port”;
org.apache.doris.system.SystemInfoService.addBackend()
- 在元数据中记录新增节点的ip&port
Master FE 向 BE 发送心跳
org.apache.doris.system.HeartbeatMgr.java#BackendHeartbeatHandler
心跳信息: gensrc/thrift/HeartbeatService.thrift#TMasterInfo
- 心跳信息中会包含MasterInfo
BE接收心跳
epoch主要是一致性协议需要,即判断发送方是不是真正的master,类似raft协议
BE 启动流程 – 节点认证
防止错误的节点加入集群
新节点的 IP:PORT 必须在元数据中显式注册。
双向认证:
FE只会发送心跳给已注册的BE节点,防止未注册的节点被错误加入。
BE会校验FE发送的心跳信息中的FE信息,防止接收到其他FE发送的错误心跳。
FEIP、epoch、cluster_id、token
删除BE NODE
删除的两种方式
DROP 和 DECOMMISSION
ALTER SYSTEM DROP BACKEND:直接删除
- org.apache.doris.system.SystemInfoService.dropBackend()
ALTER SYSTEM DECOMMISSION BACKEND:数据迁移后删除
Org.apache.doris.alter.SystemHandler.process()
标记副本为“下线”状态,触发副本修复逻辑。全部数据迁移完成后,会自动 DROP BACKEND
FE 配置:drop_backend_after_decommission
- true:在decommission结束后auto drop backend
FE节点没有decommission操作的原因
fe节点是doris集群中负责元数据管理和查询协调的节点。
元数据是指描述doris集群中表、分区、副本等信息的数据。
元数据的正确性和一致性对于doris集群的正常运行非常重要。
因此,doris集群采用了一种叫做raft的协议来保证元数据的高可用性和强一致性。
raft协议是一种分布式一致性算法,它要求集群中的每个节点都有一个角色,分为leader、follower和candidate三种。
- leader节点是负责处理客户端请求和同步数据给其他节点的节点,follower节点是跟随leader节点并复制其数据的节点,candidate节点是在leader节点失效时,试图成为新的leader节点的节点。
doris集群中的fe节点也遵循raft协议,但是为了简化实现,它将角色分为两种:follower和observer。
follower节点相当于raft协议中的leader或follower节点,observer节点相当于raft协议中的非投票型follower节点。
follower节点会参与元数据的写入和选举,而observer节点只会同步元数据并提供读服务。
集群中的一个follower节点会被选举为master节点,负责处理元数据的写请求。
如果master节点宕机或者网络异常,集群会自动选举一个新的master节点。
因此,用户无法直接下线一个fe节点,而只能通过修改fe.conf文件中的role参数来改变fe节点的角色。
如果想要下线一个fe节点,可以将其role参数设置为observer,并重启该fe节点。
这样,该fe节点就不会再参与元数据的写入和选举,也不会被选为master节点。
如果想要彻底删除一个fe节点,可以先将其role参数设置为observer,并等待其同步完所有元数据后,再停止该fe节点,并删除其元数据目录。
BE有decommission的原因
decommission操作可以用于安全地下线一个be节点,而不影响集群的数据可用性和一致性。
decommission操作会先将该be节点上的所有数据分片迁移到其他be节点上,然后再从集群中删除该be节点。这样,可以避免数据丢失或者副本不足的风险。
decommission操作也可以用于实现集群的扩缩容,或者在节点增加新的磁盘后,将数据均衡到新的磁盘上。
be节点下线过程中和没下线时工作职能的区别主要体现在:
be节点下线过程中不会参与数据导入,而没下线时会参与数据导入。
be节点下线过程中只能提供有限的查询服务,而没下线时可以提供完整的查询服务。
be节点下线过程中会消耗更多的网络和磁盘资源,而没下线时则不会。
Be下线过程中依然在集群中,但是不会被分配新的数据分片,也不会参与数据导入和选举。只有当be节点完成数据迁移并从集群中删除自己后,才会完全退出集群。
节点管理常见问题
broker节点
该节点是无状态的,可以随意删除
而像fe、be节点这种有状态的节点就不能随意删除了
priority_network配置需要主动配置
无论BE、FE,这个参数我们在安装的时候都是必须要配置的,特别是当一台机器拥有多个IP地址的时候,我们要为FE、 BE 指定唯一的IP地址
- 避免拿到127.0.0.1 抑或docker虚拟网桥的ip
Invalid cluster id
这个错误可能会在show backends 或 show frontends 命令的结果中出现。通常出现在某个FE或BE节点的错误信息列中。
这个错误的含义是,Master FE向这个节点发送心跳信息后,该节点发现心跳信息中携带的 cluster id和本地存储的 cluster id不同,所以拒绝回应心跳。
Doris的 Master FE 节点会主动发送心跳给各个FE或BE节点,并且在心跳信息中会携带一个cluster_id。
cluster_id是在一个集群初始化时,由Master FE生成的唯一集群标识。
当FE或BE第一次收到心跳信息后,则会将cluster_id以文件的形式保存在本地。
FE的该文件在元数据目录的image/目录下,BE则在所有数据目录下都有一个cluster_id文件。
之后,每次节点收到心跳后,都会用本地cluster_id的内容和心跳中的内容作比对,如果不一致,则拒绝响应心跳。
该机制是一个节点认证机制,以防止接收到集群外的节点发送来的错误的心跳信息。
如果需要恢复这个错误。
首先要先确认所有节点是否都是正确的集群中的节点。
之后,对于FE节点,可以尝试修改元数据目录下的 image/VERSION 文件中的 cluster_id 值后重启FE。
对于BE节点,则可以删除所有数据目录下的 cluster_id 文件后重启 BE
被 DROP 的 BE 能否恢复?
FE 的故障恢复
核心思路:通过清空“元数据的元数据”使FE恢复到单节点初始状态
元数据的元数据
Doris 的元数据主要存储4类数据:
用户数据信息。
- 包括数据库、表的 Schema、分片信息等。
各类作业信息。
- 如导入作业,Clone 作业、SchemaChange 作业等。
用户及权限信息。
集群及节点信息。
元数据的元数据指fe raft协议中的拓扑状态
清空元数据的元数据
- 即先将一个节点的fe 拓扑状态清空,其自然变成master节点,然后清空其他节点,然后加入master
当只有两个flower节点的时候所有节点都挂掉了
- 因为flower通过raft一致性协议要保证多数节点成功,而两个节点无法满足达成多数节点成功,所以其自身就退出了
DeployManager
org.apache.doris.deploy.DeployManager
AmbariDeployManager
K8sDeployManager
LocalFileDeployManager
解决自动节点发现的问题
多个FE同时启动