使用 Apache Cassandra 实现灾难可恢复数据持久性 – 为意外做好准备
介绍
您正在阅读这篇文章,这告诉了我一些关于您的情况。
首先,这表明你已经认识到你的数据对你来说是最重要的。这也表明你有足够的经验和成熟度来承认这样一个事实:没有挑战,任何事情都无法被接受。
在数据管理方面,大多数平台都会对其数据的完整性做出承诺。
但是,作为一名负责任的专业人士,您会因为“一旦您迁移到这项技术,您的数据将(安全/可靠/等等)”这一承诺而冒着业务风险吗?有些人可能会,但同样,如果您必须阅读这篇文章,那么这个“有些人”不是您。您更了解情况。在谈到数据完整性时,我指的是数据准确性和数据一致性的因素。
大多数情况下,您(技术用户)可以正确地认为数据准确性和数据一致性都不是免费的。
例如,为了保持数据的准确性,您必须确保特定的数据插入请求不会(不必要地)覆盖以前存储的数据。
无论使用哪种技术,在处理数据层时,算法正确性都是必需的。没有任何技术可以完全保护您免受恶意错误的侵害。算法正确性将帮助您实现数据的逻辑完整性。
一旦解决了逻辑完整性问题,您现在就可以进入物理完整性的领域。
达到数据的高度物理完整性意味着您已经考虑过与硬件设备、计算机网络、网络域、服务器以及数据所依赖的任何物理设备相关的挑战。
一般来说,解决物理完整性问题最常见的方法是使用分布式架构。分布式架构有各种风格、大小和形状。大多数都有某种冗余机制。有些有数据复制的概念。
在本文中,我想回顾一下Apache Cassandra的物理数据完整性概念,Apache Cassandra 是我很高兴使用的一种最流行的分布式数据库技术。
如果您希望在深入阅读本文之前对 Apache Cassandra 有一个更基本的了解,我在最新的课程中写了一个专门的模块。欢迎在这里查看。
让我们开始吧!
关于 Apache Cassandra
Apache Cassandra 是一个 NoSQL 分布式数据库。我们用这个简单的陈述描述了部署模型(分布式而非集中式)和数据模型(非“标准”关系表格数据)。
我们在介绍中已经提到,数据的物理完整性可能会受到硬件物理故障的挑战。采用分布式方法,从统计上降低了这种风险。通过部署多个物理资源(例如托管服务器、存储阵列)并将我们的软件层(在我们的例子中,是 Apache Cassandra 集群中的软件层)“放置”在其之上,将大有裨益。但是……
福利金额可能会发生变化,且取决于多种因素。
第一个因素是我们引入了相关的额外物质资源。
Apache Cassandra集群由节点组成。这些节点基本上是在主机上运行的进程,为集群贡献其功能。
这些节点可以根据逻辑数据中心和机架进行分组,配置简单。
为什么我在讨论物理资源时要强调“相关”一词,而在讨论集群中节点的适当分组时要强调“逻辑”一词?让我给你讲一个真实的故事。
案例研究
我在 Cassandra 之上为客户端开发了一个数据层(从现在开始我将省略“Apache”前缀,尽管在本文中我讨论的是 Cassandra 的 Apache Cassandra 版本)。
我的客户要求将 Cassandra 托管在 docker 容器中,因此我创建了一个相关的 docker 镜像,该镜像可以在基于它实例化容器后接收配置参数。
我已确保为 Cassandra 集群中的节点创建相关的配置文件。
我把它交给了 DevOps 团队,集群启动了,大家都很开心。这是一种危险的、错误的开心。
显然 - 这绝对是我的责任,以确保这种情况不会发生 - DevOps 团队在单个主机上创建了整个集群。
现在,它是一台“强大的”主机,每个 Cassandra 节点都有一个专用核心、充足的 RAM 和超快的存储。但它是一个集群,一种分布式技术,部署在一台机器上。单点故障!主机的任何断电或灾难性硬件故障都可能导致停机和数据丢失,从而违背了 Cassandra 分布式功能的目的。
事情可能会出错
在我们深入探讨如何可以做得更好之前,让我们先讨论一下事情在某些时候容易出错的原因。
当谈到 Cassandra 集群时,我们的主要资源是什么?
我们的节点作为进程部署在主机上。然后,每个进程管理自己的数据文件,对吗?总之,每个进程都通过网络接口与其他节点通信。
显然还有其他资源,例如 RAM,但我提到的这些足以让我表达我的观点。
一般来说,我们有托管机器、它用于执行数据管理任务的内部资源以及与集群其余部分通信所需的资源。
现在,有几种情况,其中任何一台(有时不止一台)、它们的内部资源或它们与集群通信的能力都会受到阻碍。
我们的责任是确保我们的数据层能够承受任何情况下的致命问题。
准备是关键
“你打出本垒打不是靠运气,而是靠准备。”——罗杰·马里斯
对于集中式数据库,大部分针对灾难的准备都是基于备份和对相对可靠的存储设备的依赖。
一些系统采用了其他方法,例如运行两个独立的数据库实例,如果其中一个出现故障,系统可以依赖另一个。
但是,这种方法的开销非常高,不是吗?每个实例都是一个成熟的数据库,就像是唯一的系统数据库一样运行。此外,在这样的部署中,我们添加到系统中的任何实例都不会提高系统处理更多数据的能力。这很麻烦,因为我们在获得相同的性能的同时添加了高成本的资源?我们不能做得更好吗?
确实可以。
有了 Cassandra,每个节点除了建立我们存储数据的整体完整性之外,还可以增加我们的系统带宽 - 当然,谈论的是数据。
但部分带宽需要依赖一些事先的准备。
而这种准备主要是通过考虑我们部署集群的方式。通过考虑我们配置集群节点的方式,我们可以提高系统在非常糟糕的情况下(硬件故障)维护数据完整性的能力。
选择如何在逻辑机架和数据中心以及物理机架和数据中心之间分布节点将会产生不同的效果。
部署注意事项
节点命名 - 保持一致
“我接受混乱,但我不确定它是否接受我。”——鲍勃·迪伦
在规划集群时,我强烈建议为 Cassandra 节点使用一致、有意义的名称。选择一个命名约定,至少要反映以下内容:
- 数据中心名称
- 机架名称
- 节点 ID
节点名称要简洁明了,因为您需要在配置文件中使用它们。
例如,以下建议的结构怎么样:
DC<数据中心 ID>机架<机架 ID>节点<节点 ID>
因此,如果我们在每个数据中心有四个节点,每个机架有两个节点,我们将有
DC1Rack1Node1
DC1Rack1Node2
DC1Rack2Node1
DC1Rack2Node2
DC2Rack1Node1
DC2Rack1Node2
DC2Rack2Node1
DC2Rack2Node2
现在,这涉及到一些本来应该微不足道的事情,但同时也是我在令人惊讶的情况下遇到的事情。确保逻辑名称反映物理部署。将物理上位于数据中心 x 和机架y上的节点命名为“DCxRack z ”是没有意义的,对吧?
使用正确的分区程序
分区器是一种负责在集群节点之间分发副本的算法。
出于性能原因,您应该确保副本以统一的方式分布在集群中。
但是,使用不正确的(例如自定义的)分区器可能会阻碍整个集群中副本的分布,甚至可能影响灾难恢复能力。
强烈建议使用经过验证的开箱即用的分区程序,例如Murmur3Partitioner 。
使用适当的复制策略
顾名思义,复制策略就是 Cassandra 集群在集群内分发副本的方式。
当您的集群部署在单个数据中心内时(不推荐),SimpleStrategy 就足够了。
但是,当转移到多数据中心部署时,请确保使用 NetworkTopologyStrategy ,它将允许定义跨多个数据中心所需的复制。
我个人建议无论如何都使用 NetworkTopologyStrategy。做好准备。
机架感知集群配置 - 高效
机架内节点通信非常高效。
您可能想将整个集群部署到同一个数据中心服务器机架上。但不要这么做。
服务器机架是故障点。断电、火灾或普通的维护都可能导致整个机架离线。
一般来说,每个数据中心至少使用两个不同的服务器机架。
确保在机架之间均匀分布 Cassandra 节点(假设每个机架具有相同的硬件资源)。
使用机架感知告密者。
机架感知告密者将确保 Cassandra 集群了解每个节点的物理位置,并可以相应地在机架之间分配副本。
但是,配置一个机架感知告密器是否足以确保我们的数据在服务器机架之间正确复制?不,还缺少了一些东西。
该某些内容是在键空间级别定义的复制因子的适当配置值。
选择正确的复制因子一开始可能会令人困惑,因为设置复制因子与其他配置参数并不正交,例如写入级别(需要确认写入操作的副本数量)和读取级别(需要确认读取操作的副本数量)。
一个好的做法是确保将写入级别添加到读取级别时大于复制因子。
因此,在由 4 个节点组成、分布在 2 个机架上的集群中,假设写入级别为 2,读取级别为 1,您需要确保复制因子大于 3。
此设置实际上意味着您可以承受最多(任意)两个节点的丢失,而不会导致应用程序停机!
现在,假设您听取了我的建议并在可用机架上正确分配节点,那么您可以“承受”任何机架故障而不会丢失数据/可用时间。
虽然我们通过固有的开销实现了这一目标(我们所有的节点都存储了 100% 的数据) - 但我们确保在服务器机架发生故障的情况下我们可以“保持活力”!
正如我之前提到的,您的集群大小(节点数)、复制因子、写入一致性和读取一致性并不相互正交。更改其中一个可能会影响您的集群的行为,无论是性能方面还是一致性方面。
确保您阅读并理解上述问题中提到的参数,并根据您的使用情况适当调整它们。
我见过“按部就班”地完成部署,当涉及到扩展节点并正确定义所有相关的复制参数时,却发现所有节点都使用相同的存储设备。
即使您使用的是带有 RAID 阵列的顶级网络存储设备,也请不要跨节点或机架共享相同的存储硬件。
即使是最好的存储阵列最终也会发生故障。在节点之间共享它们意味着一个故障就会导致多个节点不可用。
在讨论 Cassandra 集群中的节点存储时,我强烈建议使用本地存储。您可以使用 raid 保护本地节点存储 - 只需确保您在本地工作即可。
请注意,我并不是说网络存储不好。如果您喜欢,那就使用它。只需确保您使用的每个存储资源都位于单个 Cassandra 节点本地即可。
数据中心感知集群配置 - 保持警惕
多个架子很棒,但还不够。
假设整个数据中心可能离线并不是虚构的假设。过去最大的公司和云提供商都发生过这种情况。再次发生这种情况只是时间问题。如果您关心您的数据和您的用户在这种情况下保持在线 - 请负责任并确保您的集群(正确)部署在多个数据中心。
使用 Cassandra 来实现这一点不仅是可能的,而且配置起来也相当简单。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~