文章目录

  • 一、初识ElasticSearch
  • 1、用途与发展历史
  • 2、倒排索引
  • 3、ES核心概念
  • 4、ES与MySQL的概念点对比
  • 二、安装部署
  • 1、单节点部署ES
  • 2、安装kibana
  • 3、安装IK分词器



先看下翻译:

ES8安装 设置密码_ES8安装 设置密码

一、初识ElasticSearch

1、用途与发展历史

elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容

以下是生活中ES的使用场景:

ES8安装 设置密码_spring cloud_02

ES8安装 设置密码_ES8安装 设置密码_03

项目在运行的时候会产生海量的日志信息,而elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK),即ELK技术栈。被广泛应用在日志数据分析、实时监控等领域。

ES8安装 设置密码_docker_04

而ES是ELK技术栈的核心,负责存储、搜索、分析数据。

ES8安装 设置密码_分布式_05

在ES的底层的实现,是Lucene,Lucene是一个Java语言的搜索引擎类库(jar包),是Apache公司的顶级项目,官网地址:https://lucene.apache.org/

Lucene的优势:

  • 易扩展,可二开
  • 高性能(基于倒排索引)

Lucene的缺点:

  • 只限于Java语言开发
  • 学习曲线陡峭
  • 不支持水平扩展

ES就是基于Lucence开发的,官网地址: https://www.elastic.co/cn/。相比与lucene,elasticsearch具备下列优势:

  • 支持分布式,可水平扩展
  • 提供Restful接口,可被任何语言调用
小总结:

什么是elasticsearch?
一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能

什么是elastic stack(ELK)?
是以elasticsearch为核心的技术栈,包括beats、Logstash、kibana、elasticsearch

什么是Lucene?
是Apache的开源搜索引擎类库,提供了搜索引擎的核心API

2、倒排索引

传统数据库如MySQL采用的是正向索引,如给下表中的id创建索引:

ES8安装 设置密码_分布式_06


给id创建索引,生成一个B+树,根据id检索的数据就会非常快。但当检索的是标题字段(标题较长,一般不加索引,即便加了,以后模糊匹配也就不生效了),如下:

ES8安装 设置密码_spring cloud_07

这样逐行扫描,最终也能拿到完整的数据集,但大数据量下,这个耗时太长!接下来看倒排索引:(倒字是为了凸显和之前的大不一样,不是刚好相反的意思)

ES8安装 设置密码_分布式_08

elasticsearch采用倒排索引:

  • 文档(document):每条数据就是一个文档
  • 词条(term):文档按照语义分成的词语

给title建立倒排索引的时候,先按照词条分开,再和文档id一起存入。重复的词条不再重复插入,只在文档id后面加上新id即可。如此,词条不重复,建立索引的时候可哈希,也可B+树

ES8安装 设置密码_elasticsearch_09


以上:虽然要先查询倒排索引,再查询正向索引(id),但是无论是词条、还是文档id都建立了索引,查询速度非常快!无需全表扫描。到这儿,应该加深了对倒排索引的"倒"字的理解了,倒即相对正,之前是根据id查数据,现在是根据关键字查id,再由id查数据。

posting list

倒排索引中包含两部分内容:

1)词条词典(Term Dictionary):记录所有词条,以及词条与倒排列表(Posting List)之间的关系,会给词条创建索引,提高查询和插入效率

2)倒排列表(Posting List):记录词条所在的文档id、词条出现频率 、词条在文档中的位置等信息

  • 文档id:用于快速获取文档
  • 词条频率(TF):文档在词条出现的次数,用于评分

ES8安装 设置密码_elasticsearch_10

什么是文档和词条?
- 每一条数据就是一个文档
- 对文档中的内容分词,得到的词语就是词条
什么是正向索引?
基于文档id创建索引。查询词条时必须先找到文档,而后判断是否包含词条。是**根据文档找词条的过程**。

什么是倒排索引?
对文档内容分词,对词条创建索引,并记录词条所在文档的信息。查询时先根据词条查询到文档id,而后获取到文档。是**根据词条找文档的过程**。

正向索引

  • 优点:
  • 可以给多个字段创建索引
  • 根据索引字段搜索、排序速度非常快
  • 缺点:
  • 根据非索引字段,或者索引字段中的部分词条查找时,只能全表扫描。

倒排索引

  • 优点:
  • 根据词条搜索、模糊搜索时,速度非常快
  • 缺点:
  • 只能给词条创建索引,而不是字段
  • 无法根据字段做排序

3、ES核心概念

文档和字段

elasticsearch是面向文档存储的,文档可以是数据库中的一条商品数据,一个订单信息。文档数据会被序列化为json格式后存储在elasticsearch中。

ES8安装 设置密码_分布式_11


而Json文档中往往包含很多的字段(Field),类似于数据库中的列。

索引(index)

索引(Index),就是相同类型的文档的集合。

ES8安装 设置密码_ES8安装 设置密码_12


例如:

  • 所有用户文档,就可以组织在一起,称为用户的索引;
  • 所有商品的文档,可以组织在一起,称为商品的索引;
  • 所有订单的文档,可以组织在一起,称为订单的索引;

ES8安装 设置密码_docker_13

因此,可以把索引当做是数据库中的表。 一个索引下的文档字段结构相同,一个MySQL表下的数据字段结构相同。

映射(mapping)

数据库的表会有约束信息,用来定义表的结构、字段的名称、类型等信息。因此,索引库中就有映射(mapping),是索引中文档的字段约束信息,类似表的结构约束。

小总结:

- 文档:一条数据就是一个文档,es中是Json格式
- 字段:Json文档中的字段
- 索引:同类型文档的集合
- 映射:索引中文档的约束,比如字段名称、类型

4、ES与MySQL的概念点对比

ES和MySQL的整体概念对比如下:

ES8安装 设置密码_docker_14


二者并不是替代关系,而是一种互补:

  • Mysql:擅长事务类型操作,可以确保数据的安全和一致性
  • Elasticsearch:擅长海量数据的搜索、分析、计算

ES8安装 设置密码_分布式_15

二、安装部署

1、单节点部署ES

后面要部署ES可视化工具kibana的容器,因此需要让es和kibana容器互联。这里先创建一个网络:

docker network create es-net

拉取镜像

docker pull elasticsearch:7.12.1
# 有镜像包的话也可直接导入
docker load -i es.tar

启动ES容器

docker run -d \
	--name es \
    -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
    -e "discovery.type=single-node" \
    -v es-data:/usr/share/elasticsearch/data \
    -v es-plugins:/usr/share/elasticsearch/plugins \
    --privileged \
    --network es-net \
    -p 9200:9200 \
    -p 9300:9300 \
elasticsearch:7.12.1
  • -e "cluster.name=es-docker-cluster":设置集群名称
  • -e "http.host=0.0.0.0":监听的地址,可以外网访问
  • -e "ES_JAVA_OPTS=-Xms512m -Xmx512m":ES运行时的内存大小,默认1G
  • -e "discovery.type=single-node":非集群模式
  • -v es-data:/usr/share/elasticsearch/data:挂载逻辑卷,绑定es的数据目录
  • -v es-logs:/usr/share/elasticsearch/logs:挂载逻辑卷,绑定es的日志目录
  • -v es-plugins:/usr/share/elasticsearch/plugins:挂载逻辑卷,绑定es的插件目录
  • --privileged:授予逻辑卷访问权
  • --network es-net :加入一个名为es-net的网络中
  • -p 9200:9200:端口映射配置,暴露端口,9200是供用户访问的
  • -p 9300:9300:ES各个节点容器之间互联的端口,单机模式下不暴露也行

http://IP:9200 即可看到elasticsearch的响应结果即为安装成功:

ES8安装 设置密码_ES8安装 设置密码_16

2、安装kibana

部署ES可视化工具kibana,先下载镜像,注意和ES版本保持一致

docker pull kibana:7.12.1
# 或者
docker load -i yourPath/kibana.tar

运行docker命令,部署kibana

docker run -d \
	--name kibana \
	-e ELASTICSEARCH_HOSTS=http://es:9200 \
	--network=es-net \
	-p 5601:5601  \
kibana:7.12.1
  • --network es-net :加入一个名为es-net的网络中,与elasticsearch在同一个网络中
  • -e ELASTICSEARCH_HOSTS=http://es:9200":设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch
  • -p 5601:5601:端口映射配置

kibana启动一般比较慢,需要多等待一会,可以通过命令:

docker logs -f kibana

看到这个日志即为安装成功:

ES8安装 设置密码_ES8安装 设置密码_17

访问5601端口:

ES8安装 设置密码_ES8安装 设置密码_18

试试Dev Tools这个工具,来发送DSL语句:

ES8安装 设置密码_elasticsearch_19

运行DSL语句测试:

ES8安装 设置密码_分布式_20

3、安装IK分词器

es在创建倒排索引时需要对文档分词;在搜索时,需要对用户输入内容分词,而默认的分词规则对中文处理并不友好。

在kibana的DevTools中测试:

POST /_analyze
{
  "analyzer": "standard",
  "text": "测试中文分词效果!"
}


/_analyze:请求路径,省略了http://IP:9200,有kibana补充

请求参数:(json)
- analyzer:分词器类型,这里是默认的standard分词器
- text:要分词的内容

分词效果如下:

ES8安装 设置密码_分布式_21

可以看到分词效果为0,不识字。想处理中文分词,可以使用IK分词器。https://github.com/medcl/elasticsearch-analysis-ik

在线安装:(较慢)

# 进入容器内部
docker exec -it elasticsearch /bin/bash

# 在线下载并安装
./bin/elasticsearch-plugin  install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip

#退出
exit
#重启容器
docker restart elasticsearch

离线安装:(推荐)

  • 查看数据卷目录
# 安装插件需要知道elasticsearch的plugins目录位置
# 而上面安装ES时,用了数据卷挂载,因此先查看下这个数据卷的目录
docker volume inspect es-plugins

返回:
[
    {
        "CreatedAt": "2023-05-06T10:06:34+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/es-plugins/_data",
        "Name": "es-plugins",
        "Options": null,
        "Scope": "local"
    }
]

# 说明plugins目录被挂载到了:`/var/lib/docker/volumes/es-plugins/_data `这个目录中。
  • 解压缩分词器安装包,重命名为ik
  • ES8安装 设置密码_docker_22

  • 上传到es容器的插件数据卷中(有挂载关系,上传到宿主机目录es容器中也就有了)
  • ES8安装 设置密码_ES8安装 设置密码_23

  • 重启es
docker restart es
  • 查看es的日志
docker logs -f es

测试效果:

注意版本保持一致,版本不一致会报错:

ES8安装 设置密码_ES8安装 设置密码_24

效果:

ES8安装 设置密码_ES8安装 设置密码_25

ik分词器包含两种模式:

  • ik_smart:最少切分,粗粒度
  • ik_max_word:最细切分,细粒度

最少切分的效果:(粗粒度,这四个字能组成一个词,就不看这四个字内部能不能再组成了)

ES8安装 设置密码_docker_26

最细切分的效果:

ES8安装 设置密码_ES8安装 设置密码_27



词条的拓展与停用:

思考分词器底层的实现:应该是一个类似字典的东西,它里面包含的词汇肯定不全,最先想到的就是新词,如白嫖:

ES8安装 设置密码_spring cloud_28

要拓展ik分词器的词库,只需要修改一个ik分词器目录中的config目录中的IkAnalyzer.cfg.xml文件

ES8安装 设置密码_ES8安装 设置密码_29

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 *** 添加扩展词典-->
        <entry key="ext_dict">ext.dic</entry>
</properties>

然后在这个目录下再新建个名为ext.dic的文件中,添加想要拓展的词语即可。同样的,禁用敏感词汇,还是IkAnalyzer.cfg.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典-->
        <entry key="ext_dict">ext.dic</entry>
         <!--用户可以在这里配置自己的扩展停止词字典  *** 添加停用词词典-->
        <entry key="ext_stopwords">stopword.dic</entry>
</properties>

ES8安装 设置密码_分布式_30

然后在名为stopword.dic的文件中,添加想要禁用的词语即可:

ES8安装 设置密码_spring cloud_31

# 重启生效
docker restart es