这篇博文是涵盖MongoDB PIT备份系列文章的第二篇。 你可以在这里找到第一部分。
本系列的第一篇博文关注的是简单的单副本集环境中的MongoDB备份。 在这篇文章中,我们将看看横向扩展用例。 分割时,我们遇到的问题与在单个副本集上遇到的问题完全相同。 但是,现在问题是集群中副本集的数量成倍增加。 此外,我们还有一个额外的问题:每个副本集都有唯一的数据。 这意味着要获得真正一致的群集快照,我们需要协调我们的备份以捕获单个一致的时间点。 就像我们在同一页上一样,这意味着每个副本集都需要在最慢的副本集停止的同一时间或接近同一时间停止它们的备份。 你现在够困惑了吗? 让我进入一个我在第一篇文章中忘记涉及的基本概念,然后我会给你一个问题的简单描述。
到目前为止,我忽略了在进行一致备份时“写问题”的重要作用。 在MongoDB中,默认情况下数据库是不持久的。 所谓“持久”,我指的是当数据库确认收到来自您的应用程序的操作时,“在磁盘上”。 这很可能有几个原因。 最有可能的是,由于缺乏并发性,最初最大的问题可能是吞吐量。
但是,副作用是由于仅在内存中应用的操作丢失,可能会导致数据丢失。 将写操作改为“日志记录”j : 真实的)将改变这种行为,以便MongoDB日志在确认它们之前改变(您还需要在启用日志的情况下运行)。
小费:为了在副本集中实现真正的持久性,您应该对操作使用“多数”的写关注点,并对所有副本集成员使用writeConcernMajorityJournalDefault默认值:true(新版本为v3)。4)。 这还有一个额外的好处,那就是大大减少了选举后的回滚机会。
冒着重复的风险,这个问题的关键是我们需要在每个碎片(副本集)上运行备份。 这是必要的,因为每个碎片都有不同的数据集。 数据集的每一部分都是获得集群(以及您的应用程序)数据集的完整图像所必需的。 由于我们使用的是mongodump,因此在备份完成时,我们只有一个一致的快照。 这意味着我们必须在一致的时间点结束每个碎片的备份。 我们不能期望每个碎片上的备份在完全相同的时间内完成,这是我们在整个集群中保持一致的时间点所需要的。 这意味着碎片1可能有一个与下午12:05一致的备份,以及另一个与下午12:06一致的碎片m. 在高流量环境中(这种环境可能需要横向扩展),这可能意味着数千份文档丢失。 这里有一个图表:
以下是说明这个问题的数学方法:
- Shard1的备份将包含30,000个文档((100个文档* 60秒)* 5分钟)。
- Shard2的备份将包含36,000个文档((100个文档* 60秒)* 6分钟)。
在本例中,为了获得一个一致的时间点,您需要从碎片1的备份完成(6000个文档)开始,删除碎片2上发生的所有插入、更新和删除操作。 这意味着检查操作日志中每个操作的时间戳,并反转它的操作。 这是一个非常密集的过程,对于每个执行的mongodump都是唯一的。 此外,这是一件非常棘手的事情。 可重复且高效得多的方法是让备份以一致的状态完成,以便在需要时随时恢复。
数据库同步 幸运的是,佩科纳掩护了你!
拥有数据很重要,但是知道你有什么数据更重要。 以下是如何确保您知道您的蒙古数据库备份中有什么:
大卫·墨菲发布了他的 蒙古数据库一致备份工具 并就此写了一篇内容丰富的博文。 我写这些博文的目的是让理解问题和如何解决问题变得更加容易。 我们已经对这个问题进行了大规模和小规模的详尽讨论。 解决方案怎么样?
其实很简单。 从基本层面上来说,解决方案是使用一个简单的算法来决定何时可以达到集群范围内的一致时间点。 在MongoDB一致备份工具中,这是由备份主机在每个碎片的“已知良好成员”上启动备份来完成的(这本身就是一个非常酷的特性),然后跟踪每个转储的进度。 在启动备份的同时,备份主机启动一个单独的线程,跟踪每个“已知良好成员”上的操作日志,直到最慢碎片上的mongodump完成。 通过使用这种方法,我们有一种非常简单的方法来决定何时可以获得群集范围的一致快照。 换句话说,当最慢的成员完成了他们的工作负荷。 这是图4中相同的工作负载,但是使用了蒙古数据库一致备份工具方法:
小费:执行这些备份所需的时间通常由两个因素决定:
- 数据在碎片间的分布有多均匀(平衡)
- 每个碎片包含多少数据(是否平衡)。
这里的要点是,您可能需要分片,以便每个分片都有可管理的数据量。 这使您可以更轻松地打开备份/恢复窗口。
当你认为你已经对任何困难的概念有所了解时,总会有一个“陷阱”。 当然,这没什么不同。
分片中有一个我们没有涉及到的非常重要的概念:跟踪哪些数据位于哪个分片上。 这对于将工作负载路由到正确的位置以及在碎片之间平衡数据非常重要。 在MongoDB中,这是由配置服务器完成的。 如果您无法访问(或恢复)您的配置服务器,您的整个群集都将丢失! 出于显而易见的原因,您也需要备份它们。 使用Percona实验室MongoDB一致备份工具,实际上有两种模式用于备份配置服务器:v3。2和更大,和遗产。 原因是在v3中。配置服务器从镜像变成了标准的副本集。 在v3中。2模式,我们只是把配置服务器当作另一个副本集。 他们有自己的蒙古垃圾场和奥普洛尾线。 他们获得的备份与群集中所有其他碎片的时间点一致。 如果您使用的是v3之前的MongoDB版本。如果你对传统模式的解释感兴趣,请回到大卫的博客。
在本文和之前的博文中,我们已经研究了在运行MongoDB的环境中获得一致备份的问题。 无论您是拥有单个副本集还是分片集群,您都应该更好地了解问题所在以及Percona如何为您解决问题。 如果你仍然困惑,或者你只是想问一些额外的问题,请在下面的部分发表评论。 或者给我发一条推特@jontobs,我一定会回复你的。