[翻译]Tumblr 如何存储帖子内容

原文:https://engineering.tumblr.com/post/644763186513444864/how-post-content-is-stored-on-tumblr

我们目前推出了一个可选测试版的使用 Neue 帖子格式的新帖子编辑器。已经有很长一段时间了 - Neue 帖子格式的工作始于 2015 年,最初的代号为“Poster Child”,它源于我们从以前发布的帖子编辑器上学到的很多东西。多年来,人们在互联网上不同平台上发帖的方式发生了巨大变化。但在 Tumblr 上,我们仍然希望忠于我们的博客根源,同时提供广阔的创意空间,而 Neue 帖子格式让它成为可能。

Tumblr 上有数十亿(数百亿!)的帖子,我们如何在不破坏一切的情况下将这种内容引擎从一种格式转移到另一种格式?它经历了许多阶段,在网络上发布新的编辑器将是最后完成的部分之一。要了解我们已经走了多远以及我们必须面对的挑战,您需要了解我们如何在 Tumblr 上存储帖子内容的秘密。这个我们都喜欢的地狱现场是由胶带、良好的意愿和运气组成的,我们一直在努力让它变得更好!

帖子看似是一个非常简单的数据模型:它有作者,有内容,并且是在某个时间发布的。每个帖子在创建后都有一个唯一标识符。在转发的情况下,他们还拥有转发它的“父”帖子和博客(更多关于转发如何工作在这里)。在标准规范化数据库表中,这些列如下所示:

  • 帖子标识符 (一个很大的整数)
  • 作者博客标识符 (一个指向“blogs”数据库表的整数)
  • 父帖子标识符 (如果是转发)
  • 父博客标识符 (如果是转发)
  • 发布时间 (某种时间戳)
  • 帖子内容 (more on this in a minute)

在 Neue 帖子格式之前,帖子有不同的“类型”,所以类型也是一个字段。但是一旦有了这些“类型”,就必须确定如何存储每个“类型”的内容。对于照片帖子,有一组一个或多个图像。对于视频帖子,要么是对上传视频文件的引用,要么是指向外部视频的 URL。对于文本帖子,它只是 HTML 格式的文本。因此,“发布内容”列的实际值可能会根据它的类型而改变。

这是一个简单的示例,请注意每种帖子类型如何具有不同类型的内容:

https://void.oss-cn-beijing.aliyuncs.com/img/202207280012873.png

随着 Tumblr 的发展,它的能力也在增长。我们添加了为照片、视频和音频帖子添加标题的功能。我们添加了添加“来源”来引用帖子的功能。我们需要在某个地方存储新的帖子内容。因为当时 Tumblr 发展得如此之快,所以这需要快速发生,所以我们采取了最简单的方法:添加一个新字段!第一个“帖子内容”栏被重命名为“one”,新的帖子内容栏被命名为“two”。随着 Tumblr 帖子越来越多,最终我们添加了“three”。并且每列的值可能会根据帖子类型而有所不同。

https://void.oss-cn-beijing.aliyuncs.com/img/202207280016467.png

不用说,最终这使得我们很难有一致且易于理解的模式诸如……计算帖子中有多少张图片?由于我们添加了在标题中添加图像的功能,因此“one”、“two”或“three”列中都可能有图像,但根据帖子类型,每个列的格式可能不同。 转发使存储设计进一步复杂化,因为转发将帖子内容从其父帖子复制并重新格式化到新帖子。渲染帖子的代码变得非常复杂且难以向其中添加更多功能。

更复杂的是,大多数(但不是全部)帖子内容字段都利用 HTML 或 PHP 的内置序列化逻辑作为文字数据格式。在 PHP 7 之前,PHP 中的 HTML 解析(Tumblr 在使用的)非常慢,因此随着帖子的转发路径增加或帖子内容复杂性的增加,渲染帖子变得更加困难。 HTML 和 PHP 的序列化逻辑不容易移植到其他语言,如 Go、Scala、Objective-C、Swift 或 Java,这些我们在其他后端服务和移动应用程序中使用这些语言。

考虑到这一切,在 2015 年,两个需求融合在一起:需要从数据库一直到应用程序共享更易于理解和可移植的数据格式,以及需要支持更多类型的帖子内容,与帖子类型解耦。 Neue 帖子格式诞生了:一种基于 JSON 的数据模式,用于内容块及其布局。这为我们提供了更快地提供新类型内容的灵活性,而不必担心我们将如何以 HTML 格式存储它,并且使帖子内容格式可以从数据库适应到 Android 应用程序、iOS 应用程序,以及新的基于 React 的 Web 客户端。

https://void.oss-cn-beijing.aliyuncs.com/img/202207280029885.png

回到帖子的标准规范化数据库表模式,我们现在已经通过“帖子内容”列中的灵活 JSON 结构实现了存储的简单性。存储帖子时,我们根本不再需要帖子类型。帖子可以包含任何和所有内容类型,而不是根据帖子类型单独使用无数令人困惑的选项。现在帖子可以同时是视频和照片帖子!当网络上的新编辑器完全发布时,我们终于可以说这种格式是推动 Tumblr 内容引擎的燃料。它将使我们能够更快地构建以前无法构建的块类型和布局,例如投票、博客卡片块和重叠的图像/视频/文本。完全没有限制。