首页 ES查询时索引延迟或更新导致数据不一致
文章
取消

ES查询时索引延迟或更新导致数据不一致

ES查询时索引延迟或更新导致数据不一致

当数据更新比较频繁时,我们短时间内使用相同的查询条件,得到的结果和记录数却不同。实际的业务要求查询的结果一致,以下是一些解决办法。

问题可能是由于Elasticsearch的索引延迟或更新造成的。可以考虑以下步骤来解决:

  1. 检查索引刷新率:确保索引的刷新率设置合理。默认情况下,Elasticsearch每秒刷新一次,但根据需要可能需要调整。
  2. 使用search_type=dfs_query_then_fetch:这确保查询使用全局词频,有助于提高结果的一致性。
  3. 使用时间点(PIT):为了在查询之间保持结果的一致性,可以使用PIT来保持索引的快照。
  4. 检查索引健康:确保没有正在进行的索引操作或问题影响查询结果。 本文说下2和3方案

    使用 search_type=dfs_query_then_fetch

    解释: search_type=dfs_query_then_fetch 是 Elasticsearch 的一种搜索模式,用于提高查询的准确性。在默认的 query_then_fetch 模式中,查询是按分片进行的,每个分片独立计算文档频率,然后将结果合并。但这可能会导致在频繁更新的情况下结果的不一致。 dfs_query_then_fetch 模式首先在所有分片上计算全局词频(Document Frequency),然后执行查询和排序。这使得查询和排序基于全局的词频信息,从而提供更一致的查询结果。

使用方法: 在查询请求中,你可以添加search_type=dfs_query_then_fetch参数。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
GET /your_index/_search?search_type=dfs_query_then_fetch
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "time": {
              "from": "2024-08-14 08:00:00",
              "to": "2024-08-15 08:00:00"
            }
          }
        },
        {
          "term": {
            "fileds1": "xxx"
          }
        },
        {
          "term": {
            "fileds2": "xx"
          }
        }
      ]
    }
  },
  "size": 0,
  "aggs": {
    "xsd_count": {
      "terms": {
        "field": "fileds1",  //根据fileds1去重查询top5
        "size": 5
      }
    },
    "xsd_total": {
      "cardinality": {
        "field": "fileds1" //根据fileds1去重查询总数
      }
    }
  }
}

使用时间点(PIT)

解释: 时间点(Point in Time, PIT)是一种在 Elasticsearch 中获取一致查询结果的机制。使用 PIT 可以在一个固定的索引快照上执行多个查询,确保查询结果在整个 PIT 生命周期内的一致性。 PIT 的主要优点是它允许在一个固定的时间点快照上进行多次查询,这样即使索引在查询期间发生了变化,查询结果依然会保持一致。(数据快照)

使用方法:

  1. 创建 PIT 首先,你需要创建一个 PIT。发送一个 POST 请求到 _pit 接口以创建 PIT,例如: POST /_pit?keep_alive=1m 这将返回一个 PIT ID,你可以在后续查询中使用它。

  2. 使用 PIT 执行查询: 在查询请求中,添加 pit 参数和 PIT ID,例如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    GET /_search
    {
      "pit":{"id":"your_pit_id","keep_alive":"1m"},
      "query":{
     "bool":{
         "must":[{
             "range":{"time":{"from":"2024-08-14 08:00:00","to":"2024-08-15 08:00:59"}}
                 }]
             }
      }
    }
    
  3. 关闭 PIT: 查询完成后,你可以关闭 PIT 以释放资源,例如: DELETE /_pit?id=your_pit_id

在PIT id错误会返回错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
    "error": {
        "root_cause": [
            {
                "type": "illegal_argument_exception",
                "reason": "java.io.EOFException"
            }
        ],
        "type": "illegal_argument_exception",
        "reason": "java.io.EOFException",
        "caused_by": {
            "type": "e_o_f_exception",
            "reason": null
        }
    },
    "status": 400
}

PIT id超过时间过期后返回错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
    "error": {
    "root_cause": [
        {
                "type": "search_context_missing_exception",
                "reason": "No search context found for id [4635252]"
        }],
    "phase": "query",
    "grouped": true,
    "failed_shards": [
        {
            "shard": 0,
            "index": "index-2022",
            "node": "4sIEuxxxxxxxxxx",
            "reason": {
                "type": "search_context_missing_exception",
                "reason": "No search context found for id [12345678]"
            }
        }],
    "status": 404
    }
}
本文由作者按照 CC BY 4.0 进行授权

深入浅出 Netty

-

载入天数...载入时分秒...