1.1 Elasticsearch概述

Elasticsearch是一个分布式的、开源搜索与分析引擎,具有分布式集群的水平扩展、高可靠性、易于管理等诸多优点,能处理结构化、非结构化、时间序列等异构数据。Elasticsearch来源于Shay Bannon的第一个开源项目Compass。Compass是一个基于事务的对象/搜索引擎映射与一个Java持久层框架,但Elasticsearch目前已经不再仅局限于单纯的搜索业务。作为开源分布式搜索与数据处理平台,Elasticsearch不仅是一个库,还是一个基于Lucene构建的开源、分布、基于RESTful的信息检索框架,能够实时搜索,检索性能高效,并采用JSON数据格式以及Ruby DSL设计模式,提供基于Aggregations的统计功能,提供便捷的部署和设置,集群可方便地扩展(可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据,当然它也可以运行在单台PC上);能对海量规模数据完成分布式索引与近似实时的信息检索,并提供多种管理工具,各种相关插件也可方便地集成到Elasticsearch中;它对外提供一系列基于Java和HTTP的API,可用于分布式索引、检索、日志分析与数据挖掘等,且大多数配置是可修改的。Elasticsearch语句可包括如下几部分:

· 相应的HTTP请求方法或者变量(如GET、POST、PUT、DELETE)。

· 集群中任意一个节点的访问协议、主机名以及端口。

· 请求的路径。

· 查询后再加上?pretty可增强可读性。

· 一个JSON编码的请求主体(如果需要的话)。

Tips:RESTful(REpresentational State Transfer)意即“表现层状态转化”,是目前流行的一种互联网软件架构,具有结构清晰、符合标准、易于理解、扩展方便等特点。这种架构下的每一个URI代表一种资源,客户端通过GET(获取资源)、POST(新建或更新资源)、PUT(更新资源)、DELETE(删除资源)等方式来对服务器端的资源进行操作。Elasticsearch中,RESTful接口URL的格式是:http://ipaddress:9200/<index>/<type>/[<id>]。其中,index可理解为数据库,type可理解为数据表,id相当于数据记录的主键。增、删、改分别对应HTTP请求的PUT、GET、DELETE方法。对PUT方法来说,调用时如果数据不存在,就创建它;如已存在,就更新它。Elasticsearch可能会返回一个HTTP状态码(类似“200OK”等)以及一个JSON格式的主体。

值得一提的是,在使用Elasticsearch时,有很多基础服务可以用插件的方式来提供。这也是很多Lucene用户在面对大数据时转而使用Elasticsearch的原因之一,如和MongoDB、CouchDB同步的River插件、中文分词插件、Hadoop插件、脚本支持插件等。另外,Elasticsearch对分布式数据处理提供支持,其索引能分拆为多个分片,每个分片可有零或多个副本,集群中的每个数据节点都可承载一个或多个数据分片,并且能协调和处理各种操作;负载再平衡(rebalancing)和路由选择(routing)在大多数情况下都是自动完成的。而Elasticsearch5.0带来了许多增强功能和新特性[搜狐,2016],部分特点如下:

(1)索引吞吐量大幅提升。根据应用场景的不同,索引吞吐量提升在25%~80%之间。

(2)添加数据更便捷。Elastic Stack将一些流行的Logstash过滤器(如grok、split)直接在Elasticsearch中实现为处理器,多个处理器可组合成一个管道,在索引时应用到文档上。

(3)Elastic采用新的脚本语言painless。

(4)借助即时聚合,Kibana图表生成速度显著提升。在搜索方面,默认的相关性计算已经由TF-IDF算法换成了BM25。

(5)Elasticsearch分布式模型的每一部分都被分解、重构和简化,提升了可靠性。集群状态更新会等待集群中所有节点确认。如果一个复制片(replica shard)被主片(primary)标记为失败,则主片会等待主节点(master)的响应。

Elasticsearch的基本架构如图1.2所示。从图中可以看出,Elasticsearch可以接受本地、共享、云平台上的数据;在Lucene提供的基本功能上,通过构建分布式索引,完成对大数据的加工处理(其中,Zen用来实现节点自动发现和master节点选举;EC2(Elastic Compute Cloud)借由提供Web服务的方式让使用者可弹性地运行自己的Amazon机器映像,提供可调整的云计算能力)。用户可基于RESTful和客户端(如Java客户端)的方式,借助Elasticsearch提供的API完成数据操作、管理等工作。

Tips:在Elasticsearch2.4及更早的版本中,其自身可以集成Head、Marvel、Shield、Watcher、Reporting、Graph等多种插件。升级到5.0版本之后,Head不再以插件的形式集成,有关Head的安装和使用方法将在第2章进行介绍。而对于Marvel、Shield、Watcher、Reporting、Graph等插件,ElasticStack推出了新的X-Pack插件取而代之。X-Pack插件包含了Security、Monitoring(即之前版本中的Marvel)、Alertingand Notification以及Graph等功能。有关X-Pack插件的详细内容,将在后面的章节中进行介绍。

1.1.1 Elasticsearch的安装与简单配置

“工欲善其事,必先利其器”。要想了解Elasticsearch,就要从该软件的安装入手。传统上,Java类的软件及使用往往比较烦琐,但Elasticsearch的安装却非常简单,几乎是“开箱即用”的。当然,前提是需要先下载JDK并配置相应的环境变量,同时确保系统可用内存大于2GB。

图1.2 Elasticsearch的基本架构

下面对Elasticsearch的安装进行说明。进入官网http://www.elastic.co,找到对应的Elasticsearch软件版本下载并解压。Elasticsearch本身可以集成一些基本插件,在GitHub网站中有这些插件对应不同版本的官方源码,可以按照网站上的简介来安装使用。截至本书出版时,Elasticsearch发布了5.4版本,其索引文件的大小只是原始文件大小的一部分,这可为集群节省服务器硬件采购费用。Elasticsearch的config文件夹里面有三个配置文件:elasticsearch.yml是基本配置文件,jvm.options是Java虚拟机配置文件,log4j2. properties是日志配置文件。下面简介在Ubuntu系统上安装Elasticsearch5.0.0的主要步骤。

首先,在官网上下载对应系统(如Linux)的Elasticsearch软件包,进入到安装文件所在目录下执行操作tar-xvfelasticsearch-5.0.0.tar.gz完成安装,具体步骤不再赘述。如果将Elasticsearch作为一个系统service应用,可安装Java Service Wrapper。该工具在其官网http://wrapper.tanukisoftware.com/doc/english/download.jsp可以下载,限于篇幅,这里不再赘述。进入Elasticsearch的bin文件夹,执行./elasticsearch命令,启动Elasticsearch。

Tips:若要关闭Elasticsearch,可在正在运行Elasticsearch的终端界面中按下组合键Ctrl+C来终止该节点的运行,此时该节点将会自动从群集中删除自身,将translog同步到磁盘,以及执行其他相关的清理活动。如果Elasticsearch正作为一个系统service应用运行,则应使用相应的系统service管理程序来关闭。一个正确有序的关闭操作可以确保Elasticsearch有机会清除和关闭未完成处理的资源。

之后,打开浏览器,输入类似http://ipaddress:9200,会显示类似图1.3的内容。其中:

(1)name:Elasticsearch实例的名字,默认情况下它是大小写字母和数字的组合,生成后长期留存,其设置同样是在config/elasticsearch.yml文件中完成的。

(2)version:版本号,以JSON格式表示了一组信息,其中的number字段代表了当前运行Elasticsearch的版本号,build_snapshot字段代表了当前运行的版本是否从源代码构建而来,lucene_version表示Elasticsearch基于Lucene的版本(图1.3显示该版本是基于Lucene6.2.0而构建的)。

图1.3 Elasticsearch启动后的界面

(3)tagline:包含了Elasticsearch的第一个tagline:"You Know, for Search"。

图1.3中出现了JSON格式的数据。JSON(JavaScript Object Notation)是基于Javascript的轻量级数据交换格式,是独立于语言的文本格式。在Javascript中处理JSON数据不需要任何特殊的API或工具包,利用JSON可简单地表示半结构化数据,而且目前多数编程语言支持对JSON数据的解析。JSON的基本语法表示如下:

(1)数据在用双引号表示的“名称:值”对中,中间用冒号隔开,如:“name”:“smith”。

(2)可创建包含多个“名称:值”的记录,如:{“name”:“smith”,“email”:“abc@sjtu. org”}等,它表示以上两个值是同一记录的一部分,数据由逗号分隔,花括号保存对象,方括号保存数组。

XML示例代码:

    <? xml version="1.0"encoding="utf-8"? >
    <book>
        <name>Elasticsearch Searching
        </name>
        <author>
          <name>Gao</name>
          <sex>male</sex>
          <age>45</age>
          <country>China</country>
        </author>
        <price>10</peice>
    </book>

JSON示例代码:

    {
      "book": {
        "name":"Elasticsearch Searching",
        "author": {
          "name": "Gao",
          "sex": "male",
          "age":45,
          "country": "China"
        },
        "price":10,
      }
    }

这些代码是对同样数据的XML和JSON表示形式。在Elasticsearch应用中,可以在很多地方看到JSON的身影。

1.1.2 Elasticsearch API的简单使用方式

(1)非客户端方式:通过HTTP方式的JSON格式进行调用。关于HTTP的相关参数设置可在elasticsearch.yml中进行(出于安全考虑,也可禁用HTTP接口,只需在配置文件中将http.enabled设置为false即可)。

(2)客户端方式:对Java来说,Elasticsearch内置了传输客户端TransportClient,它是一种轻量的传输客户端,可被用来向远程集群发送请求。它不加入集群本身,而是把请求转发到集群中的节点。客户端都使用Elasticsearch的传输协议,通过9300端口与Java客户端进行通信。集群中的各个节点也是通过9300端口进行通信。

Tips:Elasticsearch的9200端口是HTTP接口,9300端口是Transport接口。