ElasticSearch学习

Elasticsearch简介

Elasticsearch(简称ES)是一个基于Apache Lucene?的开源搜索引擎,无论在开源还是专有领域,Lucene 可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。注意,Lucene 只是一个库。想要发挥其强大的作用,你需使用 Java 并要将其集成到你的应用中。

Lucene 非常复杂,你需要深入的了解检索相关知识来理解它是如何工作的,就跟学习 springmvc 之前先从 servlet 开始,繁琐复杂的工作,Solor、Elasticsearch 应由而生, 其使用 Java 编写并使用 Lucene 来建立索引并实现搜索功能,但是它的目的是通过简单连贯的 RESTful API 让全文搜索变得简单并隐藏 Lucene 的复杂性。

Elasticsearch安装部署

安装虚拟机

官网的VMwareWorkstation安装包(附激活码)收集地址

https://github.com/201853910/VMwareWorkstation

安装过程省略

安装镜像

本次使用的系统为 Centos7.6

官网下载地址 https://vault.centos.org/7.6.1810/isos/x86_64/CentOS-7-x86_64-DVD-1810.iso

(嫌慢可以自行寻找国内镜像)

安装过程略

初始化系统

换源

换成阿里源 速度快一些

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cd /etc/yum.repos.d/  						# 进入文件夹
mv CentOS-Base.repo CentOS-Base.repo_back # 备份原始配置文件

wget -O CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# 若没有 wget 可使用 curl
curl -o CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

wget -O epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
# 若没有 wget 可使用 curl
curl -o epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

# 清理缓存
yum clean all
# 重新生成缓存
yum makecache
# 更新
yum -y update

关闭防火墙

彻底关闭防火墙

1
systemctl disable firewalld.service

完事后克隆两台出来, 然后改一下ip,不再赘述

配置免密

先改hosts

1
vi /etc/hosts
1
2
3
192.168.153.101 node1
192.168.153.102 node2
192.168.153.103 node3

配免密

1
2
3
4
5
6
7
8
9
cd /root/.ssh/
ssh-keygen -t rsa
# 三下回车

# 三个机器都给node1
ssh-copy-id node1

scp authorized_keys root@node2:/root/.ssh/
scp authorized_keys root@node3:/root/.ssh/

安装Elasticsearch

本次选取ES的7.10版本

https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.0-linux-x86_64.tar.gz

下载 解压到三台机器上

配置Elasticsearch

修改配置文件

vim ./config/elasticsearch.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#1、集群名称
cluster.name: my-es
#2、节点名称
node.name: node1
#3、网络主机设置
network.host: 0.0.0.0
#4、端口
http.port: 9200
#5、集群主节点信息
cluster.initial_master_nodes: ["node-1"]
#6、位置信息
path:
data: /var/data/elasticsearch
logs: /var/log/elasticsearch
#7、初始集群设置
discovery.seed_hosts:
- node1
- node2
- node3
#8、角色设置
node.roles: [ master,data ]

设置其他参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 设置内核参数
vi /etc/sysctl.conf

vm.max_map_count = 655360

#使生效
sysctl -p

#修改进程与线程数

sudo vi /etc/security/limits.conf

* soft nofile 65536
* hard nofile 65536
* soft nproc 4096
* hard nproc 4096

创建运行es的用户

es为了安全原因,不允许使用root用户运行es

1
2
3
4
5
6
7
8
9
10
11
# 1、创建新的用户
adduser es

# 2、设置用户密码
passwd es

# 3、授权给新建用户es文件夹的权限
chown -R es:es xxxx

# 4、切换用户
su es

启动Elasticsearch

跑起来

三台机器依次./bin/elasticsearch

image-20220517150959836

检查

curl node1:9200

image-20220517151031489

image-20220517170010026

curl node1:9200/_cluster/health?pretty

image-20220518102738772

到此部ES初始化完成

加密节点连接

  1. 为集群创建认证机构

    在node1的非root用户下进入es根目录下执行

    1
    2
    3
    bin/elasticsearch-certutil ca 
    # 直接回车就行 (文件 密码使用默认名)

  2. 为节点颁发证书

    1
    2
    3
    4
    5
    6
    bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 
    # 依次输入上一个步骤的密码。回车(文件使用默认名),密码(建议与上一步密码相同)
    bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
    # 继续回车
    bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
    # 继续回车
  3. 多节点配置

    将生成的elastic-certificates.p12、elastic-stack-ca.p12文件mv到config目录下,并连同elasticsearch.keystore 文件 scp到其他节点(ip/hosts映射)的config目录中。

    1
    scp elastic-certificates.p12 elasticsearch.keystore elastic-stack-ca.p12 root@node1:/elk/elasticsearch-7.10.0/config/ 
  4. 修改配置

    在elasticsearch-7.10.0/config/elasticsearch.yml中增加一下配置,启用x-pack安全组件,启用ssl加密通信,并且配置认证证书:

    1
    2
    3
    4
    5
    6
    7
    #---------------------security------------------
    #
    xpack.security.enabled: true
    xpack.security.transport.ssl.enabled: true
    xpack.security.transport.ssl.verification_mode: certificate
    xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
    xpack.security.transport.ssl.truststore.path: elastic-certificates.p12

    配置修改完成后,重启es服务,重启成功后

    访问http://node1:9200/

    可以看到访问Es服务要输入用户名和密码

设置内置用户密码

通过设置访问密码,这是elastic用户和其他一些系统内置用户的密码

1
bin/elasticsearch-setup-passwords interactive

设置成功后,可以通过用户名密码访问es服务:

http://localhost:9200/ 访问Es服务,输入配置的用户名和密码

image-20220518112430205

image-20220518112439943

或者curl node1:9200 -uelastic:123456

image-20220518112647045

结果同加密之前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"name" : "node-1",
"cluster_name" : "my-es",
"cluster_uuid" : "D7DBMaCARKGspQSV2E4_6Q",
"version" : {
"number" : "7.10.0",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "51e9d6f22758d0374a0f3f5c6e8f3a7997850f96",
"build_date" : "2020-11-09T21:30:33.964949Z",
"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"
}

Kibana访问ES

注意:8.0版本之后,设置kibana.yml访问es的用户名 不能使用”elastic”账户名

不要在kibana.yml配置文件里面配置es访问的用户密码明文,需要通过keystore配置加密的用户名密码信息,具体如下:

安装好并配置好权限

kibana-7.10.0-linux-x86_64/bin

1
2
3
4
5
6
7
8
#创建keystore
./kibana-keystore create

#设置kibana访问es的用户名
./kibana-keystore add elasticsearch.username

#设置kibana访问es的密码
./kibana-keystore add elasticsearch.password

Elasticsearch基本介绍

核心概念

字段

在ES中可以理解为JSON数据的键,下面的JSON数据中,name就是一个字段。

1
2
3
{
"name":"jack"
}

文档 Document

文档 在ES中相当于传统数据库中的行的概念,ES中的数据都以JSON的形式来表示,在MySQL中插入一行数据和ES中插入一个JSON文档是一个意思。下面的JSON数据表示,一个包含3个字段的文档。

1
2
3
4
5
{
"name":"jack",
"age":18,
"gender":1
}

映射Mapping

映射 是对文档中每个字段的类型进行定义,每一种数据类型都有对应的使用场景。例如:string的数据会被作为全文本来处理,这种数据类型适合需要搜索的场景。有些数据类型,你不需要对它进行搜索,相反需要对它做聚合运算,那么keyword、integer 数据类型就更合适。
正如上面说的,每个文档都有映射,但是在大多数使用场景中,我们并不需要显示的创建映射,因为ES中实现了动态映射。我们在索引中写入一个下面的JSON文档,在动态映射的作用下,name会映射成text类型,age会映射成long类型。

1
2
3
4
{
"name":"jack",
"age":18,
}

既然有动态映射,我们当然也可以自定义映射,在深度使用中,我们需要对数据类型进行精确的控制,以达到我们实际场景的要求,ES可能不知道我们需要数据类型,这种情况下我们可以使用自定义映射。通过映射API,我们可以方便的创建修改查看删除映射。

索引 Index

索引是ES中最大的数据单元,相当于关系型数据库中 的概念。前面我们说一个文档 相当于MySQL中一行数据,如果按照关系型数据库中的对应关系,还应该有的概念。ES中没有的概念,这是ES和数据库的一个区别,在我们建立索引之后,可以直接往 索引 中写入文档。在6.0版本之前,ES中有Type的概念,可以理解成关系型数据库中的,但是官方说这是一个设计上的失误,所以在6.0版本之后Type就被废弃了。

分片 Shards

上面我们说索引是ES中最大的数据存储单元,我们可以往索引中不断写入文档,到了一定数量级,索引文件就会占满整个服务器的磁盘,磁盘容量只是其中一个问题,索引文件变的大,会严重降低搜索的效率。怎么解决这个问题呢?分片就是用来解决这些问题的,简单来讲,分片就是把单索引文件分成多份存储,且这些索引的分片可以分部在不同的机器上。假设单台机器磁盘容量1TB,现在需要存放5TB的索引数据,那就可以把5TB索引分成10份,分别存放到10台机器上每份500G,这就是所谓的分片

副本 Replicas

我们已经知道,一个索引可以分成多个分片,分部在不同的机器上。那假设上面所说的10台机器中有一台发生故障了,在这台机器上的分片也就没了,就会导致索引损坏。为了解决索引高可用的问题,ES引入了副本机制,这里的副本指的就是分片的副本,分片的原始数据称为主分片,主分片和副本会放在不同的机器上,这样假设有一个分配丢失了,另外的分片可以作为后备。如果主分片的机器挂掉了,其中一个副本分片就会升级成主分片。同时,因为副本分片的工作和主分片是一样的,所以增加副本的数量可以提升查询性能。

词项 term

在传统关系型数据库中,假如想要存储一篇几千字的文本,可以通过text直接存进去,和存储其它类型的数据没什么不同。存储虽然很方便,但是要对文本中的关键词进行搜索,查询速度非常慢,尤其是在大数据量的时候。还是上面的场景,在ES中存储这篇文章,它不会直接存进去,而是先把大文本切割成很多个小的词,这些词就是我们所说的词项,它是ES搜索的最小单位,每个查询都是按词项搜索的。ES使用了倒排索引来存储数据,什么是倒排索引?在关系型数据中,最好的方式是用主键id来查询,可以快速定位到文章内容,而倒排索引则相反,它建立的是词项和文章id的对应关系,索引它更适合文本搜索,下面是一个倒排索引,hello和world这两个词都命中了id=1的文章。

词项 id
hello 1
word 1

倒排索引底层原理决定了ES天生适合做全文本搜索。

配置 Setting

Settings是对集群中索引的定义信息,比如一个索引默认的分片数、副本数等。

分析器 Analyzers

前面说过,ES中不会把一篇文章直接存入磁盘,在存储时它会先对文本进行分析,分析器的就是用来分析这些文本,中间包括过滤、分词等过程,经过分析处理后再存储到磁盘。分析器由3部分组成,分别是字符过滤器分词器词项处理器。字符过滤器把原始文本作为字符流来处理,它可以过滤一些特殊字符、html标签等;分词器是分析器的核心部分,它负责把大文本分割成多个词项,比如文本 "Quick brown fox!",可以被分割成 3个词项,[Quick, brown, fox!]词项处理器接受词项流,它可以移除一些不需要的词。ES提供了多种分析器,默认使用标准的分析器,能满足大部分的需求,实在不行也可以使用自定义的分析器,除了分析器以外,分词器、字符过滤器等在ES中也提供了多种选择。

节点 Node & 集群 Cluster

简单来讲,节点就是一个ElasticSearch进程,当我们启动一个ElasticSearch程序,就启动了一个节点,很多个节点集合在一起就成了集群,即使只有单个节点,也可以把它看成只有单个节点的集群。节点也分多种类型,主要分为 主节点、数据节点、协调节点和Ingest节点,每个节点都有各自的职责,如果集群中只有单个节点,那这个节点会扮演多个节点的角色,它需要独自完成整个搜索和索引的过程。集群对外提供服务时,相当于一个整体,集群中的每个节点都可以处理Http请求,每个请求经过一系列内部转发,处理完成后返回数据给外部客户端。集群内部每个节点之间通信使用Java API ,它的底层是基于TCP的自定义协议,而对于外部客户端,ES使用的是Restful风格的Http协议。

在Elasticsearch集群中,节点的状态有Green、Yellow、Red三种。

  • Green,绿色,表示节点运行状态为健康状态。所有主分片和副本分片都可以正常工作,集群100%健康。
  • Yellow,黄色,表示节点的运行状态为预警状态。所有的主分片都可以正常工作,但是至少有一个副本分片是不能正常工作的。此时集群仍然可以正常工作,但集群的高可用性在某种程度上被弱化。
  • Red,红色,表示集群无法正常工作。此时,集群中至少有一个分片的主分片及他的全部副本都不可正常工作。虽然集群的查询操作还可以进行,但是也只能返回部分数据(其他正常分片的数据可以被正常返回),而分配到这个有问题分片的写入请求会报错,最终造成数据丢失。

ES倒排索引

正排索引

正排索引也称为”前向索引”,这种组织方法在建立索引的时候结构比较简单,建立比较方便且易于维护;因为索引是基于文档建立的,若是有新的文档加入,直接为该文档建立一个新的索引块,挂接在原来索引文件的后面。若是有文档删除,则直接找到该文档号文档对应的索引信息,将其直接删除。
他适合根据文档ID来查询对应的内容。但是在查询一个keyword在哪些文档里包含的时候需对所有的文档进行扫描以确保没有遗漏,这样就使得检索时间大大延长,检索效率低下。

文档ID 文档内容
1 elasticsearch是最流行的搜索引擎
2 php是世界上最好的语言
3 搜索引擎是如何诞生的
  • 优点:工作原理非常的简单。
  • 缺点:检索效率太低,只能在一起简单的场景下使用。

倒排索引

根据切分的关键词表去找含有这个关键词的文档ID

单词 文档ID列表
elasticsearch 1
流行 1
搜索引擎 1,3
php 2
世界 2
最好 2
语言 2
如何 3
诞生 3

倒排索引基本概念

  • 单词编号(Word ID):与文档编号类似,搜索引擎内部以唯一的编号来表征某个单词,单词编号可以作为某个单词的唯一表征。

  • 单词词典(Lexicon):搜索引擎的通常索引单位是单词,单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向“倒排列表”的指针。

  • 倒排列表(PostingList):倒排列表记载了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。

    倒排文件(Inverted File):所有单词的倒排列表往往顺序地存储在磁盘的某个文件里,这个文件即被称之为倒排文件,倒排文件是存储倒排索引的物理文件。

    • 单词ID:记录每个单词的单词编号;
    • 单词:对应的单词;
    • 文档频率:代表文档集合中有多少个文档包含某个单词
    • 倒排列表:包含单词ID及其他必要信息
    • DocId:单词出现的文档id
    • TF:单词在某个文档中出现的次数
    • POS:单词在文档中出现的位置

    img

    img

    img