1. ElasticSearch简介


1.0 MySQL模糊查询的问题



1.1 ElasticSearch是什么

ElasticSearch(简称为es)是一个分布式搜索引擎的底层实现。其底层是Lucene。


1.2 ElasticSearch能做什么

它对任何类型的数据提供了近乎实时的查询功能、分析功能。也就是说,无论你的数据是有结构的,或是没有结构的,是数字类型的数据,或是地理位置数据等等,es都可以把所有这些各式各样的数据,以“特定方式”存储起来,并创建索引。正是因为这个“特定方式”,才使得我们使用es检索数据时,会以最短的时间获取到结果。ElasticSearch的功能,不仅仅是数据检索、数据聚合,es更强大的功能是它能够发现你数据中的趋势。并且当数据量增大时,ElasticSearch天然的分布式特点可以让我们无缝地横向扩展服务。


1.3 ElasticSearch实际应用效果

1.简介与安装_lucene


从这个例子中,我们看到了:分词、相关性排名、高亮、每条搜索记录的部分内容。


1.4 重点概念解释


分词器

后续章节会详细讲解分词器,但是分词器对我们理解es的内容至关重要,所以这里提前讲解一点分词器的内容:

<dependencies>

<dependency>

<groupId>org.apache.lucene</groupId>

<artifactId>lucene-core</artifactId>

<version>7.3.1</version>

</dependency>

<dependency>

<groupId>org.apache.lucene</groupId>

<artifactId>lucene-analyzers</artifactId>

<version>3.6.2</version>

</dependency>

<dependency>

<groupId>org.apache.lucene</groupId>

<artifactId>lucene-highlighter</artifactId>

<version>7.3.1</version>

</dependency>

<dependency>

<groupId>org.apache.lucene</groupId>

<artifactId>lucene-queryparser</artifactId>

<version>7.3.1</version>

</dependency>

<dependency>

<groupId>com.jianggujin</groupId>

<artifactId>IKAnalyzer-lucene</artifactId>

<version>8.0.0</version>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version>

</dependency>

</dependencies>


import org.apache.lucene.analysis.Analyzer;

import org.apache.lucene.analysis.TokenStream;

import org.apache.lucene.analysis.core.SimpleAnalyzer;

import org.apache.lucene.analysis.standard.StandardAnalyzer;

import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;

import org.junit.Test;

import org.wltea.analyzer.lucene.IKAnalyzer;


public class App {

英文分词器:

输入字符串-->分割字符串-->去除停用词

private Analyzer a1 = new StandardAnalyzer();

简单分词器

private Analyzer a2 = new SimpleAnalyzer();

中文分词器(词库分词)

private Analyzer a3 = new IKAnalyzer();


private String text = "What a beautiful girl! How beautiful the girl is!";

我们是中国人";


@Test

public void test() throws Exception {

analyzer(a3, text2);

}


private void analyzer(Analyzer analyzer, String text) throws Exception {

在这里,第一个参数没有实际作用

TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(text));

获取每个单词信息

CharTermAttribute attribute = tokenStream.addAttribute(CharTermAttribute.class);

tokenStream.reset();

while(tokenStream.incrementToken()) {

System.out.println(attribute);

}

tokenStream.end();

tokenStream.close();

}

}



文档

文档,就是要被索引的数据,在被搜索引擎索引之后的一种结构,下面的图有详细的解释,以下是两个原始文档

doc1:

飞雪连天射白鹿

doc2:

胡天八月即飞雪


正向索引

若我们使用mysql中的全文检索,那么mysql会对如上两个原始文档分别进行分词处理,结果如下:

飞雪连连天射白鹿


胡天八月即飞雪


假设我们要搜索的关键字是:飞雪,正向索引就会到第一个文档中去查找“飞雪”这个关键字,如果查找到了,则将第一个文档加入到结果中,再到第二个文档中查找“飞雪”这个关键字,如果查找到了,就将第二个文档加入到结果中。当文档的数量规模上到PB的时候,以正向索引的这种方式进行数据检索的话,效率将会很低!


倒排索引

倒排索引是按照分词与文档的映射建立的,如下:

1.简介与安装_elasticsearch_02



全文检索基本原理

1.简介与安装_分词器_03


关键在于:用空间换时间。创建好了倒排索引,在用户查询数据的时候,便可以利用倒排索引大大减少查询的时间。



Lucene中的重点概念

下图展示了很多个Lucene中的概念:

1.简介与安装_lucene_04


可以看出:

1. 在创建索引时用到了 分词器,在搜索数据时,也用到了分词器

2. 文档是由各个Field组成的,比如上图中的内容、大小、日期



相关性得分

在搜索的时候,输入的搜索内容,如果命中的分词越多,则相关性得分也就越多。比如搜索时如果输入“白鹿在飞雪中奔跑”,而“飞雪连天射白鹿”,就同时命中了“飞雪”和“白鹿”这两个词,而“白鹿原”则只命中了一个“白鹿”,所以前者的相关性得分是大于后者的,最终展现结果的时候,“飞雪连天射白鹿”就会排在“白鹿原”的前面。



2. 安装、启动

es比较吃内存,所以我建议大家为即将安装es的虚拟机设置大一点的内存,将来在安装好es以后,也就可以随时调整es内置的jvm的内存大小了。(-Xms2g -Xmx2g)

软件

下载地址

ElasticSearch

https://www.elastic.co/cn/start

Kibana

https://www.elastic.co/cn/start


2.1 创建账户

es要求必须以非root账户启动服务,所以我们创建以下账户

adduser elk

passwd elk


2.2 解压ElasticSearch

以root用户登录,上传elasticsearch-7.10.2-linux-x86_64.tar.gz到linux

1.简介与安装_分词器_05



并将elasticsearch-7.10.2-linux-x86_64.tar.gz移动到elk账户的家目录下

mv elasticsearch-7.10.2-linux-x86_64.tar.gz /home/elk/


进入/home/elk目录,然后解压

tar -zxvf elasticsearch-7.10.2-linux-x86_64.tar.gz


然后授予elk权限

chown -R elk /home/elk/elasticsearch-7.10.2/


2.3 启动es服务

为了让es服务能够被指定机器访问,在es家目录下的config目录下,修改es配置文件:

elasticsearch-7.10.2/config/elasticsearch.yml,可直接把该文件内容整体替换成以下内容

cluster.name: my-application

node.name: node-1


# 允许任何机器链接当前es服务

network.host: 0.0.0.0

http.port: 9200


# 有成为主节点资格的节点列表

# 127.0.0.1和[::1]都代表本机

discovery.seed_hosts: ["127.0.0.1", "[::1]"]

cluster.initial_master_nodes: "node-1"



修改/etc/security/limits.conf,设置系统最大线程个数(否则启动es服务时会报错:max number of threads [2988] for user [elk] is too low, increase to at least [4096]),在该配置文件的末尾追加以下内容:

* soft nofile 65535

* hard nofile 131072

* soft nproc 4096

* hard nproc 4096


修改/etc/sysctl.conf(否则启动es服务时会报错:max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144])

vm.max_map_count=262144


为了加载这个修改,再执行以下命令:

sysctl -p


es服务默认占用9200端口,所以我们要开放9200端口(切换到root用户再执行以下命令):

firewall-cmd --znotallow=public --add-port=9200/tcp --permanent

firewall-cmd --reload


切换到elk用户

su elk


启动es服务

./bin/elasticsearch



访问,能看到以下画面,就说明es服务已经启动成功了!

1.简介与安装_分词器_06



另外,如果不小心以root用户启动了es服务,那么服务肯定会启动失败的,更重要的是,在es的logs文件夹下也会产生本次启动失败的日志文件,这些日志文件的owner是root,这就导致,就算我们再以elk用户来启动es服务时,仍然会出现“没有权限”的提示,尽管这并不影响es服务的启动。所以每当我们不小心用root启动es服务之后,都应该妥善处理掉那些owner为root的日志文件。


Docker安装ElasticSearch

docker pull elasticsearch:7.11.2


docker run --name es -d -e ES_JAVA_OPTS="-Xms1024m -Xmx1024m" \

-e "discovery.type=single-node" -p 9200:9200 -p 9300:9300 \

elasticsearch:7.11.2


1.简介与安装_elasticsearch_07




2.4 启动Kibana

切换到root用户

su root


将kibana-7.10.2-linux-x86_64.tar.gz上传到linux,并移动到elk账户的家目录下

mv soft/kibana-7.10.2-linux-x86_64.tar.gz /home/elk/


进入/home/elk目录,解压

tar -zxvf kibana-7.10.2-linux-x86_64.tar.gz


授权

chown -R elk kibana-7.10.2-linux-x86_64


修改Kibana的配置文件config/kibana.yml,可用以下内容直接替换该配置文件中的内容:

# kibana端口

server.port: 5601

# 允许任意远程机器连接kibana

server.host: "0.0.0.0"

# kibana要连接的es服务的url

elasticsearch.hosts: ["http://192.168.3.128:9200"]


elasticsearch.requestTimeout: 60000 # Kibana等待elasticsearch响应的最大时间


切换到elk,进入到Kibana的根目录,执行以下命令,以启动Kibana

./bin/kibana


1.简介与安装_elasticsearch_08



切换到root,开放5601端口

firewall-cmd --znotallow=public --add-port=5601/tcp --permanent

firewall-cmd --reload


访问:

1.简介与安装_lucene_09



在首页点击“Dev tools”

1.简介与安装_lucene_10



点击以下的三角按钮,在右边看到结果,就说明环境搭建全部成功了:

1.简介与安装_分词器_11



Docker安装Kibana

docker pull kibana:7.11.2


docker run -d -e ELASTICSEARCH_HOSTS=http://192.168.217.128:9200 \

-p 5601:5601 kibana:7.11.2


1.简介与安装_分词器_12



3. 简单测试

查看所有节点

GET /_cat/nodes?v


查看所有节点的健康情况

GET /_cat/health?v


查看主节点信息

GET /_cat/master?v


查看索引

GET /_cat/indices?v



4. 分词器抢先体验

开篇,就重点介绍了分词器的概念和作用,当时用的是lucene中的分词器,当时是需要自己编码的,而在es中,分词器早已被封装了,我们直接请求即可:

GET _analyze

{

"analyzer": "standard",

"text": "How are you?"

}


GET _analyze

{

"analyzer": "standard",

我是中国人"

}