ElasticSearch学习笔记

本文是对ElasticSearch组件初步学习的一个知识总结,包括如下章节的内容:

  • 概述
  • 快速上手
  • 逻辑概念
  • 用户接口
  • 关于ELKB

预备知识:

1、本文对ElasticSerach的介绍会涉及与关系数据库的对比,为了更好地学习,可提前对关系数据库的基本概念有所了解。
2、ElasticSerach的数据存储采用JSON的数据格式,为了更好地学习,可提前对JSON的概念有所了解。
3、ElasticSerach对外提供的是RESTful Api访问接口,为了更好地学习,可提前对RESTful的概念有所了解。

二、快速上手

ES虽然是一个强大的分布式系统,但其易用性设计的非常好,安装和使用都很简单,下面我们来快速体验下。

(一)安装

ES需要java环境,最好是java8,需要设置JAVA_HOME环境变量。ES的安装非常简单,开箱即用,首先我们可以从官网www.elastic.co下载相应的二进制版本,对于Windows操作系统,可下载zip文件,对于linux操作系统,可下载tar文件。

下载二进制包后,解压到任何一个目录下。如果不做任何配置,则采用默认的配置启动ES。运行ES安装目录下的bin目录的elasticsearch脚本(windows下为elasticsearch.bat)则可以以单实例的方式启动ES。在linux系统中启动ES有可能会报错误,这在下面会详细介绍。

我们这里是启动的ES的单个实例,ES可以以集群的方式运行(即在多台机器上启动多个ES实例)。因为单节点模式和集群模式从使用角度看并没有太多的区别,所以本文介绍的都是基于ES在单节点方式运行的。集群的方式在后续的文章中介绍。

启动ES后,下面就可以利用ES提供的RESTful API去使用它。我们可以在浏览器或任何web工具中输入 http://localhost:9200 地址,得到如下的信息(ES系统的基本信息):

{
  "name" : H12K5tk",cluster_nameelasticsearchcluster_uuid2RAwSskjQh6xDxLrDHBTtQversion : {
    number5.6.9build_hash877a590build_date2018-04-12T16:25:14.838Zbuild_snapshot" : falselucene_version6.6.1
  },1)">taglineYou Know,for Search
}

返回的是本节点(ES实例的)name,以及ES集群的一些基本信息,如集群名,版本信息等

(二)启动错误

在Linux系统中启动ES,可能会报一些错误,导致启动失败。下面是一些常见的错误与解决方案(这也是本文在Centos7系统中启动ES碰到的问题)。

1、错误1:max file descriptors [4096] for elasticsearch process is too low,increase to at least [65536]
错误很好理解,就是指es进程可允许打开的最大文件数只有4096,太小了,需要提升到65536。因为ES需要打开很多文件,最大4096个不够,需要调整操作系统中的配置。
在Linux的系统中对于进程(Process)会有一些限制(limit),限制有很多种,常见的如对打开文件(Open Files)最大数量的限制。在linux中这些限制是分为软限制(soft limit)和硬限制(hard limit)两类。它们的区别就是软限制可以在程序的进程中自行改变(突破限制),而硬限制则不行(除非程序进程有root权限)。
使用ulimit 命令可以分别查看软限制和硬限制,区别是在查看的参数前加 S 或 H。例如,查看打开文件数限制(参数是n):
#查看软限制
ulimit -Sn
#查看硬限制
ulimit -Hn

改变这个限制的办法是修改/etc/security/limits.conf文件,增加配置,如在配置文件中增加如下信息:

*     soft    nofile    65536
*     hard    nofile   65536

注意,最前面的 * 代表这个设置对所有进程都有效,如果只对指定进程有效,将*改为具体的进程名。

2、错误2:max virtual memory areas vm.max_map_count [65530] is too low,increase to at least [262144]

这个错误是指Linux进程的vma大小不足,需要提高。这可以修改/etc/sysctl.conf文件,增加配置vm.max_map_count=262144,如:

vm.max_map_count=262144

修改配置文件后,执行 命令sysctl -p 让生效(注意,一定要执行),如:

[hadoop@master bin]$ sudo sysctl -p
[sudo] password for hadoop:
vm.max_map_count = 262144

另外,在操作系统配置文件被修改后,最好重新登录,确保新的终端能获取到修改后的信息。

(三)访问ES

因为ES对外提供了RESTful的访问接口,所以我们可以用任意一种web client工具来访问ES,最简单的如linux下的curl程序,还可以用如Postman这样的工具(Postman是一个非常有用的 Http Client 工具,可用来测试 Web 服务),也可以在浏览器上安装插件,如chrome中的Sense插件(该插件可以很方便的操作ES)。

当然我们可以利用第三方http client库自己编写代码来访问ES。不过ES自身也提供了JAVA API来操作ES,这个在后面介绍

下面我们使用RESTful API来举例使用ES。一个完整的REST请求包括如下三部分:
1、操作类型,如GET,PUT,POST,DELETE等
2、URL部分,如http://localhost:9200/blogs/blog/1
3、请求正文内容。对于GET请求,没有单独的请求正文内容,请求信息都包含在URL中。对于PUT,POST等操作,可以带正文内容,正文内容采用josn的格式,具体下面例子会看到。

ES的REST请求的返回内容的格式绝大部分都是JOSN格式的。也就是说请求和响应的内容都是JSON格式,这样有较好的一致性。

下面来看具体的例子:

1、插入数据
往ES中插入数据,可以执行如下的操作:

PUT  http://localhost:9200/blogs/blog/1
{
    title": es infocontentabout elasticsearchauthorjackyear":2018
}
这里执行的是http的PUT操作,url后面跟着的json格式内容是请求的正文,即保存到ES中的数据。关于该url和json内容的含义我们在后面介绍,这里只需知道这样一个简单的http的PUT请求就把一条json数据保存到ES中。上述操作我们可以在如Postman这样的工具中进行。
该请求成功后服务器返回的信息如下:
_indexblogs_typeblog_id1_version1resultcreated_shards: {
    total2successfulfailed0": true
}

上面响应信息的格式也是josn格式,其中字段的含义我们后面再介绍。

 2、查询数据

上面往ES中插入了一条数据,下面我们可以利用http的GET操作来获取刚才插入的数据。http请求如下:

GET  http:localhost:9200/blogs/blog/1

该请求成功后服务器返回的信息如下:

found_source
  }
}

可以看出,返回的josn内容中,相比插入操作,有这几个字段的内容发生了变化:

updatedfalse

可以看到,记录的 Id 没变,但是版本(version)从1变成2操作类型(result)从created变成updatedcreated字段变成false,因为这次不是新建记录,而是修改操作。

这时如果我们执行

GET  http:localhost:9200/blogs/blog/1

查询操作,会看到返回的Document数据是修改后的数据。

ES文档的版本号是有用的,我们在修改数据时,可以传入一个版本号。这样当在一个客户端读取和更新文档的间隔中,有另外客户端更新了数据。如果这个客户端的更新操作传入了版本号(前面读取的版本号),这时因为传入的版本号和当期实际的版本号不一致,就会操作失败。这样就防止可能的数据冲突。这也是ES采用乐观并发控制(OCC)机制的体现

加入版本号进行更新,只需在url后面加上version参数,如:

PUT http:localhost:9200/blogs/blog/1?version=2

4、删除操作
通过DELETE操作,可以删除ES中的数据。HTTP请求如下:

DELETE  http:deleted
  }
}

如果我们这时去执行GET操作,如

GET http:
}

从响应的结果可以看出,没有查到数据。

5、搜索操作
下面我们来看下ES最强大的搜索操作,首先我们来先插入2条数据,包括前面插入和被删除的数据。

PUT  http:
}

PUT  http:localhost:9200/blogs/blog/2
zk infoabout zookeeper
}

下面我们来执行根据给定的字符串进行查找,只要数据中有包含给定字符串的内容就认为匹配上,查询命令如下:

POST http:localhost:9200/_search
query: {
        query_string: {
            
        }
    }
}

返回的结果如下:

took3timed_out10skippedhitsmax_score0.26742277: [
      {
        _score: {
          
        }
      }
    ]
  }
}

可以看出,搜索到了数据。我们可以试着改变上面查询条件中"query"参数的值,来观察结果的变化。

上面的搜索是搜索整个json数据中的信息,我们也可以只搜索指定json字段中的内容。如:

POST http:fields": []
        }
    }
}

上面的REST语句表示只在字段author中查找存在jack字符串的数据。字段通过查询条件中的filelds参数指定,可以看出,同时可指定多个字段。 对比关系数据库,ES的搜索操作有点类似关系数据库中带like子句的select语句。

可以看出,利用ES的RESTful Api进行操作还是比较简单的,当然我们只是列举了几个最基本的操作。上面通过举例让我们站在用户的角度对ES有了个初步的认识,下面章节继续展开更为详细的介绍。

(四)远程访问

上面例子中我们都是在本地利用REST接口访问ES的,即web客户端运行在ES实例所在的机器上,所以url中用的是localhost。 如果需要支持对ES的远程访问,可以修改ES安装目录的config/elasticsearch.yml文件,去掉network.host的注释,将它的值改成0.0.0.0,然后重新启动 ES。配置文件中信息如:

network.host: 0.0.0.0

上面配置,设成0.0.0.0让任何一台机器都可以访问。线上服务不要这样设置,要设成具体的 IP,如:

network.host: 192.168.0.1

三、逻辑概念

我们上面的例子使用了 http://localhost:9200/blogs/blog/1 这样的ulr来进行数据的插入、查询及搜索和删除操作。抛开操作的方式,感觉和关系数据库的操作有类似的地方。这其实也是正常的,因为数据库也是用来进行数据存储和分析(查找)的,所以从功能上说肯定有很多类似的地方。我们知道关系数据库有数据库、表、记录、字段等概念,为了更好地理解ES的逻辑架构,我们在介绍ES的一些重要概念的时候会对比关系数据库中的一些概念

(一)索引(Index)

ES数据管理的顶层单位就叫做 Index(索引)。它不是关系数据库中索引的概念,是单个数据库的同义词,即可以把它等价于关系数据库中的单个数据库。Index的名称必须小写。

既然Index是ES管理数据的顶层单位,肯定先需要有索引,才能进行后续的数据存储等操作,类似关系数据库中得首先有数据库一样。可前面的操作我们并没有看到创建Index的操作。是不是ES启动后有一个默认的Index呢?

其实情况是这样的,上面的REST请求 http://localhost:9200/blogs/blog/1 中的 blogs就是一个索引名,当我们执行数据插入操作时,如果url中指定的索引不存在,则ES会自动创建该索引。就如我们前面的例子,我们插入数据时,索引blogs并不存在,所以ES按照默认的设置自动创建了blogs索引。

我们可以单独创建一个索引,操作如下:

PUT  http:localhost:9200/topics

上面操作通过http的PUT操作,创建了一个名称为topics的索引。
操作成功后的响应信息如下:

acknowledgedshards_acknowledgedindextopics
}

我们可以查看到ES中的所有索引,操作如下:

GET  http:localhost:9200/_cat/indices?v

响应结果如下:

health  status  index  uuid  pri  rep  docs.count  docs.deleted  store.size   pri.store.size
yellow  open   blogs  hM...  5    1      2          0         10.2kb      .2kb
yellow  open   topics  hV...  0          0         810b        810b

结果以表格的形式显示,第一行为表头。因为前面的操作我们已经创建了blogs索引,加上刚创建的topics索引,所以我们看到结果有2条记录。

通过DELETE操作,我们可以删除指定的索引,如下面操作:

DELETE  http:localhost:9200/topics

操作成功的响应结果如下:


}

这表示删除索引成功,如果我们这时再去查找所有索引,会发现topics索引没有了。

(二)类型(Type)

在索引中,可以定义一个或多个类型(type),类型是索引的逻辑分区,是同一索引中有公共字段的文档的集合。比如在一个博客系统中,我们可以将用户数据放到一种类型中,将文章数据放到一种类型中,将对文章的评论信息放到一种类型中。

类型不需要单独创建,在插入数据(如上面的例子)会自动创建。对于 http://localhost:9200/blogs/blog/1 这个url,其中的blog就是类型(type)名。

相对关系数据库来说,类型可以类比成关系数据库中的表。
需要注意的是,根据规划,Elastic 6.x 版只允许每个 Index 包含一个 Type,7.x 版将会彻底移除 Type。

所以我们在实际使用中,不用过多考虑Type的作用。

(三)文档(Document)

Document是Index中的单条记录,它就像关系数据库中表中的记录(行)。Document 使用 JSON 格式表示,如上面插入数据时的url后面跟的请求数据:

PUT http:
}

ES的每个存储在Index中的Document都有一个类型(type)和一个唯一的ID。这个ID可以用户在创建文档时显示指定,如上面url最后的1,也可以由ES自动生成(后面会介绍)。

JSON数据是一种半结构化的数据格式,它由一个个的字段组成,字段有字段名、字段的值,和字段类型,比如上面的title字段就是一个字符串类型,year字段就是一个整数类型。JSON数据的字段类型不需要显示定义,由字段的内容推断出来,比如字符串是要放到引号中,整数则不能。

同一个 Index 里面的 Document(即使是位于同一个Type下),不要求有相同的结构(即相同的字段和字段类型),但是最好保持相同,这样有利于提高搜索效率。需要注意的是,同一个字段名的字段,不能在这个文档中是字符串类型,而在另外一个字符串中是数组类型。举个例子,上面举例中我们插入了如下的数据:

PUT http:
}

这时如果插入如下数据:

PUT http:2018年
}

也就是这里插入的year字段值是个字符串,则时ES的响应就会报错,报类型不一致的错误,因为前面插入的数据已经让ES把year字段认作为整型数据。但如果我们写成 "year": "2018" 这样的格式,虽然看上去year字段是字符串类型,但因为实际数据是整数,则不会报错。

因为即使是同一个Type下的Docuemnt也不要求有相同的数据模型,所以逻辑上Type与关系数据库的表对应,实际意义差别还是挺大的。在关系数据库下,表中的每条记录数据模型都是严格相同的。

(四)字段(Field)

上面已经提到了字段,字段就是Docuemnt对应的json内容的字段。一个Docuemnt可以包括零个或多个字段,字段可以是一个简单的值(如字符串、整数、日期),也可以是一个数组或对象的嵌套结构。每个字段都对应一个数据类型,如整数、字符串、数组、对象等。

(五)映射(mapping)

mapping是类似于数据库中的表结构定义,主要作用如下:

  • 定义index下的字段名
  • 定义字段类型,比如数值型、浮点型、布尔型等
  • 定义倒排索引相关的设置,比如是否索引、记录position等
  • 设置分词器等

与表结构不同的是,关系数据库的表的结构必须事先通过create table语句来明确。而映射既可以显示的通过命令来事先定义,也可以在存储文档(插入数据)时由ES来自动识别。如我们上面的例子,并没有显示的去定义Index的mapping信息。

可以通过 GET http://localhost:9200/_mapping 来查看Index的mapping信息。

(六)主键(ID)

ES中的每个Document都有一个唯一的ID(在type下唯一),也就是说 index/type/id必须是唯一的。
我们可以插入数据时显示的指定ID,如前面的操作:

PUT  http:localhost:9200/blogs/blog/1

也可以也ES系统自动生成,注意这时就不能用PUT操作,要用POST操作,如下面操作:

POST  http:localhost:9200/blogs/blog
2018
}

上面请求中url的最后没有指定要插入的Document的ID,操作成功后的响应信息如下:

AWeXZiyTS_34KbUEtT3A
}

可以看出,响应信息中带回来了ES自动生成的ID值。

关于ELKB

先说下ELK,ELK是一个流行的日志系统解决方案,注意,ELK不是一个软件名,而是一个解决方案的缩写,即Elasticsearch+Logstash+Kibana(ELK Stack)这三个软件的集合。

这几个都是开源的java产品,但是众所周知,java的东西很吃内存和CPU,Logstash在作为收集日志的Agent时,就显得太过臃肿了。后来官方在logstash-forwarder的基础上推出了beat系列,里面包括四个系统,分别是:

1、Packetbeat(搜集网络流量数据);
2、Topbeat(搜集系统、进程和文件系统级别的 CPU 和内存使用情况等数据);
3、Filebeat(搜集文件数据),Filebeat占用资源少,适合于在各个服务器上搜集日志后传输给Logstash;
4、Winlogbeat(搜集 Windows 事件日志数据)。

所以Filebeat也就这样加入了“日志收集分析”的团队里,所以虽然大家还是习惯性的叫ELK,其实准确的说法已经是ELKB了。

ELKB中的几个软件的分工如下:

1、Elasticsearch:分布式搜索和分析引擎,具有高可伸缩、高可靠和易管理等特点。基于 Apache Lucene 构建,能对大容量的数据进行接近实时的存储、搜索和分析操作。通常被用作某些应用的基础搜索引擎,使其具有复杂的搜索功能。

2、Logstash:数据收集额外处理和数据引擎。它支持动态的从各种数据源搜集数据,并对数据进行过滤、分析、丰富、统一格式等操作,然后存储到用户指定的位置。

3、Kibana:数据分析和可视化平台。通常与 Elasticsearch 配合使用,对其中数据进行搜索、分析和以统计图表的方式展示。

4、FilebeatELK 协议栈的新成员,在需要采集日志数据的服务器上安装 Filebeat,并指定日志目录或日志文件后,Filebeat 就能读取数据,迅速发送到 Logstash 进行解析,亦或直接发送到 Elasticsearch 进行集中式存储和分析。



相关文章

文章浏览阅读774次,点赞24次,收藏16次。typescript项目中我...
文章浏览阅读784次。react router redux antd eslint pretti...
文章浏览阅读3.9k次,点赞5次,收藏11次。需要删除.security...
文章浏览阅读1.2k次,点赞23次,收藏24次。Centos 8 安装es_...
文章浏览阅读3.2k次。设置完之后,数据会⾃动同步到其他节点...
文章浏览阅读1.9k次,点赞2次,收藏7次。针对多数据源写入的...