内容


使用 IBM Spectrum Protect for Linux on Power 备份和还原 MongoDB 数据的方法

Comments

本文将重点介绍如何备份非常大的 MongoDB 实例。我们可以使用 IBM®Spectrum Protect™ 完成此任务,该产品以前称为 IBM Tivoli® Storage Manager (TSM),可在所有 MongoDB 服务器上作为备份和管理代理运行。本文将展示如何将 MongoDB 与 IBM Spectrum Protect 等传统或现有备份工具相集成,甚至在生产级规模上进行集成。

此任务可使用为 IBM Power Systems™构建的 MongoDB 版本(例如 MongoDB Enterprise v3.4 for ppc64le)完成。MongoDB 中直接嵌入了许多工具和特性,它们有助于完成集成过程并为 MongoDB 的备份能力提供补充,以下各节将介绍这些工具和特性。

IBM Spectrum Protect 背景知识

IBM Spectrum Protect 为多供应商计算机环境提供存储管理解决方案。它为文件服务器、工作站、虚拟机和应用程序提供了自动化的、集中调度的、通过策略管理的备份、存档和空间管理功能。此外,IBM Spectrum Protect 支持所有规模的系统[包括虚拟机、文件服务器、电子邮件、数据库、企业资源规划 (ERP) 系统、大型机和台式机]。IBM Spectrum Protect 在一个随数据增长而扩展的环境中完成所有这些工作。

本文将介绍 IBM Spectrum Protect 的备份和恢复功能,描述如何使用它来保护 MongoDB 数据。此外,选择 IBM Spectrum Protect 还有一些特定的原因。首先,作为大型企业系统的可靠备份管理器,它取得了值得信赖的优秀成绩。许多大型客户多年来一直非常信任它,而且可能已将它集成到自己的企业系统中。即使尚未使用 IBM Spectrum Protect 的客户,也无需制定需要使用特定于每个计划的单独备份软件的单独备份计划。

使用 IBM Spectrum Protect 作为备份解决方案还有其他重要原因。IBM Spectrum Protect 有一个管理备份数据的稳固平台。一些应用程序将数据堆积在其他某个服务器的硬盘上,而且需要手动还原这些数据。或者,必须手动管理数据存储位置和不断对它执行的操作。可为 IBM Spectrum Protect 配置一些自动程序,比如将数据写入磁盘和磁带,而且 IBM Spectrum Protect 拥有大量存档特性。还原数据时,IBM Spectrum Protect 代理可以轻松地找到特定系统的最新备份,并执行将数据放回所属位置的过程。

MongoDB 背景知识

MongoDB 是一个开源数据库,被视为最流行且增长最快的 NoSQL 数据库,这主要由于它能很好地处理传统 SQL 数据库无法处理的问题。它非常善于处理大型非结构化数据集,而且读取存储数据的速度非常快。再结合用 JavaScript 编写的强大查询,这些使得 MongoDB 成为了适合现代应用程序(比如需要频繁读取和使用数据的移动和分析应用程序)的强大工具。虽然 MongoDB 不会取代所有存储结构化数据的 SQL 应用程序,但它为大量非结构化数据和移动流量提供了一个现代解决方案。

此外,MongoDB 的设计目标是高度可扩展且高度可用。这些特性已内置于 MongoDB 环境的设计和结构中。生产环境中的 MongoDB 是一个运行不同任务的流程集群,这些任务通常在不同系统上运行。它包含 3 种不同类型的服务器:

  1. 配置服务器 -这些服务器存储有关数据位置的元数据。在生产环境中,正好需要 3 个配置服务器。这些服务器是元数据服务器,用于保存集群化数据库的所有重要信息。它们保存关于数据存储位置和存储量的所有信息。
  2. 查询路由器 - 这些特殊的 MongoDB 实例是外部应用程序与 MongoDB 中存储的数据之间的接口或网关。请求传入这些服务器中,所请求的数据通过查询路由器返回到应用程序。任何数据都不会永久存储在这些服务器中,这在连接外部世界时提供了一个额外的安全层。这些 MongoDB 实例通过查询配置服务器来查找数据应该存储的位置。然后,它们智能地抓取数据并将其返回给应用程序。它们还充当着执行集群级管理的管理接口。所有配置都存储在配置服务器上,查询路由器是管理控制台,您可以通过它们访问所有设置和首选项。可以有任意多个 MongoDB 服务器,但要让数据库正常运行,至少需要一个功能服务器。
  3. 分片 -这是数据在系统中的存储位置。分片的目的是水平扩展 NoSQL 数据库。数据分解为片段(即分片)并存储在一组服务器中,以保持数据一致且可用,同时避免瓶颈。由于更多分片会增加复杂性和成本,所以应根据需要使用分片,而不要过量使用。IBM Power®服务器的优势在于,它们能扩展计算、内存和 I/O,从而减少对分片的需求,使每个分片能处理的工作负载比 x86 服务器多。这些服务器也会自动进行负载平衡,以防止某个服务器被不均衡地填满或变大。使用这些服务器的目的是尽可能合理地分解数据集并将它分散在不同系统上。可以添加更多分片,而且数据库会平等地重新分布数据,使 MongoDB 能处理更多流量。当然,每个分片不是一个单独的服务器。每个分片是一系列重复服务器,称为一个副本集。

    副本集 - 这是大型数据库(尤其是 NoSQL 种类的数据库)可能面临的数据冗余和可用性问题的解决方案。此系统的目标是以同步方式备份所有数据,能够在无需停机的情况下自动处理整个服务器完全失效的状况。各个副本集之间有一种选举机制,以挑选一个服务器作为主服务器。这个主服务器是负责与副本集的写入操作通信的服务器。所有写入操作都由主服务器首先处理,该服务器将它们写入一个操作日志中,再将操作日志分发给副本集的辅助成员。然后,辅助成员回放该日志,并对自己的数据应用所有操作。副本集的一个非常有趣的特性是,在主服务器处理所有写入操作的时候,可同时从所有副本服务器读取数据。这意味着,整个副本集可对同一数据片段同时执行读取操作。这样做可以获得更好的可用性。在故障转移方面,副本集旨在自动检测副本集中任何服务器(包括主服务器)故障并执行故障转移。主服务器发生故障时,这些服务器将自动选举一个新的主服务器并继续操作。

图 1. MongoDB 结构图

如图 1 所示,在生产环境中,数据库的每个分片也是一个副本集。所以,始终存在内置的数据冗余性。MongoDB 集群中任何地方的数据都不只存在一次。

事实是,MongoDB 的构建目的是获得持久且可靠的数据,这也是它拥有原生的分片和副本集的原因。分片主要专注于数据的可扩展性,在数据超出一个分片的能力范围后,将数据库拆分到多个服务器中。正如上面提到的,与 x86 服务器相比,Power 服务器支持更大的分片。副本集中包含多组相同的分片,这些分片位于不同服务器上,用于实现冗余和提高速度。

还有一个称为日志记录的特性,在将数据写入磁盘之前,数据库会将待处理的写入操作存储在一个日志文件中。这些文件的大小可增长到 1 GB,仅在日志中的所有操作都已完成或正常关闭服务器时才会删除。在异常关闭时,只要服务器恢复运行,就会读取并回放日志文件,以确保所有操作都已落实,还会落实尚未落实的操作。同样,此过程可在服务器上的 MongoDB 实例恢复在线后自动完成。如果发生写入错误,MongoDB 将重新启动来修复问题。MongoDB 会重新启动,读取日志,删除旧日志文件,然后创建新的日志文件。

在日志、分片和副本集中,有大量针对细微问题(比如主要分片失去连接和离线)的自动故障转移功能。系统可以继续顺利运行,故障分片会在重新启动后自动恢复运行。但是,在存储需要保留的重要数据的更大文件系统上,备份至关重要。在本文中,我们使用 IBM Spectrum Protect 作为解决方案,不仅支持对 MongoDB 执行有计划的完全备份操作,还支持对整个企业生态系统执行该操作。

在企业系统中,需要拥有所有数据的完整备份,以实现记录维护、审计和灾难恢复等操作。MongoDB 通过其 Ops Manager 进程提供备份,该进程通常由数据库管理员管理。Ops Manager 的使用不在本文的讨论范围。通过使用 IBM Spectrum Protect,可以将 MongoDB 与已有适当备份策略的现有企业基础架构合并。

在我们的备份过程中,IBM Spectrum Protect 使用一个称为Logical Volume Manager (LVM) 快照的内置 Red Hat 操作系统特性(其他大多数主要 Linux® 发行版也提供了该特性),在一个复制的服务器上对我们的 MongoDB 文件执行文件系统复制。此过程包含一系列步骤,以下各节将全面介绍它们。此刻应该指出的是,所有日志和数据库文件都需要位于同一个逻辑卷中,以避免存储不必要数据的快照。最后,IBM Spectrum Protect 会依据自己的存储过程对快照进行压缩和存储。

MongoDB 备份流程依靠一个专门的副本集成员来处理严格用于备份的每个分片。为了可用于生产环境,一个服务器应有多个副本。为了实现备份,我们想要一个预定义为备份实例的副本。这意味着它不能是主服务器,MongoDB 提供了实现此目标的配置选项。在备份期间,仍继续将其作为正常运行的副本集成员进行操作。但是,我们知道备份过程将占用备份服务器上的一些资源,而且我们不想减慢集群运行速度。在设计生产环境和备份计划时应考虑到这一点。

这个备份过程显示了 MongoDB 集群的一些最低要求。这与 MongoDB 文档中描述的生产环境最低要求一致。

优势

作为一个备份和还原工具,IBM Spectrum Protect 提供了以下优势来增强 MongoDB 的功能:

  • 适用于所有应用程序的单一备份管理器
  • 稳固且可配置的存储介质和过程
  • 能使用 IBM System Storage®SAN Volume Controller (SVC) 执行快速逻辑备份和管理数据移动
  • 备份编目
  • 仅备份更改的数据
  • 内置调度功能
  • 单一控制点
  • 存储日志、配置、统计数据、元数据的数据库

以下各节将介绍如何利用其中一些特性将 MongoDB 打造为更健壮的数据库。

MongoDB 环境设置

依据最佳实践,为复制的 MongoDB 服务器设置副本和分片。

按照文章“开始在运行 Linux 的 IBM Power Systems 上使用 MongoDB”中的说明,将 MongoDB 安装在 IBM POWER8® 服务器上。

确保备份环境满足以下最低要求:

  • 有 3 个配置服务器。
  • 每个分片至少有 3 个服务器作为副本集,也就是说,每个分片一个主服务器和两个辅助服务器。
  • 出于故障转移目的,集群中的所有服务器都通过其域名联网,而不直接通过其 IP 地址联网。
  • 至少必须有一个 MongoDB 路由器实例 (mongos) 能够处理所有请求。路由器数量应足以处理传入和传出的请求。应在需要时添加更多的路由器。

备份 MongoDB 的过程是本文的主要主题。本文不会介绍创建或维护生产 MongoDB 实例的整个过程。要获得关于该主题和其他 MongoDB 配置的更多信息,请参考官方文档:http://docs.mongodb.org/manual/

IBM Spectrum Protect 资源和设置

需要执行以下步骤来设置 IBM Spectrum Protect 服务器和客户端。

  1. 使用 IBM Spectrum Protect 服务器

    要一致且灵活地执行 MongoDB Linux on Power 备份/还原方法,建议使用以下 IBM Spectrum Protect 服务器资源。

    用于 Linux on Power LE (RHEL 7.3) 的 IBM Spectrum Protect Server V8.1.1.00

  2. 使用 IBM Spectrum Protect 备份/归档客户端

    要一致地执行 MongoDB Linux on Power 备份/还原方法,建议使用以下 IBM Spectrum Protect 备份/归档客户端资源。

    用于 Linux on Power LE(RHEL 7.1、Ubuntu 14.04 或 16.04,或者 SUSE LE 12 或更高版本)的 IBM Spectrum Protect 备份/归档客户端 V8.1

  3. 安装和配置 IBM Spectrum Protect 备份/归档客户端。
  4. 应在每个 Linux on Power MongoDB 服务器上安装 IBM Spectrum Protect 备份/归档客户端。自行向 IBM Spectrum Protect 服务器 (TSMLINUX) 注册 IBM Spectrum Protect 备份/归档客户端。安装和配置 IBM Spectrum Protect 客户端调度程序。

本文将重点介绍 IBM Spectrum Protect 的用法。要获得如何执行安装和设置的示例,请参考使用 IBM Spectrum Protects for Linux on z 的 MongoDB 备份/还原方法

实现

我们的 IBM Spectrum Protect 代理备份的目标是,为 MongoDB 环境提供一个可完全在本地实施的稳固且可靠的备份解决方案。对于已在使用稳固的 IBM Spectrum Protect 软件的客户,或者要备份的内容不只是 MongoDB 的客户,这提供了一个统一的解决方案。此示例将展示多个分片,但也可以通过单个分片实现该示例。

捕获时间点备份的最佳方法是,跨所有已备份的服务器同时创建 LVM 快照。这些服务器继续在集群中运行,快照仅冻结正在备份的数据。完成备份后,服务器继续正常运行。所以,在这种备份方法中,任何 MongoDB 实例都不会宕机。本节将概述整个备份过程,具体命令会在测试部分给出。

IBM Spectrum Protect 按以下方式备份数据:

  • 运行一段脚本来关闭整个集群中的 MongoDB 平衡器,以确保快速准确地执行备份。
  • 3 个配置服务器中的一个将关闭,以执行备份过程(这样就无法更改任何数据)。
  • 同时在指定的备份副本成员和一个配置服务器上执行 IBM Spectrum Protect 备份过程。
  • 完成备份后,配置服务器将重新开启,而且它会自动开始与其他两个配置服务器同步
  • 平衡器将恢复运行,MongoDB 集群将恢复所有正常操作。

执行以下步骤来还原备份:

  1. 使用 IBM Spectrum Protect 命令将整个逻辑卷的备份还原到系统。
    • 要还原到的系统上必须有一个同名的卷组,而且有足够的空间来存储备份卷。
    • 应确保新系统的所有 DNS 和主机名设置与备份系统匹配。
    • 确保这个新系统的配置文件与作为还原来源的系统相同。
  2. 运行该命令后,启动 MongoDB 实例,请注意,它会像已备份的原始服务器一样运行。

跟踪环境的主机名和配置文件可能变成一项日益复杂的任务。我们的解决方法是,使用通过 Ansible 生成的动态配置文件和主机名。无论采用哪种方法,设置和配置元数据都值得备份,因为所采用的方法可能导致系统恢复延迟。

测试方案

AcmeAir 是一个示例应用程序,可用来验证 Spectrum Protect 如何实现 MongoDB 备份过程。可以在 https://github.com/acmeair/acmeair-nodejs 上找到这个驱动程序的源代码和文档。

AcmeAir 是一个开源应用程序,用于模仿一个包含航班查询和订票系统的航空公司网站。一些客户将数据附加到他们的登录帐户,可以包括待预订的航班信息、多段预订信息、航班预订人信息和当前的客户在线会话。这需要使用 Node.js 环境来运行一个 Web 程序,该程序通过一个 JMeter 自动化驱动程序针对该环境来驱动流量。流量通过 API 发送到网页,而应用程序使用 Node.js 驱动程序针对我们的 MongoDB 系统来运行流量。“到底如何对数据进行分片?”的问题仍然存在。在此领域,MongoDB 主要利用动态分片值所带来的改进。现在,我们将介绍 AcmeAir 数据库的索引分片。

AcmeAir 数据库包含 5 个集合,每个集合在某个点上进行分片(例如 booking、flight、flightSegment)。对该数据库启用分片,然后 5 个集合中的每个集合都应获得自己的分片索引,而且每个集合都将独立地分片。

首先,我们需要在数据库中加载一些初始数据,并运行几次该驱动程序来获得一些测试数据。该数据库会为分片做好准备,但不会主动进行分片。我们这么做是因为我们不知道这些集合中将包含哪些值,也不知道值的分布情况。如果提前知道预期的分布,就可以在将数据添加到集合之前进行分片。然后,可以使用以下命令访问主服务器的 MongoDB shell:
mongo ipaddress:port

其中 port 是数据库的主要副本正在运行的端口。

然后,您将进入 MongoDB shell。接下来,键入以下命令:
use acmeair

这会将焦点切换到我们正在使用的正确数据库。

接下来,我们需要使用以下命令获取数据库中的所有集合:
db.getCollectionInfos()

这会提供数据库中存在的集合列表。在我们的 AcmeAir 示例中,来自此命令的输出如下所示:

rs1:PRIMARY> db.getCollectionInfos()

[
        {
                "name" : "airportCodeMapping",
                "options" : {
                }
        },
        {
                "name" : "booking",
                "options" : {
                }
        },
        {
                "name" : "customer",
                "options" : {
                }
        },
        {
                "name" : "customerSession",
                "options" : {
                }
        },
        {
                "name" : "flight",
                "options" : {
                }
        },
        {
                "name" : "flightSegment",
                "options" : {
                }
        }
]

也可以使用以下命令获得集合名称的压缩列表:
db.getCollectionNames()

获得的输出如下所示:

[
        "airportCodeMapping",
        "booking",
        "customer",
        "customerSession",
        "flight",
        "flightSegment"
]

拥有集合的名称后,可以使用以下命令找到组成它们的字段:
db.collectionName.find()

其中 collectionName 是集合的实际名称,比如 airportCodeMapping

以下是该命令的示例输出:

rs1:PRIMARY> db.airportCodeMapping.find()
{ "_id" : "BOM", "airportName" : "Mumbai" }
{ "_id" : "DEL", "airportName" : "Delhi" }
{ "_id" : "FRA", "airportName" : "Frankfurt" }
{ "_id" : "HKG", "airportName" : "Hong Kong" }
{ "_id" : "LHR", "airportName" : "London" }
{ "_id" : "YUL", "airportName" : "Montreal" }
{ "_id" : "SVO", "airportName" : "Moscow" }
{ "_id" : "JFK", "airportName" : "New York" }
{ "_id" : "CDG", "airportName" : "Paris" }
{ "_id" : "FCO", "airportName" : "Rome" }
{ "_id" : "SIN", "airportName" : "Singapore" }
{ "_id" : "SYD", "airportName" : "Sydney" }
{ "_id" : "IKA", "airportName" : "Tehran" }
{ "_id" : "NRT", "airportName" : "Tokyo" }

Mongo 要求手动选择分片字段,在本例中,我们将选择 airportName 字段。

确定想要分片的字段后,是时候执行分片了。该过程的第一步是进入 mongos admin shell,您在上一步中应该已进入其中。

然后需要发出 use dataBaseName,将焦点切换到您选择的数据库。

对数据库中的每个集合重复接下来的步骤。请记住,正要分片的数据库是由这些集合组成的(大致等效于传统关系 SQL 数据库中的表)。基本上讲,分片过程就是基于集合的一个字段为集合建立索引,然后在该索引的中间点拆分该集合。

以下是操作步骤。

  1. 建立索引之前,应该使用命令 db.collectionName.getIndex() 检查是否已存在一个不错的索引。
  2. 运行db.collectionName.createIndex( { fieldName :1} ) 命令,以便在 fieldname 字段上为 collectionName 集合建立索引在本例中,字段名后的 1 表示降序。-1 表示升序。
    • 备注:仅在字段数据已存储到索引中时,才有必要为字段建立索引。如果预先知道数据的格式,可以跳过这个手动建立索引的步骤。MongoDB 会自动将分片键创建为索引。之后,可以使用以下命令设置分片键:
      sh.shardCollection("db.collection", shard-key)
    • 例如:
      sh.shardCollection("acmeair.airportCodeMapping",{"airportName":1})

备份过程和脚本

现在我们已经有一个全面设置的 MongoDB 数据库,可以开始备份了。我们选择使用 LVM 快照来获得系统的时间点备份的主要原因之一是,如果没有完全关闭每个 MongoDB 备份实例,则无法保证能够得到完美的时间点备份。MongoDB 方法 fsynclock()可用于停止针对数据库的写入操作,但事实证明,MongoDB 中的 fsynclock() 方法无法保证它的存储引擎 WiredTiger 会实际停止写入。因为这会导致数据完整性问题,所以我们使用了 LVM 快照。实际上,这会让备份过程变得更简单,而且我们剩下的唯一问题是停止平衡器,尝试让 IBM Spectrum Protect 代理同步执行备份。

部分需要脚本化的工作包括停止平衡器。此平衡器是锁定机制,它管理 MongoDB 集群中的分片间的数据重新分布。例如,如果按 Last Name 字段对某个集合进行了分片,那么两个分片之间的拆分位置可能是字母“L”。如果 MongoDB 注意到“A-L”分片中的条目比“M-Z”分片中的条目明显多得多,它可能将拆分点从“L”更改为“K”。在本例中,所有包含以“L”开头的姓氏的数据都会从分片 1 转移到分片 2。明智的做法是关闭平衡器,因为您不想让平衡器在备份过程中转移数据。新数据仍将基于其分片键而存放在正确的分片中,但分片点在平衡器关闭时不会更改。这意味着在平衡器关闭时,MongoDB 仍能接受新的写入和读取操作。

如果从分片键的一部分中流入大量数据,数据可能在此期间变得不平衡。要减少这种不平衡,可以使用更复杂的分片键,比如井号键,或者按不同的值进行分片。无论如何,MongoDB 都会在重新启用平衡器后重新平衡自身。必须注意的是,平衡器需要处于停止并禁用的状态,而不仅仅是其中一个状态。可能会遇到平衡器卡顿的问题。我们发现,处理此问题的最佳方法是,找到导致问题的 mongos 实例并将它软关闭。可通过以下过程完成此操作:

  1. 通过 MongoDB shell 连接到一个 mongos 实例。
    mongo ipaddr:27017
  2. 进入 MongoDB shell 中后,您可能想要使用配置数据库。然后,查看数据库的状态
    use config sh.status()
  3. 在输出数据顶部附近,有一个名为 balancer 的字段。该数据如下所示:
    balancer: 
        Currently enabled: yes
               Currently running: yes
    Balancer lock taken at Sat Jul 08 2017 16:18:45 GMT-0400 (EDT) by ltmngo10:27017:1444334119:1804289383:Balancer:846930886
            Failed balancer rounds in last 5 attempts: 0
            Migration Results for the last 24 hours: 
                    No recent migrations
  4. 该数据会告诉您平衡器是否已启用,是否正在运行,以及是何时启动的。平衡器可能已禁用,但仍在运行,因为禁用平衡器不会停止正在运行的进程,只会等待它们停止运行。为此,请运行以下命令:
    sh.setBalancerState(false)
  5. 可以再次检查并查看平衡器何时停止运行,以便开始备份流程。如果平衡器没有停止运行,而且上述代码中的锁定开始时间是在几个小时以前,您可能需要手动修复此问题。
  6. 首先,尝试使用以下命令让 MongoDB 执行处理:
    sh.stopBalancer()
    • 这会实时提示您有哪些活动进程,以便关闭平衡器。
  7. 根据我们的经验,如果此方法不起作用,您将需要关闭持有锁的服务器。在上述状态中,列出了持有锁的服务器。该服务器应该是一个可以安全地关闭并恢复运行的 mongos 服务器,且不会引起严重的后果。在 Bash shell 中,运行:
    ps aux | grep mongos
    • 这会向您提供需要结束的 mongos 实例的 PID。
      kill xxxxx
    • 这会结束您指定的 ID 编号为 xxxxx 的进程。
    • 让该进程重新上线,留出一定的时间让锁超时(至多 15 - 30 分钟),然后再次尝试。默认超时时间应为 900,000 毫秒或约 5 分钟。
  8. 平衡器停止后,mongos 数据服务器就做好备份准备了,但配置服务器尚未做好准备。
    • 要获得干净的配置服务器备份,需要完全关闭一个配置服务器。我们这么做是因为完全关闭该服务器可以保证不会对该配置执行读或写操作,而且我们拥有一个真正的时间点备份。另一个好处是,配置服务器不会尝试执行任何数据块迁移,或者不会允许在一个服务器关闭时执行任何类型的配置更改,从而确保备份能顺利进行。
    • 实现此目标的方法是,使用命令 service mongos stop 停止期望的备份设备上正在运行的 mongod 服务:。
    • 现在我们已准备好启动 IBM Spectrum Protect 备份流程。

关于备份流程

IBM Spectrum Protect 有一个名为 backup imagedev/vg/logical_volume 的内置方法。在 Linux 系统上,此方法运行一个备份过程,该过程涉及使用 Linux 的内置 LVM 来备份指定的逻辑卷。具体来讲,LVM 创建了一个逻辑卷快照,IBM Spectrum Protect 创建了该快照的备份,并将其上传到 IBM Spectrum Protect 服务器。

LVM 快照的工作方式是,在卷组的空闲空间中创建逻辑卷的写时拷贝克隆。这实际上意味着,通过在卷组的空闲空间中创建一个虚拟驱动器,LVM 创建了实际的逻辑卷的虚拟副本。它在虚拟快照驱动器中存储硬链接,这些链接指向真实逻辑卷上的数据。这意味着一个静态数据集上的快照几乎不占(或完全不占)存储空间(硬链接的存储空间可忽略不计)。有数据要写入原始副本时,会将原始数据复制到该快照,然后才会将新数据写入实际磁盘。也就是说,在运行该命令的时刻开始执行时间点备份,与此同时,可以保持实例正常运行,并对数据库执行新的写入操作。快照始终包含您启动快照时在逻辑卷上包含的准确数据。

一定要注意的是,MongoDB 自动创建的日志文件也包含在此快照中。日志文件是 MongoDB 跟踪在写入磁盘之前执行的最新更改的方法。这在备份流程中特别重要,因为 MongoDB 将在内存中存储一些数据,然后将其批量写入磁盘中。通过备份日志,我们拥有了已在数据库上发生但还未完全写入磁盘的所有事务的记录。快照功能可以在完全相同的时间捕获数据库和日志文件的状态,以确保该过程中不会丢失任何数据。MongoDB 将在还原时读取日志文件并应用所有待处理或未完成的更新。

当然,还需要注意一些存储考虑因素,而且各个实例的考虑因素可能有所不同。从逻辑上讲,实时备份期间更改的所有数据都会写入磁盘。这个快照空间来自逻辑卷所属的卷组的空闲空间。卷组中需要有足够的空闲空间,以存储备份期间可能发生的所有更改。在最糟糕的情况下,卷组中的空闲空间量需要与逻辑卷占用的空间相等。但是,根据数据库在备份时的重写比例,通常不会出现这种情况。此外,可向卷组添加用于备份的空间,以后再删除它。

尽管需要额外的磁盘空间,但它提供了执行实时备份的能力。我们在备份时不需要停止任何数据库服务器。所以,在执行备份的过程中不会有显著的性能影响。分片中的主服务器仍将全速运行,只有备份服务器正在处理的查询的读取时间有所减少。也可以通过一些特殊副本服务器模式消除此影响,比如 Hidden 可以预防在备份服务器上发生读操作。

另外值得注意的是,这是 MongoDB 目前推荐的备份方法,而且许多云备份公司目前在采用该方法。MongoDB 提供了一些备份和转储工具,但 IBM Spectrum Protect 提供了一种实施 LVM 快照备份的更简洁方式,而且它在后端服务器上存储和保护文件。

实际的 IBM Spectrum Protect 命令非常简单。在所有备份服务器上同时发出以下命令:
dsmc backup image /dev/volumeGroup/data

这是通过客户端服务器上的命令行启动备份的基本命令,但您应了解其中的某些部分和选项。

首先,dsmc 是 Linux 命令行上的 IBM Spectrum Protect 命令,程序需要响应该命令。我们从 shell 运行的所有 IBM Spectrum Protect 命令都以 dsmc 开头。

backup image 命令告诉 IBM Spectrum Protect 要执行的操作 (backup),以及要使用的技术 (image)。

此命令的最后一部分是需要备份的逻辑卷名称。一定要注意的是,必须使用设备路径 (/dev/volume_group/volume),而不是仅使用挂载点的名称(比如 /data)。IBM Spectrum Protect 对使用文件系统挂载点(比如 /data)有不同的解释,而且它将尝试执行文件系统备份,而不是 LVM 逻辑卷快照。

还有另外几个很有用并值得了解的命令。

第一个是 snapshotcahesize。这是一个选项,允许您设置 IBM Spectrum Protect 在卷组中保留的空间占逻辑卷总大小的比例。所以,如果 /data 目录为 100 GB,将 10 传递给此选项会导致 LVM 在卷组中为快照保留 10 GB 的空间。如果在备份期间,最初的 100 GB 中有超过 10 GB 的内容发生更改,IBM Spectrum Protect 代理会返回错误,备份将失败。在任务关键型、时间非常敏感的备份中,您可能希望卷组中的所有逻辑卷空间都是空闲且未分配(在本例中,总空间为 100 GB)。
dsmc backup image -snapshotcachesize=10 /dev/volumeGroup/data

请记住,默认值为 100%。因此,如果不使用此标志,卷组空闲空间必须大于或等于正使用的逻辑卷的实际大小。在我们的测试中,我们使用的值约为 25,而且绝不会耗尽空间。应该逐个案例地监控和设置此值。您还会注意到,该标志通过一个等号与该值连接,这与 Linux 标准不同。

指定 55% 的缓存大小时,该命令如下所示:
dsmc backup image-snapshotcachesize=55 /dev/volumeGroup/data

最后一个重要命令行选项是 compression。此选项允许您压缩此备份,然后再将它上传到 IBM Spectrum Protect 服务器。稍后我们将详细介绍压缩。该命令如下所示:
dsmc backup image -compressi=yes /dev/volumeGroup/data

剩下的所有工作就是备份我们的 MongoDB 集群了。借助正确设计的 LVM 布局和精心规划的配置,IBM Spectrum Protect 可用一条命令完成备份。

您应该知道这是一个时间点备份。此备份的目的是在启动备份流程时捕获数据库的完美副本。尽管 MongoDB 数据服务器正在运行,而且正在执行读写操作,但备份的数据是启动备份那一刻位于磁盘上的数据。在启动到完成备份流程的过程中传入或删除的所有数据,都会在服务器的当前状态中反映出来,而不是反映在备份数据中。

运行命令

可采用一些不同的命令运行方式来执行备份流程。您需要向 MongoDB 发出一些不同的命令,还要发出一个 IBM Spectrum Protect 命令。对这些命令编写脚本的确切方法取决于数据库管理员的脚本偏好和技能集。编写脚本过程中的一个非常重要的因素是,所有 IBM Spectrum Protect 备份流程几乎都需要同时启动。为了顺利获得时间点快照,您可能不希望将任何数据传入到无法在配置服务器中识别的任何数据服务器中。此数据将孤立地保存在数据库中,配置数据库中没有它的引用,所以它毫无意义!要尽量避免这种情况,需要一种可靠的同步机制。我们相信一些方法可以满足此要求:

  • cron 和 shell 脚本-用 shell 脚本将此任务编写为脚本,然后在所有备份系统上运行一次同步的 cron,这是执行 Linux 管理的典型方式。您可能需要观察 IBM Spectrum Protect 服务的状态,以确保同时在所有系统上执行备份,并确保备份相对不容易出错。
  • MongoDB 命令-向正在运行的数据库发出关闭和启动命令可能有点棘手。但是可通过许多方式完成此任务。可以用 JavaScript(mongos 原生语言)实际编写关闭命令,并通过 bash 将该 JavaScript 文件传递给 MongoDB shell。还有一些 Python 驱动程序(比如 PyMongo),如果这是您首选的脚本编写方法。可以从您管理 MongoDB 所需的 PyMongo 驱动程序执行任何操作。您能使用的每种语言都有驱动程序。
  • 自动化软件-这包括 Chef、Puppet、Ansible 和 SaltStack 等软件。许多公司已在使用这些服务来管理其基础架构,而且对 MongoDB 使用这些服务有很多好处。可通过添加新系统、分片和副本来扩展 MongoDB。集群可能很快变复杂,而且您不希望手动管理它。但具体来讲,在备份方面,可使用这些服务从单一控制点管理备份。这使您能通过自动化软件同步所有服务器。在本文中,我们选择使用 ansible 来构建和备份我们的 MongoDB 集群。它不仅灵活,而且易于使用。

还原数据库

同样地,在还原数据库时,使用 IBM Spectrum Protect 命令很简单,但也需要注意以下考虑因素:

  1. 假设
    您正尝试从一个时间点快照进行恢复,该快照位于新服务器上,或者位于以前运行 MongoDB 且数据已损坏或丢失的服务器上。无论采用哪种方式,恢复过程几乎是相同的。
  2. 重要考虑因素

    MongoDB 的一些设计特性影响着我们还原备份数据的方式。回顾一下已经介绍过的一些内容:

    • 生产集群中始终有 3 个基本相同的配置服务器。
    • 有多个分片,每个分片包含整个 MongoDB 数据库的一小段。
    • 每个分片都被复制,这意味着有多个 MongoDB 实例包含相同的数据。
    • MongoDB 服务器实例不会持久保存任何数据,只需要一个指向要运行的 MongoDB 配置服务器的配置文件。配置服务器包含大部分集群的分片规则和配置。配置服务器还包含表明实际数据存储位置的所有元数据。
    • MongoDB 实例实际存储了关于自己的主服务器和辅助服务器的信息。
    • Mongo 服务器是通过主机名进行识别的。所以,您需要 3 种资源才能完全还原一个系统:配置文件、数据和主机名。这些事实决定了备份和还原的方式。根据这些观察结果,我们得出了一些重要结论。

    首先,如果一个服务器与另一个服务器相同,则不需要单独备份每个服务器并还原它们。相反,可以创建一个相同服务器的备份。现在,在还原它时,可将它传播到集群中的所有相同的服务器。

    其次,因为所有配置文件都包含在备份中,所以精心规划且正确执行的还原操作可以还原旧配置,不需要用户执行额外的配置。最终,您只需给还原后的系统通电,就会观察到它与备份时完全相同。这使还原变得更简单更快捷,尤其是在进行大规模还原时。为此,可以将配置文件和备份数据一起保存在逻辑卷中,或者使用上面提到的自动化平台之一动态创建配置文件。

    最后,通过主机名识别的服务器使得更换硬件和还原到完全不同的系统变得很容易。如果需要在执行还原时更换部分或所有硬件,只需更改系统上的主机名,使之与原始配置中的信息相匹配。这样,您的整个配置将保持不变,而且 MongoDB 能继续通过网络在整个集群中进行通信。

  3. 服务器配置

    您的服务器需要进入与 MongoDB 崩溃前完全相同或相似的状态。因此,强烈建议使用某个自动化软件将基础架构创建为代码。这会使得部署结构相同的服务器变得很容易。在任何情况下,都需要确保一些步骤是在运行任何 IBM Spectrum Protect 还原特性前执行的。这些步骤与最初设置服务器所采用的步骤几乎相同。必须在还原的集群中包含的所有服务器上执行这些步骤。

    1. 确保 MongoDB 已安装,而且在正确的位置有一个相同的配置文件。这包括确保日志和进程 ID (PID) 文件需要的所有目录均存在。这些文件应归将要运行 mongos 实例的用户所有。如果不是这样,请使用 chown 确保 mongo 进程能访问任何这些文件。
    2. 确保您创建的逻辑卷空间至少有备份的原始逻辑卷那么大(可通过备份文件的大小确定这一点)。
      lvcreate -L 10G -n data rhel7_system
    3. 在询问是否想要重写文件系统块的提示中,回答 yes。我们需要的底层文件系统实际上位于我们将要还原的镜像上。
    4. IBM Spectrum Protect 要求已分配了一个逻辑卷来还原备份。它不会还原到空闲的卷组空间。它需要逻辑卷的 shell。
    5. 不能还原比备份镜像更小的逻辑卷。如果尝试这么做,将会失败。如果还原的逻辑卷更大,还原仍会成功,但您不能在新创建的 LVM 上构建文件系统。

      如果在新创建的 shell 逻辑卷上创建文件系统,特别是 XFS 文件系统,并尝试还原更小的备份镜像,IBM Spectrum Protect 代理会尝试压缩该文件系统,以便自动将它们匹配在一起。问题在于 XFS 没有文件系统压缩命令,所以此操作会失败。对于这种从完整 LVM 快照进行还原的还原类型,不需要在(将文件系统还原到其上的)逻辑卷上构建文件系统。由于已发现的潜在错误,应避免采用这种方法。

    6. 确保挂载点存在,用于在还原后附加 LVM。如果没有,请使用 mkdir /FileName (i.e. mkdir /data) 命令创建它。
    7. 确保 IBM Spectrum Protect 代理已安装在系统上,而且所在目录不同于还原 MongoDB 所用的目录(例如,如果 IBM Spectrum Protect 存储在 /opt 中,则不应尝试 还原 /opt 逻辑卷)。
    8. 如果使用不同的硬件,一定要更改主机名,使之与配置文件中的主机名相匹配,并确保主机位于您将还原的镜像所在的副本集中。
  4. 还原命令
    • 如果还原到最初从中获取备份的相同系统,可使用以下命令:
      dsmc restore image /dev/rhel7_system/data
    • 如果希望将 IBM Spectrum Protect 镜像还原到不同的系统,需要授权这个新系统,允许它访问原始系统的备份镜像。为此,请执行以下操作:
    • 访问备份起源服务器。通过输入 dsmc 终端命令进入 IBM Spectrum Protect shell。
    • 请注意,您的提示符为 tsm>
    • 输入 q access 命令来识别有访问权的节点,或者输入 q files 命令来查看所有已备份的文件。set access backup "*" nodeName. set access backup "*" nodeName 命令列出了包含 nodeName 的能够访问当前节点的备份文件的所有节点。
    • 目标还原服务器能访问备份后,可使用以下命令执行还原:
      dsmc restore image -fromnode=LTMNGO09 /dev/rhel7_system/data /dev/rhel7_system/data
    • 还原 LVM 后,需要将它重新挂载到文件系统。运行以下命令:
      mount /dev/mapper/<volumeGroup> - <name> <mountPoint>

      (例如 mount dev/mapper/rhel7_system-data /data

    • 在该服务器上启动 MongoDB 实例,尝试使用 mongo —port <port> 连接到本地 MongoDB shell。确认系统在正确的配置下正常运行后,停止 MongoDB 实例。

      还原过程的这一阶段可能稍微不同。因为我们拥有相同的服务器,所以只需查看一个副本的备份镜像。在还原时,需要将这个镜像还原回所有副本。完成此任务的两种最简单方法是:

      • 使用 IBM Spectrum Protect 还原到一个服务器,使用 copy 命令将文件从还原的服务器移动到它的所有副本

      或者,

      • 将 IBM Spectrum Protect 代理安装在所有系统上,同时从 IBM Spectrum Protect 服务器还原该镜像,以观察复制的服务器。这需要执行前面提及的步骤,以确保副本集中的其他每个节点都能访问备份节点。

      在还原后复制文件的优势在于能减少 IBM Spectrum Protect 代理的数量。因为我们只需要来自一个系统的备份数据,所以安装的大部分 IBM Spectrum Protect 代理仅执行还原操作,绝不执行任何备份任务。将文件从还原的备份服务器复制到副本集时,IBM Spectrum Protect 服务器执行的工作更少,而且只需在备份服务器上安装 Spectrum Protect 代理。根据 IBM Spectrum Protect 的定价套餐,这可能有一定的影响,尤其是在大规模执行还原时。当然,您必须编写一个程序来将文件从还原的服务器中复制并分发到其他服务器,而且需要稍微更多的自定义工作。

      对所有服务器使用 Spectrum Protect 还原功能可能更加简单。但是,集群中所有系统上都需要有一个 Spectrum Protect 代理。Spectrum Protect 服务器上的压力也会增加,因为 MongoDB 集群中的每个节点都需要直接从该服务器还原 LVM 镜像。在本文中,我们使用了两种方法,并发现两种方法都很令人满意。

      方法 1(复制文件):按照上面的解释,使用 Spectrum Protect 代理还原到服务器。进入已还原的卷的数据目录,并使用 TCP 将数据传输到其他服务器。

      scp -r /data/mongo/….. hostname1:/

      例如:

      scp -r /data/mongo root@ltmgo04:/data

      然后一定要在文件到达另一个服务器时在这些文件上使用 chown,以确保文件归运行 MongoDB 的用户(默认为 mongod)所有。也可以使用 rsync 或其他某种文件复制/同步方法在服务器之间传递文件。

      方法 2(在所有服务器上使用 IBM Spectrum Protect:在此方法中,需要在所有服务器上安装 Spectrum Protect,并运行上面给出的 set access 方法。需要对拥有自己的副本集的每个成员的每个备份系统运行这些方法。这样,它们就能自由访问该 Spectrum Protect 镜像。然后,可以按照之前提到的所有还原步骤,使用远程还原方法来还原文件系统。然后,应该更改数据目录的所有权,确保它归运行 MongoDB 的用户所有。

      这个还原过程同样适用于所有 MongoDB 数据服务器和 MongoDB 配置服务器。mongos 服务器唯一需要还原的是,放置在要运行它们的服务器上的配置文件。

      既然我们已知道如何备份所有单独的服务器,接下来需要确保按正确顺序启动集群。

      在还原过程的这一阶段,MongoDB 实例应包含其所有数据并正常运行。然后,应再次关闭 MongoDB 服务,让所有 MongoDB 服务目前都处于关闭状态。

      接下来,我们将启动 MongoDB 服务,保持它们运行,确保没有任何错误。这是还原 MongoDB 实例的启动顺序,与原始启动顺序完全相同。

      首先,必须启动单个副本集的每个成员。需要确保有一个主节点和一个辅助节点,而且它们都能相互通信并将自己识别为同一个副本集的成员。必须对所有不同的副本集执行此操作,并在前进到下一步时保持它们正常运行。

      其次,激活所有副本集后,是时候处理配置服务器了。这些服务器必须在所有 mongos 实例之前开启。所有 3 个服务器都正常运行后,就可以开始启动 mongos 实例。保证(永远)不会更改配置服务器的主机名。即使还原到了新的配置服务器,也应该更改它们的主机名,使之与原始 mongos 配置中的主机名相匹配。

      应该首先启动一个 mongos 实例,检查日志,确保可以连接到所有配置服务器实例。看到这些操作完成后,通过 mongos 实例连接到 MongoDB shell。然后可以运行分片测试,查看数据,确保所有一切都在。如果一切都运行正常,那么您已成功还原一个 MongoDB 备份,并运行着一个有效的集群。您可以启动想要的任意多个 mongos 实例,并尽情使用您刚还原的服务器。

  5. 将数据放在何处

    根据与备份过程相关的各种因素,我们确定 MongoDB 的数据部分应保留在一个单独的卷组中,并挂载到 /data 目录。现在,可以将它挂载到现有卷组,但必须是它自己的逻辑卷。我们不想在执行备份时浪费任何空间,而且希望能够轻松地将它挂载到已知位置。

性能考虑因素

备份过程中要知道的考虑因素:

  • 时间 - 时间不是一个重要因素,因为在备份期间 MongoDB 集群性能没有任何影响。物理备份的吞吐量依赖于基础架构的吞吐量和同时备份的分片数量。
  • CPU 性能 - 备份过程中可以观察到更高的 CPU 利用率。执行无压缩备份时,可以看到运行期间的空闲空间比例下降了 10% 到 20%。最极端的情况是在开启压缩时。我们看到在执行压缩备份时,一些系统的空闲空间比例在短时间内(30 秒)保持在 0%,这种情况肯定不理想。这些系统在执行备份时确实正在运行,并可能被要求执行查找,如此高的 CPU 利用率可能会导致 MongoDB 性能瓶颈。但是,我们注意到,在执行压缩备份期间,MongoDB 集群性能没有出现明显下降。显然 CPU 与网络流量和存储之间达到了某种平衡。应根据每个案例来确定最佳方法。一定要记住,MongoDB 通常不受 CPU 利用率约束。内存空间和磁盘 I/O 更有可能带来压力。鉴于在我们的测试案例中,备份服务器是一个辅助副本,它仅处理偶尔的读操作,不会处理直接写入操作,所以备份过程使用的 CPU 周期应可以忽略不计。根据设计,备份流程是在负载低于主服务器且能快速备份的服务器上执行的,而剩余服务器可用来处理使用高峰期内的请求,并与数据库的剩余部分保持同步,而不需要在备份后再赶上进度。
  • MongoDB 性能 -备份允许所有服务器(包括备份服务器)保持运行并能执行正常任务。这应该不会影响 MongoDB 的性能,除非在最大压力情况下。备份过程中最大胆的性能权衡措施是禁用某个配置服务器。这意味着 mongos 服务器必须从 2 个而不是 3 个服务器中检索所有元数据。但是,MongoDB 3.0 版不会扩展到 3 个配置服务器以上,这意味着拥有更多配置服务器实际上不会提升性能;这更多地是一种冗余措施。配置服务器恢复上线后,它将进入同步模式,以捕获在它离线期间可能发生的任何元数据更改。该操作通常会在几秒内完成,完全不会引起问题。
  • 压缩与非压缩备份- 对于 Spectrum Protect Server 的 IBM Power 版本,可以选择使用压缩和非压缩备份。压缩镜像备份需要更多时间才能完成。

结束语

MongoDB 变得越来越流行,并广泛应用于 Power 环境中。IBM Spectrum Protect(以前称为 Tivoli Storage Manager)是一个成熟、久经考验、战略性的世界级数据保护平台,能帮助所有规模的企业满足其数据保护需求。

本文介绍了使用 IBM Spectrum Protect 备份 MongoDB 数据的方法。如果客户已在其数据中心内建立了 Spectrum Protect,那么 Spectrum Protect 备份功能将是一个不错的数据保护选项。

这里回顾的备份过程推荐使用 IBM Spectrum Protect 为一个专门用作备份服务器的 MongoDB 副本集成员创建 Linux 文件系统快照。文中定义了设置备份环境的最低要求。列出了对数据和日志文件执行备份的步骤。在执行备份的同时,应用程序可以写入数据,而不会宕机。

使用 IBM Spectrum Protect 还原 MongoDB 数据库的方法也已经过测试和备案。本文包含准备目标文件系统的步骤和发起还原的 IBM Spectrum Protect 命令。推荐的复原选项是使用 IBM Spectrum Protect 恢复一个副本集成员,使用 Linux 命令将数据复制到副本集的其他成员。另一个选项是将 Spectrum Protect 代理安装在所有服务器上,并使用 IBM Spectrum Protect 还原它们。因此,本文提供了多种选择:我们展示了此解决方案的灵活性,并尽力让客户能确定哪种选项最适合他们的环境。

致谢

本文改编自白皮书“使用 IBM Spectrum Protect for Linux on z 的备份还原方法”,该白皮书由 Ryan Bertsche、Robert McNamara、Kyle Moser 和 Dulce Smith 为 IBM z Systems 编写。


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Linux, Big data and analytics
ArticleID=1049367
ArticleTitle=使用 IBM Spectrum Protect for Linux on Power 备份和还原 MongoDB 数据的方法
publish-date=09062017