Elasticsearch介绍

Elasticserch是一个开源且分布式、RESTful风格的搜索引擎和数据分析引擎,由Java编写,它的内部使用的是Apache Lucene做索引功能,Elasticsearch建立在一个全文的搜索引擎库“Apache Lucene”基础之上,作为Elastic Stack的核心,它集中存储你的数据。
Elasticsearch不仅仅只是一个全文搜索引擎,它还可以用作全文检索、结构化搜索、分析以及这三个功能的组合。

  1. 全文检索:一个分布式的实时文档存储,每个字段都可以被索引与搜索
  2. 结构化搜索:能胜任上百个服务节点的扩展,并支持PB级别的结构化或者非结构化数据
  3. 分析:一个分布式实时分析搜索引擎

Elasticsearch特性

查询:
通过Elasticsearch能够执行及合并多种类型的搜索结构化数据、非结构化数据、地理位置、指标等。

分析:
找到与查询最匹配的十个文档很简单,但如果面对的是十亿行日志呢?Elasticsearch聚合让你能够从远处看,探索数据的趋势和模式。

速度:
Elasticsearch很快,快到不可思议。

可扩展性:
可以在笔记本电话运行。也可以在承载了PB级数据的成百上千台服务器运行。原型环境和生产环境可无缝切换;无论Elasticsearch是在一个节点上运行,还是在一个包含300个节点的集群上运行,都可以以相同的方式与Elasticsearch进行通信。它能够水平扩展,每秒钟处理海量事件,同时能够自动管理索引和查询在集群中的分布方式,以实现极其流畅的操作。

弹性:
硬件故障。网络分割。Elasticserch可以检测这些故障并确保集群和数据的安全性及可用性。通过跨集群复制功能,辅助集群可以作为热备份随时投入使用。

灵活性:
数字、文本、地理位置、结构化数据、非结构化数据。应用搜索、安全分析、指标或日志分析只是全球众多公司利用Elasticsearch解决各种挑战的冰山一角。

客户端库:
Elasticsearch使用的是标准的RESTful风格的API和JSON。此外,Elasticsearch还构建和维护了很多语言的客户单,例如JAVA、Python、.NET、SQL、PHP等。

延展Elasticsearch:
为你的集群添加用户名和密码,监控Elasticsearch的性能表现,通过运行Machine Learning任务来发现异常等等。

HADOOP和SPARK:
hadoop中有大量的数据,Elasticsearch-Hadoop(ES-Hadoop)连接器的实时搜索和分析功能足够处理Hadoop的大量数据。

Elasticsearch的基本概念

Elasticsearch的基本概念大致可以分为以下几点:ClusterNodeIndexShardsReplicasDocument
下面简单介绍这几种概念:

Cluster

集群是一个或多个节点的集合,它们共同保存整个数据,并提供跨所有节点的联合索引和搜索功能。集群由唯一名称标识,默认情况下为"elasticsearch"。此名称很重要,因为如果节点设置为按名称加入集群,则该节点只能是集群的一部分。确保不要在不同的环境中用相同集群名称,否则最终会导致节点加入错误的集群。每个集群都要有自己唯一的集群名称。

Node

节点
节点是作为集群一部分的单个服务器,存储数据并参与集群的索引和搜索功能。与集群一样,节点由名称标识,默认情况下,该名称是在启动时分配给及节点的随机通用唯一标识符(UUID)。如果不需要默认值,可以定义所需的任何节点名称。此名称对于管理目的非常重要,可以在其中识别网络中的哪些服务器与Elasticsearch集群中的哪些节点相对应。
可以将节点配置按集群名称加入特定集群。默认情况下,每个节点都设置为加入一个名为elasticsearch的集群,这意味着如果你在网络上启动了许多节点并且假设它们可以相互发现,它们将自动形成并加入一个名为elasticsearch的集群。
在单个集群中,可以拥有任意数量的节点。此外,如果网络上当前没有其它Elasticsearch节点在运行,则默认情况下启动单个节点将形成一个名为elasticsearch的新节点集群。

Index

索引
索引是具有某些类似特征的文档集合。例如,你可以拥有客户数据的索引,产品目录的另一个索引以及订单数据的另一个索引。索引由名称标识(必须全部为小写),并且此名称用于在对其中的文档执行索引,搜索,更新和删除操作时引用索引。在单个集群中,你可以根据需要定义任意数量的索引。Index 体现了逻辑空间的概念,每个索引都有自己的 Mapping 定义,用于定义包含文档的字段名称和字段类型。

  • 索引的 Mapping 与 Settings
    • Mapping 定义文档字段的类型
    • Setting 定义不同的数据分布

索引元数据内包含 Mapping 和 Setting

索引元数据
一个完整的索引元数据包含Mapping信息Setting信息。

{
  "movies" : {                                      #索引名称
    "aliases" : { },                                #索引别名
    
    Mapping元数据
    "mappings" : {                                  #Mapping设置
      "properties" : {  
        "@version" : {                              #Version为字段名称,字段为写到es中自定义的字段
          "type" : "text",                          #Version字段名称处的字段类型,这里为字符串,在es中为 text
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "genre" : {                                 #gener字段类型
          "type" : "text",                          #类型为字符串
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "id" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "year" : {                                  #year字段类型
          "type" : "long"                           #year字段类型为数值,数值在es中为 long
        }
      }
    },
    
    Setting元数据
    "settings" : {                                  #Setting设置
      "index" : {
        "creation_date" : "1575518947108",          #创建索引的时间戳
        "number_of_shards" : "1",                   #索引的分片数量
        "number_of_replicas" : "1",                 #索引的副本数量
        "uuid" : "r4qFegpeSmCnxmJzYVPO6w",          #索引的UUID,具备唯一性
        "version" : {                               #版本信息
          "created" : "7040099"                     #版本信息创建时间
        },
        "provided_name" : "movies"
      }
    }
  }
}

Document

文档
文档是可以建立索引的基本信息单元,是所有可搜索数据的最小单位,。例如,你可以为单个客户创建一个文档,为单个产品创建另一个文档,为单个订单创建另一个文档。这些文档会被序列化成 JSON 格式,保存在 Elasticsearch 的分片中,因为Elasticsearch用JSON(JavaScript对象表示法)表示,格式为 Key=>Value,这是一种无处不在的internet数据交换格式。在索引中,可以存储任意数量的文档。
Key在Elasticsearch被称为字段名称
Value在Elasticsearch中被称为字段值。
每个字段Key都有对应的字段类型 (字符串text/数值long/布尔boolean/日期date/二进制binary/范围类型range)等。。。
字段类型我们可以自己定义,也可以先插入文档后通过 Elasticsearch 自动推算字段类型。
每个文档都有一个 Unique ID,你可以通过创建文档时指定,或者通过 Elasticsearch 自动生成。

文档的Metadata元数据

    {
  "_index": "movies",                   #文档所属的索引名称
  "_type": "_doc",                      #文档所属的类型名称
  "_id": "288",                         #文档唯一 ID
  "_version": 1,                        #文档版本信息
  "_score": 0,                          #相关性打分
  "_source": {                          #文档的原始 Json 数据
    "year": 1994,                       #字段year:字段值1994
    "id": "288",                        
    "title": "Natural Born Killers",
    "@version": "1",
    "genre": [
      "Action",
      "Crime",
      "Thriller"
    ]
  }
}

Shards & Replicas

分片和副本
一个索引可能存储大量数据,这些数据可以超过单个节点的硬件限制。例如一个包含10条文档占用1TB磁盘空间的索引显然不适合在单个节点上,肯定会很慢而且不能单独来处理单个节点的搜索请求。
为了解决这个问题,Elasticsearch提供了将你的索引细分为多个碎片或者叫分片的能力。在创建索引时,可以简单的定义所需的分片数量。每个分片本身就是一个功能完全独立的索引“索引”,可以驻留在集群中的任何节点上。
分片之所以重要,主要由两个原因:

  • 它允许水平地分割/扩展内容卷
  • 它允许你夸分片(可能在多个节点上)分布和并行操作,从而提高性能和吞吐量

在一个网络环境中随时都可能出现故障,强烈推荐有容灾机制。Elasticsearch允许你将一个或多个索引分片复制到其它地方,这被称之为副本。
复制之所以重要,有两个主要原因:

  • 它在分片/节点出现故障时提供高可用性。因此,副本分片永远不会在从中复制的原始/主分片相同的节点上分配。
  • 它允许你扩展搜索量/吞吐量,因为可以在所有副本上并行执行搜索

在Elasticsearch7开始,创建的索引默认是一个主分片和一个副本分片,在Elasticsearch5和6中,每个索引默认分配了5个主分片和1个副本分片。

总而言之,每个索引可以拆分多个分片。索引也可以复制为零(表示没有副本)或更多次。一旦被复制,每个索引都将具有主分片(被复制的原始分片)和副本分片(主分片的副本)。在创建索引时,可以为每个索引定义分片和副本的数量。创建索引后,你可以随时动态的更新副本的数量,但不能更改事后分片的数量。除非Reindex。

一个分片是一个运行的 Lucene 的实例。
主分片数在索引创建时指定,后续不允许修改,除非 Reindex
副本不可以和主分片在同一台ES实例中,否则会报 “yellow”

分片的设定

  1. 分片数设置过小
    1) 导致后续无法增加节点实现水平扩展。
    2) 单个分片的数据量太大,导致数据重新分配耗时。
  2. 分片数设置过大
    1) 影响搜索结果的相关性打分,影响统计结果的准确性。
    2) 单个节点上过多的分片,会导致资源浪费,同时也会影响性能。

Elasticsearch原理概述

在一次搜索中,Elasticsearch原理如下

Elasticsearch分片图示
Elasticsearch分片图示

图示,两个ES节点组成的Elasticsearch Cluster,每个主机上都有两个分片,分别为主分片和副本分片。
以上图讲解的是ES集群面对用户请求的响应操作。
请求处理流程:假如用户请求的读read到Node1来请求数据,一般我们由副本分片来处理,主分片能读能写,但是我们一般是要求主分片是处理写操作,而副本分片来进行读操作,我们的Node1接收到读请求后,自己主机处理一部分请求,另外一部分请求转发给Node2的副本分片来处理,结果处理后Node2返回一部分结果给Node1,Node1再把自己返回的请求和Node2返回给自己的请求进行整合后返回给应用程序。
在ES集群中,所有节点都可以接收到来自于应用程序的请求,只不过是有接收应用程序的主机自己处理了一部分请求,而另一部分请求代理转发给集群中的其它节点处理。
注意:读请求可以发给副本分片,但是写请求只能由主分片来处理,当然主分片也可以处理读请求。

Elasticserch的由来

多年前,一个叫做Shay Banon的刚结婚不久的失业开发者,由于妻子要去伦敦学习厨师,他便跟着也去了。在他找工作的过程中,为了给妻子构建一个食谱的搜索引擎,他开始构建一个早期版本的Lucene。
直接基于Lucene工作会比较困难,所以Shay开始抽象Lucene代码以便Java程序员可以在应用中添加搜索功能。他发布了他的第一个开源项目,叫做“Compass”。
后来Shay找到一份工作,这份工作处在高性能和内存数据网格的分布式环境中,因此高性能的、实时的、分布式的搜索引擎也是理所当然需要的。然后他决定重写Compass库使其成为一个独立的服务叫做Elasticsearch。
第一个公开版本出现在2010年2月,在那之后Elasticsearch已经成为Github上最受欢迎的项目之一,代码贡献者超过300人。一家主营Elasticsearch的公司就此成立,他们一边提供商业支持一边开发新功能,不过Elasticsearch将永远开源且对所有人可用。

据说:Shay的妻子依旧等待着她的食谱搜索……

本站文章基于国际协议BY-NA-SA 4.0协议共享;
如未特殊说明,本站文章皆为原创文章,请规范转载。

0

欢迎来到Elastic Stack技术栈~~