关于Elastic Stack的备忘录
这篇文章是关于Elastic Stack(包括Elasticsearch、Kibana和Logstash)的How To个人备忘录。我假设安装了Elastic Stack 7.2在RHEL 7上并进行记录。
Elasticsearch 弹性搜索
从外部服务器访问Elasticsearch。
在“/etc/elasticsearch/elasticsearch.yml”文件中添加以下内容。
network.bind_host: 0
discovery.seed_hosts: ["127.0.0.1", "[::1]"]
默认情况下,将绑定到本地主机(localhost)。0等同于0.0.0.0,将绑定到所有地址。
由于更改绑定会导致discovery出错,因此还需要添加seed_hosts的配置。
将数据文件迁移
在安装了Elasticsearch的情况下,数据文件将被创建在 /var/lib/elasticsearch 目录中。
要将其移动到另一个目录,执行以下步骤。
-
- 将位于/var/lib/elasticsearch的文件打包成tar文件,然后将其移动到目标位置。
在/etc/elasticsearch/elasticsearch.yml中,将配置文件指定为目标文件。
# ----------------------------------- Paths ------------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /path/to/the/new/location
由于”路径”数据已经定义了数据文件的位置,所以将其更改为目标位置。
在Elasticsearch中显示索引的列表。
GET /_cat/indices?v
在Elasticsearch中使用N-gram。
创建索引如下:
全角半角视为同一,并且大小写视为同一。
但是,“サイド”不能通过“サイド”进行搜索,但可以通过“サイト”进行匹配。
PUT /my-index
{
"settings": {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"type": "custom",
"tokenizer": "ngram_1to2_tokenizer",
"filter": ["cjk_width", "lowercase"]
}
},
"tokenizer": {
"ngram_1to2_tokenizer": {
"type": "ngram",
"min_gram": 1,
"max_gram": 2,
"token_chars": []
}
}
}
}
}
此外,还需在字符串字段中设置分析器。
PUT /my-index/_mapping
{
"properties": {
"body": {
"type": "text",
"analyzer": "ngram_analyzer"
}
}
}
现在使用nGram,可以搜索body字段了。
如果要创建一个只包含body字段的索引,并可以使用n-gram进行搜索,可以按照以下方式进行设置。
PUT /my-index
{
"mappings" : {
"properties" : {
"body" : {
"type" : "text",
"analyzer": "ngram_analyzer"
}
}
},
"settings" : {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"type": "custom",
"tokenizer": "ngram_1to2_tokenizer",
"filter": ["cjk_width", "lowercase"]
}
},
"tokenizer": {
"ngram_1to2_tokenizer": {
"type": "ngram",
"min_gram": 1,
"max_gram": 2,
"token_chars": []
}
}
}
}
}
索引创建性能的提升
如果你需要创建大量的文件,并且不需要立即在搜索结果中反映出来,你可以通过增加刷新间隔来提高性能。默认情况下,刷新间隔是1秒钟,但你可以通过”refresh_interval”来延长。
PUT /my-index
{
"settings" : {
"index" : {
"refresh_interval" : "-1",
}
}
}
在这个例子中,我们将-1设置为自动更新无效。在这种情况下,您可以调用GET /my-index/_refresh来手动更新。
Kibana 是一种数据可视化工具。
从外部服务器访问Kibana。
将以下内容添加到/etc/kibana/kibana.yml文件中。
server.host: 0.0.0.0
默认情况下,绑定到本地主机。
日志聚合
在使用Logstash读取文件后,确保文件不会被删除。
默认情况下,文件在加载后会被删除。这是因为file_completed_action被设置为delete。要防止删除,需要将其设置为log。
input {
file {
mode => "read"
path => ["/my-file.csv"]
file_completed_action => "log"
file_completed_log_path => "/file-complete-log.log"
为了避免在Logstash读取CSV时添加多余的字段,请采取相应措施。
在读取CSV时,似乎默认会将message、host和path作为字段进行注册。如果不需要,可以使用remove_field进行配置。
filter {
csv {
remove_field => ["message","host","path"]
Python的应用程序编程接口
我想调用Python来调用Elasticsearch。
公式页面里有相关信息。指南。API参考。
原则上,
pip install elasticsearch
在这之后,
from elasticsearch import Elasticsearch
es = Elasticsearch()
可以这样做。在假设localhost上运行有服务器的情况下进行调用,所以在调用远程服务器时,应该
client = Elasticsearch(hosts='192.168.0.200:9200')
可以按照这样的方式进行指定。
从XML导入
如果要批量导入大型XML数据,可以按照以下方式进行。设置从XML生成导入数据的生成器,然后将其传递给streaming_bulk函数。
from elasticsearch import Elasticsearch
from elasticsearch.helpers import streaming_bulk
import lxml.etree as ET
def gen_data():
with open('/my/xml/file', mode='rb') as f:
context = ET.iterparse(f, events=('end',), tag='s') # to import <s> tag
for _, elem in context:
yield {'body': elem.text}
elem.clear()
for ancestor in elem.xpath('ancestor-or-self::*'):
while ancestor.getprevious() is not None:
del ancestor.getparent()[0]
del context
es = Elasticsearch(timeout=60)
for ok, action in streaming_bulk(client=es, index='my-data', actions=gen_data()):
if not ok:
print(f'error: {action}')
由于环境或数据的不同,连接服务器时可能会出现超时情况,请根据需要调整超时时间。
如果还有其他事情,我会进行补充。