三篇文章了解 TiDB 技术内幕 —— 谈调度

任何一个复杂的系统,用户感知到的都只是冰山一角,数据库也不例外。

前两篇文章介绍了 TiKV、TiDB 的基本概念以及一些核心功能的实现原理,这两个组件一个负责 KV 存储,一个负责 SQL 引擎,都是大家看得见的东西。在这两个组件的后面,还有一个叫做 PD(Placement Driver)的组件,虽然不直接和业务接触,但是这个组件是整个集群的核心,负责全局元信息的存储以及 TiKV 集群负载均衡调度。

本篇文章介绍一下这个神秘的模块。这部分比较复杂,很多东西大家平时不会想到,也很少在其他文章中见到类似的东西的描述。我们还是按照前两篇的思路,先讲我们需要什么样的功能,再讲我们如何实现,大家带着需求去看实现,会更容易的理解我们做这些设计时背后的考量。

为什么要进行调度

先回忆一下第一篇文章提到的一些信息,TiKV 集群是 TiDB 数据库的分布式 KV 存储引擎,数据以 Region 为单位进行复制和管理,每个 Region 会有多个 Replica(副本),这些 Replica 会分布在不同的 TiKV 节点上,其中 Leader 负责读/写,Follower 负责同步 Leader 发来的 raft log。了解了这些信息后,请思考下面这些问题:

如何保证同一个 Region 的多个 Replica 分布在不同的节点上?更进一步,如果在一台机器上启动多个 TiKV 实例,会有什么问题?
TiKV 集群进行跨机房部署用于容灾的时候,如何保证一个机房掉线,不会丢失 Raft Group 的多个 Replica?
添加一个节点进入 TiKV 集群之后,如何将集群中其他节点上的数据搬过来?
当一个节点掉线时,会出现什么问题?整个集群需要做什么事情?如果节点只是短暂掉线(重启服务),那么如何处理?如果节点是长时间掉线(磁盘故障,数据全部丢失),需要如何处理?
假设集群需要每个 Raft Group 有 N 个副本,那么对于单个 Raft Group 来说,Replica 数量可能会不够多(例如节点掉线,失去副本),也可能会 过于多(例如掉线的节点又回复正常,自动加入集群)。那么如何调节 Replica 个数?
读/写都是通过 Leader 进行,如果 Leader 只集中在少量节点上,会对集群有什么影响?
并不是所有的 Region 都被频繁的访问,可能访问热点只在少数几个 Region,这个时候我们需要做什么?
集群在做负载均衡的时候,往往需要搬迁数据,这种数据的迁移会不会占用大量的网络带宽、磁盘 IO 以及 CPU?进而影响在线服务?
这些问题单独拿出可能都能找到简单的解决方案,但是混杂在一起,就不太好解决。有的问题貌似只需要考虑单个 Raft Group 内部的情况,比如根据副本数量是否足够多来决定是否需要添加副本。但是实际上这个副本添加在哪里,是需要考虑全局的信息。整个系统也是在动态变化,Region 分裂、节点加入、节点失效、访问热点变化等情况会不断发生,整个调度系统也需要在动态中不断向最优状态前进,如果没有一个掌握全局信息,可以对全局进行调度,并且可以配置的组件,就很难满足这些需求。因此我们需要一个中心节点,来对系统的整体状况进行把控和调整,所以有了 PD 这个模块。

调度的需求

上面罗列了一大堆问题,我们先进行分类和整理。总体来看,问题有两大类:

作为一个分布式高可用存储系统,必须满足的需求,包括四种:

副本数量不能多也不能少
副本需要分布在不同的机器上
新加节点后,可以将其他节点上的副本迁移过来
节点下线后,需要将该节点的数据迁移走
作为一个良好的分布式系统,需要优化的地方,包括:

维持整个集群的 Leader 分布均匀
维持每个节点的储存容量均匀
维持访问热点分布均匀
控制 Balance 的速度,避免影响在线服务
管理节点状态,包括手动上线/下线节点,以及自动下线失效节点
满足第一类需求后,整个系统将具备多副本容错、动态扩容/缩容、容忍节点掉线以及自动错误恢复的功能。满足第二类需求后,可以使得整体系统的负载更加均匀、且可以方便的管理。

为了满足这些需求,首先我们需要收集足够的信息,比如每个节点的状态、每个 Raft Group 的信息、业务访问操作的统计等;其次需要设置一些策略,PD 根据这些信息以及调度的策略,制定出尽量满足前面所述需求的调度计划;最后需要一些基本的操作,来完成调度计划。 调度的基本操作

我们先来介绍最简单的一点,也就是调度的基本操作,也就是为了满足调度的策略,我们有哪些功能可以用。这是整个调度的基础,了解了手里有什么样的锤子,才知道用什么样的姿势去砸钉子。

上述调度需求看似复杂,但是整理下来最终落地的无非是下面三件事:

增加一个 Replica
删除一个 Replica
将 Leader 角色在一个 Raft Group 的不同 Replica 之间 transfer
刚好 Raft 协议能够满足这三种需求,通过 AddReplica、RemoveReplica、TransferLeader 这三个命令,可以支撑上述三种基本操作。

信息收集

调度依赖于整个集群信息的收集,简单来说,我们需要知道每个 TiKV 节点的状态以及每个 Region 的状态。TiKV 集群会向 PD 汇报两类消息:

每个 TiKV 节点会定期向 PD 汇报节点的整体信息

TiKV 节点(Store)与 PD 之间存在心跳包,一方面 PD 通过心跳包检测每个 Store 是否存活,以及是否有新加入的 Store;另一方面,心跳包中也会携带这个 [Store 的状态信息][1],主要包括:

总磁盘容量
可用磁盘容量
承载的 Region 数量
数据写入速度
发送/接受的 Snapshot 数量(Replica 之间可能会通过 Snapshot 同步数据)
是否过载
标签信息(标签是具备层级关系的一系列 Tag)
每个 Raft Group 的 Leader 会定期向 PD 汇报信息

每个 Raft Group 的 Leader 和 PD 之间存在心跳包,用于汇报这个 [Region][2] 的状态,主要包括下面几点信息:

Leader 的位置
Followers 的位置
掉线 Replica 的个数
数据写入/读取的速度
PD 不断的通过这两类心跳消息收集整个集群的信息,再以这些信息作为决策的依据。除此之外,PD 还可以通过管理接口接受额外的信息,用来做更准确的决策。比如当某个 Store 的心跳包中断的时候,PD 并不能判断这个节点是临时失效还是永久失效,只能经过一段时间的等待(默认是 30 分钟),如果一直没有心跳包,就认为是 Store 已经下线,再决定需要将这个 Store 上面的 Region 都调度走。但是有的时候,是运维人员主动将某台机器下线,这个时候,可以通过 PD 的管理接口通知 PD 该 Store 不可用,PD 就可以马上判断需要将这个 Store 上面的 Region 都调度走。

调度的策略

PD 收集了这些信息后,还需要一些策略来制定具体的调度计划。

一个 Region 的 Replica 数量正确

当 PD 通过某个 Region Leader 的心跳包发现这个 Region 的 Replica 数量不满足要求时,需要通过 Add/Remove Replica 操作调整 Replica 数量。出现这种情况的可能原因是:

某个节点掉线,上面的数据全部丢失,导致一些 Region 的 Replica 数量不足
某个掉线节点又恢复服务,自动接入集群,这样之前已经补足了 Replica 的 Region 的 Replica 数量多过,需要删除某个 Replica
管理员调整了副本策略,修改了 [max-replicas][3] 的配置
一个 Raft Group 中的多个 Replica 不在同一个位置

注意第二点,『一个 Raft Group 中的多个 Replica 不在同一个位置』,这里用的是『同一个位置』而不是『同一个节点』。在一般情况下,PD 只会保证多个 Replica 不落在一个节点上,以避免单个节点失效导致多个 Replica 丢失。在实际部署中,还可能出现下面这些需求:

多个节点部署在同一台物理机器上
TiKV 节点分布在多个机架上,希望单个机架掉电时,也能保证系统可用性
TiKV 节点分布在多个 IDC 中,向单个机房掉电时,也能保证系统可用
这些需求本质上都是某一个节点具备共同的位置属性,构成一个最小的容错单元,我们希望这个单元内部不会存在一个 Region 的多个 Replica。这个时候,可以给节点配置 [lables][4] 并且通过在 PD 上配置 [location-labels][5] 来指名哪些 lable 是位置标识,需要在 Replica 分配的时候尽量保证不会有一个 Region 的多个 Replica 所在结点有相同的位置标识。

副本在 Store 之间的分布均匀分配

前面说过,每个副本中存储的数据容量上限是固定的,所以我们维持每个节点上面,副本数量的均衡,会使得总体的负载更均衡。

Leader 数量在 Store 之间均匀分配

Raft 协议要读取核写入都通过 Leader 进行,所以计算的负载主要在 Leader 上面,PD 会尽可能将 Leader 在节点间分散开。

访问热点数量在 Store 之间均匀分配

每个 Store 以及 Region Leader 在上报信息时携带了当前访问负载的信息,比如 Key 的读取/写入速度。PD 会检测出访问热点,且将其在节点之间分散开。

各个 Store 的存储空间占用大致相等

每个 Store 启动的时候都会指定一个 Capacity 参数,表明这个 Store 的存储空间上限,PD 在做调度的时候,会考虑节点的存储空间剩余量。

控制调度速度,避免影响在线服务

调度操作需要耗费 CPU、内存、磁盘 IO 以及网络带宽,我们需要避免对线上服务造成太大影响。PD 会对当前正在进行的操作数量进行控制,默认的速度控制是比较保守的,如果希望加快调度(比如已经停服务升级,增加新节点,希望尽快调度),那么可以通过 pd-ctl 手动加快调度速度。

支持手动下线节点

当通过 pd-ctl 手动下线节点后,PD 会在一定的速率控制下,将节点上的数据调度走。当调度完成后,就会将这个节点置为下线状态。

调度的实现

了解了上面这些信息后,接下来我们看一下整个调度的流程。

PD 不断的通过 Store 或者 Leader 的心跳包收集信息,获得整个集群的详细数据,并且根据这些信息以及调度策略生成调度操作序列,每次收到 Region Leader 发来的心跳包时,PD 都会检查是否有对这个 Region 待进行的操作,通过心跳包的回复消息,将需要进行的操作返回给 Region Leader,并在后面的心跳包中监测执行结果。注意这里的操作只是给 Region Leader 的建议,并不保证一定能得到执行,具体是否会执行以及什么时候执行,由 Region Leader 自己根据当前自身状态来定。 总结

时间: 2024-09-28 23:25:01

三篇文章了解 TiDB 技术内幕 —— 谈调度的相关文章

Matrix上的三篇文章

 今天无聊在网上搜索自己的名字时,忽然搜到了两年前参与Matrix网翻译项目时的三篇文章,这里做一个链接,也方便自己以后查找.   XFire:轻松简单地开发Web Services 作者:Shahid Ahmed ;mydeman原文:http://www.javaworld.com/javaworld/jw-05-2006/jw-0501-xfire.htmlMatrix:http://www.matrix.org.cn/resource/article/2006-09-24/XFire_6

软文营销之最 三篇文章给我带来80个意向客户

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 我们公司是做批发生意的,公司取了个很有创意的名字"闲贫爱富",创办的平台就是闲贫爱富批发网.我的任务就是负责推广这个网站,利用网站来寻找意向客户.站长朋友都知道,南昌有个地宝网,地宝网确实人气很大,我在地宝网发布的软文广告都被很快的收录.同时迅速收到很多网友的咨询.下面我将自己的敲推广窍门分享给大家. 一,寻找本地人气最大

有关WebService的三篇文章

让用户做好出发的准备.NET My Services 是XML Web服务的集合,它能够使集成目前已经存在的信息仓库(silo)的过程变得更容易.据微软称,这种服务让用户控制他们自己的数据和信息,保护个人信息的安全并提供一个新级别的易用性和个性化功能.从开发者的角度看,这种服务提供一个平台无关的方法来访问你的用户的信息.更仔细的说,有两种使用.NET My Services的开发方法.首先,我们可以用HailStorm-in-a-box创建自己的信息仓库,每个人都会从PDC学到这种方法.第二,我

三篇原创文章成功推广个人博客经验分享

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 看文章标题唬头很大,而且还有点不切实际.其实我想说的是做seo类的博客,要有分享的精神,博文必须要从自己优化经验.技巧.方法着手,让读者看完之后有种立即就想去做的冲动,那才是成功之作.切不可写一些云里雾里,不知所云的,让读者看完之后毫无所获,那回访用户就基本为零了.现如今推广优化分享类的文章大多是老生常谈了,看我们也不能不看,有时做优化到瓶颈

网上有篇文章谈了让李明远睡不好觉的3件事

网上有篇文章谈了让李明远睡不好觉的3件事:人才和选择,时间管理,权衡百度业务的加减法.其中,李明远透露了不少百度的移动互联网思路和布局,从搜索.地图.O2O谈到互联网金融,对外界关心的百度收购91是否值得,也做出了回应: 我们的股价从收购之后也上涨了很多.今天看依然是值得的,百度和91是互补的,因为我们做技术和系统比较强,91做商业和运营比较强比较灵活,他们离开发者更近.我觉得收购以后两边要花大力气去整合,在这方面百度等互联网公司都在摸索. 那么百度和91无线分别都进行了哪些摸索,现阶段摸索出来

鼠绘技术内幕完全接触-动物篇

动物是生态世界中重要的组成部分,在卡通绘画中,动物也是重要的组成部分,动物的千姿百态被设计师们充分的发挥利用,并注入了人类的思想感情,使得动物也变得和人一样感情丰富,幽默风趣.而且,在卡通的世界里,动物过着人一样的生活,和人一样也有忠奸善恶.喜怒哀乐,让原本有趣的卡通世界更加丰富多彩. 在讲述鼠绘动物技术内幕之前,先教大家几个学习动物鼠绘的方法: 集思广益:在动画世界里,动物占有相当大的比例,所以这方面成功的例子很多,大家可以收集并分析;了角同一种动物的不同种表现方法,以便更好的掌握它的形象特征

城市大脑技术厉害了!阿里 iDST 三篇相关论文入选ACM MM

在近日召开的ACM Multimedia 2017会议上,来自阿里巴巴iDST(Institute of Data Science and Technologies)团队的三篇关于"城市大脑"的论文入选其中,三位论文作者受邀赴峰会做报告. ACM MM是全球多媒体领域的顶级会议,属中国计算机学会(CCF)指定的A类国际会议.今年受邀赴美作口头报告的论文作者占比仅为7.5%,ACM MM组委会在邮件中称整个论文评选过程为"艰难激烈的".此次阿里巴巴入选的三篇论文涉及的

Spark技术内幕: Shuffle详解(三)

前两篇文章写了Shuffle Read的一些实现细节.但是要想彻底理清楚这里边的实现逻辑,还是需要更多篇幅的:本篇开始,将按照Job的执行顺序,来讲解Shuffle.即,结果数据(ShuffleMapTask的结果和ResultTask的结果)是如何产生的:结果是如何处理的:结果是如何读取的. 在Worker上接收Task执行命令的是org.apache.spark.executor.CoarseGrainedExecutorBackend.它在接收到LaunchTask的命令后,通过在Driv

COM技术内幕(笔记)

COM--到底是什么?--COM标准的要点介绍,它被设计用来解决什么问题?基本元素的定义--COM术语以及这些术语的含义.使用和处理COM对象--如何创建.使用和销毁COM对象.基本接口--描述IUnknown基本接口及其方法. 掌握串的处理--在COM代码中如何处理串.应用COM技术--例子代码,举例说明本文所讨论的所有概念. 处理HRESULT--HRESULT类型描述,如何监测错误及成功代码. COM--到底是什么?     简单地说,COM是一种跨应用和语言共享二进制代码的方法.与C++