Springboot 系列 (19) - Springboot+ElasticSearch 实现全文搜索(一)| 安装配置
全文检索(Full-text Search)是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。
在全文搜索的世界中,存在着几个主流工具,主要有:
(1) Apache Lucene
(2) ElasticSearch
(3) Solr
(4) Ferret
ElasticSearch (ES) 是一个分布式的 RESTful 风格的全文搜索和数据分析引擎,能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据。
ElasticSearch 建立在全文搜索引擎库 Apache Lucene 基础之上,用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单,通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。
ElasticSearch 被用作全文检索、结构化搜索、分析以及这三个功能的组合,以下是具体的应用案例:
(1) Wikipedia: 使用 ElasticSearch 提供带有高亮片段的全文搜索,还有 search-as-you-type 和 did-you-mean 的建议。
(2) 卫报: 使用 ElasticSearch 将网络社交数据结合到访客日志中,实时的给它的编辑们提供公众对于新文章的反馈。
(3) Stack Overflow: 将地理位置查询融入全文检索中去,并且使用 more-like-this 接口去查找相关的问题与答案。
(4) GitHub: 使用 ElasticSearch 对 1300 亿行代码进行查询。
ElasticSearch 的核心概念:
(1) Cluster(集群):一个集群由一个唯一的名字标志,默认为 “ElasticSearch”。集群名称非常重要,具体相同集群名的节点才会组成一个集群,集群名称可以在配置文件中指定;
(2) Node(节点):存储集群的数据,参与集群的索引和搜索功能。像集群有名字,节点也有自己的名称,默认在启动时会以一个随机的 UUID 的前七个字符作为节点的名字,可以为其指定任意的名字。通过集群名在网络中发现同伴组成集群;
(3) Index(索引):一个索引是一个文档的集合(等同于 solr 中的集合)。每个索引有唯一的名字,通过这个名字来操作它。一个集群中可以有任意多个索引;
(4) Type(类型):指在一个索引中,可以索引不同类型的文档,如用户数据、博客数据。从 6.0.0 版本起已废弃,一个索引中只存放一类数据;
(5) Document(文档):被索引的一条数据,索引的基本信息单元,以 JSON 格式来表示;
(6) Fields(字段):每个 Document 都类似一个 JSON 结构,它包含了许多字段,每个字段都有其对应的值,多个字段组成了一个 Document,可以类比关系型数据库数据表中的字段;
(7) Shard(分片):在创建一个索引时可以指定分成多少个分片来存储。每个分片本身也是一个功能完善且独立的 “索引”,可以被放置在集群的任意节点上。分片的好处:允许我们水平切分/扩展容量,可在多个分片上进行分布式的、并行的操作,提高系统的性能和吞吐量。
(8) Near Realtime(NRT,近实时):数据提交索引后,立马就可以搜索到;
ElasticSearch 和关系型数据库各重要概念具体对应关系如下表所示:
关系型数据库 (RDBMS) | EasticSearch (ES) |
Database (库) | Index(索引) |
Table(表) | Type(类型,从 6.0.0 版本起已废弃) |
Schema(结构、定义) | Mapping(映射) |
Row(数据行) | Document(文档) |
Column(数据列) | Field(字段) |
SQL(查询等语句) | DSL(查询等语句) |
ElasticSearch:https://elastic.co/downloads/elasticsearch
ElasticSearch GitHub: https://github.com/elastic/elasticsearch
1. EasticSearch 安装配置
1) Windows 10 下安装
访问 https://elastic.co/downloads/elasticsearch 下载 elasticsearch-7.10.2-windows-x86_64.zip,保存到目录 C:\Applications\Java\,解压后目录是 elasticsearch-7.10.2。
进入 C:\Applications\Java\elasticsearch-7.10.2\bin 目录,双击 elasticsearch.bat 运行,自动启动命令行控制台,显示如下:
... [2021-03-28T09:42:13,878][INFO ][o.e.x.i.a.TransportPutLifecycleAction] [CHSHL01096TKUAN] adding index lifecycle policy [watch-history-ilm-policy] [2021-03-28T09:42:14,007][INFO ][o.e.x.i.a.TransportPutLifecycleAction] [CHSHL01096TKUAN] adding index lifecycle policy [ilm-history-ilm-policy] [2021-03-28T09:42:14,116][INFO ][o.e.x.i.a.TransportPutLifecycleAction] [CHSHL01096TKUAN] adding index lifecycle policy [slm-history-ilm-policy] [2021-03-28T09:42:14,367][INFO ][o.e.l.LicenseService ] [CHSHL01096TKUAN] license [76dad8a9-b5b1-47ea-aece-fe8d22925547] mode [basic] - valid [2021-03-28T09:42:14,368][INFO ][o.e.x.s.s.SecurityStatusChangeListener] [CHSHL01096TKUAN] Active license is now [BASIC]; Security is disabled
注:运行 elasticsearch.bat 命令前,要先设置好系统的 JAVA_HOME 环境变量。
ElasticSearch 的 Web 服务默认启动绑定主机是 localhost,端口是 9200,可以在 conf\elasticsearch.yml 中修改主机和端口。
浏览器访问 http://localhost:9200,显示结果如下:
{ "name" : "CHSHL01096TKUAN", "cluster_name" : "elasticsearch", "cluster_uuid" : "QagiO3dcTBSVNYl10ibjPQ", "version" : { "number" : "7.10.2", "build_flavor" : "default", "build_type" : "zip", "build_hash" : "747e1cc71def077253878a59143c1f785afa92b9", "build_date" : "2021-01-13T00:42:12.435326Z", "build_snapshot" : false, "lucene_version" : "8.7.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
注: CHSHL01096TKUAN 是 Windows 主机的 hostname。
2) Ubuntu 20.04 下安装
$ cd ~/apps # 在 /home/xxx 目录(Linux 用户根目录)下手动创建 apps 目录
$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.2-linux-x86_64.tar.gz
$ tar -zvxf elasticsearch-7.10.2-linux-x86_64.tar.gz # 解压后目录是 elasticsearch-7.10.2
$ cd elasticsearch-7.10.2/bin
$ ./elasticsearch
...
注:运行 ./elasticsearch 命令前,要先设置好系统的 JAVA_HOME 环境变量。
# 另开一个命令行窗口(控制台),运行 curl 访问 http://localhost:9200
$ curl http://localhost:9200
{ "name" : "Ubuntu20-04", "cluster_name" : "elasticsearch", "cluster_uuid" : "H0Nlh1UiRDK-BSZokqKzdw", "version" : { "number" : "7.10.2", "build_flavor" : "default", "build_type" : "tar", "build_hash" : "747e1cc71def077253878a59143c1f785afa92b9", "build_date" : "2021-01-13T00:42:12.435326Z", "build_snapshot" : false, "lucene_version" : "8.7.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
注: Ubuntu20-04 是 Unbuntu 主机的 hostname。
2. Kibana 安装配置
Kibana 是一个开源的分析和可视化平台,Kibana 提供搜索、查看和与存储在 ElasticSearch 索引中的数据进行交互的功能。开发者或运维人员可以轻松地执行高级数据分析,并在各种图表、表格和地图中可视化数据。
Kibana:https://www.elastic.co/downloads/kibana
Kibana GitHub:https://github.com/elastic/kibana
1) Windows 10 下安装
下载 https://artifacts.elastic.co/downloads/kibana/kibana-7.10.2-windows-x86_64.zip,保存到目录 C:\Applications\Java\,解压后修改目录为 kibana-7.10.2。
进入 C:\Applications\Java\kibana-7.10.2\bin 目录,双击 kibana.bat 运行,自动启动命令行控制台,显示如下:
... log [09:56:17.150] [info][kibana-monitoring][monitoring][monitoring][plugins] Starting monitoring stats collection log [09:56:17.152] [info][plugins][watcher] Your basic license does not support watcher. Please upgrade your license. log [09:56:19.580] [info][listening] Server running at http://localhost:5601 log [09:56:24.956] [info][server][Kibana][http] http server running at http://localhost:5601 log [11:37:14.605] [error][plugins][taskManager][taskManager] [Task Poller Monitor]: Observable Monitor: Hung Observable restarted after 33000ms of inactivity
Kibana 的 Web 服务默认启动绑定主机是 localhost,端口是 5601,可以在 conf\kibana.yml 中修改主机和端口,浏览器访问 http://localhost:5601 。
2) Ubuntu 20.04 下安装
$ cd ~/apps
$ wget https://artifacts.elastic.co/downloads/kibana/kibana-7.10.2-linux-x86_64.tar.gz
$ tar -zvxf kibana-7.10.2-linux-x86_64.tar.gz # 解压后修改目录为 kibana-7.10.2
$ cd kibana-7.10.2/bin
$ ./kibana
...
在 conf\kibana.yml 中修改主机 IP 和端口,浏览器访问 http://ip:5601 。
3. Logstash 安装配置
Logstash 就像一根具备实时数据传输能力的管道,负责将数据信息从管道的输入端传输到管道的输出端;与此同时这根管道可以根据自己的需求在中间加上滤网,Logstash 提供里很多功能强大的滤网以满足你的各种应用场景。
Logstash 常用于日志关系系统中做日志采集设备,最常用于 ELK(Elasticsearch + Logstash + Kibana)中作为日志收集器使用。
Logstash 将数据流中每一条数据称之为一个 event,Logstash 的事件在处理流程中有三个主要角色:
(1) inpust:必选项,负责产生事件(Inputs generate events),常用:File、syslog、redis、beats(如:Filebeats);
(2) filters:可选选,负责数据处理与转换(filters modify them),常用:grok、mutate、drop、clone、geoip;
(3) outputs:必选项,负责数据输出(outputs ship them elsewhere),常用:elasticsearch、file、graphite、statsd。
Logstash:https://www.elastic.co/downloads/logstash
Logstash GitHub:https://github.com/elastic/logstash
1) Windows 10 下安装
下载 https://artifacts.elastic.co/downloads/logstash/logstash-7.10.2-windows-x86_64.zip,保存到目录 C:\Applications\Java\,解压后修改目录为 logstash-7.10.2。
进入 C:\Applications\Java\logstash-7.10.2\config 目录,复制 logstash-sample.conf 生成 logstash.conf 文件,修改 logstash.conf,内容如下:
input { stdin{} } output { elasticsearch { hosts => ["http://localhost:9200"] index => "stdin-%{+YYYY.MM.dd}" #user => "elastic" #password => "changeme" } }
控制台命令方式进入 C:\Applications\Java\logstash-7.10.2\bin 目录,运行如下命令:
C:\Applications\Java\logstash-7.10.2\bin>logstash -f ..\config\logstash.conf
... [2022-12-06T16:40:16,610][INFO ][logstash.javapipeline ][main] Pipeline Java execution initialization time {"seconds"=>0.67} [2022-12-06T16:40:16,651][INFO ][logstash.javapipeline ][main] Pipeline started {"pipeline.id"=>"main"} The stdin plugin is now waiting for input: [2022-12-06T16:40:16,696][INFO ][logstash.agent ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]} [2022-12-06T16:40:16,914][INFO ][logstash.agent ] Successfully started Logstash API endpoint {:port=>9600} Hello World!
我们在 logstash.conf 设置了 input 是 stdin,在控制台输入 “Hello World!”,此时 EasticSearch 的控制台也会出现如下信息:
[2022-12-06T16:41:57,351][INFO ][o.e.c.m.MetadataCreateIndexService] [CHSHL01096TKUAN] [stdin-2022.12.06] creating index, cause [auto(bulk api)], templates [], shards [1]/[1] [2022-12-06T16:41:57,890][INFO ][o.e.c.m.MetadataMappingService] [CHSHL01096TKUAN] [stdin-2022.12.06/6T0rsD94ShChX220Vt_fmA] create_mapping [_doc]
一般 EasticSearch 是在后台运行(没有控制台),可以使用 curl 或 postman 查看索引下的文档。这里的 stdin-2022.12.06 是索引(index),6T0rsD94ShChX220Vt_fmA 是索引的 uuid,使用 curl 查看方式如下:
C:\>curl -X GET "http://localhost:9200/stdin-2022.12.06/_search" --basic -u elastic:123456 -H "Content-Type:application/json" --data "{"""query""":{"""match_all""":{}}}"
{"took":4,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":1,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"stdin-2022.12.06","_type":"_doc","_id":"t9qZ5oQBJg73ZDV_T7R6","_score":1.0,"_source":{"message":"Hello world!\r","@version":"1","host":"CHSHL01096TKUAN","@timestamp":"2022-12-06T08:41:57.176Z"}}]}}
注意 Windows 下 curl 命令行 --data 参数里双引号的使用方式。
Logstash 的 Web 服务默认启动绑定主机是 localhost,端口是 9600,可以在 conf\logstash.yml 中修改主机和端口,浏览器访问 http://localhost:9600,显示内容如下:
{"host":"CHSHL01096TKUAN","version":"7.10.2","http_address":"127.0.0.1:9600","id":"19508d0a-257b-45f8-9f43-3a58f4097958","name":"CHSHL01096TKUAN","ephemeral_id":"7fae378b-6fed-463a-9643-a6c5b90aae05","status":"green","snapshot":false,"pipeline":{"workers":8,"batch_size":125,"batch_delay":50},"build_date":"2021-01-13T02:43:06Z","build_sha":"7cebafee7a073fa9d58c97de074064a540d6c317","build_snapshot":false}
2) Ubuntu 20.04 下安装
$ cd ~/apps
$ wget https://artifacts.elastic.co/downloads/logstash/logstash-7.10.2-linux-x86_64.tar.gz
$ tar -zvxf logstash-7.10.2-linux-x86_64.tar.gz # 解压后修改目录为 logstash-7.10.2
$ cd logstash-7.10.2/config
$ cp logstash-sample.conf logstash.conf
$ vim logstash.conf
input { stdin{} } output { elasticsearch { hosts => ["http://localhost:9200"] index => "stdin-%{+YYYY.MM.dd}" #user => "elastic" #password => "changeme" } }
$ cd ~/apps/logstash-7.10.2/bin
$ ./logstash -f ../config/logstash.conf
...
在 conf\logstash.yml 中修改主机 IP 和端口,浏览器访问 http://ip:9600 。
4. ElasticSearch 安全设置
ElasticSearch 7.7 以后的版本将安全认证功能已免费开放,并将 X-pack 插件集成了到了开源的 ElasticSearch 版本中,这里以 Windows 版的 ElasticSearch 为例,介绍如何利用 X-pack 给 ElasticSearch 相关组件设置用户名和密码。
1) 设置 X-Pack
进入 C:\Applications\Java\elasticsearch-7.10.2\config 目录,修改 elasticsearch.yml 文件,添加如下内容
http.cors.enabled: true http.cors.allow-origin: "*" http.cors.allow-headers: Authorization xpack.security.enabled: true xpack.security.transport.ssl.enabled: true
2) 添加密码
控制台命令方式进入 C:\Applications\Java\elasticsearch-7.10.2\bin 目录,运行如下命令:
C:\Applications\Java\elasticsearch-7.10.2\bin>elasticsearch-setup-passwords interactive
future versions of Elasticsearch will require Java 11; your Java version from [C:\Program Files\Java\jdk1.8.0_121\jre] does not meet this requirement Initiating the setup of passwords for reserved users elastic,apm_system,kibana,kibana_system,logstash_system,beats_system,remote_monitoring_user. You will be prompted to enter passwords as the process progresses. Please confirm that you would like to continue [y/N]y Enter password for [elastic]: Reenter password for [elastic]: Enter password for [apm_system]: Reenter password for [apm_system]: Enter password for [kibana_system]: Reenter password for [kibana_system]: Enter password for [logstash_system]: Reenter password for [logstash_system]: Enter password for [beats_system]: Reenter password for [beats_system]: Enter password for [remote_monitoring_user]: Reenter password for [remote_monitoring_user]: Changed password for user [apm_system] Changed password for user [kibana_system] Changed password for user [kibana] Changed password for user [logstash_system] Changed password for user [beats_system] Changed password for user [remote_monitoring_user] Changed password for user [elastic]
注:这里把所有账号的密码都设置为 123456,修改密码之后,需要重新设置 kibana 的配置文件(config/kibana.yml)和 logstash 的配置文件(config/logstash.conf),
kibana 修改如下:
... elasticsearch.username: "kibana_system" elasticsearch.password: "123456"
logstash 修改如下:
... output { elasticsearch { hosts => ["http://localhost:9200"] index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}" user => "elastic" password => "123456" } }
以上修改完成后,重启 ElasticSearch、Kibana 和 Logstash。
使用 curl 访问需要安全验证的 ElasticSearch,命令如下:
C:\> curl http://localhost:9200
{"error":{"root_cause":[{"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}}],"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}},"status":401}
带上用户名和密码,命令如下:
C:\> curl --basic -u elastic:123456 http://localhost:9200
{ "name" : "CHSHL01096TKUAN", "cluster_name" : "elasticsearch", "cluster_uuid" : "QagiO3dcTBSVNYl10ibjPQ", "version" : { "number" : "7.10.2", "build_flavor" : "default", "build_type" : "zip", "build_hash" : "747e1cc71def077253878a59143c1f785afa92b9", "build_date" : "2021-01-13T00:42:12.435326Z", "build_snapshot" : false, "lucene_version" : "8.7.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
以上安装配置的 ElasticSearch、Logstash 和 Kibana 简称 ELK,三者配合使用可以实现大部分公司基本的数据收集、数据搜索和数据分析的功能。