我计划将Elasticsearch用于社交网络平台,用户可以在其中发布"更新",与其他用户成为朋友并关注他们的朋友'饲料。基本的,可能是最常见的查询将是"由我关注的朋友与我共享的帖子" 。此查询可以通过其他约束(如标记或geosearch)进行扩充。
我了解到社交网络通常会采用粉丝写出方式来传播更新"跟随者,以便查询更加本地化。所以我可以看到两种潜在的索引策略:
从搜索的角度来看,第二个选项显然更有效率,尽管它会带来同步挑战(例如,当我停止关注朋友时需要删除帖子)。但我最关心的是指数的倍增;在(成功的)社交网络中,我们至少可以期待成千上万的用户......
所以我的问题是:
由于
答案 0 :(得分:2)
每个elasticsearch 索引分片是一个单独的 Lucene索引,这意味着几个打开的文件描述符和内存开销。通常,即使在从默认值5减少每个索引的分片数量之后,每用户索引情况下的资源消耗也可能太大。
很难给出任何具体的数字,但我的猜测是,如果你坚持每个索引两个分片,你将能够处理每m3.medium机器不超过3000个用户,这在我看来是令人望而却步的。
但是,您不一定需要为每个用户提供专用索引。您可以使用筛选的别名为多个用户使用一个索引。从应用程序的角度来看,它看起来像是一个每用户场景,而不会产生上面提到的开销。有关详细信息,请参阅此video。
话虽如此,我不认为elasticsearch特别适合粉丝写出策略。然而,这是一个非常好的解决方案,适用于扇出读取场景(类似于你所概述的(1)):
使用elasticsearch的最大优势在于您可以执行相关性评分,通常基于某些时间特征,例如浏览上下文。使用elasticsearch来检索按时间戳排序的文档意味着您没有利用其潜力。同时,像Redis这样的解决方案将为您提供远远优越的读取性能。
Fan-out-on-write场景意味着每次更新都会进行大量写入操作(特别是,如果您拥有许多关注者的用户)。 Elasticsearch不是数据库,也没有针对此类使用模式进行优化。但是,它是为频繁阅读做好准备的。
Fan-out-on-write还意味着您通过复制有关帖子的信息来生成大量“额外”数据。要将此数据保存在RAM中,您只需要在单独的文档存储和标记中存储元数据,例如文档的ID。同样,除了JSON之外,还有其他格式可以有效地存储和搜索这种结构化数据。
在两种情景之间进行选择是一个关于您的要求的问题,例如关注者的平均数量,几乎每个人都遵循的“枢纽”数量,饲料是否自然有序(例如按时间)等等。我认为决定是否要使用elasticsearch需要成为这种分析的结果。