假设我们需要创建一个系统,该系统使用大量、实时的文档数据流,并在这些文档可用时将这些文档与一组用户定义的搜索查询进行匹配。这是一项前瞻性的,而不是回顾性的搜索服务。什么是合适的持久性解决方案?
假设用户想要查看与其查询匹配的文档的实时提要(想想 Google 快讯),并且提要必须显示每个文档的某些元数据。让我们假设比赛的寿命是无限期的;即,系统将允许用户从创建特定查询时查看查询的所有匹配项。因此,流中出现的每个文档的元数据,以及文档与匹配该文档的用户查询之间的关联,都必须保存到数据库中。
让我们提出另一个要求,即用户希望能够对某些元数据进行分面:例如,用户希望仅查看特定查询的匹配文档,其元数据字段“结果类型”等于“博客”,并且想要一个博客匹配数的计数。
以下是一些假设的数字:
每天数据流中有 200,000 个新文档。
- 每个文档的元数据都被持久化。
1000 个用户,每个用户有大约 5 个搜索查询:大约 5000 个用户搜索查询。
- 这些查询是简单的布尔查询。
- 当每个新文档进来时,它会针对所有 5000 个查询进行处理,以查看哪些查询是匹配的。
每个提要(每个用户查询一个提要)每分钟向用户刷新一次。换句话说,对于每个提要,每分钟都会向数据库查询最新的匹配页面。
向用户显示提要的速度至关重要。可扩展性和高可用性也很重要。
用户和查询之间的关系是关系的,查询和匹配文档之间的关系也是如此,但文档元数据本身只是键值对。所以我最初的想法是将关系数据保存在像 MySQL 这样的关系数据库中,将元数据保存在 NoSQL DB 中,但是在 NoSQL DB 中可以实现分面要求吗?此外,构建提要需要调用两个单独的数据存储,这会增加复杂性。或者也许将所有内容都推入 MySQL,但这将需要大量的连接和计数。如果我们将所有数据作为键值对存储在其他类型的数据存储中,我们将如何进行分面?对于匹配多个搜索查询的文档,会有大量冗余元数据。
什么样的数据库适合这种情况?我知道诸如Twitter Storm和 Yahoo's S4之类的工具,它们可用于构建此类系统的整体架构,但鉴于数据存储、容量和查询/分面,我想专注于数据库要求。