0

我一直在从事一个涉及对 elasticsearch 进行大量更新的项目,我发现当以高频率更新应用于单个文档时,无法保证一致性。

对于每次更新,我们都是这样做的(scala 代码)。请注意,我们必须显式删除原始字段并将其替换为新字段,因为“合并”不是我们想要的(_update 实际上是弹性搜索中的合并)。

def replaceFields(alarmId: String, newFields: Map[String, Any]): Future[BulkResponse] = {
def removeField(fieldName: String): UpdateDefinition = {
  log.info("script: " + s"""ctx._source.remove("${fieldName}")""")
  update id alarmId in IndexType script s"""ctx._source.remove("${fieldName}")"""
}

client.execute {
  bulk(
    {newFields.toList.map(ele => removeField(ele._1)) :+
      {update id alarmId in IndexType doc (newFields)}} : _*
  )
}}
4

1 回答 1

0

这不可以。您可以将写入仲裁级别提高到所有(请参阅Undestanding the write_consistency and quorum rule of Elasticsearch了解有关此问题的一些讨论;另请参阅文档https://www.elastic.co/guide/en/elasticsearch/reference/2.4/docs -index_.html#index-consistency),这会让你更接近。但是 Elasticsearch 没有任何线性化保证(例如https://aphyr.com/posts/317-jepsen-elasticsearch的示例和https://aphyr.com/posts/313-strong-consistency-models的定义),它是不难编造出 ES 不一致的场景。

话虽如此,它在大多数时候往往是一致的。但是在高更新环境中,您将在 JVM 上施加很大的 GC 压力以清除旧文档。我假设你知道更新在 ES 中是如何工作的,但如果你不知道,也值得关注https://www.elastic.co/guide/en/elasticsearch/reference/current/_updating_documents.html

于 2016-11-11T21:22:46.460 回答