ElasticSearch入门到精通详解

原文链接:https://www.jianshu.com/p/60b242cbd8b4

1.ElasticSearch的简介

Elasticsearch的特点

1)可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司;也可以运行在单机上,服务小公司
2)Elasticsearch不是什么新技术,主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;lucene(全文检索),商用的数据分析软件(也是有的),分布式数据库(mycat)
3)对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分钟部署一下ES,就可以作为生产环境的系统来使用了,数据量不大,操作不是太复杂
4)数据库的功能面对很多领域是不够用的(事务,还有各种联机事务型的操作);特殊的功能,比如全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理;Elasticsearch作为传统数据库的一个补充,提供了数据库所不能提供的很多功能

什么是搜索?
1)百度,谷歌,必应。我们可以通过他们去搜索我们需要的东西。但是我们的搜索不只是包含这些,还有京东站内搜索啊。

2)互联网的搜索:电商网站。招聘网站。新闻网站。各种APP(百度外卖,美团等等)

3)windows系统的搜索,OA软件,淘宝SSM网站,前后台的搜索功能

总结:搜索无处不在。通过一些关键字,给我们查询出来跟这些关键字相关的信息
什么是全文检索
全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。

全文检索的方法主要分为按字检索和按词检索两种。按字检索是指对于文章中的每一个字都建立索引,检索时将词分解为字的组合。对于各种不同的语言而言,字有不同的含义,比如英文中字与词实际上是合一的,而中文中字与词有很大分别。按词检索指对文章中的词,即语义单位建立索引,检索时按词检索,并且可以处理同义项等。英文等西方文字由于按照空白切分词,因此实现上与按字处理类似,添加同义处理也很容易。中文等东方文字则需要切分字词,以达到按词索引的目的,关于这方面的问题,是当前全文检索技术尤其是中文全文检索技术中的难点,在此不做详述。
什么是倒排索引
以前是根据ID查内容,倒排索引之后是根据内容查ID,然后再拿着ID去查询出来真正需要的东西。

 
image.png

什么是Lucene
Lucene就是一个jar包,里面包含了各种建立倒排索引的方法,java开发的时候只需要导入这个jar包就可以开发了。
Lucene的介绍及使用
典型的用空间换时间。
ES 和 Lucene的区别
Lucene不是分布式的。

ES的底层就是Lucene,ES是分布式的
为什么不用数据库去实现搜索功能?
我们用搜索“牙膏”商品为例

 
image.png

如果用我们平时数据库来实现搜索的功能在性能上就很差。
ES的由来
因为Lucene有两个难以解决的问题,

1)数据越大,存不下来,那我就需要多台服务器存数据,那么我的Lucene不支持分布式的,那就需要安装多个Lucene然后通过代码来合并搜索结果。这样很不好

2)数据要考虑安全性,一台服务器挂了,那么上面的数据不就消失了。

ES就是分布式的集群,每一个节点其实就是Lucene,当用户搜索的时候,会随机挑一台,然后这台机器自己知道数据在哪,不用我们管这些底层、

 
image.png

ES的优点
1.分布式的功能

2、数据高可用,集群高可用

3.API更简单

4.API更高级。

5.支持的语言很多

6.支持PB级别的数据

7.完成搜索的功能和分析功能

基于Lucene,隐藏了Lucene的复杂性,提供简单的API

ES的性能比HBase高,咱们的竞价引擎最后还是要存到ES中的。
搜索引擎原理
反向索引又叫倒排索引,是根据文章内容中的关键字建立索引。
搜索引擎原理就是建立反向索引。
Elasticsearch 在 Lucene 的基础上进行封装,实现了分布式搜索引擎。
Elasticsearch 中的索引、类型和文档的概念比较重要,类似于 MySQL 中的数据库、表和行。
Elasticsearch 也是 Master-slave 架构,也实现了数据的分片和备份。
Elasticsearch 一个典型应用就是 ELK 日志分析系统。
ES的作用
1)全文检索:

类似 select * from product where product_name like '%牙膏%'

类似百度效果(电商搜索的效果)

2)结构化搜索:

类似 select * from product where product_id = '1'

3)数据分析

类似 select count (*) from product
ES的安装
参考https://www.jianshu.com/p/198a874cc14f
直接解压就能用(针对中小型项目),大型项目还是要调一调参数的

2.用数据库实现搜素的功能

 
image.png

3.ES的核心概念

3.1 NRT(Near Realtime)近实时


 
image.png

3.2 cluster集群,ES是一个分布式的系统
ES直接解压不需要配置就可以使用,在hadoop1上解压一个ES,在hadoop2上解压了一个ES,接下来把这两个ES启动起来。他们就构成了一个集群。

在ES里面默认有一个配置,clustername 默认值就是ElasticSearch,如果这个值是一样的就属于同一个集群,不一样的值就是不一样的集群。

3.3 Node节点,就是集群中的一台服务器
3.4 Index(索引-数据库)
我们为什么使用ES?因为想把数据存进去,然后再查询出来。

我们在使用Mysql或者Oracle的时候,为了区分数据,我们会建立不同的数据库,库下面还有表的。

其实ES功能就像一个关系型数据库,在这个数据库我们可以往里面添加数据,查询数据。

ES中的索引非传统索引的含义,ES中的索引是存放数据的地方,是ES中的一个概念词汇

index类似于我们Mysql里面的一个数据库 create database user; 好比就是一个索引库

3.5 Type(类型-表)
ES6以后一个index只能有一个type,为了提高查询效率。

3.6 Document(文档-行)
文档就是最终的数据了,可以认为一个文档就是一条记录。

是ES里面最小的数据单元,就好比表里面的一条数据

3.7 Field(字段-列)
好比关系型数据库中列的概念,一个document有一个或者多个field组成。

3.8 mapping(映射-约束)
数据如何存放到索引对象上,需要有一个映射配置,包括:数据类型、是否存储、是否分词等。

elasticsearch与数据库的类比
关系型数据库(比如Mysql)非关系型数据库(Elasticsearch)
数据库Database 索引Index
表Table 类型Type
数据行Row 文档Document
数据列Column 字段Field
约束 Schema 映射Mapping

3.9 shard:分片
一台服务器,无法存储大量的数据,ES把一个index里面的数据,分为多个shard,分布式的存储在各个服务器上面。

kafka:为什么支持分布式的功能,因为里面是有topic,支持分区的概念。所以topic A可以存在不同的节点上面。就可以支持海量数据和高并发,提升性能和吞吐量

3.10 replica:副本
一个分布式的集群,难免会有一台或者多台服务器宕机,如果我们没有副本这个概念。就会造成我们的shard发生故障,无法提供正常服务。

我们为了保证数据的安全,我们引入了replica的概念,跟hdfs里面的概念是一个意思。

可以保证我们数据的安全。

在ES集群中,我们一模一样的数据有多份,能正常提供查询和插入的分片我们叫做 primary shard,其余的我们就管他们叫做 replica shard(备份的分片)

当我们去查询数据的时候,我们数据是有备份的,它会同时发出命令让我们有数据的机器去查询结果,最后谁的查询结果快,我们就要谁的数据(这个不需要我们去控制,它内部就自己控制了)

总结:

在默认情况下,我们创建一个库的时候,默认会帮我们创建5个主分片(primary shrad)和5个副分片(replica shard),所以说正常情况下是有10个分片的。

同一个节点上面,副本和主分片是一定不会在一台机器上面的,就是拥有相同数据的分片,是不会在同一个节点上面的。

所以当你有一个节点的时候,这个分片是不会把副本存在这仅有的一个节点上的,当你新加入了一台节点,ES会自动的给你在新机器上创建一个之前分片的副本。


 
image.png

3.11 举例

比如一首诗,有诗题、作者、朝代、字数、诗内容等字段,那么首先,我们可以建立一个名叫 Poems 的索引,然后创建一个名叫 Poem 的类型,类型是通过 Mapping 来定义每个字段的类型。

比如诗题、作者、朝代都是 Keyword 类型,诗内容是 Text 类型,而字数是 Integer 类型,最后就是把数据组织成 Json 格式存放进去了。

 
image.png

Keyword 类型是不会分词的,直接根据字符串内容建立反向索引,Text 类型在存入 Elasticsearch 的时候,会先分词,然后根据分词后的内容建立反向索引。
 
image.png

4. ES集群的安装

以后补充

5. 安装 Kibana

https://www.jianshu.com/p/198a874cc14f

6. ES的相关命令

GET _cat/health 查看集群的健康状况

GET _all

PUT 类似于SQL中的增

DELETE 类似于SQL中的删

POST 类似于SQL中的改

GET 类似于SQL中的查

index的操作:

PUT /aura_index 增加一个aura_index的index库


 
image.png

GET _cat/indices 命令查询ES中所有的index索引库


 
image.png

5:代表的是 primary shard的个数

1:代表的是replica shard的个数是5,因为副本数为1代表有5个副分片,注意这个地方说的1是不包括自己本身的,我们的HDFS block3代表的是包括自己本身的

DELETE /aura_index 删除一个aura_index的index库


 
image.png

7. ES的CURD操作

通过演示一个电商的例子,感受到ES的语法特点

1)插入一条商品数据


 
image.png

注意:我们插入数据的时候,如果我们的语句中指明了index和type,如果ES里面不存在,默认帮我们自动创建

2)查询商品数据
使用这种语法: GET /index/type/id


 
image.png

3)修改商品数据

使用POST来修改数据,其实使用PUT也可以实现修改数据,原理和hbase比较像。POST的修改数据的方法在第4条中


 
image.png

 
image.png

换个方式,下面这种操作也是成功的,会丢数据,是全局的修改


 
image.png

 
image.png

4)删除商品数据
 
image.png

再次插入之前的数据,发现version是5,这就说明跟hbase是类似的,不会立刻删除,会在合适的时机进行删除。


 
image.png

这次我们使用POST的方式进行修改数据,POST是局部更新数据,别的数据不动。PUT是全局更新
 
image.png

 
image.png

5)接着插入两条数据
 
image.png

 
image.png

现在查看所有数据,类似于全表扫描
 
image.png

took:耗费了6毫秒

shards:分片的情况

hits:获取到的数据的情况

total:3 总的数据条数

max_score:1 所有数据里面打分最高的分数

_index:"ecommerce" index名称

_type:"product" type的名称

_id:"2" id号

_score:1 分数,这个分数越大越靠前出来,百度也是这样。除非是花钱。否则匹配度越高越靠前


 
image.png

 
image.png

8.DSL语言

ES最主要是用来做搜索和分析的。所以DSL还是对于ES很重要的

下面我们写的代码都是RESTful风格

query DSL:domain Specialed Lanaguage 在特定领域的语言

案例:我们要进行全表扫描使用DSL语言,查询所有的商品


 
image.png

使用match_all 可以查询到所有文档,是没有查询条件下的默认语句。

案例:查询所有名称里面包含chenyi的商品,同时按价格进行降序排序

如上图所示,name为dior chenyi的数据会在ES中进行倒排索引分词的操作,这样的数据也会被查询出来。


 
image.png

match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。

下面我们按照价格进行排序:因为不属于查询的范围了。所以要写一个 逗号


 
image.png

这样我们的排序就完成了

案例:实现分页查询

条件:根据查询结果(包含chenyi的商品),再进行每页展示2个商品


 
image.png

案例:进行全表扫面,但返回指定字段的数据

现在的情况是把所有的数据都返回了,但是我们想返回指定字段的数据内容就需要下面的方法了


 
image.png

案例:搜索名称里面包含chenyi的,并且价格大于250元的商品

相当于 select * form product where name like %chenyi% and price >250;

因为有两个查询条件,我们就需要使用下面的查询方式

如果需要多个查询条件拼接在一起就需要使用bool

bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含以下操作符:

must :: 多个查询条件的完全匹配,相当于 and。

must_not :: 多个查询条件的相反匹配,相当于 not。

should :: 至少有一个查询条件匹配, 相当于 or。

这些参数可以分别继承一个过滤条件或者一个过滤条件的数组
 
image.png

案例:展示一个全文检索的效果


 
image.png

首先查询条件也会进行分词

kama

chenyi

并集

案例:不要把条件分词,要精确匹配

但是我们现有有一种需求我就是想查询kama chenyi不要分词,要精确匹配到


 
image.png

百度就类似于这样

案例:把查询结果进行高亮展示


 
image.png

<em>kama</em>这个标签是默认的标签,是可以自定义的进行替换的,比如我们可以替换成<span style="color:red">kama</span>,把这个输出到网页上,自然而然就是红色的了。

9.聚合分析

案例:计算每个标签tag下商品的数量

按标签进行分组类似于 select count(*) from product group by tag;


 
image.png

 
image.png

terms 跟 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配

error是报错,但是这个语句是对的,这个报错在ES2之前是没有的,在ES5以后才有的,在5中fielddata=true 默认是false,以前都是true

group_by_tag是个名字随意取

所以我们需要先执行下面的代码进行一下设置的修改:


 
image.png

再次执行一次


 
image.png

如果不想显示具体内容,加上"size":0
GET ecommerce/product/_search
{
  "size": 0,
  "aggs": {
    "group_by_tags": {
      "terms": {
        "field": "tags"
      }
    }
  }
}

案例:对商品名称里面包含chenyi的,计算每个tag下商品的数量


 
image.png

案例:查询商品名称里面包含chenyi的数据,并且按照tag进行分组,计算每个分组下的平均价格


 
image.png

案例:查询商品名称里面包含chenyi的数据,并且按照tag进行分组,计算每个分组下的平均价格,按照平均价格进行降序排序
 
image.png

注意写的位置

案例:查询出producer里面包含producer的数据,按照指定的价格区间进行分组,在每个组内再按tag进行分组,分完组以后再求每个组的平均价格,并且按照降序进行排序

range过滤允许我们按照指定范围查找一批数据


 
image.png

 
image.png

Elasticsearch对复杂分布式机制的透明隐藏特性

1)Elasticsearch是一套分布式系统,分布式是为了应对大数据量,隐藏了复杂的分布式机制

分片机制(我们之前随随便便就将一些document插入到es集群中,我们没有关心过数据是怎么进行分片的,数据到哪个shard中去)

cluster discovery(集群发现机制,我们之前做集群status从yellow转green,直接启动第二个es进程,那个进程直接作为一个node自动就发现了集群,并且加入了进去,还接受了部分数据,replica shard)

shard负载均衡(假设现在有3个node,总共有25个shard要分配到3个节点上去,es会自动进行均匀分配,以保持每个节点的均衡的读写负载请求)

shard副本请求路由集群扩容shard重分配

2)Elasticsearch的垂直扩容与水平扩容

垂直扩容:采购更强大的服务器,成本高昂,会有瓶颈

水平扩容:业界经常采用的方式,采购越来越多的普通服务器,性能比较一般,但是很多普通服务器组织在一起,就能构成强大的计算和存储能力。

3)增加或减少节点时的数据rebalance:
比如现在有3个节点,4个shard。这样肯定有一台节点上存储2个shard,总会有那么一台节点负荷重一点,当增加一个节点时,es集群会自动把有2个shard的节点分出一个shard给新增加的节点,保持负载均衡。

4)master节点
管理es集群的元数据:比如创建或删除index,维护索引元数据,节点的增加和删除,维护集群的元数据。

默认情况下,会自动选择出一台节点,作为master节点。

master节点不承载所有的请求,所以不会是一个单点瓶颈。

5)节点对等的分布式架构
节点对等,每个节点都能接收所有的请求

自动请求路由(如果请求要找的数据不在这台节点上,这个节点会自动把请求路由到数据所在的节点)

响应收集(数据所在节点会接收到其他节点发送的请求,并且响应回client)

shard&replica机制梳理

(1)index包含多个shard
(2)每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整的建立索引和处理请求的能力
(3)增减节点时,shard会自动在nodes中负载均衡
(4)primary shard和replica shard,每个document肯定只存在于某一个primary shard以及其对应的replica shard中,不可能存在于多个primary shard
(5)replica shard是primary shard的副本,负责容错,以及承担读请求负载
(6)primary shard的数量在创建索引的时候就固定了,replica shard数量可以随时修改
(7)primary shard的默认数量是5,replica默认是1,默认有10个shard,5个primary shard,5个replica shard
(8)primary shard不能和自己的replica shard放在同一个节点上(否则节点宕机,primary shard和副本全部丢失,起不到容错作用),但是可以和其他primary shard的replica shard放在同一个节点

单node环境下创建index是什么样子

(1)单node环境下,创建一个index,有3个primary shard,3个replica shard
(2)集群status是yellow
(3)这个时候,只会将3个primary shard分配到仅有的一台node上去,另外3个replica shard无法分配
(4)集群可以正常工作,但是一旦出现节点宕机,数据全部丢失,而且集群不可用,无法承载任何请求

PUT /test_index
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  }
}
原文地址:https://www.cnblogs.com/fswhq/p/13750386.html