Cassandra-Medusa备份工具介绍

备份Cassandra的挑战

备份Apache Cassandra数据库很困难,并不复杂。您可以使用nodetool snapshot手动做快照,并将其从节点移到另一个节点。现有的开放源代码工具(例如tablenap)就是这样做的。但是,它们都往往缺少线上生产中所需的某些功能,尤其是在还原数据时,这是对备份解决方案的终极测试。
为Cassandra提供灾难恢复有一些有趣的挑战和机遇:

  • 每个SSTable中的数据都是不可变的,从而允许进行高效的差异备份,该差异备份仅复制自上次备份以来的更改。
  • 每个SSTable都包含该节点负责的数据,还原过程必须确保将其放置在也负责该数据的节点上。否则,客户端可能无法访问。
  • 要恢复到不同的群集配置,节点数或令牌数的变化,需要按照Cassandra的规则将数据重新分配到新的拓扑中。

medusa(美杜莎)介绍

Medusa是一个命令行备份和还原工具,可了解Cassandra的工作方式。
该项目最初由Spotify创建,以替换其旧式备份系统。TLP在不久之后被聘来接管开发工作,使其可以投入生产并进行开源。
它已在小型和大型集群上使用,并提供了运营团队所需的大多数功能。
美杜莎支持:

  1. 备份单个节点。
  2. 恢复单个节点。
  3. 还原整个群集。
  4. 选择性还原keyspace和表。
  5. 支持单个令牌和vnode群集。
  6. 清除旧数据的备份集。
  7. 完整或增量备份模式。
  8. 自动验证还原的数据。

使用Python 3.6版的命令行工具,需要安装在要备份的所有节点上。它支持2.1.0之后的所有版本的Cassandra,并且由于Apache libcloud项目可以在许多平台上存储备份,包括:

  • Amazon Web服务S3。
  • Google Cloud Platform GCS。
  • 本地文件存储。
  • 任何支持libcloud的provider都只需最少的努力。

使用Medusa备份单个节点

一旦安装并配置了medusa,就可以使用一个简单的命令来备份节点:

medusa backup --backup-name=<backup name>

当这样执行时,美杜莎将:

  1. 使用Cassandra nodetool命令创建快照。
  2. 将快照上载到配置的存储提供程序。
  3. 从本地节点清除快照。

与SSTables一起,Medusa将为每个备份存储三个元文件:

  • 完整的CQL schema。
  • 令牌映射,节点列表及其令牌所有权。
  • 清单,带有md5哈希值的备份文件列表。

完整备份和差异备份

所有Medusa备份仅从节点复制新的SSTable,从而减少了所需的网络流量。然后,它有两种方法来管理备份目录中的文件,我们称之为完全备份或差异备份。对于差异备份,每个新备份仅保留对SSTables的引用,因此每个SStable无论其有多少个备份,仅有一份数据,。差异备份是默认的,在Spotify中的操作减少了某些群集的备份大小高达80%
完全备份每次运行时都会在节点上创建所有SSTable的完整副本。自上次备份以来未更改的文件将在备份目录中复制到新备份中(而不是从节点上复制)。与仅创建对文件的引用的差分方法相反。当您需要制作完整副本并将所有文件放在一个位置时,完全备份非常有用。

Cassandra-Medusa备份工具介绍

差异备份利用了由Cassanda使用的LSM存储引擎创建的不可变SSTable的特点。在这种模式下,Medusa会检查SSTable之前是否已经备份过,并且仅复制新文件(就像往常一样)。但是,该节点的所有SSTable然后都存储在一个公用文件夹中,并且备份清单仅包含元数据文件和对SSTable的引用。

Cassandra-Medusa备份工具介绍

使用Medusa备份群集

Medusa当前缺少业务流程层来为您在所有节点上运行备份。实际上,我们一直在使用crontab进行群集范围的备份。虽然我们一直在考虑了自动化执行此操作的最佳方法,但我们建议使用以下技术:

  • 通过crontab在每个节点上调度。
  • 使用pssh在所有节点上手动进行。
  • 使用cstar编写脚本。

列出备份

具有相同“备份名称”的所有备份均被视为群集的同一备份的一部分。Medusa可以提供群集的所有备份的清单,包括备份的开始和结束时间以及所有节点是否都已完成备份。
要列出集群的所有现有备份,请在一个节点上运行以下命令:

$ medusa list-backups
2019080507 (started: 2019-08-05 07:07:03, finished: 2019-08-05 08:01:04)
2019080607 (started: 2019-08-06 07:07:04, finished: 2019-08-06 07:59:08)
2019080707 (started: 2019-08-07 07:07:04, finished: 2019-08-07 07:59:55)
2019080807 (started: 2019-08-08 07:07:03, finished: 2019-08-08 07:59:22)
2019080907 (started: 2019-08-09 07:07:04, finished: 2019-08-09 08:00:14)
2019081007 (started: 2019-08-10 07:07:04, finished: 2019-08-10 08:02:41)
2019081107 (started: 2019-08-11 07:07:04, finished: 2019-08-11 08:03:48)
2019081207 (started: 2019-08-12 07:07:04, finished: 2019-08-12 07:59:59)
2019081307 (started: 2019-08-13 07:07:03, finished: Incomplete [179 of 180 nodes])
2019081407 (started: 2019-08-14 07:07:04, finished: 2019-08-14 07:56:44)
2019081507 (started: 2019-08-15 07:07:03, finished: 2019-08-15 07:50:24)

在上面的示例中,名为“ 2019081307”的备份被标记为未完成,因为180个节点中有1个节点未能完成备份。
还可以验证是备份中所有期望的文件,并且它们的内容与备份时生成的哈希值匹配。更多操作在Medusa README文件中进行了详细说明。

恢复备份

当缺少备份的编排时,Medusa协调还原整个群集,因此您只需要运行一个命令即可。该过程通过SSH连接到节点,并根据需要启动和停止Cassandra,直到可以使用集群为止。还原过程处理三种不同的用例。

  1. 还原到同一群集。
  2. 还原到具有相同数量节点的其他群集。
  3. 还原到具有不同数量节点的其他群集。

案例1-还原到同一群集

这是最简单的情况:将备份还原到同一群集。群集的拓扑结构未更改,创建备份时存在的所有节点仍在群集中运行。
Cassandra-Medusa备份工具介绍


使用以下命令运行就地还原:

$ medusa restore-cluster --backup-name=<name of the backup> \
                         --seed-target node1.domain.net

种子目标节点将用作发现群集中其他节点的联系点。Medusa将发现集群中节点和令牌分配的数量,并检查其是否与源集群的拓扑匹配。
要完成此还原,每个节点将:

  1. 将备份数据下载到/tmp目录中。
  2. 停止cassandra。
  3. 删除提交日志,保存的缓存和数据目录(包括系统keyspace)。
  4. 将下载的SSTables移到数据目录中。
  5. 启动Cassandra。

不需要重新创建schema,因为它包含在系统keyspace中,并且可以从备份中复制。

情况2-还原到具有相同节点数的其他群集

还原到具有相同数量节点的其他群集会有些困难,因为:

  • 目标群集可能具有不同的名称,该名称存储在system.local表中。
  • 节点可以具有不同的名称。
  • 节点可以具有不同的令牌分配。

Cassandra-Medusa备份工具介绍


使用以下命令运行远程还原:

$ medusa restore-cluster --backup-name=<name of the backup> \
                         --host-list <mapping file>

host-list参数告诉Medusa如何从原始备份节点映射到新集群中的目标节点,该新集群假定为正在工作的Cassandra集群。映射文件必须是具有以下各列的命令分隔文件(无标题行):

  1. is_seedTrueFalse指示目标节点是否是种子节点。因此,我们可以首先还原并启动种子节点。
  2. target_node:目标集群中节点的主机名。
  3. source_node:要从中复制备份数据的源节点的主机名。

例如:

True,new_node1.foo.net,old_node1.foo.net
True,new_node2.foo.net,old_node2.foo.net
False,new_node3.foo.net,old_node3.foo.net

除了上面为案例1列出的步骤之外,在执行到远程集群的备份时,还执行以下步骤:

  1. 不会修改system.local和system.peers表以保留集群名称并防止目标集群连接到源集群。
  2. 除非将--keep-auth标志传递给restore命令,否则从备份中还原system_auth keyspace。
  3. 通过在-Dcassandra.initial_token重新启动节点时传递JVM参数,在目标节点上更新令牌所有权以匹配源节点。这将中更新本地system keyspace,会引起重新更改数据所有权。

情况#3-还原到具有不同数量节点的其他群集

恢复到具有不同数量节点的其他集群是最难处理的情况,因为:

  • 目标群集可能具有不同的名称,该名称存储在system.local表中。
  • 节点可以具有不同的名称。
  • 节点可以具有不同的令牌分配。
  • 令牌范围永远不能相同,因为节点数不同。

最后一点是问题的症结所在。我们无法获得相同的令牌分配,因为我们有不同数量的节点,并且令牌被分配为在节点之间平均分配数据。但是,我们备份的SSTables包含与源群集中定义的令牌范围对齐的数据。还原过程必须确保根据新令牌分配将数据放置在作为副本的节点上,否则数据似乎已丢失。
为了支持将数据还原到其他拓扑中,Medusa使用了Cassandra代码库中的sstableloader工具。尽管比从备份中复制文件要慢,但是sstableloader能够将数据“修复”到目标群集中。它通过读取令牌分配并将SSTable中与新令牌范围匹配的部分流式传输到集群中的所有副本来实现。
Cassandra-Medusa备份工具介绍


使用以下命令来运行到具有不同拓扑的集群的还原:

$ medusa restore-cluster --backup-name=<name of the backup> \
                         --seed-target target_node1.domain.net

使用此技术还原数据有一些短板:

  1. 还原将花费更长的时间。
  2. 加载到群集中的数据量将是备份集的大小乘以复制因子。例如,具有复制因子3的群集的备份将具有9个数据副本的副本。多余的副本将通过压缩删除,但是在还原过程中磁盘上的总负载将比还原结束时的总负载高。参见下面的进一步讨论。
  3. 将删除集群中的当前schema,并使用备份中的schema创建一个新的。默认情况下,当删除schema时,Cassandra将做一个快照,该快照由auto_snapshot配置设置控制,Medusa或Cassandra不会清除该快照,这个快照将占用额外的磁盘空间。这是明智的安全预防措施,一种简单的解决方法是手动确保目标群集中没有任何数据。

使用sstableloader还原时,有一些关于数据放大的额外说明。备份具有多副本的数据,假如我们的复制因子为3,大致来说每个分区有3个副本。这些副本散布在我们从每个节点收集的SSTable上。当我们处理每个SSTable时,sstableloader将数据修复回群集,并将其发送到3个新副本。因此,备份包含3个副本,我们将处理每个副本,然后将每个副本发送到3个新副本,这意味着:

  • 还原将九份数据副本发送到群集。
  • 每个节点获得三个数据副本,而不是一个。

运行这种类型的还原时,将发生以下操作序列:

  1. 删除schema并重新创建它们(一次用于整个集群)
  2. 将备份数据下载到/ tmp目录中
  3. 为备份中的每个表运行sstableloader

现在可以在GitHub上使用

Medusa现在可以在GitHub上使用,并且很快将通过PyPi提供。使用此博客文章和存储库中的自述文件,您应该能够在开始的几分钟内进行备份。与往常一样,如果您有任何问题,请在GitHub项目中创建一个问题以获取帮助。它已经在Spotify中使用了几个月,并在Google Cloud Storage(GCS)中存储了PB的备份,并且我们感谢Spotify向社区捐赠了该软件,以使其他人也可以放心地对其数据进行安全备份。
最后一件事,我们很乐于地接受社区贡献patch,尤其是增加支持新对象存储源,如阿里OSS

入群邀约

为了营造一个开放的 Cassandra 技术交流环境,社区建立了微信群公众号和钉钉群,为广大用户提供专业的技术分享及问答,定期开展专家技术直播,欢迎大家加入。另外阿里云提供免费Cassandra试用:https://www.aliyun.com/product/cds
Cassandra-Medusa备份工具介绍

上一篇:ApacheCon 2019 Cassandra分会各大议题深度剖析,解读cassandra前沿工作


下一篇:cassandra主键索引介绍