zoukankan      html  css  js  c++  java
  • elasticsearchBouncing Results问题

    bouncing results问题,两个document排序,field值相同;不同的shard上,可能排序不同;每次请求轮询打到不同的replica shard上;每次页面上看到的搜索结果的排序都不一样。这就是bouncing result,也就是跳跃的结果。

    比如当你使用一个timestamp
    字段对结果进行排序,有两份文档拥有相同的timestamp。因为搜索请求是以一种循环(Round-robin)的方式被可用的分片拷贝进行处理的,因此这两份文档的返回顺序可能因为处理的分片不一样而不同,比如主分片处理的顺序和副本分片处理的顺序就可能不一样。
    这就是结果跳跃问题:每次用户刷新页面都会发现结果的顺序不一样。
    这个问题可以通过总是为相同用户指定同样的分片来避免:将preference
    参数设置为一个任意的字符串,比如用户的会话ID(Session ID)。让每个user每次搜索的时候,都使用同一个replica shard去执行,就不会看到bouncing results了

    对于preference

    偏好这个参数 preference 允许 用来控制由哪些分片或节点来处理搜索请求。 它接受像 _primary, _primary_first, _local, _only_node:xyz, _prefer_node:xyz, 和 _shards:2,3 这样的值, 这些值在 search preference 文档页面被详细解释。

    但是最有用的值是某些随机字符串,它可以避免 bouncing results 问题。

    例如,使用用户的会话ID xyzabc123,如下所示:

    GET /test_index/_search?preference=xyzabc123
    {
      "query": {
        "match": {
          "test_field": "hello"
        }
      }
    }
    
    {
      "took" : 1,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 2,
          "relation" : "eq"
        },
        "max_score" : 0.20521778,
        "hits" : [
          {
            "_index" : "test_index",
            "_type" : "_doc",
            "_id" : "2",
            "_score" : 0.20521778,
            "_source" : {
              "test_field" : "hello, how are you"
            }
          },
          {
            "_index" : "test_index",
            "_type" : "_doc",
            "_id" : "1",
            "_score" : 0.16402164,
            "_source" : {
              "test_field" : "hello you, and world is very good"
            }
          }
        ]
      }
    }

    https://www.jianshu.com/p/c25abefd7d2b

    以前使用elasticsearch,排序上设定了以时间+score的排序方式:

    sort_setting = [
        {"pub_date": {"order": "desc"}},
        {'_score': {"order": "desc"}},
    ]
    

    搜索结果也一直没有问题。但是最近一个项目,通过爬虫爬取后的数据不停的入ES。同样的搜索条件返回的不同的结果。

    下面就是分析思路:

    1.排除es集群的问题,因为之前遇到过es设置不对,导致同一查询在不同节点返回的结果不一致的情况。把es的hosts设置为单一主机,结果仍然是会变化。
    2.限定查询的时间范围,如果日期的上线为今天,那么不停入库的数据肯定会导致结果的变化,限定为过去的时间段后,毫无改善。
    3.去掉pub_date排序字段,限定为按关联度排序,毫无改善。
    4.最后居然开始怀疑merge的问题,使用forcemerge,结果表示没啥用。
    

    这个时候我才意识到了文档里提过的Bouncing Results问题。因为时间格式为%Y-%m-%d,那么同样时间的数据会有很多。es如果不做任何设置,将会按round-robined的方式从primary和replica里取了再排序,这样结果就不能保证每次都一样的。毕竟primary有的relica里不一定有,尤其是在不停往es里丢数据的情况。

    最后解决方法也很简单,直接设置preference为primary即可



    search_result = es.search(index=index_name,
                              body=search_body, preference="primary")

    最大的担心就是这样会有性能问题,不过没时间来测。

  • 相关阅读:
    java中的成员变量、静态变量与局部变量
    java中static关键字的作用
    java中super关键字的作用
    java中this关键字的作用
    Java创建对象的4种方式
    IO体系、集合体系、多线程、jdbc
    二分搜索树
    二叉树搜索(二分查找法)
    索引堆
    原地堆排序
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/13022117.html
Copyright © 2011-2022 走看看