写点什么

云计算架构下 Cloud TiDB 的技术奥秘「下」

  • 2019-11-13
  • 本文字数:3484 字

    阅读完需:约 11 分钟

云计算架构下 Cloud TiDB的技术奥秘「下」

《云计算架构下 Cloud TiDB的技术奥秘「上」》中,分析了 TiDB 与传统单机关系型数据库的区别,以及与几种技术整合之后所形成的总体架构。接下来,我们将深度探讨 Cloud TiDB 的关键特性和实现细节。

自动化运维

数据库产品上云的一个先决条件是能实现自动化的运维管理,因为在云上靠手工运维几乎是不现实的。


第一步,用 Kubernetes 将云平台的主机资源管理起来,组成一个大资源池;

第二步,再通过 tidb-opeartor 及 tidb-cloud-manager 等组件,来自动化完成 TiDB 实例的一键部署、扩容缩容、在线滚动升级、自动故障转移等运维操作。


来看集群创建。 在上篇文章里提到过 TiDB 包含 tidb、tikv 和 pd 三大核心组件,每个服务又都是一个多节点的分布式结构,服务和服务之间的启动顺序也存在依赖关系。此外,pd 节点的创建和加入集群方式与 etcd 类似,是需要先创建一个单节点的 initial 集群,后加入的节点需要用特殊的 join 方式,启动命令上也有差别。


有一些操作完成后还需要调用 API 进行通知。Kubernetes 自身提供的 StatefulSet 很难应付这种复杂部署,所以需要 tidb-operator 中实现特定 Controller 来完成这一系列操作。同时,结合 Kubernetese 强大的调度功能,合理规划和分配整个集群资源,尽量让新部署的 TiDB 实例节点在集群中均匀分布,最终通过 LB 暴露给对应的租户使用。


在线升级也类似。 由于 tikv/pd 的 Pod 挂载是本地存储,并不能像云平台提供的块存储或网络文件系统那样可以随意挂载。如果 tikv/pd 迁移到其它节点,相当于数据目录也被清空,所以必须保证 tikv/pd 的 Pod 在升级完成后仍然能够调度在原地,这也是要由 tidb-operator 的 Controller 来保证。


TiDB 的数据副本之间由 Raft 算法来保证一致性,当集群中某一个节点暂时断开,可以不影响整个服务,所以在集群升级过程中,必须严格按照服务的依赖关系,再依次对 Pod 进行升级。


当节点出现故障时。 同样是由于挂载本地数据盘的原因,也不能像 StatefulSet 那样直接把 Pod 迁移走。当 TiDB Operator 检测到节点失效,首先要等一段时间,以确认节点不会再恢复了,再开始迁移恢复的操作。


首先调度选择一个新节点启动一个 Pod, 然后通知 TiDB 将失效节点放弃掉,并将新启的 Pod 加入集群。后面会由 TiDB 的 PD 模块来完成数据副本数恢复以及数据往新节点上迁移,从而重新维持集群内数据平衡。


以上仅列举了 TiDB 几种典型的运维操作流程,实际生产上运维还有很多 case 需要考虑,这些都以程序的方式在 tidb-operator 里实现。借助 Kubernetes 和 tidb-operator 来代替人工,高效地完成 TiDB 数据库在云平台上的复杂运维管理。



(图:Cloud TiDB 总体架构图)

动态扩缩容

弹性水平伸缩是 TiDB 数据库最主要的特性之一。在大数据时代,人们对数据存储的需求快速膨胀,有时用户很难预估自己业务规模的增长速度,如果采用传统存储方案,可能很快发现存储容量达到了瓶颈,然后不得不停机来做迁移和扩容。如果使用 Cloud TiDB 的方案,这个过程就非常简单,只需在 Cloud 控制台上修改一下 TiDB 的节点数量,就能快速完成扩容操作,期间还不会影响业务的正常服务。


那么,在 Cloud 后台,同样借助 Kubernetes 和 tidb-operator 的能力来完成 TiDB 增减节点操作。Kubernetes 本身的运作是基于一种 Reconcile 机制,简单来说就是当用户提交一个新请求,比如期望集群里跑 5 个 TiKV 节点,而目前正在跑的只有 3 个,那么 Reconcile 机制就会发现这个差异,先由 Kubernetes 调度器根据集群整体资源情况,并结合 TiDB 节点分配的亲和性原则和资源隔离原则来分配节点。另外很重要一点是选择有空闲 Local PV 的机器来创建 Pod 并进行挂载,最终通过 tidb-operator 将 2 个节点加入 TiDB 集群。


缩容的过程也类似。假如数据库存储的总数据量变少,需要减少节点以节省成本,首先用户通过云控制台向后端提交请求,在一个 Reconciling 周期内发现差异,tidb-operator 的 Controller 开始通知 TiDB 集群执行节点下线的操作。安全下线可能是比较长的过程,因为需要由 PD 模块将下线节点的数据搬移到其他节点,期间集群都可以正常服务。当下线完成,这些 TiKV 变成 tombstone 状态,而 tidb-operator 也会通知 Kubernetes 销毁这些 Pod,并且由 tidb-volume-manager 来回收 Local PV。

资源隔离

资源隔离也是云上用户关心的一个问题。尤其是数据库这类应用,不同租户的数据库实例,甚至一个租户的多套数据库实例,都跑在一套大 Kubernetes 管理集群上,相互间会不会有资源争抢问题?某个实例执行高负载计算任务时,CPU、内存、I/O 等会不会对同台机器上部署的其他实例产生影响?


其实,容器本身就是资源隔离的一个解决方案,容器底层是 Linux 内核提供的 cgroups 技术,用于限制容器内的 CPU、内存以及 IO 等资源的使用,并通过 namespace 技术实现隔离。而 Kubernetes 作为容器编排系统,能根据集群中各个节点的资源状况,选择最优策略来调度容器。同时,tidb-operator 会根据 TiDB 自身特性和约束来综合决策 TiDB 节点的调度分配。


举例来说,当一个 Kubernetes 集群横跨多个可用区,用户申请创建一个 TiDB 集群,那么首先根据高可用性原则,将存储节点尽量分配到不同可用区,并给 TiKV 打上 label。那么同一个可用区内也尽量不把多个 TiKV 部署到相同的物理节点上,以保证集群资源最大化利用。


此外,每个 Local PV 也是一块独立磁盘,每个 TiKV 的 Pod 分别挂载不同的盘,所以 I/O 上也是完全隔离。


Kubernetes 还可以配置 Pod 之间的亲和性(affinity)和反亲和性(anti-affinity)。例如:在 TiKV 和 TiDB 之间,可以通过亲和性使其调度到网络延时较小的节点上,提高网络传输效率。TiKV 之间借助反亲和性,使其分散部署到不同主机、机架和可用区上,降低因硬件或机房故障而导致的数据丢失风险。


上面解释了容器层的隔离,也可以看作是物理层的隔离。再来看数据层的隔离,TiDB 的调度体系也有所考虑,比如一个大的 TiDB 集群,节点分布在很多台主机,跨越多个机架、可用区,那么用户可以定义 Namespace,这是一个逻辑概念,不同业务的数据库和表放置在不同的 Namespace,再通过配置 Namespace、TiKV 节点以及区域的对应关系,由 PD 模块来进行调度,从而实现不同业务数据在物理上的隔离。

高可用性

TiDB 作为一个分布式数据库,本身就具有高可用性,每个核心组件都可以独立地扩缩容。任意一个模块在部署多份副本时,如果有一个挂掉,整体仍然可以正常对外提供服务,这是由 Raft 协议保证的。


但是,如果对数据库节点的调度不加任何限制,包含一份数据的多个副本的节点可能会被调度到同一台主机。这时如果主机发生故障,就会同时失去多个副本,一个 Raft 分组内失去多数派节点就会导致整个集群处于不可用状态,因此 tidb-operator 在调度 TiKV 节点时需要避免出现这种情况。


另外,TiDB 支持基于 label 的数据调度,能给不同 TiKV 实例加上描述物理信息的 label,例如地域(Region)、可用区(AZ)、机架(Rack)、主机(Host),当 PD 在对数据进行调度时,就会参考这些信息更加智能地制定调度策略,尽最大可能保证数据的可用性。


例如,PD 会基于 label 信息尽量把相同数据的副本分散调度到不同的主机、机架、可用区、地域上,这样在物理节点挂掉、机架掉电或机房出故障时,其它地方仍然有该数据足够的副本数。借助 tidb-operator 中 controller-manager 组件,可以自动给 TiKV 实例加上物理拓扑位置标签,充分发挥 PD 对数据的智能调度能力,实现数据层面的高可用性。


同时,还可以达到实例级别的高可用性,通过 Kubernetes 强大的调度规则和扩展的调度器,按优先级会尽量选择让 TiKV 部署到不同的主机、机架和可用区上,把因主机、机架、机房出问题造成的影响降到最低,使数据具有最大的高可用性。


另外,运行在 Kubernetes 之上,能实时监测到 TiDB 各组件运行情况,当出现问题时,也能第一时间让 tidb-operator 对集群进行自动修复 (self-healing)。具体表现为 tidb/tikv/pd 实例出现故障时,执行安全的下线操作,同时增加新实例来保证集群的规模和之前一致。

小结

TiDB 作为一款 Cloud Native Database,通过 tidb-operator 方式充分发挥 Kubernetes 平台的强大能力,实现云上自动化管理,极大降低人力运维成本。用户可以根据业务需要进行动态扩容缩容,多租户隔离特性让不同租户的实例可以共享计算和存储资源,互不干扰,同时最大程度充分使用云上资源。Raft 算法和 tidb-operator 自动修复能力以及两层调度机制保证了 Cloud TiDB 的高可用性。


本文转载自公众号 UCloud 技术(ID:ucloud_tech)。


原文链接:


https://mp.weixin.qq.com/s/EKUimeulhGc-hXR8Sto2rQ


2019-11-13 17:101045

评论

发布
暂无评论
发现更多内容

HDI硬件设备接口介绍

科技汇

Demo:第三章:权限框架spring security oauth2

爱好编程进阶

程序员 后端开发

DM 是如何处理 DML 的丨TiDB 工具分享

PingCAP

npm install xxxx --legacy-peer-deps命令是什么?

华为云开发者联盟

前端 npm install 依赖树 对等依赖关系

Java培训MySQL体系构架、存储引擎和索引结构

@零度

MySQL JAVA开发

java不使用客户端授权密码直接用账号密码发送带附件的邮件

爱好编程进阶

程序员 后端开发

dubbo实战之二:与SpringBoot集成

爱好编程进阶

Java 程序员 后端开发

秒云 (元来云志)获邀加入中国开源云联盟,共筑开源生态

MIAOYUN

开源 开源生态 开源中国

简述数仓的时间域函数

华为云开发者联盟

数据库 时间 时间戳 GaussDB(DWS) 时间域函数

使用xdebug调试php详细教程

CRMEB

ArrayList 与 LinkedList 的方法及其区别

爱好编程进阶

程序员 后端开发

BIO、NIO、AIO 介绍和适用场景分析

爱好编程进阶

Java 程序员 后端开发

助力提升研发效能的“黄金三角”

博文视点Broadview

JAVA API调用elasticsearch实现基本增删改查

爱好编程进阶

程序员 后端开发

聊聊如何在华为云IoT平台进行产品开发

华为云开发者联盟

物联网平台 IoT 华为云 iotda 设备接入

Go 语言入门很简单:net/http 包

宇宙之一粟

HTTP Go web 4月月更

Java-进阶:集合框架1

爱好编程进阶

程序员 后端开发

Java8新特性-Optional

爱好编程进阶

Java 程序员 后端开发

Java中当对象不再使用时,不赋值为null会导致什么后果?

爱好编程进阶

Java 程序员 后端开发

BATJAndroid高级工程师大厂面试题集合之Java-基础面试知识点

爱好编程进阶

Java 程序员 后端开发

网易云信 QUIC 应用优化实践

网易云信

音视频开发

git(8)Git 与其他系统

爱好编程进阶

Java 程序员 后端开发

OpenHarmony新增两个分布式能力!快来了解~

科技汇

Choreographer全解析

爱好编程进阶

Java 程序员 后端开发

curl 的用法指南

爱好编程进阶

Java 程序员 后端开发

Hibernate实现CRUD(附项目源码)

爱好编程进阶

Java 程序员 后端开发

与多家机构战略合作,背后彰显PlatoFarm元宇宙龙头的实力

西柚子

使用APICloud & MobTech SDK 快速实现分享到社交平台功能

YonBuilder低代码开发平台

APP开发 APICloud MobTech袤博科技 社交分享

web前端培训React 中Router的必备知识点

@零度

前端开发 React

Docker Swarm从部署到基本操作

爱好编程进阶

Java 程序员 后端开发

GitHub上超火的阿里调优专家的677页Java性能调优笔记,已让我拿下5个offer

爱好编程进阶

Java 程序员 后端开发

云计算架构下 Cloud TiDB的技术奥秘「下」_文化 & 方法_UCloud技术_InfoQ精选文章