TSDB 的备份机制

假设你有存储了TB级数据的 TSDB 。你如何管理这些数据的备份?你是否认为数据太大而无法备份,并盲目依赖数据库多副本来保证数据安全?那么你就麻烦了。

为什么多副本无法完美解决数据可靠性

多副本是指在不同的硬件资源上创建相同数据的多个副本,并保持这些数据的一致性状态。副本可以防止硬件故障,即如果某个节点或磁盘失效,你的数据不应该丢失或损坏,因为至少应该保留一份数据副本。我们安全吗?
不:

  • 如果你在数据库迁移期间意外删除了数据?它会从所有副本中删除。数据丢失了。没有办法恢复它。
  • 如果你在例行的数据库集群升级或重新配置期间犯了错误,导致数据丢失?副本在这种情况下也无济于事。

如何防止这些问题?使用传统的备份。

传统的备份

有多种数据备份选项,比如附近的 HDD、磁带专用存储系统Amazon S3Google Cloud Storage 等。

S3 和 GCS 是备份最有前途的存储选项。它们价格低廉、可靠且耐用。但它们有一些限制:

  • 对上传到对象存储的文件大小有限制:最大对象大小为 5TB一次上传的最大块大小为 5GB。如果你需要备份超过这些大小的文件怎么办?
  • 网络带宽有限,因此完整备份可能需要几天才能完成。例如,通过千兆网络传输10TB数据需要超过27小时。
  • 网络错误的概率不为零。如果在上传10TBs文件的末尾发生网络错误怎么办?再花27小时重新上传?
  • 从数据库所在的数据中心支付出口流量费用。备份大小和备份频率增加了网络带宽成本。

有没有办法克服这些限制?如果满足某些条件,答案是肯定的:

  • 数据必须拆分成多个文件,以便每个文件可以独立备份。
  • 文件必须是不可变的,即其内容不应随时间变化。这允许每个文件只上传一次到备份存储。
  • 新数据必须进入新文件,因此增量备份可以很便宜——只需备份新文件。
  • 文件总数不应太多。这减少了每个文件操作的开销和管理成本
  • 数据必须以压缩形式存储在磁盘上,以减少备份期间的网络带宽使用。

如果数据库根据这些条件存储所有数据,那么在 S3 或 GCS 上设置廉价且快速的增量备份就相当容易。通过在旧备份和新备份之间服务器端复制共享的不可变文件,也可以加快完整备份的速度。GCS 和 S3 都支持服务器端对象复制。当在同一个桶中复制任何大小的对象时,此操作通常很快,因为只复制元数据。

哪种数据结构符合上述原则并可用作 TSDB 的构建块?B-tree——大多数数据库的核心?LMDBPGDATA 或 Postgresql 的 TOAST

不。这些数据结构都会修改磁盘上的文件内容。

LSM Tree 和备份

LSM tree 符合上述所有条件:

  • 它将数据存储在多个文件中。
  • 文件是不可变的。
  • 新数据进入新文件。
  • 由于后台将较小的文件合并成较大的文件,总文件数保持较低。
  • 排序行通常具有良好的压缩比。

LSM 树可以用于构建键值存储,例如 LevelDBRocksDB。这些构建块可以用于创建任意复杂的数据库:

理论上,如果这些数据库将所有数据存储在类似 LSM 的数据结构中,它们都可以支持增量备份。但是,当新文件不断添加且旧文件不断从数据库中删除时,如何从实时数据中进行备份?由于 LSM 类数据结构中的文件不可变,通过硬链接进行即时快照然后从快照中备份数据是很容易的。

结论

  • 虽然复制在硬件问题期间提供了可用性,但它不能防止数据丢失。请使用备份。
  • 如果使用合适的数据库,大型备份可以快速且廉价。我推荐 VictoriaMetrics :)
  • VictoriaMetrics 备份可以用于备份从多个 Prometheus 实例收集的数据。