云原生应用需要云原生数据库来实现下一阶段的成熟和规模化目标,但什么是云原生数据库呢?我们来尝试定义它的含义并弄清楚它与 Kubernetes 之间的关系。——Jeff Carpenter
“云原生”的概念已经成为众多应用逻辑和基础设施(包括数据库)最佳实践的集合。然而,许多支持我们应用程序的数据库已经存在了几十年,甚至在早在云或云原生出现之前就已经诞生。现在,与这些遗留解决方案相关的数据引力限制了我们迁移应用程序和负载的能力。随着云上迁移的到来,我们该如何变革数据存储方法?我们需要云原生数据库吗?数据库云原生到底意味着什么?我们来一起看看这些问题的答案。
什么是云原生?
术语定义是一个很好的研究起点。理解“云原生”时,我们可以从“原生”这个词开始研究。在英文中,原生(native)能让人自然地联想起母语、母国或原籍贯。在自然界中,native 会让人想到野生动物居住的原始栖息地,以及物种适应各自环境的途径。我们可以借此来理解云原生的含义。
以下是云原生计算基金会(CNCF)对该术语的定义:
“云原生技术使组织能够在现代、动态的环境(例如公共云、私有云和混合云)中构建和运行可扩展的应用程序,容器、服务网格、微服务、不可变基础设施和声明式 API 都是这种方法的例证。基于这些技术可以实现具有弹性、可管理和可观察的松散耦合系统。结合强健的自动化能力,它们让工程师能够以最少的工作量频繁且可预测地做出高影响力的更改。”
这是一个内涵丰富的定义,但用这个定义来解释“什么是云原生数据库”还是有点困难。正如 CNCF 全景图中数据库部分所展示的那样:数据库只是拥挤的云计算领域的一小部分。
仔细观察,你会在图上发现各种各样的产品:传统的关系型数据库和 NoSQL 数据库、各种不同的数据模型,包括键/值、文档和图形。你还会发现在现有数据库之上分层集群、查询或模式管理功能的技术。还有 CNCF 领域中的相关类别,例如用于数据移动的流式传输和消息传递,或用于持久性的云原生存储。
这些数据库中哪些是云原生的?除了那些为云设计的,我们是否应该包括那些可以适应在云中工作的?Bill Wilder 在他 2012 年出版的《云架构模式》一书中提供了一个有趣的观点,将“云原生”定义为:
任何旨在充分利用云平台的应用程序。
根据这个定义,云原生数据库是那些被设计为充分利用底层云基础设施的数据库。这其实显而易见。
为什么要关心数据库是否云原生?
云原生数据库有什么优势?我们考虑推动云计算普及的两个主要因素:成本和上线速度。
成本——即用即付的能力对于云采用率的提升至关重要。(但这并不意味着云计算很便宜,或成本管理总是简单明了的。)
上线速度——快速启动基础设施以进行原型设计、开发、测试和交付新应用程序和功能的能力。(但这并不意味着云开发和运维很容易。)
这些目标关系着你的数据库选择,就像它们关系着技术栈的其他所有部分一样。
云原生数据库有哪些特点?
现在我们可以重新审视 CNCF 的定义并提取云原生数据库的特征了,这将有助于实现我们的成本和上线速度目标:
可扩展性——系统必须能够动态增加容量以吸收额外的工作负载;
弹性——必须能够缩减规模,以便你只需为所需的资源付费;
可靠性——系统必须在故障不丢失数据的情况中幸存下来;
可观察性——跟踪你的活动,以及运行状况检查和处理故障转移;
自动化——将操作任务作为可重复的逻辑来执行,以减少出错的可能性。这个特性是最难实现的,但对于大规模实现高交付速度至关重要。
云原生数据库旨在体现这些特征,这将它们与“云就绪”数据库区分开来,即那些可以通过一些调整就部署到云中的数据库。
云原生数据库有什么好例子?
让我们以 Apache Cassandra™为例来测试这个云原生数据库的定义。虽然在开发 Cassandra 时“云原生”一词还没有普及,但它受到了许多相同的架构思想影响,比如亚马逊的 Dynamo Paper 和谷歌的 BigTable 等公共云基础设施。因此,Cassandra 体现了上述原则:
Cassandra 通过添加节点提供了了水平可扩展性,并且可以弹性缩减以在高峰负载期之外释放资源。
默认情况下,Cassandra 是一个 AP 系统,也就是说,它优先考虑可用性和分区容错性而不是一致性,如 CAP 定理所述。Cassandra 的内置复制、无共享架构和自我修复功能有助于保证弹性。
Cassandra 节点公开日志记录、指标和查询跟踪,从而实现可观察性。
与数据库一样,自动化是 Cassandra 最具挑战性的方面。
虽然自动化 Cassandra 集群的初始部署是一项相对简单的任务,但其他任务(例如扩展或升级)可能非常耗时且难以自动化。毕竟,即使是单节点数据库运维也可能具有挑战性,许多 DBA 都可以证明这一点。幸运的是,K8ssandra 项目提供了在 Kubernetes 上部署 Cassandra 的很多最佳实践,包括在“第 2 天”运维自动化方面取得的重大进展。
云原生数据库是否必须在 Kubernetes 上运行?
当我们谈论云中的数据库时,我们实际上是在谈论需要某种存储的有状态负载。但在云世界中,有状态是痛苦的。数据引力是一个真正的挑战——由于法规和法律的限制,数据可能难以移动,而且成本可能会变得非常昂贵。于是,要让应用程序接近其数据的代价是很高的。
当我们开始使用 Kubernetes 部署容器化应用程序时,挑战只会进一步增加,因为它最初不是为有状态负载设计的。为了通过在单个平台上运行整个堆栈来最大限度地提高开发和运维效率,业界开始试图在部署数据库时让它们在 Kubernetes 上运行。Kubernetes 对云原生数据库有哪些额外要求?
容器化
首先,数据库必须在容器中运行。这听起来显而易见,但需要做一些具体工作。存储必须外部化,内存和其他计算资源必须适当调整,应用程序日志和指标必须可用于基础设施进行监控和日志聚合。
存储
接下来,我们需要将数据库的存储需求映射到 Kubernetes 结构上。至少,每个数据库节点都会声明一个持久卷,Kubernetes 可以使用它来分配具有适当容量和 I/O 特征的存储卷。数据库通常使用 Kubernetes 状态集进行部署,这有助于管理存储卷到 pod 的映射并保持一致、可预测的身份。
自动化运维
最后,我们需要工具来管理和自动化数据库运维,包括安装和维护。这通常通过 Kubernetes 操作员模式实现。Operator(操作员)基本上是控制循环,它观察 Kubernetes 资源的状态并采取措施帮助实现所需的状态。通过这种方式,它们就像是在 Kubernetes 中内置的控制器,但关键区别在于它们了解特定于域的状态,从而帮助 Kubernetes 做出更好的决策。
例如,K8ssandra 项目使用cass-operator,它定义了一个名为“CassandraDatacenter”的 Kubernetes 自定义资源(CRD)来描述 Cassandra 集群的每个顶级故障域的期望状态。这提供了比处理有状态集或单个 pod 更高的抽象级别。
Kubernetes 数据库操作员通常会帮助回答以下问题:
故障转移期间会发生什么?(pod、磁盘、网络)
当你向外扩展时会发生什么?(pod 重新计划)
如何执行备份?
我们如何有效地检测和预防故障?
软件如何升级?(滚动重启)
结论和下一步
云原生数据库的设计考虑了云原生原则,包括可扩展性、弹性、弹性、可观察性和自动化。正如我们在 Cassandra 中看到的那样,自动化通常是最终实现的里程碑,但在 Kubernetes 中运行数据库实际上可以帮助我们朝着自动化目标前进。
原文链接:
https://k8ssandra.io/blog/articles/the-search-for-a-cloud-native-database/
评论