如何直视 Cassandra 的眼睛而不失去数据、稳定性和对 NoSQL 的信心

如何直视 Cassandra 的眼睛而不失去数据、稳定性和对 NoSQL 的信心

他们说生活中的一切都值得至少尝试一次。 如果您习惯使用关系型 DBMS,那么首先在实践中熟悉 NoSQL 是值得的,至少对于一般开发来说是这样。 现在,由于这项技术的快速发展,关于这个话题有很多相互矛盾的观点和激烈的争论,这尤其引起了人们的兴趣。
如果深入探究这些争议的本质,就会发现它们都是由于错误的做法而产生的。 那些在需要的地方使用 NoSQL 数据库的人会感到满意,并从该解决方案中获得所有优势。 那些依赖这项技术作为万能药的实验者感到失望,因为它根本不适用,他们失去了关系数据库的优势,却没有获得显着的好处。

我将向您介绍我们实施基于 Cassandra DBMS 的解决方案的经验:我们必须面对什么、我们如何摆脱困境、我们是否能够从使用 NoSQL 中受益以及我们必须在哪些方面投入额外的精力/资金。
最初的任务是构建一个在某种存储中记录通话的系统。

系统的工作原理如下。 输入包括具有描述调用结构的特定结构的文件。 然后,应用程序确保该结构存储在适当的列中。 将来,保存的通话将用于显示订阅者的流量消耗信息(费用、通话、余额历史记录)。

如何直视 Cassandra 的眼睛而不失去数据、稳定性和对 NoSQL 的信心

他们选择 Cassandra 的原因非常清楚 - 她的写作就像机关枪一样,易于扩展且容错。

所以,这就是经验给我们的

是的,失败的节点并不是悲剧。 这就是Cassandra容错的本质。 但 一个节点可能处于活动状态,但同时性能开始受到影响。 事实证明,这会立即影响整个集群的性能。

卡桑德拉(Cassandra)不会保护您,而甲骨文(Oracle)通过其限制拯救了您。 如果应用程序的作者事先没有理解这一点,那么到达 Cassandra 的双倍并不比原来的差。 一旦它到达,我们就会把它放进去。

IB 非常不喜欢开箱即用的免费 Cassandra: 没有记录用户操作,没有权限区分。 有关通话的信息​​被视为个人数据,这意味着所有以任何方式请求/更改该信息的尝试都必须记录下来,以便进行后续审核。 此外,您还需要意识到需要为不同用户划分不同级别的权限。 一个简单的运维工程师和一个可以自由删除整个keyspace的超级管理员是不同的角色,不同的职责和能力。 如果没有这种访问权限的区分,数据的价值和完整性将比任何一致性级别更快地立即受到质疑。

我们没有考虑到呼叫需要针对各种条件进行认真的分析和定期采样。 由于随后应该删除并重写所选记录(作为任务的一部分,我们必须支持当数据最初错误地进入循环时更新数据的过程),Cassandra 在这里不是我们的朋友。 Cassandra 就像一个存钱罐——放东西很方便,但你不能数数。

我们在将数据传输到测试区时遇到问题 (测试中有 5 个节点,舞会上有 20 个节点)。 在这种情况下,无法使用转储。

更新写入 Cassandra 的应用程序的数据模式时出现的问题。 回滚将产生大量墓碑,这可能会以不可预测的方式导致生产力损失。。 Cassandra针对记录进行了优化,在写入之前不会考虑太多,任何对其中已有数据的操作也是一种记录。 也就是说,通过删除不必要的记录,我们只会产生更多记录,并且只有其中一些记录会被标记为墓碑。

插入时超时。 卡桑德拉在录音中很漂亮,但是 有时,传入的流量会让她感到非常困惑。 当应用程序开始围绕由于某种原因无法插入的几条记录进行循环时,就会发生这种情况。 我们需要一个真正的 DBA,他将监视 gc.log、系统和调试日志以了解慢速查询、压缩挂起的指标。

集群中的多个数据中心。 从哪里读取、从哪里写入?
也许分为阅读和写作? 如果是这样,是否应该有一个更靠近应用程序的 DC 来进行写入或读取? 如果我们选择了错误的一致性级别,我们最终会不会出现真正的脑裂? 有很多问题、很多未知的设置、你真正想要修改的可能性。

我们如何决定

为了防止节点下沉,禁用了SWAP。 现在,如果内存不足,节点应该关闭并且不会造成较大的GC暂停。

因此,我们不再依赖数据库中的逻辑。 应用程序开发人员正在重新培训自己,并开始在自己的代码中积极采取预防措施。 数据存储和处理的理想清晰分离。

我们从 DataStax 购买了支持。 盒装 Cassandra 的开发已经停止(最后一次提交是在 2018 年 XNUMX 月)。 同时,Datastax提供优质的服务以及针对现有IP解决方案的大量修改和改编的解决方案。

我还想指出,Cassandra 对于选择查询不是很方便。 当然,CQL 对于用户来说是一大进步(与 Trift 相比)。 但是,如果您的整个部门都习惯了这种方便的联接、任意字段的免费过滤和查询优化功能,并且这些部门正在努力解决投诉和事故,那么 Cassandra 上的解决方案对他们来说似乎是敌对和愚蠢的。 我们开始决定我们的同事应该如何制作样品。

我们考虑了两个选项:第一个选项中,我们不仅在 C* 中编写调用,还在存档的 Oracle 数据库中编写调用。 只是,与 C* 不同,该数据库仅存储当月的呼叫(对于充值情况有足够的呼叫存储深度)。 在这里,我们立即看到以下问题:如果我们同步写入,那么我们就失去了 C* 与快速插入相关的所有优势;如果我们异步写入,则根本无法保证所有必要的调用都进入 Oracle。 有一个优点,但一个很大的优点:对于操作,仍然保留相同熟悉的 PL/SQL Developer,即我们实际上实现了“Facade”模式。另一种选择。 我们实现了一种机制,可以卸载来自 C* 的调用,从 Oracle 中的相应表中提取一些数据进行丰富,连接生成的样本并给出结果,然后我们以某种方式使用该结果(回滚、重复、分析、欣赏)。 缺点:流程步骤较多,而且没有操作人员的界面。

最终我们选择了第二种方案。 Apache Spark 用于从不同的 jar 中进行采样。 该机制的本质已简化为 Java 代码,该代码使用指定的键(订阅者、调用时间 - 部分键)从 C* 中提取数据,以及从任何其他数据库中提取必要的数据。 之后,它将它们连接到内存中,并将结果显示在结果表中。 在火花上方绘制了一个网面,结果证明它非常有用。

如何直视 Cassandra 的眼睛而不失去数据、稳定性和对 NoSQL 的信心

在解决工业测试数据更新问题时,我们又考虑了几种解决方案。 两者都通过 Sstloader 进行传输,并且可以选择将测试区中的集群分成两部分,每个部分交替与促销集群属于同一集群,从而由促销集群提供支持。 更新测试时,计划交换它们:在测试中起作用的部分被清除并投入生产,而另一部分则开始单独处理数据。 但经过再思考,我们更加理性地评估了哪些数据值得转移,发现调用本身就是一个不一致的测试实体,需要时快速生成,而促销数据集是没有转移价值的。测试。 有几个存储对象值得移动,但这些实际上只是几个桌子,而且不是很重的桌子。 因此我们 作为解决方案,Spark 再次拯救了我们,在它的帮助下,我们编写并开始积极使用脚本 prom-test 在表之间传输数据。

我们当前的部署策略允许我们无需回滚即可工作。 在促销之前,有一个强制性的测试运行,其中一个错误的代价并不那么昂贵。 如果出现失败,您始终可以删除案例空间并从头开始滚动整个方案。

为了确保 Cassandra 的持续可用性,您需要一名 dba,而不仅仅是他。 每个使用应用程序的人都必须了解在哪里以及如何查看当前情况以及如何及时诊断问题。 为此,我们积极使用 DataStax OpsCenter(工作负载的管理和监控)、Cassandra Driver 系统指标(写入 C* 的超时次数、从 C* 读取的超时次数、最大延迟等),监控操作与 Cassandra 一起使用应用程序本身。

当我们思考上一个问题时,我们意识到我们的主要风险可能在哪里。 这些是数据显示表单,显示来自多个独立查询到存储的数据。 这样我们就可以获得非常不一致的信息。 但如果我们只使用一个数据中心,这个问题也同样重要。 所以这里最合理的当然是在第三方应用上创建一个读取数据的批处理函数,这将保证在单个时间段内接收到数据。 至于在性能方面对读写的划分,我们遇到了这样的风险:如果 DC 之间失去一些连接,我们最终可能会得到两个彼此完全不一致的集群。

结果,目前 写入 EACH_QUORUM 时停止在一致性级别,读取时停止于 LOCAL_QUORUM

简要印象和结论

为了从运营支持和进一步发展前景的角度评估最终的解决方案,我们决定考虑这种开发还可以应用在哪里。

立即开始,然后对诸如“方便时付款”之类的程序进行数据评分(我们将信息加载到C *中,使用Spark脚本进行计算),按区域聚合进行索赔核算,存储角色并根据角色计算用户访问权限矩阵。

正如您所看到的,剧目广泛且多样。 如果我们选择NoSQL的支持者/反对者阵营,那么我们将加入支持者的行列,因为我们得到了我们的优势,而且正是我们所期望的。

即使开箱即用的 Cassandra 选项也允许实时水平扩展,绝对轻松地解决系统中数据增加的问题。 我们能够将用于计算调用聚合的非常高负载的机制移至单独的电路中,并将应用程序模式和逻辑分开,从而摆脱在数据库本身中编写自定义作业和对象的不良做法。 我们有机会选择和配置,以加速我们将在哪些 DC 上执行计算以及我们将在哪些 DC 上记录数据,我们确保自己不会发生单个节点和整个 DC 的崩溃。

将我们的架构应用到新项目中,并且已经有了一些经验,我想立即考虑到上述细微差别,并防止一些错误,平滑一些最初无法避免的尖角。

Например, 及时跟踪Cassandra的更新因为我们遇到的很多问题已经是已知的并已解决。

不要将数据库本身和 Spark 放在同一节点上 (或者严格除以允许的资源使用量),因为 Spark 可以吃掉比预期更多的 OP,我们很快就会从列表中得到问题 1。

提高项目测试阶段的监控和操作能力。 首先,尽可能考虑我们解决方案的所有潜在消费者,因为这是数据库结构最终依赖的。

多次旋转所得电路以进行可能的优化。 选择可以序列化的字段。 了解我们应该制作哪些附加表,以便最正确和最佳地考虑,然后根据请求提供所需的信息(例如,假设我们可以将相同的数据存储在不同的表中,并根据不同的情况考虑不同的细分)不同的标准,我们可以显着节省读取请求的 CPU 时间)。

不错 立即提供附加 TTL 和清理过时数据的功能。

从 Cassandra 下载数据时 应用程序逻辑应遵循 FETCH 原则,以便并非所有行都一次加载到内存中,而是批量选择。

建议在将项目转移到所描述的解决方案之前 通过进行一系列碰撞测试来检查系统的容错能力,例如一个数据中心内的数据丢失、一定时期内损坏数据的恢复、数据中心之间的网络掉线等。 此类测试不仅可以让人们评估所提出的架构的优缺点,而且还可以为进行测试的工程师提供良好的热身实践,并且如果在生产中重现系统故障,所获得的技能也绝非多余。

如果我们处理关键信息(例如计费数据、用户债务计算),那么还值得关注能够降低由于 DBMS 功能而产生的风险的工具。 例如,使用nodesync实用程序(Datastax),已为其使用制定了最佳策略,以便 为了保持一致性,不要对 Cassandra 造成过多的负载 并且只对特定时期内的特定表使用。

卡桑德拉六个月后会发生什么? 总的来说,不存在未解决的问题。 我们也不允许发生任何严重事故或数据丢失。 是的,我们必须考虑补偿一些以前没有出现过的问题,但最终这并没有给我们的架构解决方案带来太大影响。 如果您想要并且不害怕尝试新事物,同时又不想太失望,那么请做好准备,接受没有什么是免费的这一事实。 与旧的遗留解决方案相比,您将必须更多地理解、深入研究文档并组装您自己的个人耙子,并且没有任何理论可以提前告诉您哪个耙子正在等待您。

来源: habr.com

添加评论