作者介绍:吴叶磊 PingCAP Cloud 工程师。
随着 Kubernetes(K8s)的全面成熟,越来越多的组织开始大规模地基于 K8s 构建基础设施层。然而,思考到数据库在架构中的外围位置与 K8s 在有状态利用编排上的短板,仍有不少组织认为在 K8s 上运行外围数据库会带来颇高的危险。事实上,在 K8s 上运行 TiDB 不仅能实现企业技术栈的对立,升高保护老本,还能带来更高的可用性与安全性。本次分享将介绍 TiDB 在 K8s 上的运维管理系统 TiDB Operator,再从各类故障场景动手分析 TiDB on K8s 如何实现高效的故障自愈并保障数据安全。最初,咱们会分享来自国内外一线公司的 TiDB Operator 生产环境案例,并总结出一套 TiDB on K8s 最佳实际。
要不要在 Kubernetes 上运行 TiDB?
这个问题其实始终以来也有很多的争议。大家都晓得,Kubernetes 的很多概念是为无状态利用(比方微服务)所设计的。因为云原生技术的一直遍及,Kubernetes 目前在国内外的很多技术畛域都失去大规模的落地,有一种全盘上 Kubernetes 的趋势。但在这期间也有不少人提出了质疑,比方:是不是所有的业务场景都适宜 Kubernetes?咱们的组织是不是真的须要 Kubernetes?这样的争议,其实这背地的各种声音都有各自的出发点。
首先 Kubernetes 有没有价值?必定有价值,它的遍及度就是很好的证实。那 Kubernetes 有没有问题?当然也有问题,比方,Kubernetes 会增上技术上的复杂度,此外它还有有比拟大的迁徙老本。
回到 TiDB 要不要在 Kubernetes 下面运行这个问题。答案其实往往来自于你以后的技术栈和技术团队。
举个例子,如果你的大部分利用曾经上了 Kubernetes,而且你的工程师也对 Kubernetes 很相熟,在 Kubernetes 下来做一些业务,他感觉十分难受,那么 TiDB 就不该成为一个例外。换句话说,如果以后整个组织的业务都曾经上 Kubernetes 了,但还须要专门招一个运维团队在虚拟机上运维 TiDB 的话,不仅会减少额定的保护老本,也没方法施展出技术栈投资的规模劣势。
那么,在 K8s 运行 TiDB,咱们想要什么呢? 通常,咱们想要的是 TiDB 能够和咱们在 K8s 上运行的微服务一样,能够做到申明式治理,通过 K8s 实现 TiDB 的自动化运维以及弹性资源配置 。我想扩容的时候,并不需要去专门开新的物理机,专门购买一批机器,而是间接从整个的 K8s 资源池中,弹性的给 TiDB 调配一些资源进行扩容,而后再缩容之后又把这些资源还回去。
可是,当初的状况是,即便很多公司曾经上了 K8s,但对于把数据库放在 K8s 上运行还是有肯定的担心,这个担心次要在哪儿呢?
从我集体理解到的信息来说,外围是稳定性,稳定性,最初还是稳定性 ,因为毕竟咱们要上的是数据库。几年前,大家刚开始上 K8s 的时候,会感觉我的业务上在 K8s 上用的很爽,那要不要把数据库也搞上去?那总会有一种声音是,数据库怎么能上 K8s 呢?咱们数据库的稳定性要求比 K8s 还要高啊!如果 K8s 挂了,那可能只是线上的微服务无奈提供服务,然而如果数据库挂了,咱们不仅无奈提供服务,还有可能面临数据失落的危险。所以通常来说,在组织中,数据库可靠性是处于一个外围位置的,也因而在数据库上 K8s 时,一个外围的担心就是可靠性。
那么,咱们在部署传统数据库利用的时候,是怎么保障稳定性的?一般来说,是开几台固定的物理机,而后咱们会把数据库的 Binary 传上去运行起来,这时候要点就是,运行起来之后只有不出问题就不要再动它(If it works don’t touch it)。即便要动它,也须要通过一个十分严苛的审计流程和预演,保障它最佳的稳定性。听起来,对于传统的关系型数据库而言,高度动态化的 K8s 环境并不是一个很好的解决方案。
那为什么还会举荐大家把 TiDB 放在 K8S 上运行呢?
第一点,TiDB 自身可能适应动态化的 K8S 环境 。
- TiDB 能够多正本做容错,当挂掉一个集群当中的小数节点并不会对整个集群的运行产生影响;
- TiDB 可能很好的借助 K8s 环境做程度伸缩;
- TiDB 提供了开箱自用的可观测性,大家基本上把 TiDB 部署起来,就能够看到 TiDB 的所有指标,即便是在一个动态化混部的环境外面,也能很分明的明确 TiDB 当初的状态是什么,即便有正本挂掉,也没有问题。
第二点,反回来,K8s 也能很高效的去撬动 TiDB 的后劲 。
- 申明式 API 简化集群治理,作为一个分布式数据库,TiDB 的治理会比传统的单机数据库绝对简单一点,而在 K8s 上,它的申明是 API,就能把这一点多进去的复杂度很好的消化掉;
- 弹性资源池简化扩容缩与故障转移,TiDB 的故障容忍和有限的程度伸缩都须要额定的资源,比如说,咱们去横向扩张 TiDB 集群时,须要申请一部分新的资源进来,在故障容错之后,要做故障转移把故障正本数补齐。那么 K8s 的弹性资源池就能很好的把 TiDB 在程度伸缩和故障容忍上的后劲施展进去。
因而,TiDB 和 K8S 可能十分好的进行一个联合,并且开释出更大的后劲达成 1+1 大于 2 的成果的。这当然不是一个偶合,这背地的起因是,TiDB 和 K8s 都遵循同样的云原生最佳实际准则。那么如果说咱们曾经相熟 TiDB 和 K8s 的常识,只有略微破费一些时间,用 K8s 的云原生对象就能够部署一个 TiDB 集群,而且能运行的不错。
然而,TiDB 和 Kuberentes 都有大量的最佳实际,基本上你想疾速看完是有点艰难的。那么,咱们在 K8s 上部署 TiDB 的时候,应该怎么去恪守最佳实际呢?一个根本的方法就是把这些坑都理解分明,并且写十分多的 run book 来通知 SRE team,怎么去运维好它们。run book 须要口口相传,须要一直的进行常识的交互、交换。但其实大家都晓得,程序员个别不喜爱做这个。
咱们更喜爱把这些常识写成代码,做自动化。那么,咱们怎么样把这些货色写成代码自动化呢?
你的 TiDB on Kubernetes 运维专家:TiDB Operator
答案就是 TiDB Operator。TiDB Operator 是什么?实质就是利用 K8s 自身的扩大机制,把畛域性的运维常识编写成代码,大家能够把 TiDB Operator 了解为在 K8s 上运行 TiDB 的运维专家,把一个专家型人物对 TiDB 和 K8s 的所有常识都编写成了代码。
TiDB Operator 首先增加了一组自定义类型,比如说 TiDB Cluster,代表一个 TiDB 集群,能够在这些类型里形容你想要的 TiDB 长什么样;第二,TiDB Operator 增加了一组自定义控制器,这组自定义控制器就是这些运维常识的汇合,它会用这些代码化的常识帮忙你自动化的运维 K8s 上的 TiDB 集群。
看一个例子:首先是自定义类型,当 TiDB Operator 把自定义类型增加到 K8s 中后,作为用户就能够提交资源定义到 K8s 外面,比方咱们须要一个 TiDB 集群,这个集群要的版本是什么,要多少 PD,要多少 KV。以及咱们能够定义一个 TiDBMonitor 对象,用来监控 TiDB,在对象定义里则只须要定义咱们要监控哪一个 TiDB 就能够了。
那么,大家能够发现,咱们在做这些资源定义时是遵循 K8s 自身的申明式定义的。那这些的现实状态由谁来实现呢?——由自定义控制器。自定义控制器会把所有的需要和 K8s 集群里的理论状态做一个比照,比照之后就能发现两者的不同,就须要把理论状态向冀望状态转移。比如说咱们把刚刚的 TiDB 集群对象和 TiDB 监控对象提交到 K8s,那么 TiDB Operator 的控制器就会帮忙咱们创立很多的容器以及监控。
当然,仅仅只有创立是不够的,TiDB Operator 中还集成了 TiDB 运维专家的所有的畛域常识,上面我分享几个运维常识。
运维常识:部署
- TiDB Operator 会为每个组件抉择最佳的 K8s 原生对象;
- 会主动地疏导 PD 做 Peer Discovery,无需手工配置;
- 最重要的,还会打散 TiKV 容器并主动增加 store-label,辅助 PD 实现 Region 高可用拓扑。
运维常识:降级
滚动降级 TiKV 的时候,给每个 TiKV 实例发个 SIGTEM,这时 TiKV 其实只会做一些根本的 Graceful Shutdown 操作。那就有一个问题,TiKV 退出时并不会被动的把所有的 Raft Leader 都迁徙进来。假如咱们有比拟大的流量,滚动降级时让没有受影响的 Raft Group 被动地去做一个 leader 超时从新选举,那很可能会导致咱们的数据库提早会有肯定的抖动。
那么 TiDB Operator 怎么做降级呢?在每次降级一个 TiKV 的容器之前,Operator 会先调用 PD 接口,把 TiKV 上边的 leader 全副迁徙完,不接管读写申请后才会去重建 TiKV 的容器。顺次往返,比方把 TiKV2 迁完了,就要把 TiKV2 重建,TiKV2 重建后,又能够把 leader 迁上去,接管申请,而后下一个就是把 TiKV1 的 leader 迁完,再往下。实现一个优雅的滚动降级。
运维常识:故障转移
比方,当初 TiKV1 运行的不失常,那么 Operator 的控制器就能够联合 PD 里的 TiKV1 对应的 store 状态信息和 K8s 里它所在容器的状态信息,来判断这一个 TiKV 的 store 是否异样。判断逻辑大抵是 store 处于异样状态,并且继续超过肯定工夫。检测到异样后隔多久再做故障复原以及怎么样判断是否产生异样,自身也是一种运维常识。
那 Operator 有了这些常识并且把它代码化之后,就能够在检测到异样后,过一段正当的工夫后再补充新的 store,把正本数补齐。这样即便咱们接下来 TiKV2 再挂,那集群就不会受影响,这就是 Operator 帮忙咱们做的故障转移。
Operator 在最新版里还提供了 on to scaling 的性能,咱们去查看集群当中的所有的组件的监控信息,并且依据这些监控信息,做主动的扩缩容,可想而知就须要更多的反对了。
大家可能会想,只管 Operator 带来了这么多益处,但我还是放心如果用 Operator 上了 K8s 之后会有一些问题。比方,上 K8s 会带来多少性能损耗?会影响我的稳定性吗?如果 K8s 挂了,我的数据库会不会受影响呢?一个 TiDB 和 K8s 的领域专家是能够解答这些问题的,因而,TiDB Operator 当然也能够。
运维常识:性能
- TiDB Operator 反对独享节点与混部,能够依照优先级衡量性能与老本;
- 自动化运维常识思考了本地盘,应用本地盘就能够打消近程存储的损耗;
- 反对 K8s 的 HostNetwork 部署集群,打消二层网络开销,所以说在肯定的配置下,用 TiDB Operator 部署 TiDB 其实是能够做到零 overhead 的。
运维常识:稳定性
- K8s Master 故障不会影响集群,因为只是管制节点故障,跑 TiDB 的节点并没有故障;
- K8s Node 故障会帮咱们做主动故障转移;
- 如果 K8s 的整个集群所有节点都故障了怎么办?Operator 自身有一个默认配置是在这种状况下会保留所有的存储,首先先保证数据不丢。
- 假如真的是产生了灾难性的故障,整个机房比如说被水淹了怎么办?Operator 自身也会帮你做周期的备份,至多能够找回最近一次的备份,把你的数据先复原到某个近期的工夫点上。
Operator 开箱即用给咱们很多稳定性上的加强,也就是说在稳定性方面,Operator 给了咱们一个很好的基石,咱们能够持续在基石上再做一些加强,这能够省很多的时间,并且取得更好的稳定性。
最佳实际案例:PayPay& 马上生产金融
最初再来看两个案例,第一个案例是 日本当先的在线领取公司 PayPay。PayPay 在日本就能够了解为中国的 AliPay 加微信领取。PayPay 当初是用 Operator 部署了 100 多个数据库节点,生产环境有 30 多个由 Operator 治理的节点。PayPay 过后在做 PoC 时,做了相当详尽的故障演练,包含各种过程故障、节点故障、以及 AWS 整个可用区故障和还有劫难复原。比方模仿 AWS 整个全挂了,还能不能通过周期性备份把集群复原进去,过后也是这些所有的故障演练都很好的通过了 PayPay 的审核,PayPay 才得以释怀把整套集群放到到 TiDB Operator 和 K8s 上来。
第二案例是咱们国内的马上生产金融。上线的是零碎归档和跑批业务,整个线上集群是有 60 多个物理节点,他们最显著的一点就是在用了 TiDB Kuberentes 之后,整个混部的硬件老本降落到原来物理机部署的 30% 左右。因而在整体的性价比上是一个微小的晋升。
最初总结一下,什么是 TiDB 在 K8s 上的最佳实际?其实只有一句话,Keep Calm and Use TiDB Operator。当然,用 TiDB Operator 自身还是须要肯定的上手老本的,这点咱们也在一直的做改良,大家能够参考咱们的官网,看一下 TiDB Operator 的 一系列文档,让这个运维专家来为你的 TiDB Kuberentes 之旅保驾护航。