57

云计算架构下 Cloud TiDB的技术奥秘「上」 | U刻

 6 years ago
source link: http://blog.ucloud.cn/archives/2759?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

近日,国内中立云计算服务商UCloud与国内开源分布式NewSQL数据库TiDB团队PingCAP正式达成合作,双方联手在UCloud全球数据中心推出了新一代TiDB的云端版本——Cloud TiDB。

作为一款定位于Cloud-native的数据库,截至目前TiDB在云整合上已取得了阶段性进展。Cloud TiDB产品在UCloud平台正式开启公测,TiDB弹性伸缩特性在Cloud 提供的基础设施支持下得到了淋漓尽致的展现。

在感受云数据库魅力的同时,让我们来探索一下TiDB与Cloud背后的技术秘密。

TiDB与传统单机关系型数据库的区别

首先,从TiDB的架构说起。TiDB作为一款开源的分布式数据库产品,具有多副本强一致性,能够根据业务需求非常方便的进行弹性伸缩,并且扩缩容期间对上层业务无感知。

TiDB的主体架构包含三个模块,对应Github上PingCAP组织下的三个开源项目(TiDB / TiKV / PD):

1.TiDB主要是负责SQL的解析器和优化器,它相当于计算执行层,同时也负责客户端接入和交互;

2.TiKV是一套分布式的Key-Value存储引擎,它承担整个数据库的存储层,数据水平扩展和多副本高可用特性都在这一层实现;

3.PD相当于分布式数据库的大脑,一方面负责收集和维护数据在各个TiKV节点的分布情况,另一方面PD承担调度器的角色,根据数据分布状况以及各个存储节点的负载来采取合适的调度策略,维持整个系统的平衡与稳定。

上述三个模块中的每个角色都是一个多节点组成的集群,所以最终TiDB的架构如下图所示:

1-1.png

由此可见,分布式系统本身的复杂性不仅导致手工部署和运维成本较高,而且容易出错。传统的自动化部署运维工具(如:Puppet/Chef/SaltStack/Ansible等),由于缺乏状态管理,在节点出现问题时不能及时自动完成故障转移,需要运维人员人工干预,有些则需要写大量DSL甚至与Shell脚本一起混合使用,可移植性较差,维护成本比较高。

在云时代,容器成为应用分发部署的基本单位,谷歌基于内部使用数十年的容器编排系统Borg经验,推出的开源容器编排系统Kubernetes就成为当前容器编排技术的主流。

TiDB Kubernetes的深度整合

作为Cloud Native Database,TiDB选择拥抱容器技术,并与Kubernetes进行深度整合,使其可以非常方便地基于Kubernetes完成数据库自动化管理。甚至可以说Kubernetes项目是为Cloud而生,利用云平台IaaS层提供的API可以很方便地与云进行整合。这样只要让TiDB与Kubernetes 结合得更好,进而就能实现其与各个云平台的整合,使TiDB在云上的快速部署和高效运维成为现实。

1.Kubernetes简介

Kubernetes最早是作为一个纯粹的容器编排系统而诞生,用户部署好Kubernetes集群之后,直接使用其内置的各种功能部署应用服务。由于这个PaaS平台使用起来非常便利,吸引了很多用户,不同用户也提出了各种不同需求,有些特性需求Kubernetes 可直接在其核心代码里实现,但有些特性并不适合合并到主干分支。

为了满足这类需求,Kubernetes开放出一些API供用户自己扩展,实现自身需求。当前Kubernetes已经升级到v1.8版本,内部API变得越来越开放,使其更像是一个跑在云上的操作系统。用户可以把它当作一套云的SDK或Framework来使用,而且可以很方便地开发组件来扩展满足自身业务需求,对有状态服务的支持就是一个代表性实例。

在最早期,Kubernetes 项目只支持无状态服务(Stateless Service) 来管理,无状态服务通过ReplicationController定义多个副本,由Kubernetes调度器来决定在不同节点上启动多个Pod,实现负载均衡和故障转移。对于无状态服务,多个副本对应的 Pod是等价的,所以当节点出现故障时,在新节点上启动一个Pod与失效的Pod是等价的,不会涉及状态迁移问题,因而管理非常简单。

2.有状态服务Stateful Service

不过,对于有状态服务 (Stateful Service),由于需要将数据持久化到磁盘,使得不同Pod之间不能再认为成等价,也就不能再像无状态服务那样随意地进行调度迁移。Kubernetes v1.3版本提出PetSet的概念,用来管理有状态服务并在v1.5版本中将其更名为StatefulSet。

StatefulSet明确定义了一组Pod中的每个身份,启动和升级都按特定顺序来操作。另外,使用持久化卷存储(PersistentVolume)来作为存储数据的载体,当节点失效 Pod需要迁移时,对应的PV通过umount/mount方式跟着一起迁移到新节点,或者直接使用分布式文件系统作PV底层存储,使Pod在迁移后仍然能访问到之前的数据。

同时,Pod在发生迁移时,其网络身份(例如IP地址)是会发生变化的,很多分布式系统不能接受这种情况,所以StatefulSet在迁移Pod时可以通过绑定域名的方式来保证Pod在集群中网络身份不发生变化。

然而,现实中一些分布式系统更为复杂,StatefulSet也显得捉襟见肘。举例来说,某些分布式系统的节点在加入集群或下线时,还需要做些额外的注册和清理操作,或者在滚动升级时,要考量版本兼容性等问题。

基于上述原因,CoreOS公司提出了Operator概念,并实现了etcd-operator和prometheus-operator来管理Etcd和Prometheus这样复杂的分布式系统。用户可以开发自己的Operator,在Kubernetes之上实现自定义的Controller,将有状态服务领域中特定的运维知识编码进去,从而实现对特定分布式系统的管理。同时,Operator本身也是跑在Kubernetes中的一个Pod(deployment),对Kubernetes系统并无侵入性。

3.TiDB多组件支持

针对TiDB这种复杂的分布式服务,我们开发了tidb-operator等一系列组件,来管理 TiDB集群实例在Kubernetes平台上的创建、销毁、扩缩容、滚动升级和故障转移等运维操作。同时,在上层封装了一个tidb-cloud-manager组件,提供RESTful接口,实现了与云平台的控制台打通功能。这就完成了一个DBaaS(数据库即服务)架构的基本形态。

由于TiDB对磁盘I/O有比较高的要求,通过PV挂载网络盘,会有明显的性能损耗。另外,TiKV本身维护了数据多副本,这点和分布式文件系统的多副本是有重复的,所以要给Pod上挂载本地磁盘,并且在Kubernetes上把Local PV管理起来,作为一种特定资源来维护。

Kubernetes官方长期以来一直没有提供Local PV支持,本地存储只支持hostPath和 emptyDir两种方式。其中,hostPath的生命周期是脱离Kubernetes管理的,使用 hostPath的Pod销毁后,里面的数据是不会被自动清理,下次再挂载Pod就会造成脏数据。而emptyDir更像是一个临时磁盘,在Pod重建时会被清理重置,不能成为持久化PV来使用。

为此,我们开发了一个tidb-volume-manager组件,用于管理Kubernetes集群中每台物理主机上的本地磁盘,并且将其暴露成一种特殊的PV资源。结合Operator在部署TiDB节点时会参考Local PV资源的情况,来选择特定节点进行部署,分配一个空的Local PV和Pod绑定。而当Pod销毁时,会根据具体情况决定是否结束Local PV的生命周期,释放掉的Local PV在经历一个GC周期后,被tidb-volume-manager回收,清理其盘上数据等待再次被分配使用。

 Cloud TiDB 总体架构图

2.png

将这些组件整合起来,就形成了上图描述的Cloud TiDB总体架构。在Kubenetes管理的集群上,通过tidb-operator等组件针对性的调配和使用集群资源,从而实现TiDB集群实例的生命周期管理。通过这种方式实现TiDB分布式数据库和云平台的整合。

我们将在下一篇中详细介绍针对Cloud TiDB的关键特性和实现细节。

想要获取更多技术和活动资讯,可扫描以下二维码,关注“UCloud技术公告牌”微信公众号。
6-2.png

*本平台所发布文章信息,版权归UCloud所有,如需转载请注明出处!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK