Fork me on GitHub

Elasticsearch(1):基础入门

 

1 Elasticsearch

在如今数据为王的时代,如何充分高效实现数据检索和分析是数据应用的关键。以电商平台为例,输入一个商品名称,那么就要求系统以最快的速度将所有相关的商品搜索处理。现在的数据大多存储在mysql、Oracle或其他企业自主研发的关系型数据库中,搜索能力已经逐渐跟不上实际需求。例如需要检索“格力空调”这个商品,那么,按照关系型数据库中的逻辑,sql语句大概应该是这样的:

select * from table where name like "%格力空调%"

注意,因为sql语句中使用了模糊查询,而且在“格力空调”这个关键词前面也使用了通配符,所以索引将会失效,这将倒是检索性能大大降低。

另外,我们必须承认,有时候,我们会将关键词输入错误,例如将“格力空调”输入成了“格空调”,那么这时候SQL语句将变成这样:

select * from table where name like "%格空调%"

可想而知,我们查询不出任何真正相关的结果。

另一方面,虽然目前的主流数据库都已经能够很好的支持分布式扩展,但通常需要对应用程序进行非常大的改动,才能利用上横向扩容的新增资源。

这就是目前关系型数据库在实际应用中的一些局限性。为了解决这些问题,Elasticsearch应运而生。

Elasticsearch 是一个分布式的 RESTful 风格的分布式可扩展的准实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lucene 那么简单,它不仅包括了全文搜索功能(或者说倒排索引,将一段词语进行分词,并且将分出的单个词语统一的放到一个分词库中,在搜索时,根据关键字去分词库中检索,找到匹配的内容),还可以进行以下工作:

  • 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。

  • 实时分析的分布式搜索引擎。

  • 可以通过极其简单配置扩展到上百台服务器实现分布式横向扩容,处理PB级别的结构化或非结构化数据。

2 核心概念理解

2.1 索引(index)

在elasticsearch中,索引有两种含义:

  • 一种是名词意义上的索引。我们通常所说的索引也大多指这一种,这时候的索引就是文档(Document)的容器,是具有某种相似特性文档的集合,所以,在设计elasticsearch时,通常将相似的文档存放在同一个索引中(当然,个别document可能多一个或少一个field),这样Elasticsearch对磁盘存储的利用率最高。例如,对于博客类系统,可以将文章(artical)存放为一个索引中,将作者(author)存放为一个索引。索引由一个名称(必须全部是小写,不能以'_', '-', 或 '+'开头)标识,当对其中的文档执行索引、搜索、更新和删除操作时,该名称用于引用索引。通常索引是由两部分构成:Mapping和Setting。Mapping 定义该索引包含的文档的数据结构的信息;Setting定义了该索引的数据分布信息。

  • 另一种索引是指动词意义上的索引。保存一个文档到索引(名词)的过程,就类似于SQL语句中的 INSERT关键词,当然,如果文档已存在,那就相当于数据库的UPDATE。

2.2 类型(type)

就目前7.X版本的ES来说,再谈类型(type)的概念已经不是太有意义,因为类型的概念正在被逐渐淡化抛弃。

在5.X或者更早的版本中,类型的概念确实很常用,类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。例如,在一个博客系统类的索引中,可以定义一个用于存储作者信息的类型,一个存储博客文章信息的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。

然而,从6.X开始单个索引中只能有一个类型,7.X的版本中只存在一个默认的名为“_doc”的类型,官方也不建议继续使用这一概念,甚至8.X以后完全不支持。这是为什么呢?

许多资料指出ES中“索引”的概念和关系数据库的“库”是相似的,“类型”和“表”是对等的。 这其实是一个不正确的对比,掩盖了一些基础的特性。在关系型数据库里,"表"是相互独立的,一个“表”里的列和另外一个“表”的同名列没有关系,互不影响。但在类型里字段不是这样的。在一个ES索引里,所有不同类型的同名字段内部使用的是同一个lucene字段存储。也就是说,上面例子中,作者信息类型的author_name字段和博客文章信息类型的author_name字段是存储在一个字段里的,两个类型里的这一字段必须有一样的字段定义。这可能导致一些问题,例如我们希望在类型1中的phone_number存储为数值类型,而在类型2中的phone_number字段存储为字符类型,这是不可能做到的。另外,在同一个索引中,存储仅有小部分字段相同或者全部字段都不相同的文档,会导致数据稀疏,影响Lucene有效压缩数据的能力。

所以,在一个索引中,最好只拥有一个类型,如果有多种实体数据,那就分别存储在多个索引中。

2.3 文档(document)

在索引中存储的每一个目标数据称为文档,ES中的文档可以类比关系型数据库中的每一行记录来理解。ES是面向文档的搜索,文档是ES所有可搜索数据的最小单元。在ES中文档会被序列化成json格式进行保存,每个文档都会有一个Unique ID,这个ID可以有用户在创建文档的时候指定,在用户未指定时则由ES自己生成,这个ID中在查询结果中以_id这个元数据表示。除了_id外,文档中还包括一下这些元数据:

  • _index:文档所属索引名称。

  • _type:文档所属类型名。

  • _id:文档的ID值。

  • _version:文档的版本信息。ES通过使用version来保证对文档的变更能以正确的顺序执行,避免乱序造成的数据丢失。

  • _seq_no:严格递增的顺序号,每个文档一个,Shard级别严格递增,保证后写入的Doc的_seq_no大于先写入的Doc的_seq_no。

  • primary_term:primary_term也和_seq_no一样是一个整数,每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term会递增1

  • found:查询的ID正确那么ture, 如果 Id 不正确,就查不到数据,found字段就是false。

  • _source:文档的原始JSON数据,这才是我们储存在ES中的业务数据。

2.4 映射(mapping)

ES中中的映射(Mapping)用来定义一个文档,类似于关系型数据库中的表结构的概念,但却比表结构具有更加强大的功能,如下图所示,具体来说主要包含以下功能:

  • 文档中哪些字段需要定义成全文索引字段。
  • 文档中哪些字段定义为精确值,例如日期,数字、地理位置等。
  • 文档中哪些字段需要被索引(能通过该字段的值查询文档)。
  • 日期值的格式。
  • 动态添加字段的规则定义等。

映射可以分为动态映射和静态映射:

静态映射:若在数据写入索引前,映射(mapping)已经创建,那么在写入数据时,ES会根据映射和写入数据的key进行对比,然后写入相应的映射中;

动态映射:如果mapping没有创建,elasticsearch将会根据写入的数据的key自行创建相应的mapping,并写入数据。

2.5 集群(cluster)

集群是一个或多个节点(服务器)的集合,它们共同保存你的整个数据,并提供跨所有节点的联合索引和搜索功能。一个集群由一个唯一的名称标识,默认这个唯一标识的名称是"elasticsearch"(可修改)。这个名称很重要,因为如果节点被设置为按其名称加入集群,那么节点只能是集群的一部分。

注意,在同一环境中用最好使用不同的集群名称,否则可能导致节点加入到错误的集群中。例如,你可以使用"logging-dev", "logging-test", "logging-prod"分别用于开发、测试和正式集群的名字。

ES集群实际上是一个分布式系统,这是ES的一大优势,它需要具备两个特性:

  1)高可用性

    a)服务可用性:允许有节点停止服务;

    b)数据可用性:部分节点丢失,不会丢失数据;

  2)可扩展性

    随着请求量的不断提升,数据量的不断增长,系统可以将数据分布到其他节点,实现水平扩展;

ES集群有三种健康状态:

  • green:所有主要分片和复制分片都可用

  • yellow:所有主要分片可用,但不是所有复制分片都可用

  • red:不是所有的主要分片都可用

我们可以通过查询语句对健康状态进行查询,关注和提升ES集群的健康状态对保证数据安全性、高效查询十分有必要。

2.6 节点(node)

节点是一个ElasticSearch的实例,其本质就是一个Java进程,负责进行数据存储,并且参与集群的索引和搜索功能;一台机器上可以运行多个ElasticSearch实例,但是建议在生产环境中一台机器上只运行一个ElasticSearch实例。

与集群一样,节点由一个名称标识,默认情况下,该名称是在启动时分配给节点的随机通用唯一标识符(UUID)。如果不希望使用默认值,则可以定义所需的任何节点名称。

一个集群可以有任意数量的节点。此外,如果在网络上当前没有运行任何节点,那么此时启动一个节点将默认形成一个单节点的名字叫"elasticsearch"的集群。一个节点可以通过配置集群名称来加入到一个特定的集群中。默认情况下,每个节点都被设置加入到一个名字叫"elasticsearch"的集群中,这就意味着如果你启动了很多个节点,并且假设它们彼此可以互相发现,那么它们将自动形成并加入到一个名为"elasticsearch"的集群中。

在一个ES的集群中包含着多个ES的节点,往往每个节点所扮演的角色也不尽相同,ES的节点类型主要包含以下几类:

  • Master-eligible Node:每个节点启动后,默认是一个 Master-eligible 节点,Master-eligible的节点可参加选主流程,成为Master节点,通过配置项 node.master:falase 可以禁用节点的Master-eligible职责,禁止后当前节点就不会参加选主流程;

  • Master Node:ES集群中虽然每个节点都保存了集群状态,但是只有Master节点才有修改集群状态的权限,集群状态包括:集群中节点信息、所有索引和其相关的Mapping和Setting信息、分片的路由信息。在集群启动时,第一个启动的Master-eligible节点会将自己选举为主节点;

  • Data Node:保存数据的节点,负责保存分片数据,对数据扩展有重要作用;

  • Coordinating Node:负责接受Client请求,将请求分发到合适的节点获取响应后,将结果最终汇集在一起,每个节点默认都有Coordinating节点的职责;

  • Machine Learning Node:负责运行机器学习的Job,用来做异常检测;

  • Ingest Node:数据预处理的节点,支持Pipeline管道设置,可以使用Ingest对数据进行过滤、转换等操作。

注意,每个ES节点可以承担多个职责。

2.7 分片(shard)

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

Shard有两种类型:primary和replica,即主分片及副本分片。主分片用于文档存储,每个新的索引会自动创建5个主分片,当然此数量可在索引创建之前通过配置自行定义,不过,一旦创建完成,其主分片的数量将不可更改。Replica分片是主分片的副本,用于冗余数据及提高搜索性能,为保证副本分片的有效性,主分片绝不会被创建在同一节点上。每个主分片默认配置了一个副本,但也可以配置多个,且其数量可动态更改。ES会根据需要自动增加或减少这些Replica shard的数量。

ES集群可由多个节点组成,各分片分布式地存储于这些节点上。ES可自动在节点间按需要移动分片,例如增加节点或节点故障时。简而言之,分片实现了集群的分布式存储,而副本实现了其分布式处理及冗余功能。

3 安装

3.1 ES 安装

官方下载地址:

https://www.elastic.co/cn/downloads/elasticsearch

在ES官网有很详细的安装说明:

https://www.elastic.co/guide/en/elastic-stack-get-started/current/get-started-elastic-stack.html#install-elasticsearch

这里继续给出当前版本linux系统下elasticsearch安装方法,首先下载安装包:

curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.9.0-linux-x86_64.tar.gz

解压:

tar -xzvf elasticsearch-7.9.0-linux-x86_64.tar.gz

解压后elasticsearch目录内结构如下:

其中bin目录时脚本文件,config目录存放的是ES的相关配置。

为了使局域网其他机器能够访问ES,在启动前,稍微修改一下配置:

cd elasticsearch-7.9.0

vim ./config/elasticsearch.yml

添加以下内容后保存退出:

http.host: 0.0.0.0

启动:

./bin/elasticsearch

若是启动成功,可在局域网内任何机器访问,默认端口是9200,我的服务器ip是192.168.31.221,所以访问地址为:http://192.168.31.221:9200 ,成功访问后,出现以下界面:

3.2 Kibana安装

Kibana 是一个免费且开放的用户界面,通过Kibana,我们能够对 Elasticsearch 数据进行可视化,并在 Elastic Stack 中进行导航。并且可以进行各种操作,从跟踪查询负载,到理解请求如何流经您的整个应用,都能轻松完成。

  • Kibana是ElasticSearch的一个工具,用来分析ES中的数据并以各种图形界面显示出来
  • 可以作为ElasticSearch的一个客户端,在Kibana中可以很轻松的调用ES的RESTful接口

Kibana下载地址:

https://www.elastic.co/cn/downloads/kibana

注意,一定要下载与elasticsearch对应的Kibana版本。

下载好后,解压,目录结构如下:

配置Kibana,允许其他机器访问,并添加ES的访问地址:

cd kibana-7.9.0-linux-x86_64/

vim ./config/kibana.yml

添加以下内容:

server.host: "0.0.0.0"

elasticsearch.hosts: ["http://192.168.31.221:9200"]

启动Kibana:

./bin/kibana

在浏览器中访问:http://192.168.31.221:5601/ , 出现一下界面证明成功。

尝试使用Kibana进行查询,按如下方式打开开发工具:

点击切换后界面的三角形按钮可运行查询:

具体查询语法,我们后续在具体学习。

到这一步,我们已经将ES基础概念和ES安装、Kibana安装完成。后续可正式开始学习ES。

posted @ 2020-09-22 07:24  奥辰  阅读(1010)  评论(1编辑  收藏  举报