〈一〉ElasticSearch的介绍

发表日期:2019年9月18日java


什么是ElasticSearch


ElasticSearch是一个集数据存储数据搜索数据分析为一体的系统。它是分布式的,因此能利用分布式来提升其处理能力,具备高可用性和高伸缩性。若是你须要一个可以提供高性能的搜索服务的系统,那么它或许是一个好的选择。mysql

  • 数据存储:是指它可以以JSON格式来存储数据。若是你不在乎数据的搜索,你甚至能够像相似使用mongodb那样来单纯把它做为一个数据存储系统使用。
  • 数据搜索:是指它可以对JSON格式的数据进行全文检索等搜索。
  • 数据分析:是指它可以利用一些算法来对JSON文档数据进行分析,好比得出某个月的商品销售增加量。




核心能力

ElasticSearch是一个搜索系统,搜索就是从数据集合中搜索出咱们想要的数据,例如从大量的商品数据中搜索出咱们想要的某类商品。
  如今提一个需求,例如我有一个“文章”的表,我想搜索文章表中字段content中包含有'java'的数据。
若是你不使用ES,那么从开发角度来讲,日常咱们都是使用关系型数据库系统来存储数据,而后使用相似select name,age,address from student where name like '%李%'的语句经过模糊匹配来搜索符合指定条件的数据的。(对应到上面的需求应该是select name,author,content from article where content like '%java%'算法

 但其实上面这种基于模糊匹配的搜索方式的效率是比较低的,由于数据库系统的搜索一般是逐一扫描的,也就是从头至尾的来尝试匹配,某个字段的数据越多,可能须要尝试匹配的次数就会越多(试想一下从4000字的文章中从上到下只为找到一个字),这种查找就好像最低级的遍历查找(固然并非真的就是傻傻的遍历了,各个数据库系统都会采用各类算法来优化)。
 
 而ElasticSearch因为其内部创建了每一个词的索引表,当搜索某个词时,能够根据这个词从索引表中找到匹配的记录,因此效率比较高(就好像记录了某个词的坐标,有了坐标,就能根据坐标很是快地找到那个词)。
(这里举个相似的栗子:相信你们都用过字典,那么普通的数据库搜索就好像从第一页到最后一页找一个词,而ElasticSearch根据这个词的部首结构从“部首-字的对应表”中直接查找到那个字的页数,这个效率直接就是天差地别了!)sql

 另外,数据库的搜索是根据指定词直接查找的,它是很笨的!它不能查找到某些意义上“相似”的结果,好比我搜索“mother”,但若是某个记录中包含“mom”这个词,那这条记录也应该被展现出来,而数据库的普通搜索作不到。
 而这个操做ElasticSearch就能够作到,因为它内部有分词器,在创建索引的过程当中,分词器能够把数据中的某些词都认为是指定的某一个词(好比把mother,mom统统都使用mom做为索引词),再用这个词来创建索引,而后在进行搜索的时候,将输入的词也进行一样的转化,再根据这个词从索引表中查找到符合的记录结果,这样就能够把那些意义相近的结果也搜索出来。mongodb

因此说,ElasticSearch解决了普通全文搜索的搜索效率低下和搜索不智能的问题。typescript




ES的搜索核心

介绍两个搜索方法:顺序扫描查找、全文搜索数据库

上面有说到数据库的搜索和ElasticSearch的搜索。
常见的关系型数据库的针对某个字段中的数据的搜索是顺序扫描查找,从头至尾去尝试匹配,也就是所谓的遍历查找,固然算法可能没有那么低级。(如今一些数据库系统也在尝试优化全文搜索功能。)json

而ElasticSearch的搜索是全文搜索,而什么是全文搜索?
全文搜索能够根据必定方式把非结构化的数据对应到一种结构化的标识,从而能够经过标识来检索到指定的非结构化的数据记录。
这句话可能有点难以理解,举个例子理解,好比有一大堆食物你须要去认识,食物自己能够被认做是非结构化的数据,由于他们都是独特的,但若是咱们利用他们的颜色来划分的话就能够初步地将他们进行结构化划分,这个就是一种简单的将数据结构化的手段。在ElasticSearch中,这个把非结构化的数据对应到一种结构化的标识的方式就是倒排索引,下面介绍倒排索引来理解这个概念。windows

在ElasticSearch中,处理这些非结构化的数据的方式就是创建倒排索引(Inverted Index)。
什么是倒排索引呢?
倒排索引把数据进行了拆分(好比某个字段的数据为hello world,那么就会被拆分红hello和world),咱们使用这些拆分的词来做为索引词来创建索引表,在以hello为索引词的记录中,有对hello world的指向,world也是如此。
固然,这里的拆分并非真实的拆分,原始的数据依然存储在elasticsearch中,咱们另外建立了一个索引文件来存储。

下面是一个使用倒排索引搜索的示例
1.首先,假设咱们有一个字段的数据是"I thank my mother",当咱们把这个数据存储到ElasticSearch中,ElasticSearch内部使用分词器进行处理数据,分词器用于将非结构化数据中的词进行拆分和转换,因而把"I thank my mother"拆解成了"I"、"thank"、"my"、"mother"。

2.当把数据拆分出来后(拆分红的数据单位咱们称为“词”),就会把这些词创建索引,ElasticSearch内部有一个索引表,用于创建词与数据的对应,结构相似以下(真实格式还会有词的频率、数据长度等信息),索引表存储了词和词所在记录的ID集合,因此能够经过某个词来快速搜索出相关的记录,好比搜索"I",那么会返回1和2,而后能够快速根据ID来获取对应的数据。【请注意,下图只是方便理解,并非真实的格式】

3.而后咱们搜索的时候,分词器也先把咱们输入的内容处理(为了与索引表的词统一),而后再从索引表中查找,返回对应的数据记录集合。
例如我输入mother,mother会先转成mom,而后从索引表中找到mom,返回包含mom的记录的ID,而后根据ID获取对应数据,也就是“I like my mom”




搜索引擎选择

Lucene也是一种搜索引擎,为何不直接使用Lucene?
ElasticSearch实际上底层使用的就是Lucene,虽然Lucene也有不少功能,但Lucene的使用难度较大(也正是使用难度高因此ElasticSearch才对Lucene进行封装),并且ElasticSearc的高级功能也很强大,ES支持了多样的数据分析。除了基本的功能,集群能力也是一个问题,Lucene一开始没有考虑集群,因此对于存储在不一样服务器上的大量数据的交互比较麻烦,而ElasticeSearch一开始就是集群思想的,数据存储以一个ElasticSearch节点为单位,多个节点的数据能够交流。
因为底层是Lucene,因此,对于一些elasticsearch底层的东西,有时候你彻底能够参照Lucene,好比索引词文件的存储等。

为何不是Solr?
Solr也是一个知名的搜索引擎,它与ElasticSearch各有好处,Solr适用于一些非实时搜索系统(新增的数据不要求立刻查出来的),而ElasticSearch适用于一些实时搜索要求较高的系统(电商平台等要求新商品立刻可查的系统)。由于Solr在创建索引时,搜索效率降低,实时索引搜索效率不高,而ElasticSearch创建索引的速度较快。

ElasticSearch有一个很是显著的特性"NRT":NRT全称Near Real Time,近实时,意思是你插入的数据几乎能够“立刻”就能够被搜索出来。这也是为何它能使用在实时更新要求高的场景的缘由。




搜索的处理

上面提了词的拆分,这里提一些关于底层的搜索处理的内容。介绍一下ElasticSearch另外一个协助搜索的关键组件--分词器。ElasticSearch的全文搜索离不开分词器的帮助。

分词器一般由分解器tokenizer和词元过滤器token filter组成。

分词器对数据的分词处理:为了提升索引的效率,ElasticSearch会数据进行处理,处理方式主要有字符过滤、词转换、词拆分
字符过滤:过滤一些特殊字符,例如&||、html标签,由于这些词一般搜索意义不大。

词转换:把一些意义相同的词统一转成一个词,(同词义转换)好比mom,mother统一转成mom;(大小写转换)he,He统一归为He;还处理一些词意义不大的词(停用词清除),好比英文的“the”,“to”,这些词使用频率很高,但没有具体意义。

词拆分:进行数据的拆分,拆分红词,好比把good morning,mom拆分红good,morining,mom。另外,词拆分并不彻底是按照数据的最小单位分解的,某一些分词器会把一些词进行组合,由于一些词的组合起来才有索引的意义,好比中文的一些词一般要组合起来才有意义,好比“大”和“家”要组成“你们”才有比较具体的意义,这是为了确保索引词的最小单位是有意义的(好比英文mom的最小单位是m,o,m,内部的分词器要可以区分出mom整个是有意义的才能够确保是采用mom做为索引,而不是采用m和o,也正是由于这个问题,因此英文分词器不能用于中文分词器)。【分词器有不少个,默认的分词器是不能适当对中文数据分词的,它只能把一个个数据按最小的单位拆分,由于英文分词器不能分清楚怎么把词拆分才有意义,因为配置分词器是一个较为靠后的知识点,因此前期将以英文数据为测试数据。

分词文件的存储:
分词文件通常包括三种文件:词典文件,频率文件,位置文件。
词典文件保存了关键词(索引词),还保留了指向频率文件和位置文件的指针。
频率文件记录了词出现的频率。
位置文件记录了这些词出如今哪些数据中。




补充:

  • 数据库不是被替代,而是被补充。有时候会将数据同时存储到数据库和ElasticSearch中,在单个查看的时候能够从数据库中查询,在搜索的时候从ElasticSearch中查询;也有的项目因为数据比较简单彻底使用elasticsearch来存储数据。
  • ElasticSearch是分布式的,但咱们是不须要对其集群进行部署的,它自动进行了集群部署和节点发现等功能,咱们只需进行不多的配置就能管理集群。在比较靠后的内容才会讲到如何深刻管理集群。

小节总结:

  • 1.本小节简单讲述了ElasticSearch是什么
  • 2.传统搜索的不足
  • 3.使用ElasticSearch搜索的好处
  • 4.全文搜索和倒排索引
  • 5.与其余搜索引擎的比较
  • 6.ElasticSearch对于索引词的处理(这个内容是提早讲的内容,是为了帮助了解倒排索引如何创建索引)

基本学习环境搭建


如何操做ElasticSearch

首先要说的是,ElasticSearch是一款软件,有点相似MySQL,咱们要操做它的时候,也要给它发送它能识别的命令,而ElasticSearch是面向restful(不知道restful的自查吧)的,因此咱们发送的命令是有点相似发送http请求的。

mysql是3306端口,而elasticsearch支持9200和9300端口操做,其中9200面向http,9300面向tcp。9200可以使用普通的http请求来操做elasticsearch,9300须要链接elasticsearch以后再执行命令。

  • 对于9200,由于面向http,因此咱们可使用postman发http请求来操做elasticsearch。
  • 对于9300,由于面向tcp,咱们一般使用一些elasticsearch管理工具(如kibana)进行链接elasticsearch以后再执行命令。(相似navicat之于mysql)


下载、安装和运行(Based Windows)



咱们首先来搭建好学习环境,主要是ElasticSearch和Kibana。【请注意,Elasticsearch依赖Java环境】
【Kibana是可选的,下面会介绍一下基于postman的对ElasticSearch操做。】,Kibana是一款对ElasticSearch进行管理的软件,咱们能够在Kibana上执行ElasticSearch的命令。

下载:


  • ElasticSearch下载:ElasticSearch下载【这里以6.2的为例】
  • Kibana下载:Kibana下载 【两个下载都是同一个位置,这里下载以6.2的为例】【Kibana的版本尽可能与ElasticSearch的一致,有些版本会链接错误】


安装:

  • 两个软件都是不须要安装的,下载后,直接解压便可。

运行:

  • 对于ElasticSearch,能够直接在elasticsearch-6.2.0\bin中运行elasticsearch.bat,当提示“started”时,表示运行成功。
  • 对于Kibana,能够直接在kibana-6.2.0-windows-x86_64\bin中运行kibana.bat,当提示“Server running at http://localhost:5601”时,表示运行成功。【要先运行ElasticSearch再运行Kibana,由于它要与ElasticSearch进行链接】



如何操做ES

ElasticSearch默认的TCP服务端口是9300,Kibana的服务端口是5601,当咱们启动了Kibana以后,它会默认帮咱们链接上9300,因此咱们能够从http://localhost:5601中进入Kibana的管理界面来管理ElasticSearch。
若是你是第一次使用,那么ElasticSearch会自动建立一个名为elasticsearch的集群,Kibana会在这个节点中初始化一个index


咱们在Kibana的DevTools中执行一些命令来看一下ElasticSearch。【从http://localhost:5601中进入】



在输入命令GET /_cat/health?v后,点击该行右侧的执行按钮。【GET /_cat/health?v是查看集群的健康状态的命令】

而后就能够在右侧的结果窗口中查看命令执行结果。

【你如今大概都是看不懂命令的意义和结果的意义的了,不过你应该知道哪里输入命令哪里看执行结果了】



基于postman操做

postman是一个用来发请求的软件,可使用restful风格的请求来操做elasticsearch。
好比上面的查看集群的命令:GET /_cat/health?v
转成基于restful的是:http://localhost:9200/_cat/health?vIP:9200+命令,其中9200是用于接收restful请求的es监听端口。


补充:

上面的第一次使用并无涉及到具体的知识,只是让你熟悉一下如何使用Kibana来操做ElasticSearch。下面讲到具体知识点才会具体使用。

小节总结

  • 1.讲了ES如何提供服务:9200,9300
  • 2.讲了如何下载、安装、运行ElasticSearch和Kibana
  • 3.讲述了如何在Kibana中操做ElasticSearch
  • 4.讲述了如何在postman中操做ElasticSearch

须要了解的概念


分布式模型相关

  • 集群Cluster:所谓集群,就是多个服务节点的集合,集群意味着这些节点是可以相互交流的,否则没法进行数据交互。集群的默认名称是"elasticsearch",多个提供服务的节点会根据集群名来自动加入集群
  • 节点Node:节点是集群的一部分,是集群的最小单元,是能够提供服务的节点。
  • 分片shard:分片位于节点上,分片是elasticsearch数据存储的单元,elasticsearch中的数据会存储在分片中。分片能够存储在任意一个节点上。分片分为主分片Primary Shard和副本分片Replica Shard。
  • 主分片Primary Shard:当存储一个文档document的时候,会先存储到主分片中,而后再复制到其余的副本分片Replica Shard中。
  • 副本分片Replica Shard:副本分片是主分片的复制(备份)。默认状况下,主分片有一个副本分片,主分片不能修改,但副本分片能够后续再增长。
    • 为了保证数据的不丢失,一般来讲Replica Shard不能与其对应的Primary Shard处于同一个节点中。【由于万一这个节点损坏了,那么存储在这个节点上的原数据(primary shard)和备份数据(replica shard)就所有丢失了】
    • 当主分片挂掉的时候,会选择一个副本分片做为主分片。
    • 查询能够在主分片或副本分片上进行查询,这样能够提供查询效率。【但数据的修改只发生在主分片上。】
    • 一个Primary Shard能够有多个Replica Shard,默认建立是1个。


数据存储相关

数据存储在shard中,shard中的数据是以文档document为单位的。document存储在index和type划分的逻辑空间中。document以json为格式,每个key-value中key能够称为域Field。

  • 索引Index:索引是存储具备相同结构的document的集合,意义上有点相似关系型数据库中的数据库,用于存储一系列数据,好比能够说“商品”索引,通常都是个大类,小逻辑划分由Type处理。
  • 类型Type:类型是索引的逻辑分区,意义有点相似关系型数据库中的数据表。用来划分索引下不一样子类型的数据,好比商品(索引)能够有电子产品(类型),药品(类型)。在同一个分类下的数据通常都具备同种特征,用来定义数据的字段的数量通常也是相同的。每个document都有一个type和一个id,在存储文档的时候须要指定索引、类型和ID。
  • 文档Document:相似于关系型数据库中的记录,是ElasticSearch的数据存储的基本单位,格式与JSON相同。例如:
{
  "book_id": 1,
  "book_name": "Java Core ",
  "book_desc": "A good book, you know!",
  "category_id": "1",
  "category_name": "Computer"
}
  • 域Field:相似于关系型数据库中的字段。
  • elasticsearch是面向restful的,下面是restful请求与elasticsearch操做的对应:
请求方法 对应操做 说明
GET 读取 获取数据
POST 新增 新增数据
PUT 修改 修改数据或增长数据
DELETE 删除 删除数据
  • 索引用来存储数据,分片也是用来存储数据,它们是怎么对应的?一个索引存储在多个分片上,默认状况下,一个索引有五个主分片,五个副本分片。主分片的数量一旦定下来就不能再修改,但副本分片的数量还能够修改。




小节总结

  • 讲了一下ElasticSearch的集群概念,节点是集群的基础服务单位,节点能够提供数据读写服务,数据按分片来存储,主分片是主要数据,能够读取和修改数据,副本分片不支持修改数据。
  • 主分片和副本分片的互斥性(为了保证数据不一样时丢失)
  • elasticsearch的数据的逻辑存储结构(索引->类型->文档)。索引是数据的大分类,类型是数据的小分类。
  • 文档的格式
  • 索引与分片的关系。一个索引存储在多个分片上

Hello ElasticSearch


前面提了一下index,type,document,说了ElasticSearch的逻辑存储空间。
下面以两个实例:“写document->读document”和“写document->搜索document“来初步演示一下如何存储数据和获取数据。


写->读

若是咱们要向ElasticSearch中写入一份数据(document),命令的语法应该以下:

PUT /index名称/type名称/document的ID
{
    document的数据
}

上面的语法的意思就是向一个index的一个type中插入一个document,document用id做为标识,后面咱们取document的数据也将以这个id为依据。其中index,type是能够不须要咱们预建立的,在咱们还不会如何建立index和type的时候,你能够先随便打个名字(若是ElasticSearch检测到咱们输入的index和type是不存在的,那么它就会以默认的规则帮咱们建立出来)。

请在kibana的devtool中执行如下命令来存储一份document:

PUT /douban/book/1
{
  "book_id":1,
  "book_name":"A Clockwork Orange",
  "author":"Anthony Burgess",
  "summary":"Fully restored edition of Anthony Burgess' original text of A Clockwork Orange, with a glossary of the teen slang 'Nadsat', explanatory notes, pages from the original typescript, interviews, articles and reviews Edited by Andrew Biswell With a Foreword by Martin Amis 'It is a horrorshow story ...' Fifteen-year-old Alex likes lashings of ultraviolence. He and his gang of friends rob, kill and rape their way through a nightmarish future, until the State puts a stop to his riotous excesses. But what will his re-education mean? A dystopian horror, a black comedy, an exploration of choice, A Clockwork Orange is also a work of exuberant invention which created a new language for its characters. This critical edition restores the text of the novel as Anthony Burgess originally wrote it, and includes a glossary of the teen slang 'Nadsat', explanatory notes, pages from the original typescript, interviews, articles and reviews, shedding light on the enduring fascination of the novel's 'sweet and juicy criminality'. Anthony Burgess was born in Manchester in 1917 and educated at Xaverian College and Manchester University. He spent six years in the British Army before becoming a schoolmaster and colonial education officer in Malaya and Brunei. After the success of his Malayan Trilogy, he became a full-time writer in 1959. His books have been published all over the world, and they include The Complete Enderby, Nothing Like the Sun, Napoleon Symphony, Tremor of Intent, Earthly Powers and A Dead Man in Deptford. Anthony Burgess died in London in 1993. Andrew Biswell is the Professor of Modern Literature at Manchester Metropolitan University and the Director of the International Anthony Burgess Foundation. His publications include a biography, The Real Life of Anthony Burgess, which won the Portico Prize in 2006. He is currently editing the letters and short stories of Anthony Burgess.",
  "press":"Penguin Classic",
  "publication_date":"2000-02-22"
}

若是要获取ES中存储的document,命令的语法应该以下:

GET /index名/type名/id

同样的,请在kibana中执行下述命令来获取咱们上面存储的document:

GET /douban/book/1

返回结果:【返回index名称,type名称,id,原始文档等数据】

很明显地,咱们获取到了咱们刚刚存储进去的数据。


写->搜索

同样的,咱们写多一份数据进ES中:

PUT /douban/book/2
{
  "book_id":2,
  "book_name":"Kubernetes in Action",
  "author":"Marko Luksa",
  "summary":"Kubernetes in Action teaches you to use Kubernetes to deploy container-based distributed applications. You'll start with an overview of Docker and Kubernetes before building your first Kubernetes cluster. You'll gradually expand your initial application, adding features and deepening your knowledge of Kubernetes architecture and operation. As you navigate this comprehensive guide, you'll explore high-value topics like monitoring, tuning, and scaling.Kubernetes is Greek for \"helmsman,\" your guide through unknown waters. The Kubernetes container orchestration system safely manages the structure and flow of a distributed application, organizing containers and services for maximum efficiency. Kubernetes serves as an operating system for your clusters, eliminating the need to factor the underlying network and server infrastructure into your designs.",
  "press":"Manning Publications",
  "publish_date":"2017-08-31"
}

下面将演示搜索的功能,搜索的其中一种语法是:

GET /index名/type名/_search
{
    "query":{
        "match":{
            "字段Field名称":"用于搜索的关键字"
        }
    }
}

那么,根据咱们以前存储的数据,若是咱们要查询summary字段有Orange的数据的话,命令以下:

GET /douban/book/_search
{
  "query": {
    "match": {
      "summary":"Orange"
    }
  }
}

返回的结果:


小节总结

  • 这小节涉及到了数据的插入,读取,搜索,但仅仅是一个Hello ElasticSearch的例子,因此没有讲到插入数据应该有的前置知识。理论上,你只须要记得这个流程便可。后面会补充这个流程中没有提到的内容。

--To Be Continue

相关文章
相关标签/搜索