Elasticsearch:使用经常更新的文档

11 elasticsearch

我有论坛.每个主题都有像viewCount这样的字段 - 论坛用户查看了多少次主题.

我希望所有主题领域都来自ES(id,date,title,content和viewCount).但是,在每个主题视图ES之后的这种情况必须再次重新索引整个文档 - 我问了关于堆栈的部分更新的问题 - 未编制索引的字段的部分更新.重要的是要注意 - viewCount字段没有索引,它只是存储在ES中.

问题是有两个术语 - 部分更新和部分索引.ES中有部分更新 - 您只能更改几个字段.Bu没有部分重新索引 - 这意味着如果你甚至只更改一个字段,ES将重新索引整个文档.这意味着如果主题被查看1000次,ES将索引1000次.如果我有很多用户,许多文档将被反复索引.这是第一个战略.

我认为第二种策略是从索引中获取一些主题,从数据库中获取一些主题.在这种情况下,我从DB获取viewAcount.但是,我可以将所有字段存储在数据库中,并仅使用索引作为INDEX - 来获取当前主题的ID.

解决此类问题的最佳方法是什么?

Gro*_*ify 10

关于文档的部分更新,重要的是要认识到,虽然API允许您在幕后执行部分更新,但它会通过检索文档,更改文档并重新编制索引来执行完整更新.以下内容来自Elasticsearch网站:

文档的部分更新

在更新整个文档中,我们说更新文档的方法是检索它,更改它,然后重新索引整个文档.这是真的.但是,使用更新API,我们可以进行部分更新,例如在单个请求中递增计数器.

我们还说文件是不可变的:它们不能改变,只能被替换.更新API必须遵守相同的规则.在外部,似乎我们正在部分更新文档.但是,在内部,更新API只管理我们已经描述的相同的retrieve-change-reindex进程.不同之处在于此过程在分片中发生,从而避免了多个请求的网络开销.通过缩短检索和重新索引步骤之间的时间,我们还可以降低与其他进程发生冲突的可能性.

要将全文数据存储在Elasticsearch中并且具有经常更改的字段而不重新索引整个文档,您需要将这些项存储在其他位置.这可以是另一个Elasticsearch索引或另一个系统中的元数据/计数器存储.

对于常见用例,您可以对两者运行相同的查询并合并结果.这些很可能是简单的过滤器和对不变的字段进行排序,例如主题,创作时间,作者等.

对于不匹配的搜索(例如全文查询),您可以(a)不显示该数据,或者(b)使用最终一致的方法,其中您定期使用更新的计数更新Elasticsearch主题存储.许多不具有高一致性要求的系统可以使用最终一致性方法,包括Stack Overflow,Netflix等.例如,在某些站点上,您将在一个页面/窗口小部件上获得一个计数,而在另一个页面上获得另一个计数/小部件由于最终的一致设计.


Sla*_*lam 6

对我来说,似乎在使用ES的情况下,您应该只更新索引中的所有数据并查询它.如果您要分割文本(据我所知,您将ES中的主题存储在文本搜索中)和数据存储之间的"数字"数据,您将体验到比在ES中重新索引文档的情况更大的性能.

ES可以对索引中的文档做唯一的事情 - 索引和删除.因此,有两种方法可以加速重建索引

  • 加速"有效负载" - 减少删除文档和再次索引所需的时间.这可以实现将ES索引移动到内存中,以利用LuceneRamIndexStore

  • 减少网络开销 - 使用脚本在ES端执行操作

顺便问一下,您是否已经遇到性能问题?