ElasticSearch简介
ElasticSearch是一个开源的分布式/RESTful风格的搜索引擎和数据分析引擎,它底层是开源库“Lucene”。ElasticSearch使用Java语言开发,现由Apache基金会维护,是目前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定、可靠、快速,安装方便。
我们建立一个网站,并要添加搜索功能,但是想要完成搜索工作是非常困难的。我们希望搜索解决方案要运行速度快,我们希望能有一个零配置和一个完全免费的搜索模式,我们希望能够简单使用JSON通HTTP来索引数据,我们希望我们的搜索服务器始终可用,我们希望能够从一台服务器扩展到上百台,数百条,我们要实时搜索,我们要简单的多租户,我们希望建立一个云的解决方案,因此我门使用ElasticSearch来解决这些问题以及可能出现的更多的其他问题
官方网址:https://www.elastic.co/cn/products/elasticsearch
Github:https://github.com/elastic/elasticsearch
ElasticSearch是基于Lucene的,Lucene可以说是当下最先进、高性能、全功能的搜索引擎库——无论是开源还是私有,但它仅仅只是一个库。为了充分发挥其功能,你需要使用Java并将Lucene直接集成在到应用程序。更糟糕的是,你可能需要获得信息检索学位才能了解其工作原理,因为Lucene非常的复杂。
为了解决Lucene使用时的繁复性,于是ElasticSearch便应运而生,它使用Java语言编写,内部采用Lucene做索引与搜索,但是它的目标是使全文检索变得更加简单,简单的来说就是对Lucene做了一层封装,它提供了一套简单一致的RESTful API来帮助我们实现存储和检索
当然ElasticSearch不仅仅是Lucene,并且也不仅仅是一个全文搜索引擎。用下面的来形容更加的准确
- 一个分布式的实时文档存储,每个字段可以被索引与搜索
- 一个分布式实时分析搜索引擎
- 能胜任上百个服务节点的扩展,并支持PB级别的结构化或者非结构化数据
由于ElasticSearch的功能简单强大和简单使用,像维基百科、GitHub等都采用它来做搜索。现在ElasticSearch依据成为全文搜索领域最为主流的程序之一
安装ElasticSearch
1、将下载的ES文件上传到服务器之中,并解压
tar xzvf /srv/ftp/elasticsearch-7.6.0-linux-x86_64.tar.gz -C /usr/local/
2、将解压后的文件重命名,方便后续操作
mv /usr/local/elasticsearch-7.6.0/ /usr/local/elasticsearch
3、新建ElasticSearch数据存储目录
mkdir -p /usr/data/elasticSearch/{data,logs}
4、修改config/elasticsearch.yml文件
vim /usr/local/elasticsearch/config/elasticsearch.yml
取消下列项注释并修改:
cluster.name: my-application #集群名称
node.name: node-1 #节点名称
#数据和日志的存储目录
path.data: /usr/data/elasticSearch/data
path.logs: /usr/data/elasticSearch/logs
#设置绑定的ip,设置为0.0.0.0以后就可以让任何计算机节点访问到了
network.host: 0.0.0.0
http.port: 9200 #端口
#设置在集群中的所有节点名称,这个节点名称就是之前所修改的,当然你也可以采用默认的也行,目前是单机,放入一个节点即可
cluster.initial_master_nodes: ["node-1"]
5、启动ElasticSearch,在启动的时候需要注意,ElasticSearch为了安全,不允许“root”用户进行启动,所有我们需要创建一个用户进行启动
# 创建elasticsearch用户
adduser elasticsearch
# 设置密码,要输入两次:“passwd 用户名”
passwd elasticsearch
# 将对应的文件夹权限赋给该用户
chown -R elasticsearch /usr/local/elasticsearch/ -R
chown -R elasticsearch /usr/data/elasticSearch/ -R
6、vim 编辑 /etc/security/limits.conf,在末尾加上:“*”替换为新的用户名
* soft nofile 65536
* hard nofile 65536
* soft nproc 4096
* hard nproc 4096
7、vim 编辑 vim /etc/security/limits.d/20-nproc.conf,将* 改为用户名
# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.
elasticsearch soft nproc 4096
root soft nproc unlimited
8、vim 编辑 /etc/sysctl.conf,在末尾加上:
vm.max_map_count = 262144
9、在“:/etc/security/”目录执行:sysctl -p
返回:
vm.max_map_count = 262144
10、切换新建的用户
su elasticsearch
启动提示:Java版本需要升级到JDK11
解决:下载Jdk11:wget https://download.java.net/java/GA/jdk11/13/GPL/openjdk-11.0.1_linux-x64_bin.tar.gz
tar -xzvf jdk-11.0.4_linux-x64_bin.tar.gz -C /use/local/
mv /use/local/jdk-11 /use/local/jdk11
修改:vi bin/elasticsearch 添加配置项
#配置自己的jdk11
export JAVA_HOME=/opt/jdk-11.0.1
export PATH=$JAVA_HOME/bin:$PATH#添加jdk判断
if [ -x "$JAVA_HOME/bin/java" ]; then
JAVA="/opt/jdk-11.0.1/bin/java"
else
JAVA=which java
fi
修改config/jvm.options
注释掉其它,添加下面的配置
-XX:+UseG1GC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
错误:ElasticsearchException[Failure running machine learning native code. This could be due to running on an unsupported OS or distribution, missing OS libraries, or a problem with the temp directory. To bypass this problem by running Elasticsearch without machine learning functionality set [xpack.ml.enabled: false].]
解决:vim config/elasticsearch.yml添加一条配置:
xpack.ml.enabled: false
11、启动
/usr/local/elasticsearch/bin/elasticsearch
12、在浏览器中输入:http://ip:9200,返回下面的内容,启动成功
{
"name" : "node-1",
"cluster_name" : "my-application",
"cluster_uuid" : "v4W4Jen8RWKPhTfUMIqpIA",
"version" : {
"number" : "7.6.0",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "7f634e9f44834fbc12724506cc1da681b0c3b1e3",
"build_date" : "2020-02-06T00:09:00.449973Z",
"build_snapshot" : false,
"lucene_version" : "8.4.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
13、上面的是在前台启动,如果需要后台启动加上“-d”即可
/usr/local/elasticsearch/bin/elasticsearch -d
# 查看启动结果:ps -ef|grep elasticsearch
root 4194 4125 0 22:03 pts/0 00:00:00 su elasticsearch
elastic+ 4618 1 98 22:10 pts/0 00:00:20 /usr/local/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dio.netty.allocator.numDirectArenas=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Djava.locale.providers=COMPAT -Xms1g -Xmx1g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -Djava.io.tmpdir=/tmp/elasticsearch-10955069239077689375 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=data -XX:ErrorFile=logs/hs_err_pid%p.log -Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m -XX:MaxDirectMemorySize=536870912 -Des.path.home=/usr/local/elasticsearch -Des.path.conf=/usr/local/elasticsearch/config -Des.distribution.flavor=default -Des.distribution.type=tar -Des.bundled_jdk=true -cp /usr/local/elasticsearch/lib/* org.elasticsearch.bootstrap.Elasticsearch -d
elastic+ 4633 4618 0 22:10 pts/0 00:00:00 /usr/local/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller
elastic+ 4683 4195 0 22:10 pts/0 00:00:00 grep --color=auto elasticsearch
ElasticSearch基本配置:当服务成功启动之后,就安装完成了,随后就可以对ElasticSearch进配置
ElasticSearch可配置信息
|属性名|说明|
|-------|-------|
|cluster.name|配置ElasticSearch的集群名称,默认是elasticsearch,有需要可以修改一个有意义的名称|
|node.name|节点名称,es会默认随机指定一个名称,建议指定一个有意义的名称,方便管理|
|path.conf|设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,使用逗号“,”隔开|
|path.logs|设置日志文件的存储路径,默认是es根目录下的logs文件夹|
|path.plugins|设置插件的存放路径,默认是es根目录下的plugins文件夹|
|bootstart.memory_lock|设置为true可以锁定ES使用的内存,避免内存进行swap|
|network.host|设置bind_host和publish_host,设置为0.0.0.0允许外网访问|
|http:port|设置对外服务的http端口,默认为9200|
|transport.port|集群节点直接通信接口|
|discovery.zen.minimum_master_nodes|主节点数量的最少值,此值的公式为:(master_eligible_nodes/2)+1,比如:有三个符合要求的主节点,那么这里要设置为2|
概念
在逻辑层面
- Index(索引):这里的Index是名称,一个Index就像是传统关系型数据库的DataBase(库),它是ElasticSearch用来存储数据的逻辑区域
- Type(类型):文档属于一种Type,Type就像是关系型数据库中的一个Table(表)
- Document(文档):ElasticSreach使用JSON文档来表示一个对象,就像是关系型数据库一个表中的一个(ROW)行
- Field(字段):每个文档包含多个字段,就像是关系型数据库一张表中的一个(Column)列
在物理层面
- Node(节点):node是一个运行着的ElasticSearch实例,一个node就是一个单独的server
- cluster(集群):cluster是有多个由node组成
- Shard(分片):数据分片,一个Index可能会存在于多个Shard中
配置 ik分词器
下载ik分词器:https://github.com/medcl/elasticsearch-analysis-ik
下载的版本要与ElasticSearch的版本一致,否则无法启动
新建ik文件夹:
mkdir -p /usr/local/elasticsearch/plugins/ik
将下载好的ik分词器解压到新建的ik目录中,重启ElasticSearch即可
使用Postman测试ik分词器是否可用,结果如下图所示表示配置成功
基本使用,使用PostMan测试工具
创建、修改
创建一个关于电影的索引,使用POST请求
192.168.5.168:9200/movie/adventure/1
对该链接的解释:
使用Postman测试:
可以看到,我们已经成功创建了一个 _index 为 movie,_type 为 adventure,_id 为 1 的文档。当前的result为create,上图由于我是第二次保存所以已经边长update了。
查询该索引,使用GET请求
192.168.5.168:9200/movie/adventure/1
可以发现我们保存的数据已经在"_source"里面了
如果我们数据没有设置id,ElasticSearch也可以自动生成
POST /movie/adventure/
更新整个文档,使用PUT请求
当我们调用PUT请求指明文档的_index、_type、_id时,如果_id已经存在了,则新的文段会替换掉旧的文档 ,并且此时文档的_version会增加1,result字段会为update
可以看到,actors 这个字段已经不存在了,文档的 _version 变成了 2。
检索
检索某个文档
检索整个索引比较简单,只要使用GET请求,并指出index(索引名)、type(类型)、id即可
192.168.5.168:9200/movie/adventure/1
响应内容会包含文档的元信息,文档的原数据存在_source字段中,也可以直接检索出_source字段下的数据
192.168.5.168:9200/movie/adventure/1/_source
检索所有文档
192.168.5.168:9200/movie/adventure/_search
可以看到,hits这个Object包含了hits数组,total等字段,其中hits数组包含了所有的文当,total表明了文档的数量,默认情况下最多返回10个,也可以设置from=xx&size=xx参数来获取某一范围文档的数量。
query string搜索
query string搜索以:q=field:value的形式进行查询,比如查询name字段中包含有ByXiaoLong的信息,这是完整搜索,必须搜索一个完整的value
192.168.5.168:9200/movie/adventure/_search?q=name:ByXiaoLong
也可以使用下面的方式进行
DSL 搜索
上面的 query string 搜索比较轻量级,只适用于简单的场合。Elasticsearch 提供了更为强大的 DSL(Domain Specific Language)查询语言,适用于复杂的搜索场景,比如全文搜索。我们可以将上面的 query string 搜索转换为 DSL 搜索,如下:
删除文档,使用DELETE请求
192.168.5.168:9200/movie/adventure/1
- ElasticSearch通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单
- 在创建文档的时候,我们可以使用POST方法指定将这个文档添加到某个_index_type下,来让ElasticSearch自动生成唯一的_id;使用PUT方法指定将文档的_index_type_id
Kibana安装
kibana是ElasticSearch优秀的图形化管理工具,包括控制台和图表显示等简易操作
1、解压kbana:
tar xzvf /srv/ftp/kibana-7.6.0-linux-x86_64.tar.gz -C /usr/local/
2、重命名
mv /usr/local/kibana-7.6.0-linux-x86_64/ /usr/local/kibana
3、修改配置文件
mkdir -p /usr/data/kibana/run
vim /usr/local/kibana/config/kibana.yml
取消注释:server.port: 5601
取消注释并修改:server.host: "0.0.0.0"
取消注释并修改:elasticsearch.hosts: ["http://ElasticSearch主机Ip:9200"]
取消注释并修改:pid.file: /usr/data/kibana/run/kibana.pid
4、给elasticsearch用户赋予权限
chown -R elasticsearch /usr/data/kibana/ -R
chown -R elasticsearch /usr/local/kibana/ -R
5、切换用户
su elasticsearch
6、启动kibana
/usr/local/kibana/bin/kibana &
7、查看进程
ps -ef | grep node
elastic+ 5054 5003 41 00:55 pts/1 00:00:33 /usr/local/kibana/bin/../node/bin/node /usr/local/kibana/bin/../src/cli
elastic+ 5077 5003 0 00:56 pts/1 00:00:00 grep --color=auto node
8、浏览器输入:
http://ip:5601/
出现下面的界面,启动成功
在界面有几个重要操作选项
|名字|内容|
|-------|-------|
|Discover|可视化查询分析器|
|Visualize|Visualize|
|Dashboard|自定义主面板(添加图表)|
|Timelion|Timelion是一个kibana时间序列展示组件(暂时不用)|
|Dev Tools|Console控制台(同CURL/POSTER,操作ES代码工具,代码提示,很方便)|
|Management|管理索引库(index)、已保存的搜索和可视化结果(save objects)、设置 kibana 服务器|
Kibana基本使用
ElasticSearch本质上也是存储数据库,所有有许多的概念与MySql类似
索引(indices) ----------------- 数据库
类型(Type)-------------------- 表
文档(Document) ---------------- Row行
字段(Field) ------------------- Columns行
|概念|说明|
|-------|-------|
|索引库(indices)|indices是index的复数,代表许多的索引|
|文档(document)|存入索引库的原始数据。比如每一条商品信息,就是一个文档|
|字段(field)|文档中的属性|
|映射配置(mappings)|字段的数据类型、属性、是否索引、是否存储等特性|
- 索引集(indices,index的复数):逻辑上的完整索引
- 分片(shard):数据拆分后的各个部分
- 副本(replica):每个分片的复制
需要注意的是:ElasticSearch本身就是分布式的,因此即便你只有一个节点,ElasticSearch默认也会对你的数据进行分片和副本操作,当你想集群添加数据的时候,数据也会在新加入的节点中进行平衡
创建索引(数据库)
"number_of_shards":1 分片树
"number_of_replicas":1 副本数
查询索引
查询索引库是否存在
删除索引
创建映射关系(数据库列):需要配置一些参数
- type:类型,可以使text、long、short、date、integer、object等
- index:是否索引、默认为true
- store:是否存储:默认为true
- analyzer:分词器,这里的ik_max_word既使用ik分词器
查询映射关系
添加 更新数据(我们也可以直接添加数据,这样系统会默认给我们生成一套映射关系)
如果——doc后面不知道id数,会默认生成
修改使用相同的代码,修改内容即可,重点POST people/_doc/1要相同
获取数据
获取一个
获取全部
删除数据:直接通过id即可删除
查询功能:添加三个数据
POST people/_doc/1
{
"name" : "小红",
"age" : 18,
"sex": "女"
}
POST people/_doc/2
{
"name" : "小王2",
"age" : 22,
"sex": "男"
}
POST people/_doc/3
{
"name" : "小男",
"age" : 22,
"sex": "男"
}
POST people/_doc/4
{
"name" : "小王",
"age" : 18,
"sex": "女"
}
全部查询:
基本语法
GET /索引库名/_search
{
"query":{
"查询类型":{
"查询条件":"查询条件值"
}
}
}
返回结果
time_out:是否超时
_shards:分片信息
hits:搜索结果总览对象
total:搜索到的总条数
max_score:所有结果中文档得分的最高分
hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
_index:索引库
_type:文档类型
_id:文档id
_score:文档得分
_source:文档的源数据
默认查询所有的people下的数据
GET people/_search
返回结果:太长,自己试
匹配查询
GET people/_search
{
"query": {
"match": {
"name": "小王2"
}
}
}
此时会有两个返回结果“小王”、“小王2”,但是我们如果只想要小王2,那么通过通过更改关联关系即可
GET /people/_search
{
"query": {
"match": {
"name": {"query": "小王2","operator": "and"}
}
}
}
此时就只能查到“小王2”
设置最小匹配度查询:如果只满足其中的50%q即可视为查询正确,那么“小王”和“小王2”都将被查询出来,如果设置100%那么就只能查出“小王2”
GET /people/_search
{
"query": {
"match": {
"name": {"query": "小王2","minimum_should_match": "50%"}
}
}
}
GET /people/_search
{
"query": {
"match": {
"name": {"query": "小王2","minimum_should_match": "100%"}
}
}
}
多字段查询:我们在sex和name字段中查询带“男”字的
GET /people/_search
{
"query": {
"multi_match": {
"query": "男",
"fields": ["name","sex"]
}
}
}
不管名字中有“男”字或性别是“男”的都会被查出来
词条匹配(精确查找):term查询被用于精确值匹配,这些精确值可能是数组、时间、布尔或者那些未分词的字符串,terms就是查询多个
GET /people/_search
{
"query": {
"terms": {
"sex": [
"男",
"女"
]
}
}
}
结果过滤:如果我们查询的结果只想看到“name”("_source": "name")
GET /people/_search
{
"query": {
"terms": {
"sex": [
"男",
"女"
]
}
},"_source": "name"
}
或者不想要谋个字段
GET /people/_search
{
"query": {
"terms": {
"sex": [
"男",
"女"
]
}
},"_source": {
"excludes": "sex"
}
}