Couchbase 3.1.0 - 执行完整备份时出现内存不足错误

Couchbase 3.1.0 - Hard out of memory error when performing full backup

我们最近迁移到了 Couchbase 3.1.0。奇怪的是 - 在执行存储桶的完整备份时,web UI 警报 "Hard Out Of Memory Error. Bucket X on node Y is full. All memory allocated to this bucket is used for metadata"。网络中 RAM 使用的数字 UI 与此相矛盾 - 使用了大约 75%,但不是 100%。我查看了日志,但没有发现任何类似的错误。
这还正常吗?

当您 运行 进行完整备份时,默认情况下,备份工具会通过网络从所有节点流式传输数据。这不是最好的方法,因为它会导致大量额外负载和内存使用量增加,尤其是您 运行 在 Couchbase 节点之一上进行 cbbackup。我会使用 cbbackup 的数据复制模式,它直接从磁盘上的文件复制数据:

> sudo /opt/couchbase/bin/cbbackup couchstore-files:///opt/couchbase/var/lib/couchbase/data/ /tmp/backup

当然,将数据路径更改为实际存储 Couchbase 数据的位置。 (在我的示例中,它 运行s 作为 sudo 因为只有 root 具有对 /opt/couchbase/blabla.. 的读取权限。)在每个节点上执行此操作,然后收集所有备份文件夹并将它们放在某个地方。请注意,备份非常可压缩,因此您可能希望在通过网络复制之前将它们压缩。

这是 Couchbase 服务器 3.x 版本中的一个已知问题。

要理解这个问题,我们还必须首先了解数据库更改协议 (DCP),该协议用于在整个系统中传输数据。在高层次上,DCP 的流量控制如下:

  1. 消费者创建与生产者的连接并发送打开连接消息。 Consumer 然后发送一个 Control 消息来指示每个流的流量控制。此消息将在键部分包含“stream_buffer_size”,并在值部分包含消费者希望每个流具有的缓冲区大小。
  2. 然后消费者将开始打开流,以便可以从服务器接收数据。
  3. Producer 将继续为缓冲区 space 可用的流发送数据,直到达到最大发送大小。
  4. 步骤 1-3 继续,直到连接关闭,因为消费者继续使用流中的项目。

cbbackup 实用程序不实现任何流量控制(数据缓冲区限制),但是它会尝试同时从所有节点流式传输所有 vbucket,缓冲区大小没有上限。 虽然这并不意味着它将使用与整体数据大小相同的内存量(因为流正在被 cbbackup 进程缓慢耗尽),但这确实意味着需要大量内存开销才能存储数据溪流。 当您处于繁重的 DGM(磁盘大于内存)场景中时,存储流所需的内存量可能会增长得比 cbbackup 耗尽它们的速度更快,因为它正在从磁盘流式传输大量数据,从而导致非常大流,如前所述占用大量内存。

显示有关元数据占用所有内存的轻微误导性消息,因为没有剩余内存用于数据,因此所有剩余内存都分配给元数据,使用值逐出时无法从元数据中弹出内存。

这只影响 4.0 之前的 Couchbase 服务器版本的原因是在 4.0 中对 DCP 流管理进行了服务器端改进,允许暂停 DCP 流以减少内存占用,这被跟踪为MB-12179。 因此,无论您的存储桶如何 DGM,您都不应该在 Couchbase 服务器版本 4.x+ 上遇到同样的问题。

解决方法

如果您发现自己遇到了这个问题,那么终止备份作业应该会立即释放流消耗的所有内存。 不幸的是,如果由于备份,您已经将大部分数据从内存中逐出,那么您将不得不在短时间内从磁盘而不是 RAM 中检索大量数据,这可能会增加您的获得延迟。 随着时间的推移 'hot' 数据将在请求时被带入内存,因此这只会是一小段时间的问题,但这仍然是一个相当不受欢迎的情况。

完全避免此问题的解决方法是在执行备份时一次仅流式传输少量 vbucket,而不是 cbbackup 默认执行的所有 vbucket。

这可以使用 cbbackupwrapper 实现,它与所有 Couchbase Server 版本 3.1.0 及更高版本捆绑在一起,使用 cbbackupwrapper 的详细信息可以在 the Couchbase Server documentation 中找到。 特别要注意的参数是-n标志,它指定一次批量备份的vbuckets数量。 顾名思义,cbbackupwrapper 只是 cbbackup 之上的包装脚本,它将 vbucket 分区并自动处理所有目录创建和备份生成,同时仍在后台使用 cbbackup。 例如,批处理大小为 50,cbbackupwrapper 将首先备份 vbuckets 0-49,然后是 50-99,然后是 100-149 等

建议您在反映生产环境的测试环境中使用 cbbackupwrapper 进行测试,以找到 -n-P 的合适值(控制备份进程的数量 运行 同时,这两者的组合控制了备份造成的内存压力量以及整体速度)。 您不应该发现将 -n 的值从其默认值 100 降低会降低备份速度,在某些情况下,您可能会发现备份速度实际上增加了,因为服务器上的内存压力要小得多。 但是,如果您希望进一步加快备份速度,您可能希望明智地调整 -P 参数。

下面是一个示例命令:

cbbackupwrapper http://[host]:8091 [backup_dir] -u [user_name] -p [password] -n 50

请注意,如果您使用 cbbackupwrapper 执行备份,那么您还必须使用 cbrestorewrapper 来恢复数据,因为 cbrestorewrapper 会自动识别目录结构cbbackupwrapper.

使用