设计 Twitter 搜索 - 如何对大型数据集进行排序?
Designing Twitter Search - How to sort large datasets?
我正在阅读一篇关于如何设计 Twitter 搜索的文章。基本思想是根据推文的 ID 将推文映射到每个服务器都有映射的服务器
English word -> A set of tweetIds having this word
现在,如果我们想找到所有包含某个词的推文,我们只需要查询所有服务器并聚合结果。文章随意建议我们也可以按“流行度”等参数对结果进行排序,但这不是一项繁重的任务,尤其是如果这个词是热门词吗?
这种搜索系统在实践中做了什么?
也许正在使用一些权衡?
谢谢!
首先,有两种类型的索引:本地索引和全局索引。
本地索引与推文数据存储在同一台计算机上。例如,您可能有 10 个分片,每个分片都有自己的索引;像单词“汽车”-> 推文 ID 的排序列表。
当搜索为 运行 时,我们必须将查询发送到每个服务器。因为我们不知道最受欢迎的推文在哪里。该查询将要求每个服务器 return 他们的最高结果。所有这些结果都将收集在同一个盒子上 - 执行用户请求的那个盒子 - 并且该过程将从整个人口中选出前 10 个。
由于所有结果都已在索引本身中排序,因此从所有列表中挑选前 10 个结果是一个 O(1) 操作 - 因为我们将对设定数量的推文进行简单的 heap/watermarking。
第二个很好 属性,我们可以进行分页 - 下一个查询也将发送到每个带有附加数据的框 - 给我前 10 名,流行度低于 X,其中 X 是上一条推文的流行度return已发送给客户。
全局索引是一个不同的野兽 - 它不与数据存在于同一个盒子上(它可以,但不必)。在那种情况下,当我们搜索关键字时,我们确切地知道要查找的位置。并且索引本身也是排序的,因此可以快速获得前 10 个最受欢迎的结果(或获得分页)。
由于全局索引 returns 仅推文 ID 而不是推文本身,我们将不得不为每个 ID 查找推文 - 这称为 N+1 问题 - 1 次查询以获取 ID 列表和然后对每个 id 进行一次查询。有几种方法可以解决这个问题 - 缓存和数据复制是迄今为止最常见的方法。
我正在阅读一篇关于如何设计 Twitter 搜索的文章。基本思想是根据推文的 ID 将推文映射到每个服务器都有映射的服务器
English word -> A set of tweetIds having this word
现在,如果我们想找到所有包含某个词的推文,我们只需要查询所有服务器并聚合结果。文章随意建议我们也可以按“流行度”等参数对结果进行排序,但这不是一项繁重的任务,尤其是如果这个词是热门词吗?
这种搜索系统在实践中做了什么?
也许正在使用一些权衡?
谢谢!
首先,有两种类型的索引:本地索引和全局索引。
本地索引与推文数据存储在同一台计算机上。例如,您可能有 10 个分片,每个分片都有自己的索引;像单词“汽车”-> 推文 ID 的排序列表。
当搜索为 运行 时,我们必须将查询发送到每个服务器。因为我们不知道最受欢迎的推文在哪里。该查询将要求每个服务器 return 他们的最高结果。所有这些结果都将收集在同一个盒子上 - 执行用户请求的那个盒子 - 并且该过程将从整个人口中选出前 10 个。
由于所有结果都已在索引本身中排序,因此从所有列表中挑选前 10 个结果是一个 O(1) 操作 - 因为我们将对设定数量的推文进行简单的 heap/watermarking。
第二个很好 属性,我们可以进行分页 - 下一个查询也将发送到每个带有附加数据的框 - 给我前 10 名,流行度低于 X,其中 X 是上一条推文的流行度return已发送给客户。
全局索引是一个不同的野兽 - 它不与数据存在于同一个盒子上(它可以,但不必)。在那种情况下,当我们搜索关键字时,我们确切地知道要查找的位置。并且索引本身也是排序的,因此可以快速获得前 10 个最受欢迎的结果(或获得分页)。
由于全局索引 returns 仅推文 ID 而不是推文本身,我们将不得不为每个 ID 查找推文 - 这称为 N+1 问题 - 1 次查询以获取 ID 列表和然后对每个 id 进行一次查询。有几种方法可以解决这个问题 - 缓存和数据复制是迄今为止最常见的方法。