Well,不要刷屏了

Elasticsearch:如何在 Elasticsearch 中正确使用同义词功能

原文地址 elasticstack.blog.csdn.net

同义词用于提高搜索质量并扩大匹配范围。 例如,搜索 England 的用户可能希望找到包含 British 或 UK 的文档,尽管这三个词完全不同。

Elasticsearch 中的同义词功能非常强大,如果实施得当,可以使你的搜索引擎更加健壮和强大。 在本文中,我们将通过简单的代码片段介绍在实践中实现同义词功能的要点。 特别是,我们将介绍如何更新现有索引的同义词,这是一个相对高级的话题。

在今天的展示中,我将使用最新的 Elastic Stack 8.6.0,尽管版本不对我们的展示有任何的影响。

准备

我们将使用 Docker 在本地启动一个 Elasticsearch 服务器,并使用 Kibana 来管理索引和运行命令。 如果你以前从未使用过 Elasticsearch 或想快速复习一下,这篇文章可能会对你有所帮助。 如果你在 Docker 中运行 Elasticsearch 时遇到问题,这篇文章很可能会帮助你解决问题。在今天的文章中,我们尝试使用 docker 来部署一个没有安全功能的 Elasticsearch 集群。

准备就绪后,让我们开始探索 Elasticsearch 中的同义词功能的旅程。

我们将在本文中使用的 docker-compose.yaml 文件包含以下内容,稍后我们将向其添加更多功能:

docker-compose.yml

`

1.  version: "3.9"
2.  services:
3.    elasticsearch:
4.      image: elasticsearch:8.6.0
5.      environment:
6.        - discovery.type=single-node
7.        - ES_JAVA_OPTS=-Xms1g -Xmx1g
8.        - xpack.security.enabled=false
9.      volumes:
10.        - type: volume
11.          source: es_data
12.          target: /usr/share/elasticsearch/data
13.      ports:
14.        - target: 9200
15.          published: 9200
16.      networks:
17.        - elastic

19.    kibana:
20.      image: kibana:8.6.0
21.      ports:
22.        - target: 5601
23.          published: 5601
24.      depends_on:
25.        - elasticsearch
26.      networks:
27.        - elastic      

29.  volumes:
30.    es_data:
31.      driver: local

33.  networks:
34.    elastic:
35.      name: elastic
36.      driver: bridge

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

你可以使用以下命令之一启动 Elasticsearch 和 Kibana:

docker-compose up

或者

docker-compose up -d

如果加上 -d 选项的话,Elasticsearch 会以 daemon 的形式来运行。上面是一种最为简单的方式来启动 Elasticsearch 集群及 Kibana。由于它没有设置安全,我们无需输入任何凭证就可以直接进入到 Kibana 了。

使用带有同义词列表的标准同义词 token 过滤器

让我们首先使用带有同义词列表的标准同义词标记过滤器创建一个索引。 在 Kibana 中运行以下命令,我们将在稍后解释详细信息: 

`

1.  PUT synonyms
2.  {
3.    "settings": {
4.      "index": {
5.        "analysis": {
6.          "analyzer": {
7.            "index_analyzer": {
8.              "tokenizer": "standard",
9.              "filter": [
10.                "lowercase",
11.                "synonym_filter"
12.              ]
13.            }
14.          },
15.          "filter": {
16.            "synonym_filter": {
17.              "type": "synonym",
18.              "synonyms": [
19.                "elk => Elastic Stack",
20.                "elkb => Elastic Stack"
21.              ]
22.            }
23.          }
24.        }
25.      }
26.    },
27.    "mappings": {
28.      "properties": {
29.        "name": {
30.          "type": "text",
31.          "analyzer": "index_analyzer"
32.        }
33.      }
34.    }
35.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

这里的要点

  1. 请注意设置键的嵌套级别。 settings => index => analysis => analyzer/filter 都是内置关键字。 但是,index_analyzer 和 synonym_filter 分别是自定义分析器和过滤器的自定义名称。
  2. 我们需要创建一个 type 为 synonym 的自定义过滤器。 synonym 选项明确提供了同义词列表。 这通常应该只用于测试,因为更新同义词列表不方便,我们稍后会看到。
  3. 本文中使用了 Solr 同义词。 对于此示例,使用了显式映射,这意味着 => 左侧的标记将替换为右侧的标记。 稍后我们将使用等同的同义词,这意味着提供的 token 被等同对待。
  4. synonym_filter 添加到名为 index_analyzer 的新自定义分析器的过滤器列表中。 通常过滤器的顺序很重要。 然而,对于同义词过滤器来说,它有点特殊,可能会让我们中的许多人感到惊讶。 在此示例中,即使 synonym_filter 过滤器放在小写过滤器之后,此过滤器返回的标记也会传递给小写过滤器,因此也会变成小写。 因此,你不需要在同义词列表或同义词文件中提供小写 token。
  5. 最后,在文档的映射中,为名称字段指定了自定义分析器。

我们知道在早期的 Elastic 产品中 elk 就是 Elastic Stack 的代名词。之后随着 Beats 的加入,很多开发者也把 elkb 当做 Elastic Stack 的代名词。要测试在索引中创建的分析器,我们可以调用 _analyze 端点:


1.  GET /synonyms/_analyze
2.  {
3.    "analyzer": "index_analyzer",
4.    "text": "elk is powerful"
5.  }

上面命令的输出为:

`

1.  {
2.    "tokens": [
3.      {
4.        "token": "elastic",
5.        "start_offset": 0,
6.        "end_offset": 3,
7.        "type": "SYNONYM",
8.        "position": 0
9.      },
10.      {
11.        "token": "is",
12.        "start_offset": 4,
13.        "end_offset": 6,
14.        "type": "<ALPHANUM>",
15.        "position": 1
16.      },
17.      {
18.        "token": "stack",
19.        "start_offset": 4,
20.        "end_offset": 6,
21.        "type": "SYNONYM",
22.        "position": 1
23.      },
24.      {
25.        "token": "powerful",
26.        "start_offset": 7,
27.        "end_offset": 15,
28.        "type": "<ALPHANUM>",
29.        "position": 2
30.      }
31.    ]
32.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

从上面的输出中,我们可以看到 type 为 SNONYM 的 token 为 elastic 及 stack。让我们向索引中添加一些文档并测试它在搜索中是否正常工作:


1.  PUT /synonyms/_doc/1
2.  {
3.    "name": "elk is very powerful"
4.  }

6.  PUT /synonyms/_doc/2
7.  {
8.    "name": "elkb is useful"
9.  }

11.  PUT /synonyms/_doc/3
12.  {
13.    "name": "Elastic Stack is so widely used"
14.  }

我们可以使用 match 关键字进行简单的搜索:


1.  GET /synonyms/_search?filter_path=**.hits
2.  {
3.    "query": {
4.      "match": {
5.        "name": "elk"
6.      }
7.    }
8.  }

如果没有问题,所有三个文件都应该被搜索到:

`

1.  {
2.    "hits": {
3.      "hits": [
4.        {
5.          "_index": "synonyms",
6.          "_id": "2",
7.          "_score": 0.31931418,
8.          "_source": {
9.            "name": "elkb is useful"
10.          }
11.        },
12.        {
13.          "_index": "synonyms",
14.          "_id": "1",
15.          "_score": 0.29086044,
16.          "_source": {
17.            "name": "elk is very powerful"
18.          }
19.        },
20.        {
21.          "_index": "synonyms",
22.          "_id": "3",
23.          "_score": 0.24686477,
24.          "_source": {
25.            "name": "Elastic Stack is so widely used"
26.          }
27.        }
28.      ]
29.    }
30.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

索引时间 vs 搜索时间进行同义词操作

如你所见,在上面的示例中,只创建了一个分析器,它用于索引和搜索。

不鼓励在索引(indexing)步骤中对所有文档应用同义词,因为它有一些主要缺点:

  • 如果不重新索引所有内容,就无法更新同义词列表,这在实践中是非常低效的。
  • 搜索分数会受到影响,因为同义词 token 也会被计算在内。
  • 索引过程变得更加耗时并且索引将变得更大。 对于小数据集来说可以忽略不计,但对于大数据集来说非常重要。

因此,最好在搜索步骤中只应用同义词,这样可以克服所有三个缺点。 为此,我们需要创建一个用于搜索的新分析器。

使用 search_analyzer 并应用搜索时间同义词

在 Kibana 中运行以下命令以创建具有搜索时同义词的新索引:

`

1.  PUT synonym_graph
2.  {
3.    "settings": {
4.      "index": {
5.        "analysis": {
6.          "analyzer": {
7.            "index_analyzer": {
8.              "tokenizer": "standard",
9.              "filter": [
10.                "lowercase"
11.              ]
12.            },
13.            "search_analyzer": {
14.              "tokenizer": "standard",
15.              "filter": [
16.                "lowercase",
17.                "synonym_filter"
18.              ]
19.            }
20.          },
21.          "filter": {
22.            "synonym_filter": {
23.              "type": "synonym_graph",
24.              "synonyms": [
25.                "elk => Elastic Stack",
26.                "elkb => Elastic Stack"
27.              ]
28.            }
29.          }
30.        }
31.      }
32.    },
33.    "mappings": {
34.      "properties": {
35.        "name": {
36.          "type": "text",
37.          "analyzer": "index_analyzer",
38.          "search_analyzer": "search_analyzer"
39.        }
40.      }
41.    }
42.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

关键点

  • 该类型现在更改为 synonym_graph,这是一个更复杂的同义词过滤器,旨在仅用作搜索分析器的一部分。 它可以更恰当地处理多词同义词,推荐用于搜索时分析。 但是,你可以继续使用原来的 synonym 类型,它在这篇文章中的表现是一样的。
  • 同义词过滤器从索引时间分析器中删除并添加到搜索时间分析器中。
  • search_analyzer 是为 name 字段明确指定的。 如果未指定,则相同的分析器 (index_analyzer) 将用于索引和搜索。

分析器应该返回与以前相同的 token。 然而,当你用这些命令为三个文档建立索引并再次执行相同的搜索后,结果会有所不同:


1.  PUT /synonym_graph/_doc/1
2.  {
3.    "name": "elk is very powerful"
4.  }

6.  PUT /synonym_graph/_doc/2
7.  {
8.    "name": "elkb is useful"
9.  }

11.  PUT /synonym_graph/_doc/3
12.  {
13.    "name": "Elastic Stack is so widely used"
14.  }

我们使用如下的命令来进行搜索:


1.  GET /synonym_graph/_search?filter_path=**.hits
2.  {
3.    "query": {
4.      "match": {
5.        "name": "elk"
6.      }
7.    }
8.  }

这一次,只有如下的结果返回。甚至 “elk is very powerful” 这个文档也没有被返回:


1.  {
2.    "hits": {
3.      "hits": [
4.        {
5.          "_index": "synonym_graph",
6.          "_id": "3",
7.          "_score": 2.3589978,
8.          "_source": {
9.            "name": "Elastic Stack is so widely used"
10.          }
11.        }
12.      ]
13.    }
14.  }

原因是同义词过滤器仅在搜索时应用。 搜索查询 elk 被替换为同义词标记 “Elastic Stack”。 然而,索引中的文档没有被同义词过滤器(synonym_filter)过滤,因此 “elk” 只是被标记为 elk 而没有被 Elastic Stack 替换。 类似于 elkb。 结果,只能匹配 “Elastic Stack is so widely used”。

为了使其像前面的示例一样正常工作,我们需要将同义词规则从显式映射更改为等效同义词。 让我们按如下方式更新同义词过滤器:


1.  ......
2.    "filter": {
3.      "synonym_filter": {
4.        "type": "synonym_graph",
5.          "synonyms": [
6.             "elk, elkb, Elastic Stack"
7.          ]
8.      }
9.    }
10.  ......

要更改现有索引的同义词,我们可以重新创建索引并重新索引所有文档,这是愚蠢且低效的。

更好的方法是更新索引的设置。 但是,我们需要在更新设置之前关闭索引,然后重新打开它才能访问它:


1.  POST /synonym_graph/_close

4.  PUT /synonym_graph/_settings
5.  {
6.    "settings": {
7.      "index.analysis.filter.synonym_filter.synonyms": [
8.        "elk, elkb, Elastic Stack"
9.      ]
10.    }
11.  }

13.  POST /synonym_graph/_open

请注意更新索引设置的特殊语法。

运行上述命令后,我们可以通过如下命令的返回值来进行验证:

GET synonym_graph

上面的命令返回:

`

1.  {
2.    "synonym_graph": {
3.      "aliases": {},
4.      "mappings": {
5.        "properties": {
6.          "name": {
7.            "type": "text",
8.            "analyzer": "index_analyzer",
9.            "search_analyzer": "search_analyzer"
10.          }
11.        }
12.      },
13.      "settings": {
14.        "index": {
15.          "routing": {
16.            "allocation": {
17.              "include": {
18.                "_tier_preference": "data_content"
19.              }
20.            }
21.          },
22.          "number_of_shards": "1",
23.          "provided_name": "synonym_graph",
24.          "creation_date": "1673501061514",
25.          "analysis": {
26.            "filter": {
27.              "synonym_filter": {
28.                "type": "synonym_graph",
29.                "synonyms": [
30.                  "elk, elkb, Elastic Stack"
31.                ]
32.              }
33.            },
34.            "analyzer": {
35.              "index_analyzer": {
36.                "filter": [
37.                  "lowercase"
38.                ],
39.                "tokenizer": "standard"
40.              },
41.              "search_analyzer": {
42.                "filter": [
43.                  "lowercase",
44.                  "synonym_filter"
45.                ],
46.                "tokenizer": "standard"
47.              }
48.            }
49.          },
50.          "number_of_replicas": "1",
51.          "uuid": "UCIWtpQMTsCc1TwnvsywHA",
52.          "version": {
53.            "created": "8060099"
54.          }
55.        }
56.      }
57.    }
58.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

让我们使用 _analyzer 端点测试 search_analyzer 并查看生成的 token:


1.  GET /synonym_graph/_analyze
2.  {
3.    "analyzer": "search_analyzer",
4.    "text": "elk"
5.  }

上述命令返回:

它表明 elk 搜索查询被三个同义词的 token 替换和扩展(由 expand 选项控制)。 它还证明,如果在索引时应用等效同义词,则结果索引的大小可以显着增加。

然后当我们再次执行相同的搜索时:


1.  GET /synonym_graph/_search?filter_path=**.hits
2.  {
3.    "query": {
4.      "match": {
5.        "name": "elk"
6.      }
7.    }
8.  }

这次搜索的结果是:

`

1.  {
2.    "hits": {
3.      "hits": [
4.        {
5.          "_index": "synonym_graph",
6.          "_id": "3",
7.          "_score": 1.6949677,
8.          "_source": {
9.            "name": "Elastic Stack is so widely used"
10.          }
11.        },
12.        {
13.          "_index": "synonym_graph",
14.          "_id": "2",
15.          "_score": 1.1220688,
16.          "_source": {
17.            "name": "elkb is useful"
18.          }
19.        },
20.        {
21.          "_index": "synonym_graph",
22.          "_id": "1",
23.          "_score": 1.0126972,
24.          "_source": {
25.            "name": "elk is very powerful"
26.          }
27.        }
28.      ]
29.    }
30.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

我们可以看到三个文档都被搜索出来了。

使用同义词文件

上面我们一直在创建索引时直接指定同义词列表。 但是,当你有大量同义词时,将它们全部添加到索引中会很麻烦。 更好的方法是将它们存储在一个文件中,然后动态地将它们加载到索引中。 使用同义词文件有很多好处,其中包括:

  • 方便维护大量的同义词。
  • 可以被不同的索引使用。
  • 可以在不关闭索引的情况下动态重新加载。

首先,我们需要先将同义词放入一个文件中。 每行都是一个同义词规则,与上面演示的相同。 更多细节可以在官方文档中找到。

我们将创建的同义词文件称为 synonyms.txt,但可以任意命名。 它具有以下内容:


1.  $ pwd
2.  /Users/liuxg/data/docker8
3.  $ ls
4.  docker-compose.yml synonyms.txt
5.  $ cat synonyms.txt 
6.  # This is a comment! The file is named synonyms.txt.
7.  elk,elkb,Elastic Stack

然后我们需要将同义词文件绑定到 Docker 容器中。 更新 docker-compose.yaml 如下:

docker-compose.yml

`

1.  version: "3.9"
2.  services:
3.    elasticsearch:
4.      image: elasticsearch:8.6.0
5.      environment:
6.        - discovery.type=single-node
7.        - ES_JAVA_OPTS=-Xms1g -Xmx1g
8.        - xpack.security.enabled=false
9.      volumes:
10.        - type: volume
11.          source: es_data
12.          target: /usr/share/elasticsearch/data
13.        - type: bind
14.          source: ./synonyms.txt
15.          target: /usr/share/elasticsearch/config/synonyms.txt      
16.      ports:
17.        - target: 9200
18.          published: 9200
19.      networks:
20.        - elastic

22.    kibana:
23.      image: kibana:8.6.0
24.      ports:
25.        - target: 5601
26.          published: 5601
27.      depends_on:
28.        - elasticsearch
29.      networks:
30.        - elastic      

32.  volumes:
33.    es_data:
34.      driver: local

36.  networks:
37.    elastic:
38.      name: elastic
39.      driver: bridge

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

我们可以使用 CTRL+C 来终止之前运行的 docker,然后再次使用如下命令来启动:

docker-compose up

请注意,同义词文件已加载到容器中的 config 文件夹中。你可以进入容器并使用以下两个命令之一检查它:


1.  # User docker
2.  docker exec -it elasticsearch-1  bash

4.  # User docker-compose
5.  docker-compose exec elasticsearch bash

现在我们需要停止并重新启动服务以使更改生效。 请注意,仅重新启动服务将不起作用。


1.  docker-compose stop elasticsearch
2.  docker-compose up -d elasticsearch

1.  $ docker ps
2.  CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                              NAMES
3.  3ae4b728dd44   kibana:8.6.0          "/bin/tini -- /usr/l…"   23 seconds ago   Up 21 seconds   0.0.0.0:5601->5601/tcp             docker8-kibana-1
4.  878c82384761   elasticsearch:8.6.0   "/bin/tini -- /usr/l…"   23 seconds ago   Up 22 seconds   0.0.0.0:9200->9200/tcp, 9300/tcp   docker8-elasticsearch-1
5.  $ docker exec -it docker8-elasticsearch-1 bash
6.  elasticsearch@878c82384761:~$ pwd
7.  /usr/share/elasticsearch
8.  elasticsearch@878c82384761:~$ ls
9.  LICENSE.txt  NOTICE.txt  README.asciidoc  bin  config  data  jdk  lib  logs  modules  plugins
10.  elasticsearch@878c82384761:~$ cd config/
11.  elasticsearch@878c82384761:~/config$ ls
12.  elasticsearch-plugins.example.yml  jvm.options             log4j2.properties  synonyms.txt
13.  elasticsearch.keystore             jvm.options.d           role_mapping.yml   users
14.  elasticsearch.yml                  log4j2.file.properties  roles.yml          users_roles

从上面的输出中,我们可以看到 synonyms.txt 已经被成功地加载到容器里了。

然后我们可以使用同义词文件创建一个新索引:

`

1.  PUT /synonym_graph_file
2.  {
3.    "settings": {
4.      "index": {
5.        "analysis": {
6.          "analyzer": {
7.            "index_analyzer": {
8.              "tokenizer": "standard",
9.              "filter": [
10.                "lowercase"
11.              ]
12.            },
13.            "search_analyzer": {
14.              "tokenizer": "standard",
15.              "filter": [
16.                "lowercase",
17.                "synonym_filter"
18.              ]
19.            }
20.          },
21.          "filter": {
22.            "synonym_filter": {
23.              "type": "synonym_graph",
24.              "synonyms_path": "synonyms.txt",
25.              "updateable": true
26.            }
27.          }
28.        }
29.      }
30.    },
31.    "mappings": {
32.      "properties": {
33.        "name": {
34.          "type": "text",
35.          "analyzer": "index_analyzer",
36.          "search_analyzer": "search_analyzer"
37.        }
38.      }
39.    }
40.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

关键点

  • 对于 synonyms_path,它是同义词文件相对于 Elasticsearch 服务器中 config 文件夹的路径。
  • 添加了一个新的 updateable 字段,它指定相应的过滤器是否可更新。 我们很快就会看到如何在不关闭和打开索引的情况下重新加载搜索分析器。

这个新索引 synonym_graph_file 的行为应该与前一个 synonym_graph 的行为相同。

现在让我们在同义词文件中添加更多的同义词,其内容如下:


1.  $ pwd
2.  /Users/liuxg/data/docker8
3.  $ ls
4.  docker-compose.yml synonyms.txt
5.  $ cat synonyms.txt 
6.  # This is a comment! The file is named synonyms.txt.
7.  elk,elkb,Elastic Stack
8.  JS => JavaScript
9.  TS => TypeScript
10.  Py => Python

添加同义词后,我们可以关闭并打开索引使其生效。 然而,由于我们将同义词过滤器标记为可更新,我们可以重新加载搜索分析器以使更改立即生效,而无需关闭索引,因此无需停机。

要重新加载索引的搜索分析器,我们需要调用 _reload_search_analyzers 端点:

POST /synonym_graph_file/_reload_search_analyzers

上面的命令输出为:

`

1.  {
2.    "_shards": {
3.      "total": 2,
4.      "successful": 1,
5.      "failed": 0
6.    },
7.    "reload_details": [
8.      {
9.        "index": "synonym_graph_file",
10.        "reloaded_analyzers": [
11.          "search_analyzer"
12.        ],
13.        "reloaded_node_ids": [
14.          "tZLy82KRTaiCdpsbkEYnuA"
15.        ]
16.      }
17.    ]
18.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

现在,当我们分析 JS 字符串时,我们将看到返回的 javascript token。


1.  GET /synonym_graph_file/_analyze
2.  {
3.    "analyzer": "search_analyzer",
4.    "text": "JS"
5.  }

上面的命令返回:


1.  {
2.    "tokens": [
3.      {
4.        "token": "javascript",
5.        "start_offset": 0,
6.        "end_offset": 2,
7.        "type": "SYNONYM",
8.        "position": 0
9.      }
10.    ]
11.  }

这里应该注意两件重要的事情:

  • 如果同义词过滤器的 updateable 设置为true,那么对应的分析器只能作为 search_analyzer 使用,不能用于索引,即使类型是同义词。
  • updateable 选项只能在同义词文件与 synonyms_path 选项一起使用时使用,而不是在同义词直接通过 synonyms 选项提供时使用。

恭喜你到达这里! 我们已经涵盖了在 Elasticsearch 中使用同义词功能的所有要点。

我们已经分别介绍了如何在索引时间和搜索时间分析步骤中使用同义词。 此外,还介绍了如何直接提供同义词列表,以及如何通过文件提供。 最后但同样重要的是,介绍了关于如何更新现有索引的同义词列表的不同方法。 建议重新加载索引的搜索分析器,因为它不会给服务带来停机时间。

继续阅读 »

原文地址 elasticstack.blog.csdn.net

同义词用于提高搜索质量并扩大匹配范围。 例如,搜索 England 的用户可能希望找到包含 British 或 UK 的文档,尽管这三个词完全不同。

Elasticsearch 中的同义词功能非常强大,如果实施得当,可以使你的搜索引擎更加健壮和强大。 在本文中,我们将通过简单的代码片段介绍在实践中实现同义词功能的要点。 特别是,我们将介绍如何更新现有索引的同义词,这是一个相对高级的话题。

在今天的展示中,我将使用最新的 Elastic Stack 8.6.0,尽管版本不对我们的展示有任何的影响。

准备

我们将使用 Docker 在本地启动一个 Elasticsearch 服务器,并使用 Kibana 来管理索引和运行命令。 如果你以前从未使用过 Elasticsearch 或想快速复习一下,这篇文章可能会对你有所帮助。 如果你在 Docker 中运行 Elasticsearch 时遇到问题,这篇文章很可能会帮助你解决问题。在今天的文章中,我们尝试使用 docker 来部署一个没有安全功能的 Elasticsearch 集群。

准备就绪后,让我们开始探索 Elasticsearch 中的同义词功能的旅程。

我们将在本文中使用的 docker-compose.yaml 文件包含以下内容,稍后我们将向其添加更多功能:

docker-compose.yml

`

1.  version: "3.9"
2.  services:
3.    elasticsearch:
4.      image: elasticsearch:8.6.0
5.      environment:
6.        - discovery.type=single-node
7.        - ES_JAVA_OPTS=-Xms1g -Xmx1g
8.        - xpack.security.enabled=false
9.      volumes:
10.        - type: volume
11.          source: es_data
12.          target: /usr/share/elasticsearch/data
13.      ports:
14.        - target: 9200
15.          published: 9200
16.      networks:
17.        - elastic

19.    kibana:
20.      image: kibana:8.6.0
21.      ports:
22.        - target: 5601
23.          published: 5601
24.      depends_on:
25.        - elasticsearch
26.      networks:
27.        - elastic      

29.  volumes:
30.    es_data:
31.      driver: local

33.  networks:
34.    elastic:
35.      name: elastic
36.      driver: bridge

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

你可以使用以下命令之一启动 Elasticsearch 和 Kibana:

docker-compose up

或者

docker-compose up -d

如果加上 -d 选项的话,Elasticsearch 会以 daemon 的形式来运行。上面是一种最为简单的方式来启动 Elasticsearch 集群及 Kibana。由于它没有设置安全,我们无需输入任何凭证就可以直接进入到 Kibana 了。

使用带有同义词列表的标准同义词 token 过滤器

让我们首先使用带有同义词列表的标准同义词标记过滤器创建一个索引。 在 Kibana 中运行以下命令,我们将在稍后解释详细信息: 

`

1.  PUT synonyms
2.  {
3.    "settings": {
4.      "index": {
5.        "analysis": {
6.          "analyzer": {
7.            "index_analyzer": {
8.              "tokenizer": "standard",
9.              "filter": [
10.                "lowercase",
11.                "synonym_filter"
12.              ]
13.            }
14.          },
15.          "filter": {
16.            "synonym_filter": {
17.              "type": "synonym",
18.              "synonyms": [
19.                "elk => Elastic Stack",
20.                "elkb => Elastic Stack"
21.              ]
22.            }
23.          }
24.        }
25.      }
26.    },
27.    "mappings": {
28.      "properties": {
29.        "name": {
30.          "type": "text",
31.          "analyzer": "index_analyzer"
32.        }
33.      }
34.    }
35.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

这里的要点

  1. 请注意设置键的嵌套级别。 settings => index => analysis => analyzer/filter 都是内置关键字。 但是,index_analyzer 和 synonym_filter 分别是自定义分析器和过滤器的自定义名称。
  2. 我们需要创建一个 type 为 synonym 的自定义过滤器。 synonym 选项明确提供了同义词列表。 这通常应该只用于测试,因为更新同义词列表不方便,我们稍后会看到。
  3. 本文中使用了 Solr 同义词。 对于此示例,使用了显式映射,这意味着 => 左侧的标记将替换为右侧的标记。 稍后我们将使用等同的同义词,这意味着提供的 token 被等同对待。
  4. synonym_filter 添加到名为 index_analyzer 的新自定义分析器的过滤器列表中。 通常过滤器的顺序很重要。 然而,对于同义词过滤器来说,它有点特殊,可能会让我们中的许多人感到惊讶。 在此示例中,即使 synonym_filter 过滤器放在小写过滤器之后,此过滤器返回的标记也会传递给小写过滤器,因此也会变成小写。 因此,你不需要在同义词列表或同义词文件中提供小写 token。
  5. 最后,在文档的映射中,为名称字段指定了自定义分析器。

我们知道在早期的 Elastic 产品中 elk 就是 Elastic Stack 的代名词。之后随着 Beats 的加入,很多开发者也把 elkb 当做 Elastic Stack 的代名词。要测试在索引中创建的分析器,我们可以调用 _analyze 端点:


1.  GET /synonyms/_analyze
2.  {
3.    "analyzer": "index_analyzer",
4.    "text": "elk is powerful"
5.  }

上面命令的输出为:

`

1.  {
2.    "tokens": [
3.      {
4.        "token": "elastic",
5.        "start_offset": 0,
6.        "end_offset": 3,
7.        "type": "SYNONYM",
8.        "position": 0
9.      },
10.      {
11.        "token": "is",
12.        "start_offset": 4,
13.        "end_offset": 6,
14.        "type": "<ALPHANUM>",
15.        "position": 1
16.      },
17.      {
18.        "token": "stack",
19.        "start_offset": 4,
20.        "end_offset": 6,
21.        "type": "SYNONYM",
22.        "position": 1
23.      },
24.      {
25.        "token": "powerful",
26.        "start_offset": 7,
27.        "end_offset": 15,
28.        "type": "<ALPHANUM>",
29.        "position": 2
30.      }
31.    ]
32.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

从上面的输出中,我们可以看到 type 为 SNONYM 的 token 为 elastic 及 stack。让我们向索引中添加一些文档并测试它在搜索中是否正常工作:


1.  PUT /synonyms/_doc/1
2.  {
3.    "name": "elk is very powerful"
4.  }

6.  PUT /synonyms/_doc/2
7.  {
8.    "name": "elkb is useful"
9.  }

11.  PUT /synonyms/_doc/3
12.  {
13.    "name": "Elastic Stack is so widely used"
14.  }

我们可以使用 match 关键字进行简单的搜索:


1.  GET /synonyms/_search?filter_path=**.hits
2.  {
3.    "query": {
4.      "match": {
5.        "name": "elk"
6.      }
7.    }
8.  }

如果没有问题,所有三个文件都应该被搜索到:

`

1.  {
2.    "hits": {
3.      "hits": [
4.        {
5.          "_index": "synonyms",
6.          "_id": "2",
7.          "_score": 0.31931418,
8.          "_source": {
9.            "name": "elkb is useful"
10.          }
11.        },
12.        {
13.          "_index": "synonyms",
14.          "_id": "1",
15.          "_score": 0.29086044,
16.          "_source": {
17.            "name": "elk is very powerful"
18.          }
19.        },
20.        {
21.          "_index": "synonyms",
22.          "_id": "3",
23.          "_score": 0.24686477,
24.          "_source": {
25.            "name": "Elastic Stack is so widely used"
26.          }
27.        }
28.      ]
29.    }
30.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

索引时间 vs 搜索时间进行同义词操作

如你所见,在上面的示例中,只创建了一个分析器,它用于索引和搜索。

不鼓励在索引(indexing)步骤中对所有文档应用同义词,因为它有一些主要缺点:

  • 如果不重新索引所有内容,就无法更新同义词列表,这在实践中是非常低效的。
  • 搜索分数会受到影响,因为同义词 token 也会被计算在内。
  • 索引过程变得更加耗时并且索引将变得更大。 对于小数据集来说可以忽略不计,但对于大数据集来说非常重要。

因此,最好在搜索步骤中只应用同义词,这样可以克服所有三个缺点。 为此,我们需要创建一个用于搜索的新分析器。

使用 search_analyzer 并应用搜索时间同义词

在 Kibana 中运行以下命令以创建具有搜索时同义词的新索引:

`

1.  PUT synonym_graph
2.  {
3.    "settings": {
4.      "index": {
5.        "analysis": {
6.          "analyzer": {
7.            "index_analyzer": {
8.              "tokenizer": "standard",
9.              "filter": [
10.                "lowercase"
11.              ]
12.            },
13.            "search_analyzer": {
14.              "tokenizer": "standard",
15.              "filter": [
16.                "lowercase",
17.                "synonym_filter"
18.              ]
19.            }
20.          },
21.          "filter": {
22.            "synonym_filter": {
23.              "type": "synonym_graph",
24.              "synonyms": [
25.                "elk => Elastic Stack",
26.                "elkb => Elastic Stack"
27.              ]
28.            }
29.          }
30.        }
31.      }
32.    },
33.    "mappings": {
34.      "properties": {
35.        "name": {
36.          "type": "text",
37.          "analyzer": "index_analyzer",
38.          "search_analyzer": "search_analyzer"
39.        }
40.      }
41.    }
42.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

关键点

  • 该类型现在更改为 synonym_graph,这是一个更复杂的同义词过滤器,旨在仅用作搜索分析器的一部分。 它可以更恰当地处理多词同义词,推荐用于搜索时分析。 但是,你可以继续使用原来的 synonym 类型,它在这篇文章中的表现是一样的。
  • 同义词过滤器从索引时间分析器中删除并添加到搜索时间分析器中。
  • search_analyzer 是为 name 字段明确指定的。 如果未指定,则相同的分析器 (index_analyzer) 将用于索引和搜索。

分析器应该返回与以前相同的 token。 然而,当你用这些命令为三个文档建立索引并再次执行相同的搜索后,结果会有所不同:


1.  PUT /synonym_graph/_doc/1
2.  {
3.    "name": "elk is very powerful"
4.  }

6.  PUT /synonym_graph/_doc/2
7.  {
8.    "name": "elkb is useful"
9.  }

11.  PUT /synonym_graph/_doc/3
12.  {
13.    "name": "Elastic Stack is so widely used"
14.  }

我们使用如下的命令来进行搜索:


1.  GET /synonym_graph/_search?filter_path=**.hits
2.  {
3.    "query": {
4.      "match": {
5.        "name": "elk"
6.      }
7.    }
8.  }

这一次,只有如下的结果返回。甚至 “elk is very powerful” 这个文档也没有被返回:


1.  {
2.    "hits": {
3.      "hits": [
4.        {
5.          "_index": "synonym_graph",
6.          "_id": "3",
7.          "_score": 2.3589978,
8.          "_source": {
9.            "name": "Elastic Stack is so widely used"
10.          }
11.        }
12.      ]
13.    }
14.  }

原因是同义词过滤器仅在搜索时应用。 搜索查询 elk 被替换为同义词标记 “Elastic Stack”。 然而,索引中的文档没有被同义词过滤器(synonym_filter)过滤,因此 “elk” 只是被标记为 elk 而没有被 Elastic Stack 替换。 类似于 elkb。 结果,只能匹配 “Elastic Stack is so widely used”。

为了使其像前面的示例一样正常工作,我们需要将同义词规则从显式映射更改为等效同义词。 让我们按如下方式更新同义词过滤器:


1.  ......
2.    "filter": {
3.      "synonym_filter": {
4.        "type": "synonym_graph",
5.          "synonyms": [
6.             "elk, elkb, Elastic Stack"
7.          ]
8.      }
9.    }
10.  ......

要更改现有索引的同义词,我们可以重新创建索引并重新索引所有文档,这是愚蠢且低效的。

更好的方法是更新索引的设置。 但是,我们需要在更新设置之前关闭索引,然后重新打开它才能访问它:


1.  POST /synonym_graph/_close

4.  PUT /synonym_graph/_settings
5.  {
6.    "settings": {
7.      "index.analysis.filter.synonym_filter.synonyms": [
8.        "elk, elkb, Elastic Stack"
9.      ]
10.    }
11.  }

13.  POST /synonym_graph/_open

请注意更新索引设置的特殊语法。

运行上述命令后,我们可以通过如下命令的返回值来进行验证:

GET synonym_graph

上面的命令返回:

`

1.  {
2.    "synonym_graph": {
3.      "aliases": {},
4.      "mappings": {
5.        "properties": {
6.          "name": {
7.            "type": "text",
8.            "analyzer": "index_analyzer",
9.            "search_analyzer": "search_analyzer"
10.          }
11.        }
12.      },
13.      "settings": {
14.        "index": {
15.          "routing": {
16.            "allocation": {
17.              "include": {
18.                "_tier_preference": "data_content"
19.              }
20.            }
21.          },
22.          "number_of_shards": "1",
23.          "provided_name": "synonym_graph",
24.          "creation_date": "1673501061514",
25.          "analysis": {
26.            "filter": {
27.              "synonym_filter": {
28.                "type": "synonym_graph",
29.                "synonyms": [
30.                  "elk, elkb, Elastic Stack"
31.                ]
32.              }
33.            },
34.            "analyzer": {
35.              "index_analyzer": {
36.                "filter": [
37.                  "lowercase"
38.                ],
39.                "tokenizer": "standard"
40.              },
41.              "search_analyzer": {
42.                "filter": [
43.                  "lowercase",
44.                  "synonym_filter"
45.                ],
46.                "tokenizer": "standard"
47.              }
48.            }
49.          },
50.          "number_of_replicas": "1",
51.          "uuid": "UCIWtpQMTsCc1TwnvsywHA",
52.          "version": {
53.            "created": "8060099"
54.          }
55.        }
56.      }
57.    }
58.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

让我们使用 _analyzer 端点测试 search_analyzer 并查看生成的 token:


1.  GET /synonym_graph/_analyze
2.  {
3.    "analyzer": "search_analyzer",
4.    "text": "elk"
5.  }

上述命令返回:

它表明 elk 搜索查询被三个同义词的 token 替换和扩展(由 expand 选项控制)。 它还证明,如果在索引时应用等效同义词,则结果索引的大小可以显着增加。

然后当我们再次执行相同的搜索时:


1.  GET /synonym_graph/_search?filter_path=**.hits
2.  {
3.    "query": {
4.      "match": {
5.        "name": "elk"
6.      }
7.    }
8.  }

这次搜索的结果是:

`

1.  {
2.    "hits": {
3.      "hits": [
4.        {
5.          "_index": "synonym_graph",
6.          "_id": "3",
7.          "_score": 1.6949677,
8.          "_source": {
9.            "name": "Elastic Stack is so widely used"
10.          }
11.        },
12.        {
13.          "_index": "synonym_graph",
14.          "_id": "2",
15.          "_score": 1.1220688,
16.          "_source": {
17.            "name": "elkb is useful"
18.          }
19.        },
20.        {
21.          "_index": "synonym_graph",
22.          "_id": "1",
23.          "_score": 1.0126972,
24.          "_source": {
25.            "name": "elk is very powerful"
26.          }
27.        }
28.      ]
29.    }
30.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

我们可以看到三个文档都被搜索出来了。

使用同义词文件

上面我们一直在创建索引时直接指定同义词列表。 但是,当你有大量同义词时,将它们全部添加到索引中会很麻烦。 更好的方法是将它们存储在一个文件中,然后动态地将它们加载到索引中。 使用同义词文件有很多好处,其中包括:

  • 方便维护大量的同义词。
  • 可以被不同的索引使用。
  • 可以在不关闭索引的情况下动态重新加载。

首先,我们需要先将同义词放入一个文件中。 每行都是一个同义词规则,与上面演示的相同。 更多细节可以在官方文档中找到。

我们将创建的同义词文件称为 synonyms.txt,但可以任意命名。 它具有以下内容:


1.  $ pwd
2.  /Users/liuxg/data/docker8
3.  $ ls
4.  docker-compose.yml synonyms.txt
5.  $ cat synonyms.txt 
6.  # This is a comment! The file is named synonyms.txt.
7.  elk,elkb,Elastic Stack

然后我们需要将同义词文件绑定到 Docker 容器中。 更新 docker-compose.yaml 如下:

docker-compose.yml

`

1.  version: "3.9"
2.  services:
3.    elasticsearch:
4.      image: elasticsearch:8.6.0
5.      environment:
6.        - discovery.type=single-node
7.        - ES_JAVA_OPTS=-Xms1g -Xmx1g
8.        - xpack.security.enabled=false
9.      volumes:
10.        - type: volume
11.          source: es_data
12.          target: /usr/share/elasticsearch/data
13.        - type: bind
14.          source: ./synonyms.txt
15.          target: /usr/share/elasticsearch/config/synonyms.txt      
16.      ports:
17.        - target: 9200
18.          published: 9200
19.      networks:
20.        - elastic

22.    kibana:
23.      image: kibana:8.6.0
24.      ports:
25.        - target: 5601
26.          published: 5601
27.      depends_on:
28.        - elasticsearch
29.      networks:
30.        - elastic      

32.  volumes:
33.    es_data:
34.      driver: local

36.  networks:
37.    elastic:
38.      name: elastic
39.      driver: bridge

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

我们可以使用 CTRL+C 来终止之前运行的 docker,然后再次使用如下命令来启动:

docker-compose up

请注意,同义词文件已加载到容器中的 config 文件夹中。你可以进入容器并使用以下两个命令之一检查它:


1.  # User docker
2.  docker exec -it elasticsearch-1  bash

4.  # User docker-compose
5.  docker-compose exec elasticsearch bash

现在我们需要停止并重新启动服务以使更改生效。 请注意,仅重新启动服务将不起作用。


1.  docker-compose stop elasticsearch
2.  docker-compose up -d elasticsearch

1.  $ docker ps
2.  CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                              NAMES
3.  3ae4b728dd44   kibana:8.6.0          "/bin/tini -- /usr/l…"   23 seconds ago   Up 21 seconds   0.0.0.0:5601->5601/tcp             docker8-kibana-1
4.  878c82384761   elasticsearch:8.6.0   "/bin/tini -- /usr/l…"   23 seconds ago   Up 22 seconds   0.0.0.0:9200->9200/tcp, 9300/tcp   docker8-elasticsearch-1
5.  $ docker exec -it docker8-elasticsearch-1 bash
6.  elasticsearch@878c82384761:~$ pwd
7.  /usr/share/elasticsearch
8.  elasticsearch@878c82384761:~$ ls
9.  LICENSE.txt  NOTICE.txt  README.asciidoc  bin  config  data  jdk  lib  logs  modules  plugins
10.  elasticsearch@878c82384761:~$ cd config/
11.  elasticsearch@878c82384761:~/config$ ls
12.  elasticsearch-plugins.example.yml  jvm.options             log4j2.properties  synonyms.txt
13.  elasticsearch.keystore             jvm.options.d           role_mapping.yml   users
14.  elasticsearch.yml                  log4j2.file.properties  roles.yml          users_roles

从上面的输出中,我们可以看到 synonyms.txt 已经被成功地加载到容器里了。

然后我们可以使用同义词文件创建一个新索引:

`

1.  PUT /synonym_graph_file
2.  {
3.    "settings": {
4.      "index": {
5.        "analysis": {
6.          "analyzer": {
7.            "index_analyzer": {
8.              "tokenizer": "standard",
9.              "filter": [
10.                "lowercase"
11.              ]
12.            },
13.            "search_analyzer": {
14.              "tokenizer": "standard",
15.              "filter": [
16.                "lowercase",
17.                "synonym_filter"
18.              ]
19.            }
20.          },
21.          "filter": {
22.            "synonym_filter": {
23.              "type": "synonym_graph",
24.              "synonyms_path": "synonyms.txt",
25.              "updateable": true
26.            }
27.          }
28.        }
29.      }
30.    },
31.    "mappings": {
32.      "properties": {
33.        "name": {
34.          "type": "text",
35.          "analyzer": "index_analyzer",
36.          "search_analyzer": "search_analyzer"
37.        }
38.      }
39.    }
40.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

关键点

  • 对于 synonyms_path,它是同义词文件相对于 Elasticsearch 服务器中 config 文件夹的路径。
  • 添加了一个新的 updateable 字段,它指定相应的过滤器是否可更新。 我们很快就会看到如何在不关闭和打开索引的情况下重新加载搜索分析器。

这个新索引 synonym_graph_file 的行为应该与前一个 synonym_graph 的行为相同。

现在让我们在同义词文件中添加更多的同义词,其内容如下:


1.  $ pwd
2.  /Users/liuxg/data/docker8
3.  $ ls
4.  docker-compose.yml synonyms.txt
5.  $ cat synonyms.txt 
6.  # This is a comment! The file is named synonyms.txt.
7.  elk,elkb,Elastic Stack
8.  JS => JavaScript
9.  TS => TypeScript
10.  Py => Python

添加同义词后,我们可以关闭并打开索引使其生效。 然而,由于我们将同义词过滤器标记为可更新,我们可以重新加载搜索分析器以使更改立即生效,而无需关闭索引,因此无需停机。

要重新加载索引的搜索分析器,我们需要调用 _reload_search_analyzers 端点:

POST /synonym_graph_file/_reload_search_analyzers

上面的命令输出为:

`

1.  {
2.    "_shards": {
3.      "total": 2,
4.      "successful": 1,
5.      "failed": 0
6.    },
7.    "reload_details": [
8.      {
9.        "index": "synonym_graph_file",
10.        "reloaded_analyzers": [
11.          "search_analyzer"
12.        ],
13.        "reloaded_node_ids": [
14.          "tZLy82KRTaiCdpsbkEYnuA"
15.        ]
16.      }
17.    ]
18.  }

`![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)

现在,当我们分析 JS 字符串时,我们将看到返回的 javascript token。


1.  GET /synonym_graph_file/_analyze
2.  {
3.    "analyzer": "search_analyzer",
4.    "text": "JS"
5.  }

上面的命令返回:


1.  {
2.    "tokens": [
3.      {
4.        "token": "javascript",
5.        "start_offset": 0,
6.        "end_offset": 2,
7.        "type": "SYNONYM",
8.        "position": 0
9.      }
10.    ]
11.  }

这里应该注意两件重要的事情:

  • 如果同义词过滤器的 updateable 设置为true,那么对应的分析器只能作为 search_analyzer 使用,不能用于索引,即使类型是同义词。
  • updateable 选项只能在同义词文件与 synonyms_path 选项一起使用时使用,而不是在同义词直接通过 synonyms 选项提供时使用。

恭喜你到达这里! 我们已经涵盖了在 Elasticsearch 中使用同义词功能的所有要点。

我们已经分别介绍了如何在索引时间和搜索时间分析步骤中使用同义词。 此外,还介绍了如何直接提供同义词列表,以及如何通过文件提供。 最后但同样重要的是,介绍了关于如何更新现有索引的同义词列表的不同方法。 建议重新加载索引的搜索分析器,因为它不会给服务带来停机时间。

收起阅读 »

回顾 2022 年 — 回顾 Elastic 这一年

作者:Elastic Marketing

2022 年对 Elastic 来说是非凡的一年,我们在可观察性、安全性和企业搜索解决方案、新客户和深化合作伙伴关系方面引入了数十项创新。

在我们花点时间回顾过去的一年时,我们汇总了 2022 年的热门博文。希望你喜欢!

Elastic 8.0

在年初之际,我们还推出了 Elastic 8.0 的新篇章:速度、规模、相关性和简单性的新时代。 Elastic 8.0 是 7.x 系列多年投资的结晶,旨在减少内存使用和查询开销,并引入新功能以增强相关性。

例如,我们提高了日期直方图和搜索聚合的速度,增强了页面缓存的性能,并创建了一个新的 “预过滤” 搜索阶段。 此外,我们通过减少内存堆减少了资源需求以降低客户的总拥有成本,引入了使用更少存储的新方法,并使我们的客户能够通过新的冻结层和可搜索快照轻松地将计算与存储分离。

在 8.0 中,我们还为 Elasticsearch 带来了一整套原生矢量搜索功能,使客户和员工能够使用他们自己的词汇和语言搜索和接收高度相关的结果。

Machine Learning Relevance Tuning

作为 7.x 发布版中两年多工作的结晶,使向量搜索的实现更加实用,我们还引入了对近似最近邻搜索的原生支持 — 使得可以将基于向量的查询作用于基于向量词库进行比较快速、大规模地比较。 查看我们的自然语言处理 (NLP) 博客系列,获取部署矢量搜索的快速入门指南。

Elastic Security

随着 Elastic Security for Cloud 的推出,这也是 Elastic Security 具有里程碑意义的一年。 Elastic Security for Cloud 扩展了我们的 SIEM、安全分析和端点安全功能,在单个统一平台中提供了风险和状态管理、威胁监控和工作负载保护的新功能。

我们通过再次加倍承诺公开和透明的安全来结束这一年。 我们对开放式安全的承诺在 Forrester Wave™:安全分析平台,2022 年第 4 季度中得到进一步认可,其中 Elastic 被评为领导者,并指出“Elastic 在开放式产品中提供了令人难以置信的灵活性和可视化。”
 
更多阅读:https://elasticstack.blog.csdn ... 94458
继续阅读 »
作者:Elastic Marketing

2022 年对 Elastic 来说是非凡的一年,我们在可观察性、安全性和企业搜索解决方案、新客户和深化合作伙伴关系方面引入了数十项创新。

在我们花点时间回顾过去的一年时,我们汇总了 2022 年的热门博文。希望你喜欢!

Elastic 8.0

在年初之际,我们还推出了 Elastic 8.0 的新篇章:速度、规模、相关性和简单性的新时代。 Elastic 8.0 是 7.x 系列多年投资的结晶,旨在减少内存使用和查询开销,并引入新功能以增强相关性。

例如,我们提高了日期直方图和搜索聚合的速度,增强了页面缓存的性能,并创建了一个新的 “预过滤” 搜索阶段。 此外,我们通过减少内存堆减少了资源需求以降低客户的总拥有成本,引入了使用更少存储的新方法,并使我们的客户能够通过新的冻结层和可搜索快照轻松地将计算与存储分离。

在 8.0 中,我们还为 Elasticsearch 带来了一整套原生矢量搜索功能,使客户和员工能够使用他们自己的词汇和语言搜索和接收高度相关的结果。

Machine Learning Relevance Tuning

作为 7.x 发布版中两年多工作的结晶,使向量搜索的实现更加实用,我们还引入了对近似最近邻搜索的原生支持 — 使得可以将基于向量的查询作用于基于向量词库进行比较快速、大规模地比较。 查看我们的自然语言处理 (NLP) 博客系列,获取部署矢量搜索的快速入门指南。

Elastic Security

随着 Elastic Security for Cloud 的推出,这也是 Elastic Security 具有里程碑意义的一年。 Elastic Security for Cloud 扩展了我们的 SIEM、安全分析和端点安全功能,在单个统一平台中提供了风险和状态管理、威胁监控和工作负载保护的新功能。

我们通过再次加倍承诺公开和透明的安全来结束这一年。 我们对开放式安全的承诺在 Forrester Wave™:安全分析平台,2022 年第 4 季度中得到进一步认可,其中 Elastic 被评为领导者,并指出“Elastic 在开放式产品中提供了令人难以置信的灵活性和可视化。”
 
更多阅读:https://elasticstack.blog.csdn ... 94458 收起阅读 »

Elasticsearch:使用 Node.js 将实时数据提取到 Elasticsearch 中(一)

Elasticsearch 是一个强大的 RESTful 搜索和分析引擎,能够处理越来越多的用例。 它将集中存储你的数据,以实现闪电般的快速搜索、微调相关性以及可轻松扩展的强大分析。 关于如何使用 Elastic Stack(又名 ELK 堆栈)将数据摄取到 Elasticsearch 的资源有很多。在今天的文章中,我将详细介绍如何使用 Node.js 从零开始来把地震的实时数据采集到 Elasticsearch 中。

如果你选择的编程语言是 JavaScript,并且你需要使用 RESTful API 方法从第三方应用程序获取数据,那么使用 Node.js 获取数据是一个不错的选择。 你还可以托管服务器,让它持续实时摄取数据。 该演示将向您展示如何设置一个 Node.js + Express.js 服务器,该服务器实时将数据提取到 Elasticsearch 中,然后可以对这些数据进行分析并以有意义的方式采取行动。

对于此演示,我们将使用 USGS 实时发布的公开可用的全球地震数据。
更多阅读 https://elasticstack.blog.csdn ... 05743
继续阅读 »
Elasticsearch 是一个强大的 RESTful 搜索和分析引擎,能够处理越来越多的用例。 它将集中存储你的数据,以实现闪电般的快速搜索、微调相关性以及可轻松扩展的强大分析。 关于如何使用 Elastic Stack(又名 ELK 堆栈)将数据摄取到 Elasticsearch 的资源有很多。在今天的文章中,我将详细介绍如何使用 Node.js 从零开始来把地震的实时数据采集到 Elasticsearch 中。

如果你选择的编程语言是 JavaScript,并且你需要使用 RESTful API 方法从第三方应用程序获取数据,那么使用 Node.js 获取数据是一个不错的选择。 你还可以托管服务器,让它持续实时摄取数据。 该演示将向您展示如何设置一个 Node.js + Express.js 服务器,该服务器实时将数据提取到 Elasticsearch 中,然后可以对这些数据进行分析并以有意义的方式采取行动。

对于此演示,我们将使用 USGS 实时发布的公开可用的全球地震数据。
更多阅读 https://elasticstack.blog.csdn ... 05743 收起阅读 »

Observability:从零开始创建 Java 微服务并监控它 (一)

在本教程中,你将学习如何使用 Elastic 可观察性监控 Java 应用程序:日志、基础设施指标、APM 和正常运行时间。通过本教程,你将学到:
 
  • 创建示例 Java 应用程序。
  • 使用 Filebeat 提取日志并在 Kibana 中查看你的日志。
  • 使用 Metricbeat Prometheus 模块获取指标并在 Kibana 中查看你的指标。
  • 使用 Elastic APM Java 代理检测你的应用程序。
  • 使用 Heartbeat 监控您的服务并在 Kibana 中查看您的正常运行时间数据。

 在下面的展示中,我将使用最新的 Elastic Stack 8.5.2 来进行展示。为了方便大家的学习,源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。
更多阅读:https://elasticstack.blog.csdn ... 13010
继续阅读 »
在本教程中,你将学习如何使用 Elastic 可观察性监控 Java 应用程序:日志、基础设施指标、APM 和正常运行时间。通过本教程,你将学到:
 
  • 创建示例 Java 应用程序。
  • 使用 Filebeat 提取日志并在 Kibana 中查看你的日志。
  • 使用 Metricbeat Prometheus 模块获取指标并在 Kibana 中查看你的指标。
  • 使用 Elastic APM Java 代理检测你的应用程序。
  • 使用 Heartbeat 监控您的服务并在 Kibana 中查看您的正常运行时间数据。

 在下面的展示中,我将使用最新的 Elastic Stack 8.5.2 来进行展示。为了方便大家的学习,源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。
更多阅读:https://elasticstack.blog.csdn ... 13010 收起阅读 »

Elasticsearch:将关系数据库中的数据提取到 Elasticsearch 集群中

本指南介绍了如何使用 Logstash JDBC 输入插件通过 Logstash 将关系数据库中的数据提取到 Elasticsearch 集群中。 它演示了如何使用 Logstash 高效地复制记录并从关系数据库接收更新,然后将它们发送到 Elasticsearch 中。

此处提供的代码和方法已经过 MySQL 测试。 他们应该也适用于其他关系数据库。

Logstash Java 数据库连接 (JDBC) 输入插件使你能够从许多流行的关系数据库(包括 MySQL 和 Postgres)中提取数据。 从概念上讲,JDBC 输入插件运行一个循环,该循环定期轮询关系数据库以查找自该循环的最后一次迭代以来插入或修改的记录。

原文链接:https://elasticstack.blog.csdn ... 63743
继续阅读 »
本指南介绍了如何使用 Logstash JDBC 输入插件通过 Logstash 将关系数据库中的数据提取到 Elasticsearch 集群中。 它演示了如何使用 Logstash 高效地复制记录并从关系数据库接收更新,然后将它们发送到 Elasticsearch 中。

此处提供的代码和方法已经过 MySQL 测试。 他们应该也适用于其他关系数据库。

Logstash Java 数据库连接 (JDBC) 输入插件使你能够从许多流行的关系数据库(包括 MySQL 和 Postgres)中提取数据。 从概念上讲,JDBC 输入插件运行一个循环,该循环定期轮询关系数据库以查找自该循环的最后一次迭代以来插入或修改的记录。

原文链接:https://elasticstack.blog.csdn ... 63743 收起阅读 »

ES7.5升级7.17后在写多读少场景下CPU、IO飙升

背景

1.ES PAAS管理的集群升级了100+,从7.5升级到7.17 (保证每个大版本最终仅维护一个小版本集群)

2.由于业务使用差异大,也出了不少问题,前面的文章也有提到过Integer类型字段使用terms查询效率低的情况

3.这里再分析一个CPU、IO飙升的场景

现象

1.用户报障:“ES集群写入吞吐量变小了”

2.观察下来发现确实CPU高了,IO也有明显抖动

1.png

2.png

排查与分析

1.发现YoungGC频率变高了一些,猜测可能是G1GC的问题(我们使用JDK11重新打了ES镜像),经过版本替换,没有明显变化。

参考issue:https://github.com/elastic/elasticsearch/pull/46169

这可能是另一个场景的case,经过测试,不属于我们的场景。

2.多次执行hot_threads API观察, 发现时不时会出现 update相关函数 消耗的 CPU多。

3.继续使用arthas抓取一段时间的数据,发现是 FST、DocID 读取慢

3.png

从图中可以看到Bulk请求执行过程中的getDocID方法占有大量CPU。

4.集群写多读少,使用的是niofs。可知,7.5版本的FST是在堆外,但是_id字段是在堆内。升级到7.17版本后,FST在堆外,该字段也放到了堆外(官方版本应该是7.9就开始放到堆外了)。数据放到堆外,其实也就是文件放到磁盘,读一次之后放到pagecache。

这样也就可以解释了,在upsert类请求多的时候会频繁查询docId,此时如果_id字段没有进入pageCache或者被踢出pageCache,那么就会出现响应慢,并且CPU高、IO高的情况。

5.mmapfs、hybridfs实测是什么情况暂时不明确,目前没有收到搜索类集群CPU、IO方面的报障。

测试验证

将FST、BKD等全部改成放到堆内(开源版需要改造)

4.png

可以看到,CPU有显著下降,也相对均衡。(之前蓝色线高,是因为该节点有大量的主分片)

结论

1.update、upsert、get等请求如果十分频繁,_id使用offheap将不会是个好的选择,除非给足够的堆外内存,并且保证尽可能常驻内存。

2.不同的业务场景下使用ES的同一版本也会有不一样的效果。

3.mmapfs、hybridfs在频繁update情况下,实测是什么情况暂时不明确,目前没有收到搜索类集群CPU、IO方面的报障,可能不会有这么明显的差距。(官方描述写入速度仅降低了1.8%)

4.最后吐槽一下,写入不停的情况下,translog的恢复实在是太慢了,由于大分片恢复/rebalance时,translog不会被清理,导致恢复/迁移速度急剧下降...目前各个版本也没什么好的解决方式。

继续阅读 »

背景

1.ES PAAS管理的集群升级了100+,从7.5升级到7.17 (保证每个大版本最终仅维护一个小版本集群)

2.由于业务使用差异大,也出了不少问题,前面的文章也有提到过Integer类型字段使用terms查询效率低的情况

3.这里再分析一个CPU、IO飙升的场景

现象

1.用户报障:“ES集群写入吞吐量变小了”

2.观察下来发现确实CPU高了,IO也有明显抖动

1.png

2.png

排查与分析

1.发现YoungGC频率变高了一些,猜测可能是G1GC的问题(我们使用JDK11重新打了ES镜像),经过版本替换,没有明显变化。

参考issue:https://github.com/elastic/elasticsearch/pull/46169

这可能是另一个场景的case,经过测试,不属于我们的场景。

2.多次执行hot_threads API观察, 发现时不时会出现 update相关函数 消耗的 CPU多。

3.继续使用arthas抓取一段时间的数据,发现是 FST、DocID 读取慢

3.png

从图中可以看到Bulk请求执行过程中的getDocID方法占有大量CPU。

4.集群写多读少,使用的是niofs。可知,7.5版本的FST是在堆外,但是_id字段是在堆内。升级到7.17版本后,FST在堆外,该字段也放到了堆外(官方版本应该是7.9就开始放到堆外了)。数据放到堆外,其实也就是文件放到磁盘,读一次之后放到pagecache。

这样也就可以解释了,在upsert类请求多的时候会频繁查询docId,此时如果_id字段没有进入pageCache或者被踢出pageCache,那么就会出现响应慢,并且CPU高、IO高的情况。

5.mmapfs、hybridfs实测是什么情况暂时不明确,目前没有收到搜索类集群CPU、IO方面的报障。

测试验证

将FST、BKD等全部改成放到堆内(开源版需要改造)

4.png

可以看到,CPU有显著下降,也相对均衡。(之前蓝色线高,是因为该节点有大量的主分片)

结论

1.update、upsert、get等请求如果十分频繁,_id使用offheap将不会是个好的选择,除非给足够的堆外内存,并且保证尽可能常驻内存。

2.不同的业务场景下使用ES的同一版本也会有不一样的效果。

3.mmapfs、hybridfs在频繁update情况下,实测是什么情况暂时不明确,目前没有收到搜索类集群CPU、IO方面的报障,可能不会有这么明显的差距。(官方描述写入速度仅降低了1.8%)

4.最后吐槽一下,写入不停的情况下,translog的恢复实在是太慢了,由于大分片恢复/rebalance时,translog不会被清理,导致恢复/迁移速度急剧下降...目前各个版本也没什么好的解决方式。

收起阅读 »

Elasticsearch:Hadoop 大数据集成 (Hadoop => Elasticsearch)

在本文章中,我们将学习如何使用 Elasticsearch Hadoop 处理大量数据。 对于我们的练习,我们将使用一个简单的 Apache access 日志来表示我们的 “大数据”。 我们将学习如何编写 MapReduce 作业以使用 Hadoop 摄取文件并将其索引到 Elasticsearch 中。在我们今天的练习中,我们将使用如下的架构来搭建我们的系统:

hadoop1.png


hadoop.png

 
如上所示,我们在左边的 macOS 中安装 Elasticsearch 及 Kibana,而在 Ubuntu OS 中安装 Hadoop。我们将以最新的 Elastic Stack 8.4.2 来进行展示。

Hadoop 是什么?

当我们需要收集、处理/转换和/或存储数千 GB、数千 TB 甚至更多的数据时,Hadoop 可能是完成这项工作的合适工具。它是从头开始构建的,考虑到这样的想法:
  • 一次使用多台计算机(形成一个集群),以便它可以并行处理数据,从而更快地完成工作。我们可以这样想。如果一台服务器需要处理 100 TB 的数据,它可能会在 500 小时内完成。但是如果我们有 100 台服务器,每台只能取一部分数据,例如 server1 可以取第一个 TB,server2 可以取第二个 TB,以此类推。现在他们每个人都只有 1 TB 的数据要处理,而且他们都可以同时处理自己的数据部分。这样,工作可以在 5 小时内完成,而不是 500 小时。当然,这是理论上的和想象的,因为在实践中我们不会减少 100 倍所需的时间,但我们可以非常接近如果条件理想。
  • 在需要时可以很容易地调整计算能力。有更多的数据要处理,而问题要复杂得多?将更多计算机添加到集群。从某种意义上说,这就像在超级计算机上增加了更多的 CPU 内核。
  • 数据不断增长,因此 Hadoop 也必须能够轻松灵活地扩展其存储容量,以满足需求。我们添加到集群的每台计算机都会扩展 Hadoop 分布式文件系统 (HDFS) 的可用总存储空间。
  • 与其他软件不同,它不仅会在硬件故障发生时尝试从硬件故障中恢复。设计理念实际上假设某些硬件肯定会失败。当有数千台计算机并行工作时,可以保证某处某处会不时出现故障。因此,默认情况下,Hadoop 创建数据块的副本并将它们分布在单独的硬件上,因此当偶尔的服务器起火或硬盘或 SSD 死机时,不会丢失任何内容。

总而言之,Hadoop 非常擅长摄取和处理大量信息。它将数据分布在集群中可用的多个节点上,并使用 MapReduce 编程模型在多台机器上同时处理数据(并行处理)。

但这听起来可能有点类似于 Elasticsearch 数据摄取工具所做的事情。尽管它们是为处理相当不同的场景而设计的,但它们有时可能会有些重叠。那么我们为什么以及何时使用其中一个而不是另一个呢?

Hadoop vs Logstash/Elasticsearch

首先,我们不应该考虑哪个比哪个更好。 每个人都擅长为其创造的工作。 每个都有优点和缺点。

为了尝试给你绘制一个图片并让你了解我们何时使用其中一个,让我们考虑以下场景:
  • 当我们需要从数十亿个网站中提取数据时,就像谷歌这样的搜索引擎所做的那样,我们会发现像 Elasticsearch 及 Hadoop 这样的工具非常有用和高效。
  • 当我们需要以这样一种方式存储数据并对其进行索引以便以后可以快速有效地搜索时,我们会发现像 Elasticsearch 这样的东西非常有用。
  • 最后,当我们想要收集实时数据时,例如来自互联网上许多交易所的美元/欧元价格,我们会发现像 Logstash 这样的工具非常适合这项工作。

 
更多阅读,请参阅 https://elasticstack.blog.csdn ... 97392
继续阅读 »
在本文章中,我们将学习如何使用 Elasticsearch Hadoop 处理大量数据。 对于我们的练习,我们将使用一个简单的 Apache access 日志来表示我们的 “大数据”。 我们将学习如何编写 MapReduce 作业以使用 Hadoop 摄取文件并将其索引到 Elasticsearch 中。在我们今天的练习中,我们将使用如下的架构来搭建我们的系统:

hadoop1.png


hadoop.png

 
如上所示,我们在左边的 macOS 中安装 Elasticsearch 及 Kibana,而在 Ubuntu OS 中安装 Hadoop。我们将以最新的 Elastic Stack 8.4.2 来进行展示。

Hadoop 是什么?

当我们需要收集、处理/转换和/或存储数千 GB、数千 TB 甚至更多的数据时,Hadoop 可能是完成这项工作的合适工具。它是从头开始构建的,考虑到这样的想法:
  • 一次使用多台计算机(形成一个集群),以便它可以并行处理数据,从而更快地完成工作。我们可以这样想。如果一台服务器需要处理 100 TB 的数据,它可能会在 500 小时内完成。但是如果我们有 100 台服务器,每台只能取一部分数据,例如 server1 可以取第一个 TB,server2 可以取第二个 TB,以此类推。现在他们每个人都只有 1 TB 的数据要处理,而且他们都可以同时处理自己的数据部分。这样,工作可以在 5 小时内完成,而不是 500 小时。当然,这是理论上的和想象的,因为在实践中我们不会减少 100 倍所需的时间,但我们可以非常接近如果条件理想。
  • 在需要时可以很容易地调整计算能力。有更多的数据要处理,而问题要复杂得多?将更多计算机添加到集群。从某种意义上说,这就像在超级计算机上增加了更多的 CPU 内核。
  • 数据不断增长,因此 Hadoop 也必须能够轻松灵活地扩展其存储容量,以满足需求。我们添加到集群的每台计算机都会扩展 Hadoop 分布式文件系统 (HDFS) 的可用总存储空间。
  • 与其他软件不同,它不仅会在硬件故障发生时尝试从硬件故障中恢复。设计理念实际上假设某些硬件肯定会失败。当有数千台计算机并行工作时,可以保证某处某处会不时出现故障。因此,默认情况下,Hadoop 创建数据块的副本并将它们分布在单独的硬件上,因此当偶尔的服务器起火或硬盘或 SSD 死机时,不会丢失任何内容。

总而言之,Hadoop 非常擅长摄取和处理大量信息。它将数据分布在集群中可用的多个节点上,并使用 MapReduce 编程模型在多台机器上同时处理数据(并行处理)。

但这听起来可能有点类似于 Elasticsearch 数据摄取工具所做的事情。尽管它们是为处理相当不同的场景而设计的,但它们有时可能会有些重叠。那么我们为什么以及何时使用其中一个而不是另一个呢?

Hadoop vs Logstash/Elasticsearch

首先,我们不应该考虑哪个比哪个更好。 每个人都擅长为其创造的工作。 每个都有优点和缺点。

为了尝试给你绘制一个图片并让你了解我们何时使用其中一个,让我们考虑以下场景:
  • 当我们需要从数十亿个网站中提取数据时,就像谷歌这样的搜索引擎所做的那样,我们会发现像 Elasticsearch 及 Hadoop 这样的工具非常有用和高效。
  • 当我们需要以这样一种方式存储数据并对其进行索引以便以后可以快速有效地搜索时,我们会发现像 Elasticsearch 这样的东西非常有用。
  • 最后,当我们想要收集实时数据时,例如来自互联网上许多交易所的美元/欧元价格,我们会发现像 Logstash 这样的工具非常适合这项工作。

 
更多阅读,请参阅 https://elasticstack.blog.csdn ... 97392 收起阅读 »

ES7.17版本terms查询性能问题

背景

1.对于7版本(大版本)集群希望只维护一个版本,最终选择7.17,对同大版本的7.5版本集群进行升级

2.根据官方描述,_id放到堆外性能损失非常小可以忽略,且对BKD进行了优化

3.升级完成,一段时间之后,收到用户报障

1-cpu.png

2-time.png

4.抽样检查了下部分升级的集群,其中部分受到影响,部分不受影响。且每个集群内存均有一定优化(预期内)

调查&分析

1.发现is_deleted文档特别多,怀疑是7.17版本对于碎片过于敏感。做forcemerge,没什么效果。

2.GET _nodes/hot_threads 查看耗时部分,结果展示笼统,没得到关键信息。

3.给语句加上profile,查看耗时部分。

GET index-v1/_search
{"profile":"true","query":{"bool":{"filter":[{"term":{"xid":{"value":"11111111","boost":1.0}}},{"terms":{"status":[2,3,4],"boost":1.0}},{"terms":{"platform":["aaa","bbb"],"boost":1.0}},{"terms":{"pId":[1,2],"boost":1.0}}],"adjust_pure_negative":true,"boost":1.0}},"sort":[{"time":{"order":"desc"}}]}

从脱敏的简化结果中可以看出来,主要是 status、pId 字段耗时高,这两个字段都是integer类型,并且使用了terms查询。

{
  "took": 554,
  "timed_out": false,
  "_shards": {
    "total": 3,
    "successful": 3,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 5,
      "relation": "eq"
    },
    "max_score": null,
    "hits": [
      ...
    ]
  },
  "profile": {
    "shards": [
      {
        "id": "[APxxxxxxxxxxxxxxQ][index-v1][0]",
        "searches": [
          {
            "query": [
              {
                "type": "BooleanQuery",
                "description": "#xid:111111111 #status:{2 3 4} #ConstantScore(platform:aaa platform:bbb) #pId:{1 2}",
                "time_in_nanos": 415205306,
                "breakdown": {
                  ...
                  "build_scorer": 415028271
                },
                "children": [
                  {
                    "type": "TermQuery",
                    "description": "xid:111111111",
                    "time_in_nanos": 102656,
                    "breakdown": {
                      .....
                      "build_scorer": 86264
                    }
                  },
                  {
                    "type": "PointInSetQuery",
                    "description": "status:{2 3 4}",
                    "time_in_nanos": 220394978,
                    "breakdown": {
                      ....
                      "build_scorer": 220385119
                    }
                  },
                  {
                    "type": "ConstantScoreQuery",
                    "description": "ConstantScore(platform:aaa platform:bbb)",
                    "time_in_nanos": 341845,
                    "breakdown": {
                      .....
                      "build_scorer": 282277
                    },
                    "children": [
                      {
                        "type": "BooleanQuery",
                        "description": "platform:aaa platform:bbb",
                        "time_in_nanos": 329042,
                        "breakdown": {
                          .....
                          "build_scorer": 277752
                        },
                        "children": [
                          {
                            "type": "TermQuery",
                            "description": "platform:aaa",
                            "time_in_nanos": 62446,
                            "breakdown": {
                              .....
                              "build_scorer": 37931
                            }
                          },
                          {
                            "type": "TermQuery",
                            "description": "platform:bbb",
                            "time_in_nanos": 15093,
                            "breakdown": {
                              .....
                              "build_scorer": 6981
                            }
                          }
                        ]
                      }
                    ]
                  },
                  {
                    "type": "PointInSetQuery",
                    "description": "pId:{1 2}",
                    "time_in_nanos": 194164297,
                    "breakdown": {
                      ....
                      "build_scorer": 194160452
                    }
                  }
                ]
              }
            ],
            "rewrite_time": 40044,
            "collector": [
              {
                "name": "SimpleFieldCollector",
                "reason": "search_top_hits",
                "time_in_nanos": 144012
              }
            ]
          }
        ]

4.单个的profile无法说明问题,进一步排查:使用arthas工具获取一段时间内的火焰图

3-火焰图.png

可以看到主要就是BKD数据结构占用的CPU。

5.参考官方论坛相似问题:https://discuss.elastic.co/t/very-slow-search-performance-after-upgrade-to-7-16-1/296152/3

6.integer类型的terms查询性能较差,看起来官方描述的BKD相关优化指的是range

7.测试验证,将字段改成keyword,查看结果,CPU查询耗时恢复到正常范围

4-结果.png

5-结果-time.png

继续阅读 »

背景

1.对于7版本(大版本)集群希望只维护一个版本,最终选择7.17,对同大版本的7.5版本集群进行升级

2.根据官方描述,_id放到堆外性能损失非常小可以忽略,且对BKD进行了优化

3.升级完成,一段时间之后,收到用户报障

1-cpu.png

2-time.png

4.抽样检查了下部分升级的集群,其中部分受到影响,部分不受影响。且每个集群内存均有一定优化(预期内)

调查&分析

1.发现is_deleted文档特别多,怀疑是7.17版本对于碎片过于敏感。做forcemerge,没什么效果。

2.GET _nodes/hot_threads 查看耗时部分,结果展示笼统,没得到关键信息。

3.给语句加上profile,查看耗时部分。

GET index-v1/_search
{"profile":"true","query":{"bool":{"filter":[{"term":{"xid":{"value":"11111111","boost":1.0}}},{"terms":{"status":[2,3,4],"boost":1.0}},{"terms":{"platform":["aaa","bbb"],"boost":1.0}},{"terms":{"pId":[1,2],"boost":1.0}}],"adjust_pure_negative":true,"boost":1.0}},"sort":[{"time":{"order":"desc"}}]}

从脱敏的简化结果中可以看出来,主要是 status、pId 字段耗时高,这两个字段都是integer类型,并且使用了terms查询。

{
  "took": 554,
  "timed_out": false,
  "_shards": {
    "total": 3,
    "successful": 3,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 5,
      "relation": "eq"
    },
    "max_score": null,
    "hits": [
      ...
    ]
  },
  "profile": {
    "shards": [
      {
        "id": "[APxxxxxxxxxxxxxxQ][index-v1][0]",
        "searches": [
          {
            "query": [
              {
                "type": "BooleanQuery",
                "description": "#xid:111111111 #status:{2 3 4} #ConstantScore(platform:aaa platform:bbb) #pId:{1 2}",
                "time_in_nanos": 415205306,
                "breakdown": {
                  ...
                  "build_scorer": 415028271
                },
                "children": [
                  {
                    "type": "TermQuery",
                    "description": "xid:111111111",
                    "time_in_nanos": 102656,
                    "breakdown": {
                      .....
                      "build_scorer": 86264
                    }
                  },
                  {
                    "type": "PointInSetQuery",
                    "description": "status:{2 3 4}",
                    "time_in_nanos": 220394978,
                    "breakdown": {
                      ....
                      "build_scorer": 220385119
                    }
                  },
                  {
                    "type": "ConstantScoreQuery",
                    "description": "ConstantScore(platform:aaa platform:bbb)",
                    "time_in_nanos": 341845,
                    "breakdown": {
                      .....
                      "build_scorer": 282277
                    },
                    "children": [
                      {
                        "type": "BooleanQuery",
                        "description": "platform:aaa platform:bbb",
                        "time_in_nanos": 329042,
                        "breakdown": {
                          .....
                          "build_scorer": 277752
                        },
                        "children": [
                          {
                            "type": "TermQuery",
                            "description": "platform:aaa",
                            "time_in_nanos": 62446,
                            "breakdown": {
                              .....
                              "build_scorer": 37931
                            }
                          },
                          {
                            "type": "TermQuery",
                            "description": "platform:bbb",
                            "time_in_nanos": 15093,
                            "breakdown": {
                              .....
                              "build_scorer": 6981
                            }
                          }
                        ]
                      }
                    ]
                  },
                  {
                    "type": "PointInSetQuery",
                    "description": "pId:{1 2}",
                    "time_in_nanos": 194164297,
                    "breakdown": {
                      ....
                      "build_scorer": 194160452
                    }
                  }
                ]
              }
            ],
            "rewrite_time": 40044,
            "collector": [
              {
                "name": "SimpleFieldCollector",
                "reason": "search_top_hits",
                "time_in_nanos": 144012
              }
            ]
          }
        ]

4.单个的profile无法说明问题,进一步排查:使用arthas工具获取一段时间内的火焰图

3-火焰图.png

可以看到主要就是BKD数据结构占用的CPU。

5.参考官方论坛相似问题:https://discuss.elastic.co/t/very-slow-search-performance-after-upgrade-to-7-16-1/296152/3

6.integer类型的terms查询性能较差,看起来官方描述的BKD相关优化指的是range

7.测试验证,将字段改成keyword,查看结果,CPU查询耗时恢复到正常范围

4-结果.png

5-结果-time.png

收起阅读 »

API 网关 Apache APISIX 集成 Elasticsearch 实现实时日志监控

本文将为你介绍 Apache APISIX 的 elasticsearch-logger 插件的相关信息,以及如何通过此插件获取 APISIX 的实时日志。

背景信息

Apache APISIX 是一个动态、实时、高性能的 API 网关,提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。作为 API 网关,Apache APISIX 不仅拥有丰富的插件,而且支持插件的热加载。

Elasticsearch 是一个基于 Lucene 库的搜索引擎。它提供了分布式、RESTful 风格的搜索和数据分析引擎,具有可扩展性、可分布式部署和可进行相关度搜索等特点,能够解决不断涌现出的各种用例。同时还可以集中存储用户数据,帮助用户发现意料之中以及意料之外的情况。

插件介绍

APISIXHTTP 请求的方式向 Elasticsearch 发送 APISIXRuntime 日志。插件 elasticsearch-logger 采用 bulk 的格式进行日志上报,这允许 APISIX 可以将多条日志合并后再进行上报,这使得 APISIX 在对 Elasticsearch 进行日志上报方面更加灵活并且具有较好的性能。你可以参考文档 APISIX 批处理器 对日志合进行更加细致的配置。

配置步骤

首先,你需要安装完成 APISIX,本文所有步骤基于 Centos 7.5 系统进行。详细的安装步骤参考 APISIX 安装指南

步骤1:启动 Elasticsearch

本示例只演示了通过 docker-compose 启动 Elasticsearch 单节点的方式,其它启动方式可参考 Elasticsearch 官方文档

# 使用 docker-compose 启动 1 个 Elasticsearch 节点, 1 个 kibana
version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.17.1
    container_name: elasticsearch
    environment:
      ES_JAVA_OPTS: -Xms512m -Xmx512m
      discovery.type: single-node
      xpack.security.enabled: 'false'
    networks:
      - es-net
    ports:
      - "9200:9200"
      - "9300:9300"

  kibana:
    image: docker.elastic.co/kibana/kibana:7.17.1
    container_name: kibana
    environment:
      ELASTICSEARCH_HOSTS: http://elasticsearch:9200
      I18N_LOCALE: zh-CN
    networks:
      - es-net
    depends_on:
      - elasticsearch
    ports:
      - "5601:5601"

networks:
  es-net:
    driver: bridge

步骤2:创建路由并配置插件

APISIX 默认配置文件中已启用 elasticsearch-logger 插件,所以你只需要通过下方命令创建路由并配置 elasticsearch-logger 插件就可以在 APISIX 中正常使用了。

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "plugins":{
        "elasticsearch-logger":{
            "endpoint_addr":"http://127.0.0.1:9200",
            "field":{
                "index":"services",
                "type":"collector"
            },
            "ssl_verify":false,
            "retry_delay":1,
            "buffer_duration":60,
            "max_retry_count":0,
            "batch_max_size":1000,
            "inactive_timeout":5,
            "name":"elasticsearch-logger"
        }
    },
    "upstream":{
        "type":"roundrobin",
        "nodes":{
            "127.0.0.1:1980":1
        }
    },
    "uri":"/elasticsearch.do"
}'

上述代码中配置了 Elasticsearch 地址、目标 field,用户名与密码。

通过上述设置,就可以实现将 /elasticsearch.do 路径的 API 请求日志发送至 Elasticsearch 的功能。

步骤3:发送请求

接下来我们通过 API 发送一些请求。

curl -i http://127.0.0.1:9080/elasticsearch.do\?q\=hello
HTTP/1.1 200 OK
...
hello, world

此时你可以登录 Kibana 控制台检索查看相关日志:

index

自定义日志结构

当然,在使用过程中我们也可以通过 elasticsearch-logger 插件提供的元数据配置,来设置发送至 Elasticsearch 的日志数据结构。通过设置 log_format 数据,可以控制发送的数据类型。

比如以下数据中的 $host$time_iso8601 等,都是来自于 NGINX 提供的内置变量;也支持如 $route_id$service_idApache APISIX 提供的变量配置。

curl http://127.0.0.1:9180/apisix/admin/plugin_metadata/elasticsearch-logger \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "log_format": {
        "host": "$host",
        "@timestamp": "$time_iso8601",
        "client_ip": "$remote_addr"
    }
}'

通过发送请求进行简单测试,可以看到上述日志结构设置已生效。目前 Apache APISIX 提供多种日志格式模板,在配置上具有极大的灵活性,更多日志格式细节可参考 Apache APISIX 官方文档

此时你可以登录 Kibana 控制台检索查看相关自定义日志:

如需关闭自定义日志结构,可参考下方操作。

curl http://127.0.0.1:9180/apisix/admin/plugin_metadata/elasticsearch-logger \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X DELETE

此时,插件 elasticsearch-logger 将使用默认格式上报日志。

关闭插件

如使用完毕,只需移除路由配置中 elasticsearch-logger 插件相关的配置并保存,即可关闭路由上的插件。得益于 Apache APISIX 的动态化优势,开启和关闭插件的过程都不需要重启 Apache APISIX

curl http://127.0.0.1:9080/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "methods": ["GET"],
    "uri": "/hello",
    "plugins": {},
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:1980": 1
        }
    }
}'

总结

本文为大家介绍了关于 elasticsearch-logger 插件的功能与使用步骤,更多关于 elasticsearch-logger 插件说明和完整配置列表,可以参考官方文档。

也欢迎随时在 GitHub Discussions 中发起讨论,或通过邮件列表进行交流。

继续阅读 »

本文将为你介绍 Apache APISIX 的 elasticsearch-logger 插件的相关信息,以及如何通过此插件获取 APISIX 的实时日志。

背景信息

Apache APISIX 是一个动态、实时、高性能的 API 网关,提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。作为 API 网关,Apache APISIX 不仅拥有丰富的插件,而且支持插件的热加载。

Elasticsearch 是一个基于 Lucene 库的搜索引擎。它提供了分布式、RESTful 风格的搜索和数据分析引擎,具有可扩展性、可分布式部署和可进行相关度搜索等特点,能够解决不断涌现出的各种用例。同时还可以集中存储用户数据,帮助用户发现意料之中以及意料之外的情况。

插件介绍

APISIXHTTP 请求的方式向 Elasticsearch 发送 APISIXRuntime 日志。插件 elasticsearch-logger 采用 bulk 的格式进行日志上报,这允许 APISIX 可以将多条日志合并后再进行上报,这使得 APISIX 在对 Elasticsearch 进行日志上报方面更加灵活并且具有较好的性能。你可以参考文档 APISIX 批处理器 对日志合进行更加细致的配置。

配置步骤

首先,你需要安装完成 APISIX,本文所有步骤基于 Centos 7.5 系统进行。详细的安装步骤参考 APISIX 安装指南

步骤1:启动 Elasticsearch

本示例只演示了通过 docker-compose 启动 Elasticsearch 单节点的方式,其它启动方式可参考 Elasticsearch 官方文档

# 使用 docker-compose 启动 1 个 Elasticsearch 节点, 1 个 kibana
version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.17.1
    container_name: elasticsearch
    environment:
      ES_JAVA_OPTS: -Xms512m -Xmx512m
      discovery.type: single-node
      xpack.security.enabled: 'false'
    networks:
      - es-net
    ports:
      - "9200:9200"
      - "9300:9300"

  kibana:
    image: docker.elastic.co/kibana/kibana:7.17.1
    container_name: kibana
    environment:
      ELASTICSEARCH_HOSTS: http://elasticsearch:9200
      I18N_LOCALE: zh-CN
    networks:
      - es-net
    depends_on:
      - elasticsearch
    ports:
      - "5601:5601"

networks:
  es-net:
    driver: bridge

步骤2:创建路由并配置插件

APISIX 默认配置文件中已启用 elasticsearch-logger 插件,所以你只需要通过下方命令创建路由并配置 elasticsearch-logger 插件就可以在 APISIX 中正常使用了。

curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "plugins":{
        "elasticsearch-logger":{
            "endpoint_addr":"http://127.0.0.1:9200",
            "field":{
                "index":"services",
                "type":"collector"
            },
            "ssl_verify":false,
            "retry_delay":1,
            "buffer_duration":60,
            "max_retry_count":0,
            "batch_max_size":1000,
            "inactive_timeout":5,
            "name":"elasticsearch-logger"
        }
    },
    "upstream":{
        "type":"roundrobin",
        "nodes":{
            "127.0.0.1:1980":1
        }
    },
    "uri":"/elasticsearch.do"
}'

上述代码中配置了 Elasticsearch 地址、目标 field,用户名与密码。

通过上述设置,就可以实现将 /elasticsearch.do 路径的 API 请求日志发送至 Elasticsearch 的功能。

步骤3:发送请求

接下来我们通过 API 发送一些请求。

curl -i http://127.0.0.1:9080/elasticsearch.do\?q\=hello
HTTP/1.1 200 OK
...
hello, world

此时你可以登录 Kibana 控制台检索查看相关日志:

index

自定义日志结构

当然,在使用过程中我们也可以通过 elasticsearch-logger 插件提供的元数据配置,来设置发送至 Elasticsearch 的日志数据结构。通过设置 log_format 数据,可以控制发送的数据类型。

比如以下数据中的 $host$time_iso8601 等,都是来自于 NGINX 提供的内置变量;也支持如 $route_id$service_idApache APISIX 提供的变量配置。

curl http://127.0.0.1:9180/apisix/admin/plugin_metadata/elasticsearch-logger \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "log_format": {
        "host": "$host",
        "@timestamp": "$time_iso8601",
        "client_ip": "$remote_addr"
    }
}'

通过发送请求进行简单测试,可以看到上述日志结构设置已生效。目前 Apache APISIX 提供多种日志格式模板,在配置上具有极大的灵活性,更多日志格式细节可参考 Apache APISIX 官方文档

此时你可以登录 Kibana 控制台检索查看相关自定义日志:

如需关闭自定义日志结构,可参考下方操作。

curl http://127.0.0.1:9180/apisix/admin/plugin_metadata/elasticsearch-logger \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X DELETE

此时,插件 elasticsearch-logger 将使用默认格式上报日志。

关闭插件

如使用完毕,只需移除路由配置中 elasticsearch-logger 插件相关的配置并保存,即可关闭路由上的插件。得益于 Apache APISIX 的动态化优势,开启和关闭插件的过程都不需要重启 Apache APISIX

curl http://127.0.0.1:9080/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "methods": ["GET"],
    "uri": "/hello",
    "plugins": {},
    "upstream": {
        "type": "roundrobin",
        "nodes": {
            "127.0.0.1:1980": 1
        }
    }
}'

总结

本文为大家介绍了关于 elasticsearch-logger 插件的功能与使用步骤,更多关于 elasticsearch-logger 插件说明和完整配置列表,可以参考官方文档。

也欢迎随时在 GitHub Discussions 中发起讨论,或通过邮件列表进行交流。

收起阅读 »

Observability:使用 Elastic Agent 来进行 Uptime 监控

在 Elastic Stack 7.x 中,Elastic 引入 Heartbeat 来对网站或微服务来进行监控。通过 Heartbeat 的应用,我们可以知道网站及微服务的运行情况,我们甚至可以针对服务器的证书的有效期进行监控。随着 Elastic Agent 的推出,Elastic 更建议我们使用 Elastic Agent 的方法来对网站及微服务来进行监控。为了大家能对 Heartbeat 及 Elastic Agent 有更多的认识和了解,请参阅我之前的文章:

Beats:使用 Heartbeat 进行 Uptime 监控

Observability:使用 Elastic Agent 来摄入日志及指标 - Elastic Stack 8.0

Observability:如何使用 Elastic Agents 把微服务的数据摄入到 Elasticsearch 中

1.png

 
更多阅读,请参阅 https://elasticstack.blog.csdn ... 29912
继续阅读 »
在 Elastic Stack 7.x 中,Elastic 引入 Heartbeat 来对网站或微服务来进行监控。通过 Heartbeat 的应用,我们可以知道网站及微服务的运行情况,我们甚至可以针对服务器的证书的有效期进行监控。随着 Elastic Agent 的推出,Elastic 更建议我们使用 Elastic Agent 的方法来对网站及微服务来进行监控。为了大家能对 Heartbeat 及 Elastic Agent 有更多的认识和了解,请参阅我之前的文章:

Beats:使用 Heartbeat 进行 Uptime 监控

Observability:使用 Elastic Agent 来摄入日志及指标 - Elastic Stack 8.0

Observability:如何使用 Elastic Agents 把微服务的数据摄入到 Elasticsearch 中

1.png

 
更多阅读,请参阅 https://elasticstack.blog.csdn ... 29912 收起阅读 »

Elasticsearch:如何在不更新证书的情况下为集群之间建立互信

我们知道,建立集群之间的互信非常重要。这个是为我们进行 CCR 及 CCS 操作的基础。只有建立好了集群之间的互信,我们才可以创建集群之间的 remote connection。特别是针对含有 SSL 连接的集群,他们含有各自的证书,那么我们该如何建立集群之间的互信呢?在我之前的文章 “Elasticsearch:如何为 CCR 及 CCS 建立带有安全的集群之间的互信” 中,我详述了如何通过更新证书来建立集群之间的互信。更新证书在很多的情况下,可能并不是最好的途径。在今天的文章中,我将详述如何在不更新证书的情况下,为集群之间建立互信。

在今天的展示中,我将使用如下的架构:

trust.png



如上所示,我们创建两个不同的集群。它们分别运行于两个不同的机器上。它们使用不同的 IP 地址。我将使用最新的 Elastic Stack 8.4.1 来进行展示。


如何在不更新证书的情况下为集群之间建立互信

针对非 keystore 及 truststore 的安装
如果你的 Elasticsearch 的部署不是按照 keystore 及 truststore 来进行安装的,而是参照我之前的文章 “Security:如何安装 Elastic SIEM 和 EDR” 来进行安装的话,那么你可以直接把另外一个集群的证书添加到相应的 config/elasticsearch.yml 的配置中去即可:

config/elasticsearch.yml

xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.key: /etc/elasticsearch/certs/elasticsearch.key
xpack.security.transport.ssl.certificate: /etc/elasticsearch/certs/elasticsearch.crt
xpack.security.transport.ssl.certificate_authorities: [ "/etc/elasticsearch/certs/ca/ca.crt", "certificate_from_another_cluster.crt ]
在这种情况下的配置就非常简单明了。我们就不赘述了。
 
更多阅读,请参阅 https://elasticstack.blog.csdn ... 26063
 
继续阅读 »
我们知道,建立集群之间的互信非常重要。这个是为我们进行 CCR 及 CCS 操作的基础。只有建立好了集群之间的互信,我们才可以创建集群之间的 remote connection。特别是针对含有 SSL 连接的集群,他们含有各自的证书,那么我们该如何建立集群之间的互信呢?在我之前的文章 “Elasticsearch:如何为 CCR 及 CCS 建立带有安全的集群之间的互信” 中,我详述了如何通过更新证书来建立集群之间的互信。更新证书在很多的情况下,可能并不是最好的途径。在今天的文章中,我将详述如何在不更新证书的情况下,为集群之间建立互信。

在今天的展示中,我将使用如下的架构:

trust.png



如上所示,我们创建两个不同的集群。它们分别运行于两个不同的机器上。它们使用不同的 IP 地址。我将使用最新的 Elastic Stack 8.4.1 来进行展示。


如何在不更新证书的情况下为集群之间建立互信

针对非 keystore 及 truststore 的安装
如果你的 Elasticsearch 的部署不是按照 keystore 及 truststore 来进行安装的,而是参照我之前的文章 “Security:如何安装 Elastic SIEM 和 EDR” 来进行安装的话,那么你可以直接把另外一个集群的证书添加到相应的 config/elasticsearch.yml 的配置中去即可:

config/elasticsearch.yml

xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.key: /etc/elasticsearch/certs/elasticsearch.key
xpack.security.transport.ssl.certificate: /etc/elasticsearch/certs/elasticsearch.crt
xpack.security.transport.ssl.certificate_authorities: [ "/etc/elasticsearch/certs/ca/ca.crt", "certificate_from_another_cluster.crt ]
在这种情况下的配置就非常简单明了。我们就不赘述了。
 
更多阅读,请参阅 https://elasticstack.blog.csdn ... 26063
  收起阅读 »

《Elastic Stack 实战手册》 介绍及下载

本书由数十位 Elasticsearch 技术圈的优秀开发者共创而成,得到了许多资深业界精英,社区技术大咖,Elastic Stack 相关书籍作者的支持,凝聚了众多创作人的实践经验和创作能力。 书籍涵盖了一位 Elastic Stack 开发者所需的必要知识,尤其对于刚入门的开发者,从上篇基础的 Elastic Stack 产品能力到下篇的应用实践,提供了系统性学习参考的上手指南。

Elasticsearch 无疑是大数据搜索引擎中的王者,它以其开放及免费、易用、多语言接口、卓越性能及不断创新的优势,被许多 IT 企业所采用。当今的许多IT 企业很难绕过它。在中国,Elastic Stack 有一个很强大的生态圈。在本书的创作过程中,我非常高兴看到有数十位志愿者参与到本书的创作中。这本书集众技术大咖及专家们的无私奉献,是他们牺牲了自己宝贵的时间,利用业余时间共创完成,在一遍遍的修改中把内容做得更完善。在这里衷心感谢他们的无私付出和合作。

写书和做社区贡献,是需要情怀的。我一直坚信帮助别人,也会成就自己。分享自己的知识,也是一件很快乐的事,因为这样可以证明自己的人生价值。我有超过16 年的社区参与经历,也非常喜欢分享我学到的知识。从加入Elastic 公司以来,我在CSDN 上已经发表了将近660 篇关于Elastic Stack 方面的文章,涵盖了Elastic Stack 方方面面的知识。

作为本书主编,我投入了很多时间来策划、创作、校正及阅读这本书,尽力保证本书的完整性、正确性、一致性及每篇文章的独立性。尽管如此,里面可能有不尽之处,希望读者们海涵!这本书涵盖了Elastic Stack 的介绍、安装、实操、产品能力、方案及案例,特别适合初学者,

对有经验的开发者来说也是一本难得的参考书。在未来,希望有更多的开发者分享自己的知识,

让我们一起把Elastic 社区做得更好!

我强烈推荐想学 Elastic Stack 技术的开发者,下载这本书作为参考。下载连接为 Elastic Stack 实战手册-藏经阁-阿里云开发者社区 https://developer.aliyun.com/ebook/7687
 
https://elasticstack.blog.csdn ... 01982
 

alibaba_book.png

 
 
继续阅读 »
本书由数十位 Elasticsearch 技术圈的优秀开发者共创而成,得到了许多资深业界精英,社区技术大咖,Elastic Stack 相关书籍作者的支持,凝聚了众多创作人的实践经验和创作能力。 书籍涵盖了一位 Elastic Stack 开发者所需的必要知识,尤其对于刚入门的开发者,从上篇基础的 Elastic Stack 产品能力到下篇的应用实践,提供了系统性学习参考的上手指南。

Elasticsearch 无疑是大数据搜索引擎中的王者,它以其开放及免费、易用、多语言接口、卓越性能及不断创新的优势,被许多 IT 企业所采用。当今的许多IT 企业很难绕过它。在中国,Elastic Stack 有一个很强大的生态圈。在本书的创作过程中,我非常高兴看到有数十位志愿者参与到本书的创作中。这本书集众技术大咖及专家们的无私奉献,是他们牺牲了自己宝贵的时间,利用业余时间共创完成,在一遍遍的修改中把内容做得更完善。在这里衷心感谢他们的无私付出和合作。

写书和做社区贡献,是需要情怀的。我一直坚信帮助别人,也会成就自己。分享自己的知识,也是一件很快乐的事,因为这样可以证明自己的人生价值。我有超过16 年的社区参与经历,也非常喜欢分享我学到的知识。从加入Elastic 公司以来,我在CSDN 上已经发表了将近660 篇关于Elastic Stack 方面的文章,涵盖了Elastic Stack 方方面面的知识。

作为本书主编,我投入了很多时间来策划、创作、校正及阅读这本书,尽力保证本书的完整性、正确性、一致性及每篇文章的独立性。尽管如此,里面可能有不尽之处,希望读者们海涵!这本书涵盖了Elastic Stack 的介绍、安装、实操、产品能力、方案及案例,特别适合初学者,

对有经验的开发者来说也是一本难得的参考书。在未来,希望有更多的开发者分享自己的知识,

让我们一起把Elastic 社区做得更好!

我强烈推荐想学 Elastic Stack 技术的开发者,下载这本书作为参考。下载连接为 Elastic Stack 实战手册-藏经阁-阿里云开发者社区 https://developer.aliyun.com/ebook/7687
 
https://elasticstack.blog.csdn ... 01982
 

alibaba_book.png

 
  收起阅读 »

Elasticsearch:Apache spark 大数据集成

Elasticsearch 已成为大数据架构中的常用组件,因为它提供了以下几个特性:

它使你可以快速搜索大量数据。
对于常见的聚合操作,它提供对大数据的实时分析。
使用 Elasticsearch 聚合比使用 Spark 聚合更容易。
如果你需要转向快速数据解决方案,在查询后从文档子集开始比对所有数据进行全面重新扫描要快。
用于处理数据的最常见的大数据软件现在是 Apache Spark (http://spark.apache.org/),它被认为是过时的 Hadoop MapReduce 的演变,用于将处理从磁盘移动到内存。
在本中,我们将看到如何将 Elasticsearch 集成到 Spark 中,用于写入和读取数据。 最后,我们将看到如何使用 Apache Pig 以一种简单的方式在Elasticsearch 中写入数据。

https://elasticstack.blog.csdn ... 68453
继续阅读 »
Elasticsearch 已成为大数据架构中的常用组件,因为它提供了以下几个特性:

它使你可以快速搜索大量数据。
对于常见的聚合操作,它提供对大数据的实时分析。
使用 Elasticsearch 聚合比使用 Spark 聚合更容易。
如果你需要转向快速数据解决方案,在查询后从文档子集开始比对所有数据进行全面重新扫描要快。
用于处理数据的最常见的大数据软件现在是 Apache Spark (http://spark.apache.org/),它被认为是过时的 Hadoop MapReduce 的演变,用于将处理从磁盘移动到内存。
在本中,我们将看到如何将 Elasticsearch 集成到 Spark 中,用于写入和读取数据。 最后,我们将看到如何使用 Apache Pig 以一种简单的方式在Elasticsearch 中写入数据。

https://elasticstack.blog.csdn ... 68453 收起阅读 »

一个迷惑性很高的生产故障-Elasticsearch日志rotate导致节点CPU激增

背景

Elasticsearch CPU很高的场景很常见,优化读写以及扩容即可解决问题。

如果只有一个节点CPU高,那可能的情况就比较多了,节点机器异常?读写不均匀?GC过高?forcemerge?

这里描述一个极具迷惑性的case。

问题

收到用户报障碍,突然有写入被reject,并且有一个节点的CPU突然增高。

zmccc1.png

分析、验证与结论

1.常用套路,先大致了解集群、索引。

集群层面:6.8.5 版本,18个节点(冷热分离)

索引层面:近3000个索引,大多数小索引(mb、1~10gb级别),template(设置1主分片、1副本分片)

用户行为:写多读少的OLAP场景

2.检查节点(pod)监控、宿主机监控、ES集群监控。没有很明显的异常行为。只能观测到异常节点CPU高、出现reject。用户的读写流量也没有观测到明显变化。

3.集群GC、merge等行为都很正常,并且只有一个节点CPU高(刚好用户索引都是1主1副),开始认为和热点相关。可能是某个索引的读写导致了节点CPU的上升。

4.使用 GET _nodes/hot_threads 查看CPU使用情况,果然抓到了异常节点占用CPU的主要是 write 线程。

5.由于hot_threads只能抓取瞬时的数据,不一定准确。准备进入容器,使用arthas工具抓取perf信息(arthas是阿里的开源工具、已经被我们集成到ES镜像里)。

通过arthas简要的获取热点线程:可以看到主要是write线程在执行bulk请求,然后还有日志打印的堆栈。

zmcccc2.png

继续抓取2min内的统计信息:可以看到主要是search在使用CPU。和之前获取的信息不符。

zmccc3.pg_.png

6.分析到底是读还是写影响的CPU。

a.如果是写热点导致,应该会有2个节点CPU高;

b.写入一般很难长时间打高CPU,而一个拉全量/大量数据的大请求很可能拉高CPU,由于index设置1主1副本,刚好可以解释只有一个节点CPU高;

c.考虑到抓取的数据perf结果,2min内的抓取结果比瞬时的可信;

综合来看,大查询导致的CPU高的概率很大。

7.继续走排障流程,查看日志信息

看到异常节点日志里大多都是这类异常。

elasticsearch org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to stream /usr/share/elasticsearch/logs/e100024741.log org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to stream....

由于节点已经跑了很长时间,log盘写满也是有可能的,而且不太可能瞬间拉高CPU,暂时忽略。

8.进一步验证,将异常节点重启。

果然异常节点CPU下去了,另一个节点CPU起来了,进一步证明了是查询导致的,1主1副的case下,一个节点挂了,另一个承载流量。

zmccc4.png

继续观察异常节点的流量:outgoing的流量比较高,又进一步佐证了是查询带来的异常。

zmccc5.png

继续查看IO,write/read都相对比较高。

9.考虑到查询无法被阻断、且该节点异常带来的影响并不大,准备等“拉数据的大请求”执行完毕自动恢复。

10.开始关注其他问题。等待一段时间,发现依然没有恢复,且CPU完全没有下降的趋势。考虑到一个大请求不会执行这么长时间,如果多个大请求,至少reject、cpu曲线会有些波动,不会如此稳定。准备继续排查。再次执行多次hot_thread API,依然有很多次都只抓到了write线程占用大量CPU,如果大请求存在,不会一直抓不到search请求。

11.考虑其他思路。找到重启前异常节点和重启异常节点后才异常的节点共有的index(互为主备),在众多index中发现了一个较大的index(800G)。看了下文档数:2147483519,至此,找到了问题的答案。

12.结论:使用了同一template的大量索引(1 primary 1 replica),存在一个index写了大量doc数,超过了lucene的最大限制(integer的最大值),疯狂报错reject,并且记录大量异常日志,日志不断的rotate、清理造成了CPU的大幅上升。

仔细检查异常开始时间节点的日志,可以发现如下异常信息:

[2022-07-22T12:00:36,376][DEBUG][o.e.a.b.TransportShardBulkAction] [e100024741-es-default-1][cp0006014_2022_07][0] failed to execute bulk item (index) index {[cp0006014_2022_07][event_cp][Ir_HJYIBi3-VIQ2V8GIT], source[{"rowkey":"fff5e48f-13d9-4f68-b9c9-8cfc1f0fefa3","column01":"BatchValidateRecevieCouponRealTime","column02":"1","column03":"289358095","column04":"100009826","column05":"nkryj","column06":"32001052810269459246","column08":"fff5e48f-13d9-4f68-b9c9-8cfc1f0fefa3","column09":"[34m~L[34m~A34m~O~Q34m~H[34m~D34m| "column11":"2022-07-22 20:00:29.703","column12":"1","column20":"0","datachangelasttime":1658491229707,"rules":[],"rulesh":[],"scenes":[]}]}
java.lang.IllegalArgumentException: number of documents in the index cannot exceed 2147483519
        at org.apache.lucene.index.DocumentsWriterPerThread.reserveOneDoc(DocumentsWriterPerThread.java:226) ~[lucene-core-7.7.2.jar:7.7.2 d4c30fc2856154f2c1fefc589eb7cd070a415b94 - janhoy - 2019-05-28 23:30:25]
        at org.apache.lucene.index.DocumentsWriterPerThread.updateDocument(DocumentsWriterPerThread.java:235) ~[lucene-core-7.7.2.jar:7.7.2 d4c30fc2856154f2c1fefc589eb7cd070a415b94 - janhoy - 2019-05-28 23:30:25]
        at org.apache.lucene.index.DocumentsWriter.updateDocument(DocumentsWriter.java:494) ~[lucene-core-7.7.2.jar:7.7.2 d4c30fc2856154f2c1fefc589eb7cd070a415b94 - janhoy - 2019-05-28 23:30:25]
        at org.apache.lucene.index.IndexWriter.updateDocument(IndexWriter.java:1616) ~[lucene-core-7.7.2.jar:7.7.2 d4c30fc2856154f2c1fefc589eb7cd070a415b94 - janhoy - 2019-05-28 23:30:25]
        at org.apache.lucene.index.IndexWriter.addDocument(IndexWriter.java:1235) ~[lucene-core-7.7.2.jar:7.7.2 d4c30fc2856154f2c1fefc589eb7cd070a415b94 - janhoy - 2019-05-28 23:30:25]
        at org.elasticsearch.index.engine.InternalEngine.addDocs(InternalEngine.java:1175) ~[elasticsearch-6.8.5.jar:6.8.5]
        at org.elasticsearch.index.engine.InternalEngine.indexIntoLucene(InternalEngine.java:1120) ~[elasticsearch-6.8.5.jar:6.8.5]

进一步验证:进入容器清理日志文件,会立刻生成并rotate出多个日志文件。

最终处理:清理掉异常索引立刻恢复正常:

zmccc6.png

解释前面的坑

1.arthas采集2min内的CPU信息,得到的search结论是正确的,该集群确实存在search大请求。虽然频率不高,但是采集到的概率很大。

zmccc7.png

2.异常节点的out流量很大。这个逻辑也是正确的,只是并不是导致异常的根本原因。

确实有拉数据的请求存在;节点存在大量索引的分片,无法确认流量来源是否是其他index;该异常情况下用户收到异常ack之后会有重试,影响到流量的统计。

zmccc8.pnng_.png

3.重启后另一个节点CPU就开始激增,是因为副本分片成为了主分片,然后开始reject,并疯狂打印日志、进行rotate和清理。

4.为什么只有一个节点CPU高。写入流程是主分片写入成功后,异步转发请求给所有副本(此处只有1),由于主分片写入失败,直接异常,副本也就不会受到影响。

思考

1.经验流大多情况有效,有时却不可取。时刻根据事实排障,避免先入为主。

2.相似的现象以及采集排障数据的巧合进入思维误区,集群业务复杂度增加了排障难度:

大量的日志难以查找(被AppenderLoggingException淹没),且都被判定为和本次异常无关,如 bulk reject 被认为是CPU高的场景下正常的表现,AppenderLoggingException 被认为无法快速消耗CPU,number of documents in the index cannot exceed 2147483519 刚看到时也被认为无法导致CPU增高(仅仅是无法写入);

index太多,无法从单个index层面获取更多信息。(没有明确目标的情况下难以发现那一个异常index)。

3.arthas write线程的堆栈信息中有体现,bulk之后就在打印日志,这两点之间的关联被忽略。

4.优化方向:需要更细粒度的监控和巡检能力,快速发现异常index可大大加快排障进程,不再强依赖OPS的知识体系与推理。

继续阅读 »

背景

Elasticsearch CPU很高的场景很常见,优化读写以及扩容即可解决问题。

如果只有一个节点CPU高,那可能的情况就比较多了,节点机器异常?读写不均匀?GC过高?forcemerge?

这里描述一个极具迷惑性的case。

问题

收到用户报障碍,突然有写入被reject,并且有一个节点的CPU突然增高。

zmccc1.png

分析、验证与结论

1.常用套路,先大致了解集群、索引。

集群层面:6.8.5 版本,18个节点(冷热分离)

索引层面:近3000个索引,大多数小索引(mb、1~10gb级别),template(设置1主分片、1副本分片)

用户行为:写多读少的OLAP场景

2.检查节点(pod)监控、宿主机监控、ES集群监控。没有很明显的异常行为。只能观测到异常节点CPU高、出现reject。用户的读写流量也没有观测到明显变化。

3.集群GC、merge等行为都很正常,并且只有一个节点CPU高(刚好用户索引都是1主1副),开始认为和热点相关。可能是某个索引的读写导致了节点CPU的上升。

4.使用 GET _nodes/hot_threads 查看CPU使用情况,果然抓到了异常节点占用CPU的主要是 write 线程。

5.由于hot_threads只能抓取瞬时的数据,不一定准确。准备进入容器,使用arthas工具抓取perf信息(arthas是阿里的开源工具、已经被我们集成到ES镜像里)。

通过arthas简要的获取热点线程:可以看到主要是write线程在执行bulk请求,然后还有日志打印的堆栈。

zmcccc2.png

继续抓取2min内的统计信息:可以看到主要是search在使用CPU。和之前获取的信息不符。

zmccc3.pg_.png

6.分析到底是读还是写影响的CPU。

a.如果是写热点导致,应该会有2个节点CPU高;

b.写入一般很难长时间打高CPU,而一个拉全量/大量数据的大请求很可能拉高CPU,由于index设置1主1副本,刚好可以解释只有一个节点CPU高;

c.考虑到抓取的数据perf结果,2min内的抓取结果比瞬时的可信;

综合来看,大查询导致的CPU高的概率很大。

7.继续走排障流程,查看日志信息

看到异常节点日志里大多都是这类异常。

elasticsearch org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to stream /usr/share/elasticsearch/logs/e100024741.log org.apache.logging.log4j.core.appender.AppenderLoggingException: Error writing to stream....

由于节点已经跑了很长时间,log盘写满也是有可能的,而且不太可能瞬间拉高CPU,暂时忽略。

8.进一步验证,将异常节点重启。

果然异常节点CPU下去了,另一个节点CPU起来了,进一步证明了是查询导致的,1主1副的case下,一个节点挂了,另一个承载流量。

zmccc4.png

继续观察异常节点的流量:outgoing的流量比较高,又进一步佐证了是查询带来的异常。

zmccc5.png

继续查看IO,write/read都相对比较高。

9.考虑到查询无法被阻断、且该节点异常带来的影响并不大,准备等“拉数据的大请求”执行完毕自动恢复。

10.开始关注其他问题。等待一段时间,发现依然没有恢复,且CPU完全没有下降的趋势。考虑到一个大请求不会执行这么长时间,如果多个大请求,至少reject、cpu曲线会有些波动,不会如此稳定。准备继续排查。再次执行多次hot_thread API,依然有很多次都只抓到了write线程占用大量CPU,如果大请求存在,不会一直抓不到search请求。

11.考虑其他思路。找到重启前异常节点和重启异常节点后才异常的节点共有的index(互为主备),在众多index中发现了一个较大的index(800G)。看了下文档数:2147483519,至此,找到了问题的答案。

12.结论:使用了同一template的大量索引(1 primary 1 replica),存在一个index写了大量doc数,超过了lucene的最大限制(integer的最大值),疯狂报错reject,并且记录大量异常日志,日志不断的rotate、清理造成了CPU的大幅上升。

仔细检查异常开始时间节点的日志,可以发现如下异常信息:

[2022-07-22T12:00:36,376][DEBUG][o.e.a.b.TransportShardBulkAction] [e100024741-es-default-1][cp0006014_2022_07][0] failed to execute bulk item (index) index {[cp0006014_2022_07][event_cp][Ir_HJYIBi3-VIQ2V8GIT], source[{"rowkey":"fff5e48f-13d9-4f68-b9c9-8cfc1f0fefa3","column01":"BatchValidateRecevieCouponRealTime","column02":"1","column03":"289358095","column04":"100009826","column05":"nkryj","column06":"32001052810269459246","column08":"fff5e48f-13d9-4f68-b9c9-8cfc1f0fefa3","column09":"[34m~L[34m~A34m~O~Q34m~H[34m~D34m| "column11":"2022-07-22 20:00:29.703","column12":"1","column20":"0","datachangelasttime":1658491229707,"rules":[],"rulesh":[],"scenes":[]}]}
java.lang.IllegalArgumentException: number of documents in the index cannot exceed 2147483519
        at org.apache.lucene.index.DocumentsWriterPerThread.reserveOneDoc(DocumentsWriterPerThread.java:226) ~[lucene-core-7.7.2.jar:7.7.2 d4c30fc2856154f2c1fefc589eb7cd070a415b94 - janhoy - 2019-05-28 23:30:25]
        at org.apache.lucene.index.DocumentsWriterPerThread.updateDocument(DocumentsWriterPerThread.java:235) ~[lucene-core-7.7.2.jar:7.7.2 d4c30fc2856154f2c1fefc589eb7cd070a415b94 - janhoy - 2019-05-28 23:30:25]
        at org.apache.lucene.index.DocumentsWriter.updateDocument(DocumentsWriter.java:494) ~[lucene-core-7.7.2.jar:7.7.2 d4c30fc2856154f2c1fefc589eb7cd070a415b94 - janhoy - 2019-05-28 23:30:25]
        at org.apache.lucene.index.IndexWriter.updateDocument(IndexWriter.java:1616) ~[lucene-core-7.7.2.jar:7.7.2 d4c30fc2856154f2c1fefc589eb7cd070a415b94 - janhoy - 2019-05-28 23:30:25]
        at org.apache.lucene.index.IndexWriter.addDocument(IndexWriter.java:1235) ~[lucene-core-7.7.2.jar:7.7.2 d4c30fc2856154f2c1fefc589eb7cd070a415b94 - janhoy - 2019-05-28 23:30:25]
        at org.elasticsearch.index.engine.InternalEngine.addDocs(InternalEngine.java:1175) ~[elasticsearch-6.8.5.jar:6.8.5]
        at org.elasticsearch.index.engine.InternalEngine.indexIntoLucene(InternalEngine.java:1120) ~[elasticsearch-6.8.5.jar:6.8.5]

进一步验证:进入容器清理日志文件,会立刻生成并rotate出多个日志文件。

最终处理:清理掉异常索引立刻恢复正常:

zmccc6.png

解释前面的坑

1.arthas采集2min内的CPU信息,得到的search结论是正确的,该集群确实存在search大请求。虽然频率不高,但是采集到的概率很大。

zmccc7.png

2.异常节点的out流量很大。这个逻辑也是正确的,只是并不是导致异常的根本原因。

确实有拉数据的请求存在;节点存在大量索引的分片,无法确认流量来源是否是其他index;该异常情况下用户收到异常ack之后会有重试,影响到流量的统计。

zmccc8.pnng_.png

3.重启后另一个节点CPU就开始激增,是因为副本分片成为了主分片,然后开始reject,并疯狂打印日志、进行rotate和清理。

4.为什么只有一个节点CPU高。写入流程是主分片写入成功后,异步转发请求给所有副本(此处只有1),由于主分片写入失败,直接异常,副本也就不会受到影响。

思考

1.经验流大多情况有效,有时却不可取。时刻根据事实排障,避免先入为主。

2.相似的现象以及采集排障数据的巧合进入思维误区,集群业务复杂度增加了排障难度:

大量的日志难以查找(被AppenderLoggingException淹没),且都被判定为和本次异常无关,如 bulk reject 被认为是CPU高的场景下正常的表现,AppenderLoggingException 被认为无法快速消耗CPU,number of documents in the index cannot exceed 2147483519 刚看到时也被认为无法导致CPU增高(仅仅是无法写入);

index太多,无法从单个index层面获取更多信息。(没有明确目标的情况下难以发现那一个异常index)。

3.arthas write线程的堆栈信息中有体现,bulk之后就在打印日志,这两点之间的关联被忽略。

4.优化方向:需要更细粒度的监控和巡检能力,快速发现异常index可大大加快排障进程,不再强依赖OPS的知识体系与推理。

收起阅读 »

期待已久的 Elasticserach 多集群管理平台 INFINI Console 最新的 0.3 版本正式发布!

INFINI Console v0.3 正式发布

极限实验室上新啦,期待已久的 INFINI Console 最新的 0.3 版本正式发布!

01 产品名称的变化

还记得最开始的极限数据平台么,现在已经升级成为 INFINI Console 了。

与极限实验室的其它产品保持一致,家族 Logo 一览如下:

图片

接下来,将为大家隆重介绍一下本次产品更新都有哪些亮点吧。

02 统一的监控

作为目前最方便的 Elasticsearch 管理工具,跨版本、跨集群的监控自然是必不可少的一个基础能力啦。

除了使用方便,颜值自然也是高高的,多套集群的监控终于在一起了。

INFINI Console 提供了市面上最全面的各项统计指标的监控,帮助您快速掌握集群内部运行状态,快速定位集群问题,提高诊断效率,缩短故障时间。

图片

03 统一的安全

相信您的 Elasticsearch 集群不止一个,INFINI Console v0.3 新增了平台级统一的安全管控能力。

多个集群可以统一实现基于角色的用户权限管理,数据和 UI 的权限也可以分别进行设置,可以做到不同的部门看到的集群各不一样,不同的人员看到的索引各不一样,不同的角色读写权限各不一样。

在一个平台里面统一的进行管理,再也不用割裂的维护 N 套安全配置了。

图片

04 统一的告警

平台层的监控还是空白么?还在一套集群一套集群的配置告警规则么?Elasticsearch 内的业务数据还在被动响应么?

INFINI Console v0.3 新增了强大的告警规则引擎,通过配置告警规则,将业务关注点自动化、流程化、主动化,引擎支持常见的统计函数,使用起来简单且灵活,支持 Webhook 方式灵活对接钉钉、微信、Slack 或是内部通知系统。

只要是在 Elasticsearch 的数据,都可以借助告警引擎“活”起来。

图片

05 统一的探索

还在不同 Kibana 之间来回跳转么?还在傻傻创建 IndexPattern 才能分析数据么?

拒绝复杂,回归简单,INFINI Console 新增了跨集群的数据探索功能,不需要提前创建 IndexPattern,想要探索数据一键直达,切换不同集群、切换不同索引、切换不同时间维度,都只在一步完成。

让数据分析和探索的体验尽可能简单是我们努力在做的事情。

图片

06 更多细节

当然本次更新也新增了不少细节特性和修复了不少 Bug,具体的细节请访问产品的 Release Notes 页面:

欢迎大家下载体验,下载安装及文档地址:

继续阅读 »

INFINI Console v0.3 正式发布

极限实验室上新啦,期待已久的 INFINI Console 最新的 0.3 版本正式发布!

01 产品名称的变化

还记得最开始的极限数据平台么,现在已经升级成为 INFINI Console 了。

与极限实验室的其它产品保持一致,家族 Logo 一览如下:

图片

接下来,将为大家隆重介绍一下本次产品更新都有哪些亮点吧。

02 统一的监控

作为目前最方便的 Elasticsearch 管理工具,跨版本、跨集群的监控自然是必不可少的一个基础能力啦。

除了使用方便,颜值自然也是高高的,多套集群的监控终于在一起了。

INFINI Console 提供了市面上最全面的各项统计指标的监控,帮助您快速掌握集群内部运行状态,快速定位集群问题,提高诊断效率,缩短故障时间。

图片

03 统一的安全

相信您的 Elasticsearch 集群不止一个,INFINI Console v0.3 新增了平台级统一的安全管控能力。

多个集群可以统一实现基于角色的用户权限管理,数据和 UI 的权限也可以分别进行设置,可以做到不同的部门看到的集群各不一样,不同的人员看到的索引各不一样,不同的角色读写权限各不一样。

在一个平台里面统一的进行管理,再也不用割裂的维护 N 套安全配置了。

图片

04 统一的告警

平台层的监控还是空白么?还在一套集群一套集群的配置告警规则么?Elasticsearch 内的业务数据还在被动响应么?

INFINI Console v0.3 新增了强大的告警规则引擎,通过配置告警规则,将业务关注点自动化、流程化、主动化,引擎支持常见的统计函数,使用起来简单且灵活,支持 Webhook 方式灵活对接钉钉、微信、Slack 或是内部通知系统。

只要是在 Elasticsearch 的数据,都可以借助告警引擎“活”起来。

图片

05 统一的探索

还在不同 Kibana 之间来回跳转么?还在傻傻创建 IndexPattern 才能分析数据么?

拒绝复杂,回归简单,INFINI Console 新增了跨集群的数据探索功能,不需要提前创建 IndexPattern,想要探索数据一键直达,切换不同集群、切换不同索引、切换不同时间维度,都只在一步完成。

让数据分析和探索的体验尽可能简单是我们努力在做的事情。

图片

06 更多细节

当然本次更新也新增了不少细节特性和修复了不少 Bug,具体的细节请访问产品的 Release Notes 页面:

欢迎大家下载体验,下载安装及文档地址:

收起阅读 »