Elasticsearch教程-从入门到精通

各位运维同行朋友们,你们好,很是高兴能有这么个机会与你们一块儿交流一些技术问题。此前的各位分享达人们在技术领域或管理领域均有十分精彩的分享,他们带给咱们的是多个领域中研究或实践的最前沿知识。这使我本人获益良多,首先要郑重感谢他们。数据库

   开始以前,本人首先作一下自我介绍。编程

   马永亮,马哥Linux运维培训创始人,已直接培养Linux运维工程师一千多人,他们绝大多数从事Linux运维和相关管理岗位,就业公司包括但不限于阿里、腾讯、百度、京东、网易、新浪、搜狐、大众点评、饿了么等。课程的间接受益者数万人。浏览器

   这些一线的运维或运维开发工程师不断地将知识、经验或应用趋势等反馈给咱们,也所以,咱们的课程体系也发展为了快速迭代和演进的模式。另外,不断地经过各类渠道指导他们解决实践中的问题的经验也成为课堂中案例的组成部分。缓存

   好比今天的分享,沿用咱们的一向方式,初衷是为那些不甚了解、即将或刚用到ELK stack的朋友们提供一个可落地的思路和实践方法。而ELK达人们还请多批评指正。bash

   下面进入正题。今天的分享共分为以下几个组成部分。不过,若是时间上来不及,可能只会聊前两个而不及其他。服务器

    一、搜索引擎组件介绍;
    二、ElasticSearch工做原理、查询及经常使用插件;
    三、日志收集器Logstash及常见的同类工具;
    四、可视化工具Kibina;
    五、使用案例及优化思路;微信

  

1、关于搜索引擎网络

   各位知道,搜索程序通常由索引链及搜索组件组成。数据结构

   索引链功能的实现须要按照几个独立的步骤依次完成:检索原始内容、根据原始内容来建立对应的文档、对建立的文档进行索引。app

   搜索组件用于接收用户的查询请求并返回相应结果,通常由用户接口、构建可编程查询语句的方法、查询语句执行引擎及结果展现组件组成。

   如图所示。

wKiom1ZMnkiTRk5LAAD-r_io_HQ515.jpg

   著名的开源程序Lucene是为索引组件,它提供了搜索程序的核心索引和搜索模块,例如图中的“Index”及下面的部分;而ElasticSearch则更像一款搜索组件,它利用Lucene进行文档索引,并向用户提供搜索组件,例如“Index”上面的部分。两者结合起来组成了一个完整的搜索引擎。

  

2、索引组件

   索引是一种数据结构,它容许对存储在其中的单词进行快速随机访问。当须要从大量文本中快速检索文本目标时,必须首先将文本内容转换成可以进行快速搜索的格式,以创建针对文本的索引数据结构,此即为索引过程。

   它一般由逻辑上互不相关的几个步骤组成。

 

   第一步:获取内容。

   过网络爬虫或蜘蛛程序等来搜集及界定须要索引的内容。Lucene并不提供任何获取内容的组件,所以,须要由其它应用程序负责完成这一功能,例如著名的开源爬虫程序Solr、Nutch、Grub及Aperture等。必要时,还能够自行开发相关程序以高效获取自有的特定环境中的数据。获取到的内容须要创建为小数据块,即文档(Document)。

 

   第二步:创建文档。

   获取的原始内容须要转换成专用部件(文档)才能供搜索引擎使用。

   通常来讲,一个网页、一个PDF文档、一封邮件或一条日志信息能够做为一个文档。文档由带“值(Value)”的“域(Field)”组成,例如标题(Title)、正文(body)、摘要(abstract)、做者(Author)和连接(url)等。不过,二进制格式的文档处理起来要麻烦一些,例如PDF文件。

对于创建文档的过程来讲有一个常见操做:向单个的文档和域中插入加权值,以便在搜索结果中对其进行排序。权值可在索引操做前静态生成,也可在搜索期间才动态生成。权值决定了其搜索相关度。

 

   第三步:文档分析。

   搜索引擎不能直接对文本进行索引,确切地说,必须首先将文本分割成一系列被称为语汇单元(token)的独立原子元素,此过程即为文档分析。每一个token大体能与天然语言中的“单词”对应起来,文档分析就是用于肯定文档中的文本域如何分割成token序列。

   此即为切词,或分词。

   文档分析中要解决的问题包括如何处理链接一体的各个单词、是否须要语法修正(例如原始内容存在错别字)、是否须要向原始token中插入同义词(例如laptop和notebook)、是否须要将大写字符统一转换为小写字符,以及是否将单数和复数格式的单词合并成同一个token等。这一般须要词干分析器等来完成此类工做,Lucene提供了大量内嵌的分析器,也支持用户自定义分析器,甚至联合Lucene的token工具和过滤器建立自定义的分析链。

 

   第四步:文档索引

   在索引步骤中,文档将被加入到索引列表。事实上,Lucene为此仅提供了一个很是简单的API,然后自行内生地完成了此步骤的全部功能。

 

   接下来,咱们说搜索组件。

   索引处理就是从索引中查找单词,从而找到包含该单词的文档的过程。搜索质量主要由查准率(Precision)和查全率(Recall)两个指标进行衡量。查准率用来衡量搜索系列过滤非相关文档的能力,而查全率用来衡量搜索系统查找相关文档的能力。

   另外,除了快速搜索大量文本和搜索速度以后,搜索过程还涉及到了许多其它问题,例如单项查询、多项查询、短语查询、通配符查询、结果ranking和排序,以及友好的查询输入方式等。这些问题的解决,一般须要多个组件协做完成。

     一、用户搜索界面

   UI(User Interface)是搜索引擎的重要组成部分,用户经过搜索引擎界面进行搜索交互时,他们会提交一个搜索请求,该请求须要先转换成合适的查询对象格式,以便搜索引擎能执行查询。

     二、创建查询

   户提交的搜索请求一般以HTML表单或Ajax请求的形式由浏览器提交到搜索引擎服务器,所以,须要事先由查询解析器一类的组件将这个请求转换成搜索引擎使用的查询对象格式。

     三、搜索查询

   当查询请求创建完成后,就须要查询检索索引并返回与查询语句匹配的并根据请求排好序的文档。搜索查询组件有着复杂的工做机制,它们一般根据搜索理论模型执行查询操做。常见的搜索理论模型有纯布尔模型、向量空间模型及几率模型三种。Lucene采用了向量空间模型和纯布尔模型。

     四、展示结果

   查询得到匹配查询语句并排好序的文档结果集后,须要用直观、经济的方式为用户展示结果。UI也须要为后续的搜索或操做提供清晰的向导,如完善搜索结果、寻找与匹配结果类似的文档、进入下一页面等。

 

3、Lucene

   Lucene是一款高性能的、可扩展的信息检索(IR)工具库,是由Java语言开发的成熟、自由开源的搜索类库,基于Apache协议受权。Lucene只是一个软件类库,若是要发挥Lucene的功能,还须要开发一个调用Lucene类库的应用程序。

   文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,而域的值则是真正被搜索的内容。每一个域都有其标识名称,一般为一个文本值或二进制值。将文档加入索引中时,须要首先将数据转换成Lucene能识别的文档和域,域值是被搜索的对象。例如,用户输入搜索内容“title:elasticsearch”时,则表示搜索“标题”域值中包含单词“elasticsearch”的全部文档。

   都是文字,你们可能看的眼花。参考一幅从互联网上获取的图片吧。

wKioL1ZMn4ix8Z1WAACYYV0yiYc686.jpg

 

   如前所述,ElasticSearch在底层利用Lucene完成其索引功能,所以其许多基本概念源于Lucene。

 

4、ES的基本概念

 

 索引(Index)

   ES将数据存储于一个或多个索引中,索引是具备相似特性的文档的集合。类比传统的关系型数据库领域来讲,索引至关于SQL中的一个数据库,或者一个数据存储方案(schema)。索引由其名称(必须为全小写字符)进行标识,并经过引用此名称完成文档的建立、搜索、更新及删除操做。一个ES集群中能够按需建立任意数目的索引。

 

 类型(Type)

   类型是索引内部的逻辑分区(category/partition),然而其意义彻底取决于用户需求。所以,一个索引内部可定义一个或多个类型(type)。通常来讲,类型就是为那些拥有相同的域的文档作的预约义。例如,在索引中,能够定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来讲,类型至关于“表”。

 

 文档(Document)

   文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。文档由一个或多个域组成,每一个域拥有一个名字及一个或多个值,有多个值的域一般称为“多值域”。每一个文档能够存储不一样的域集,但同一类型下的文档至应该有某种程度上的类似之处。

wKioL1ZMn7GzUl7gAACDX9Q8RfI251.jpg

   三者关系,如图中所示。

 

 映射(Mapping)

   ES中,全部的文档在存储以前都要首先进行分析。用户可根据须要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本须要进行额外处理等等。另外,ES还提供了额外功能,例如将域中的内容按需排序。事实上,ES也能自动根据其值肯定域的类型。

wKioL1ZMn8XgIKUxAACLaBiFO1o097.jpg

 

 节点(Node)
   运行了单个实例的ES主机称为节点,它是集群的一个成员,能够存储数据、参与集群索引及搜索操做。相似于集群,节点靠其名称进行标识,默认为启动时自动生成的随机Marvel字符名称。用户能够按须要自定义任何但愿使用的名称,但出于管理的目的,此名称应该尽量有较好的识别性。节点经过为其配置的ES集群名称肯定其所要加入的集群。

 

 分片(Shard)和副本(Replica)
   ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它经过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每个物理的Lucene索引称为一个分片(shard)。每一个分片其内部都是一个全功能且独立的索引,所以可由集群中的任何主机存储。建立索引时,用户可指定其分片的数量,默认数量为5个。 

  

   Shard有两种类型:primary和replica,即主shard及副本shard。Primary shard用于文档存储,每一个新的索引会自动建立5个Primary shard,固然此数量可在索引建立以前经过配置自行定义,不过,一旦建立完成,其Primary shard的数量将不可更改。Replica shard是Primary Shard的副本,用于冗余数据及提升搜索性能。每一个Primary shard默认配置了一个Replica shard,但也能够配置多个,且其数量可动态更改。ES会根据须要自动增长或减小这些Replica shard的数量。

   ES集群可由多个节点组成,各Shard分布式地存储于这些节点上。

ES可自动在节点间按须要移动shard,例如增长节点或节点故障时。简而言之,分片实现了集群的分布式存储,而副本实现了其分布式处理及冗余功能。

   如图所示。

wKiom1ZMoAiRtgT_AACPe7v-Dhw038.jpg

 

   ElasticSearch的RESTful API经过tcp协议的9200端口提供,可经过任何趁手的客户端工具与此接口进行交互,这其中包括最为流行的curl。curl与ElasticSearch交互的通用请求格式以下面所示。

curl -X<VERB> '<PROTOCOL>://<HOST>/<PATH>?<QUERY_STRING>' -d '<BODY>'
     VERB:HTTP协议的请求方法,经常使用的有GET、POST、PUT、HEAD以及DELETE;
     PROTOCOL:协议类型,http或https;
     HOST:ES集群中的任一主机的主机名;
     PORT:ES服务监听的端口,默认为9200;
     QUERY_STRING:查询参数,例如?pretty表示使用易读的JSON格式输出;
     BODY:JSON格式的请求主体;

    

   例如,查看ElasticSearch工做正常与否的信息。

~]$ curl 'http://localhost:9200/?pretty'

  

   与ElasticSearch集群交互时,其输出数据均为JSON格式,多数状况下,此格式的易读性较差。cat API会在交互时以相似于Linux上cat命令的格式对结果进行逐行输出,所以有着较JSON好些的可读性。调用cat API仅须要向“_cat”资源发起GET请求便可。具体使用方法请查阅官方文档。

   另外,ES集群的CRUD操做也很是容易进行,朋友们参考官方文档便可。

 

5、ES中的数据查询简介

   须要注意的是,文档中每一个域的值可能会存储为特定类型,而非字符串类型,所以,_all域的索引方式与特域的索引方式未必彻底相同。

   文档中,域的数据存储时支持“string”、“numbers”、“Booleans”和“dates”几种类型,不一样类型的数据在索引时是略有区别的。在建立文档时,Elasticsearch会经过检查域的值来动态为其建立mapping,可经过Mapping API来查看type的mapping,其访问端点是_mapping。

 

   下面,咱们聊一个麻烦一点的问题,ES的精确值、full-text及倒排索引。

   精确值(Exact values)就是指数据不曾加工过的原始值,而Full-text则用于引用文本中的数据。在查询中,精确值是很容易进行搜索的,但full-text则须要判断文档在“多大程度上”匹配查询请求,换句话讲,即须要评估文档与给定查询的相关度(relevant)。所以,所谓的full-text查询一般是指在给定的文本域内部搜索指定的关键字,但搜索操做该须要真正理解查询者的目的。

 

  例如:
   (1) 搜索“UK”应该返回包含“United Kingdom”的相关文档;
   (2) 搜索“jump”应该返回包含“JUMP”、“jumped”、“jumps”、“jumping”甚至是“leap”的文档;
   (3) 搜索“johnny walker”应该匹配包含“Johnnie Walker”的文档;

 

   为了完成此类full-text域的搜索,ES必须首先分析文本并将其构建成为倒排索引(inverted index),倒排索引由各文档中出现的单词列表组成,列表中的各单词不能重复且须要指向其所在的各文档。所以,为了建立倒排索引,须要先将各文档中域的值切分为独立的单词(也称为term或token),然后将之建立为一个无重复的有序单词列表。这个过程称之为“分词(tokenization)”。

wKiom1ZMoMCRhc9pAAEht--Jm_A712.jpg

 

6、Queries and Filters
 
   尽管统一称之为query DSL,事实上Elasticsearch中存在两种DSL:查询DSL(query DSL)和过滤DSL(filter DSL)。查询子句和过滤子句的天然属性很是相近,但在使用目的上略有区别。简单来说,当执行full-text查询或查询结果依赖于相关度分值时应该使用查询DSL,当执行精确值(extac-value)查询或查询结果仅有“yes”或“no”两种结果时应该使用过滤DSL。

   Filter DSL计算及过滤速度较快,且适于缓存,所以可有效提高后续查询请求的执行速度。而query DSL不只要查找匹配的文档,还须要计算每一个文件的相关度分值,所以为更重量级的查询,其查询结果不会被缓存。不过,得益于倒排索引,一个仅返回少许文档的简单query或许比一个跨数百万文档的filter执行起来并得显得更慢。

   Filter DSL中常见的有term Filter、terms Filter、range Filter、exists and missing Filters和bool Filter。而Query DSL中常见的有match_all、match 、multi_match及bool Query。鉴于时间关系,这里再也不细述,朋友们可参考官方文档学习。

   Queries用于查询上下文,而filters用于过滤上下文,不过,Elasticsearch的API也支持此两者合并运行。组合查询可用于合并查询子句,组合过滤用于合并过滤子句,然而,Elasticsearch的使用习惯中,也常会把filter用于query上进行过滤。不过,不多有机会须要把query用于filter上的。

 

   好了,朋友们,今天的分享就先到这里吧。感谢你们的时间。这些内容是我用来说课的讲义精练出的内容,用于微信的方式分享可能显得过于啰嗦,请你们将就着看啦。

相关文章
相关标签/搜索