ElasticSearch学习笔记二 初识Elasticsearch

Elasticsearch简介

Elasticsearch 是一个建立在一个全文搜索引擎库 Apache Lucene™ 基础之上构建的开源、分布式、RESTFful的全文搜索引擎。 Lucene 可能是目前存在的,不论开源还是私有的,拥有最先进,高性能和全功能搜索引擎功能的库。

但是 Lucene 仅仅只是一个库。为了利用它,你需要编写 java 程序,并在你的 java 程序里面直接集成 Lucene 包。 更坏的情况是,你需要对信息检索有一定程度的理解才能明白 Lucene 是怎么工作的。Lucene 是 很 复杂的。

Elasticsearch 也是使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目标是使全文检索变得简单, 通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。

然而,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确的形容:

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

Elasticsearch 将所有的功能打包成一个单独的服务,这样你可以通过程序去访问它提供的简单的 RESTful API 服务, 不论你是使用自己喜欢的编程语言还是直接使用命令行(去充当这个客户端)。

就 Elasticsearch 而言,起步很简单。对于初学者来说,它预设了一些适当的默认值,并隐藏了复杂的搜索理论知识。 它开箱即用 。只需最少的理解,你很快就能具有生产力。

随着你知识的积累,你可以利用 Elasticsearch 更多的高级特性,它的整个引擎是可配置并且灵活的。 从众多高级特性中,挑选恰当去修饰的 Elasticsearch,使它能解决你本地遇到的问题。

总的来说,Elasticsearch 是一个分布式文档数据库,文档中的每个字段都是被索引的数据并且可以被检索,它能够扩展支持上百个服务节点,并支持 PB 级别的结构化或者非结构化数据,它可以在很短的时间内存储、检索或者分析大量的数据。

Elasticsearch术语及概念

文本(Text)

文本(或全文)是普通非结构化的文本,如一篇文章一段话。默认情况下,文本将被分析成一个个的索引词(term),然后索引词存储在Elasticsearch索引中。文本字段在索引前需要进行分析,以便全文检索。当我们用关键词进行全文检索时,我们检索的关键词必须也先分析从而产生与全文索引时分析得到的相同的索引词。Elasticsearch是通过分析得到的索引词进行检索的。

索引词/精确值(term)

在elasticsearch里,索引词(term)是一个被索引的通过分析后得到的精确值。foo, Foo,FOO 是不同的索引词。索引词(即精确值)可以使用“term”查询接口来查询。

精确值 VS 全文

Elasticsearch 中的数据可以概括的分为两类:精确值和全文。

精确值 如它们听起来那样精确。例如日期或者用户 ID,但字符串也可以表示精确值,例如用户名或邮箱地址。对于精确值来讲,Foo 和 foo 是不同的,2014 和 2014-09-15 也是不同的。
精确值很容易查询。结果是二进制的:要么匹配查询,要么不匹配。这种查询很容易用 SQL 表示:

WHERE name    = "John Smith"
  AND user_id = 2
  AND date    > "2014-09-15"

查询全文数据要微妙的多。我们问的不只是“这个文档匹配查询吗”,而是“该文档匹配查询的程度有多大?”换句话说,该文档与给定查询的相关性如何?

我们很少对全文类型的域做精确匹配。相反,我们希望在文本类型的域中搜索。不仅如此,我们还希望搜索能够理解我们的 意图 :

搜索 UK,会返回包含United Kindom的文档。

搜索jump,会匹配jumped , jumps , jumping,甚至是leap

搜索johnny walker会匹配Johnnie Walkerjohnnie depp应该匹配Johnny Depp

fox news hunting应该返回福克斯新闻( Foxs News )中关于狩猎的故事,同时,fox hunting news应该返回关于猎狐的故事。

为了促进这类在全文域中的查询,Elasticsearch 首先 分析 文档,之后根据结果创建 倒排索引 。

分析(Analysis)与分析器

分析 包含下面的过程:

  • 首先,将一块Text(文本)分成适合于倒排索引的独立的索引词(term) 。
  • 之后,将这些词条统一化为标准格式 以提高它们的“可搜索性”,或者 recall

分析器 执行上面的工作。 分析器 实际上是三个功能:

字符过滤器

首先,字符串按顺序通过每个 字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将 & 转化成 and。

分词器

其次,字符串被 分词器 分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条。

Token 过滤器

最后,词条按顺序通过每个 token 过滤器 。这个过程可能会改变词条(例如,小写化 Quick ),删除词条(例如, 像 a, and, the 等无用词),或者增加词条(例如,像 jump 和 leap 这种同义词)。

映射(Mapping)

为了能够将时间域视为时间,数字域视为数字,字符串域视为全文或精确值字符串, Elasticsearch 需要知道每个域中数据的类型。这个信息包含在映射中。
索引中每个文档都有 类型 。每种类型都有它自己的 映射 ,或者 模式定义 。映射定义了类型中的域,每个域的数据类型,以及Elasticsearch如何处理这些域。映射也用于配置与类型有关的元数据。

映射是像关系数据库中的表字段定义。每个索引都有一个映射,它定义了每个索引的类型,再加上一些索引范围的设置。映射可以被明确地定义,或者在一个文档被索引的时候自动生成。

集群(Cluster)

Elasticsearch集群包含一个或多个分配了相同的集群名称的节点。每个集群都有一个主节点是集群自动选择产生,并且可以决定如果当前主节点失败,哪些可以替换。一个集群应该有一个唯一的名称,当一个节点被设置为相同的集群名称时,节点会自动加入集群。
我们前面提到过 Elasticsearch 可以横向扩展至数百(甚至数千)的服务器节点,同时可以处理PB级数据。这些服务器节点构成一个服务器集群,每一个节点都是集群的一个节点。

Elasticsearch 尽可能地屏蔽了分布式系统的复杂性。

  • 分配文档到不同的容器 或 分片 中,文档可以储存在一个或多个节点中
  • 按集群节点来均衡分配这些分片,从而对索引和搜索过程进行负载均衡
  • 复制每个分片以支持数据冗余,从而防止硬件故障导致的数据丢失
  • 将集群中任一节点的请求路由到存有相关数据的节点
  • 集群扩容时无缝整合新节点,重新分配分片以便从离群节点恢复

节点(Node)

一个Elasticsearch节点是一个逻辑上的服务,理论上应该是一台独立的服务器,节点是集群的一部分,它也可以存储数据,并且参与集群的索引于检索功能。在启动时,节点将使用单播(或组播,但是必须指定)来发现使用相同的群集名称的群集,并会尝试加入该群集。

分片(Shard)

一个分片是一个单一的Lucene的实例。这是一个低级别的通过ElasticSearch自动管理的“工作者”单元。索引是一个逻辑命名空间指向主分片和副本分片。索引的主分片和副本分片的数量需要明确的指定。然而你的代码应该只处理一个索引。Elasticsearch分配集群中所有节点的分片。在节点出现故障或增加新节点的时候,可以自动的将一个节点上的分片移动到另一个节点上。

一个索引可以存储很大的数据,这些数据量级可能超过任何一个单一节点的物理存储上限,为了解决这个问题,Elasticsearch会将索引分别存储在多个分片当中,当你创建一个索引的时候可以指定希望创建的分片数量,每个分片本身其实就是一个全功能的单元。
分片主要2部分的原因:

  1. 允许水平切分数据存储
  2. 允许并行操作多个分片提高速度和吞吐量。

主分片(Primary shard)

索引中的每个文档都分别存储在在一个主要分片上。当你索引一个文档时,索引首先生成在主分片上,然后才到主分片的所有副本上。默认情况下,索引有5个主分片。您可以指定更多或更少的主分片来适应索引可以处理的文档数。一旦创建了索引,就不能改变索引中主分片的数量。

副本分片(Replica shard)

每个主分片可以有零个或多个副本。副本是主分片的一个拷贝,有两个作用:

  1. 故障转移:如果主分片有问题,副本分片可以提升为主分片;
  2. 提高性能:获取和搜索请求可以处理主分片或副本分片。

默认情况下,每个主分片有一个副本,不过索引的副本数量可以动态地改变。在同一个节点上,一个副本分片将永远不会和其主分片一起运行。

复制(replica)

Elasticserach 允许你创建一个或者多个索引的拷贝来避免单点问题,当集群中的某个节点出现故障是,复制可以恢复数据,保证系统的高可用。当你创建一个索引的时候指定了创建复制,你的索引主分片就自动形成了副本分片。

索引可以有多个分片和复制,一旦复制,索引就会有主分片和副本分片,分片的数量和复制的数量可以在创建索引的时候定义,当创建索引后,你可以随意改变复制的数量,但不可以改变分片的数量。

默认情况下,每个索引会有5个分片和1个副本,这就意味着一般来讲Elasticsearch集群会有2个节点。同理一个索引会有5个主分片和5个副本分片。

路由(routing)

当索引一个文档的时候,文档会被存储到一个主分片中。 Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?当我们创建文档时,它如何决定这个文档应当被存储在分片 1 还是分片 2 中呢?

首先这肯定不会是随机的,否则将来要获取文档的时候我们就不知道从何处寻找了。实际上,这个过程是根据下面这个公式决定的:

shard = hash(routing) % number_of_primary_shards

routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值。 routing 通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards (主分片的数量)后得到 余数 。这个分布在 0 到 number_of_primary_shards-1 之间的余数,就是我们所寻求的文档所在分片的位置。

这就解释了为什么我们要在创建索引的时候就确定好主分片的数量 并且永远不会改变这个数量:因为如果数量变化了,那么所有之前路由的值都会无效,文档也再也找不到了。

索引(index)

索引 这个词在 Elasticsearch 语境中包含多重意思, 所以有必要做一点儿说明:

索引(名词)
如前所述,一个 索引 类似于传统关系数据库中的一个 数据库 ,是一个存储关系型文档的地方。 索引 (index) 的复数词为 indices 或 indexes 。

索引(动词)
索引一个文档 就是存储一个文档到一个 索引 (名词)中以便它可以被检索和查询到。这非常类似于 SQL 语句中的 INSERT 关键词,除了文档已存在时新文档会替换就文档情况之外。

我们这里说的是名词索引,是我们需要存储的一系列文档的集合。

类型(type)

在6.0之前的版本,一个ElasticSearch索引中,可以有多个类型;从6.0版本开始,一个ElasticSearch索引中,只有1个类型。一个类型是索引的一个逻辑上的分类,通常具有一组相同字段的文档组成。ElasticSearch的类型概念相当于关系数据库的数据表。

文档(document)

文档是ElasticSearch可被索引的基础逻辑单元,相当于关系数据库中数据表的一行数据。ElasticSearch的文档具有JSON格式,由多个字段组成,字段相当于关系数据库中列的概念。

Elasticsearch VS RDBMS

ElasticSearch RDBMS
索引(index) 数据库(database)
类型(type) 表(table)
文档(document) 行(row)
字段(field) 列(column)
映射(mapping) 表结构(schema)
全文索引 索引
查询DSL SQL
GET/POST/_search select
PUT/POST update
DELETE delete

字段(Field)

文档中包含的一组字段或键值对。字段的值可以是一个简单的(标量)值(如字符串,整数,日期),或者一个嵌套的结构就像一个数组或对象。一个字段就是类似关系数据库表中的一列。映射的每个字段有一个字段的类型“type”(不要与文档类型混淆),表示那种类型的数据可以存储在该字段里,如:整数,字符串,对象。映射还允许你定义(除其他事项外)一个字段的值如何进行分析。

原文档(_source)

默认情况下,你的JSON文档将被索引存储在_source字段里面,所有的get(获取)和search(搜索)请求将返回的该字段。这将允许你直接从搜索结果中访问到源数据,而不需要再次发起请求检索。
索引将返回完整的的JSON字符串给你,即使它包含无效的JSON。此字段里的内容不表示任何该对象里面的数据如何被索引。

_id

每个文档ID标识了一个文档。一个文档的index/type/id必须是唯一的。如果没有提供ID,将是自动生成。

猜你喜欢

转载自blog.csdn.net/weixin_43430036/article/details/83109348