ES入门系列 — 3 走进elasticsearch

7 篇文章 0 订阅

简单写一个ES系列,希望对NewSql、检索有兴趣的同学可以快速入手,争取在7月份完成该系列文章

ES入门系列

如果你是第一次使用elasticsearch,那么建议你先快速阅读以下上篇文章 ES入门系列 — 2 Elasticsearch介绍,科普一下elasticseach,本节主要是对elastciseach介绍的深入,从宏观层面了解elasticsearch


1 ES逻辑视觉三套件

1.1 文档(Document)

es是一个面向文档,无schema化的一个数据库,在es里面,所有需要被检索都被称为文档。最客观的理解,就是我们在csdn博客上搜索内容,而通过我们输入的词汇,csdn返回一系列博客,而这些博客在es内部就是文档的存在。我们可以通过 索引 + 类型 + 文档Id 就可以获取到某个文档,比如 索引A1 + 类型B1 + 文档id C1 对应文档a,索引A1 + 类型B1 + 文档id C2 对应文档b。

如果你用过关系类数据库,索引其实很好理解,因为在关系类数据库,我们管他叫数据库,比如mysql里面的database。而类型就是mysql database里面的表;而文档id对应的就是关系型数据库每一数据行的唯一标识,数据行id;文档则是关系数据库里面的每一行数据

### 下面操作都是mysql里面的语句
#下面语句,相当于es建了一个索引
CREATE DATABASE ms_db DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
#下面语句, 相当于es建了一个类型
CREATE TABLE `ms_table` (
	`id` int(11) NOT NULL AUTO_INCREMENT,
	`name` varchar(8) DEFAULT NULL,
	PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARSET = utf8;
#下面语句,相当于es插入一个文档,并且文档id是1
insert into `ms_table` (`id`,`name`) values (1, "name1");

和关系数据库不一样,es的文档是层次化,无模式并且灵活的,es文档可以不受模式限制,所以文档并不需要拥有映射中所定义的所有字段, 也可能提出新的字段。比如我们有一个类型的文档,文档有三个字段 address、name、age,那么这里的address 在es里面可以包含经纬度 和 地理名词,并且完全兼容存在。并且你在es使用过程中可以随变添加和忽略字段,而es也根据你插入的文档,判断新增字段的类型(当然这个建议你先声明好字段类型,否则可能存在es类型误判,具体见 ES入门系列 — 4 索引

1.2 类型(Type)

类型是文档的逻辑容器, 类似于表格是行的容器。 在不同的类型中, 最好放入不同结构(模式) 的文档。 例如, 可以用一个类型定义聚会时的分组, 而另一个类型定义人们参加的活动。每个类型中字段的定义称为映射。 例如, name 字段可以映射为string 。 而location 中的geolocation 字段可以映射为geo_point 类型(映射类型后面我们再搞个章节讨论) 。 每种字段都是通过不同的方式进行处理。如果一篇新近索引的文档拥有一个映射中尚不存在的字段,ES会自动地将新字段加入映射。 为了添加这个字段, ES不得不确定它是什么类型, 于是ES会进行猜测。 例如, 如果值是7, Elasticsearch会假设字段是长整型。这种新字段的自动检测也有缺点, 因为Elasticsearch可能猜得不对。 例如, 在索引了值7之后, 你可能想再索引hello world , 这时由于它是string 而不是long , 索引就会失败。对于线上环境, 最安全的方式是在索引数据之前, 就定义好所需的映射。

映射类型只是将文档进行逻辑划分。 从物理角度来看, 同一索引中的文档都是写入磁盘, 而不考虑它们所属的映射类型。另外,不同的类型应该有相似的结构(schema),举例来说,id字段不能在这个类型是字符串,在另一个类型是数值,这也是ES类型和关系数据库表的一个区别。技术上讲,多个类型可以在相同的索引中存在,只要它们的字段不冲突(要么因为字段是互为独占模式,要么因为它们共享相同的字段)。重要的一点是: 类型可以很好的区分同一个集合中的不同细分。在不同的细分中数据的整体模式是相同的(或相似的)。类型不适合 完全不同类型的数据 。如果两个类型的字段集是互不相同的,这就意味着索引中将有一半的数据是空的(字段将是 稀疏的 ),最终将导致性能问题。在这种情况下,最好是使用两个单独的索引。

1.3 索引(Index)

上面,你可能知道es里面有个索引的概念,可能你会有疑惑,不是有类型就足够了吗,加入索引是不是显得有点累赘?

索引是映射类型的容器。 一个Elasticsearch索引非常像关系型世界的数据库, 是独立的大量文档集合。每个索引存储在磁盘上的同组文件中; 索引存储了所有映射类型的字段, 还有一些设置。 例如, 每个索引有一个称为refresh_interval 的设置, 定义了新近索引的文档对于搜索可见的时间间隔。 从性能的角度来看, 刷新 操作的代价是非常昂贵的, 这也是为什么更新只是偶尔进行。 默认是每秒更新一次, 而不是每来一篇新的文档就更新一次。 如果看到Elasticsearch被称为准实时 的, 就是指的这种刷新过程。

而es里面的索引是一个顶层概念,物理存储上一个索引又分为多个分片。同时,同一个 Index 里面的 Document,不要求有相同的结构(scheme),但是最好保持相同,这样有利于提高搜索效率。


2 物理视觉上节点和分片

es物理上数据的组织是通过节点和分片,默认情况下, 每个索引由5个主要分片组成, 而每份主要分片又有一个副本, 一共10份分片。

一个节点就是一个Elasticsearch的实例。 多个节点可以加入同一个集群 。在服务器上启动Elasticsearch之后, 你就拥有了一个节点。 如果在另一台服务器上启动Elasticsearch, 这就是另一个节点。 甚至可以通过启动多个Elasticsearch进程, 在同一台服务器上拥有多个节点。当一个节点被选举成为  节点时, 它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。 任何节点都可以成为主节点。

如果每份分片至少有1个副本分片, 那么任何一个节点都可以宕机, 而Elasticsearch依然可以进行服务, 返回所有数据。 对于使用Elasticsearch的应用程序, 集群中有1个还是多个节点都是透明的。 默认情况下, 可以连接集群中的任一节点进行服务,es内部转发检索并访问完整的数据集。对使用者而言,就好像集群只有单独的一个节点。

Elasticsearch检索数据的最小单元是分片,分片也是Elasticsearch将数据从一个节点迁移到另一个节点的最小单位。一份分片 是Lucene的索引: 一个包含倒排索引的文件目录。分片可以是主分片, 也可以是副本分片, 其中副本 分片是主分片的完整副本。 副本分片用于搜索, 或者是在原有主分片丢失后成为新的主分片。你可以在任何时候改变每个分片的副本分片的数量, 因为副本分片总是可以被创建和移除。 这并不适用于索引划分为主分片的数量, 在创建索引之前, 你必须决定主分片的数量。


3 索引和检索过程

当索引程序向es插入一篇文章,它首先向集群的任意节点发起检索请求,节点内进行id的散列决定数据存储对应的索引分片(如下图,文档被索引到分片1),一旦目标分片确定,协调节点将请求转发目标节点的主分片,在主分片上面执行请求。如果成功了,它将请求并行转发到目标节点的所有副本分片上。一旦所有的副本分片都报告成功,主分片将向协调节点报告成功,协调节点向客户端报告成功

在搜索的时候, 接受请求的节点将请求广播转发到一组包含所有数据的分片。 Elasticsearch使用round-robin的轮询机制选择可用的分片(主分片或副本分片),每个分片在本地执行搜索并构建一个匹配文档的优先队列,一个优先队列仅仅是一个存有 top-n 匹配文档的有序列表。优先队列的大小取决于分页参数 from 和 size (例如,如下搜索请求将需要足够大的优先队列来放入100条文档)。然后从这些分片收集结果(它仅包含文档 ID 集合以及任何排序需要用到的值,例如 _score)汇聚给协调节点(既接受外部请求的节点), 协调节点将这些分片级的结果合并到自己的有序优先队列里,它代表了全局排序结果集合。 协调节点辨别出哪些文档需要被取回并向 同样处理查询阶段的分片副本 提交多个 GET 请求(采用mget命令),每个分片加载并 丰富(如高亮) 文档,如果有需要的话,接着返回文档给协调节点。最后协调节点返回结果给客户端,既完成整个检索的过程

NOTE1:谨慎使用深分页

解释:先查后取的过程支持用 from 和 size 参数分页,但是这是 有限制的 。 要记住需要传递信息给协调节点的每个分片必须先创建一个 from + size 长度的队列,协调节点需要根据 number_of_shards * (from + size) 排序文档,来找到被包含在 size 里的文档。取决于你的文档的大小,分片的数量和你使用的硬件,给 10,000 到 50,000 的结果文档深分页( 1,000 到 5,000 页)是完全可行的。但是使用足够大的 from 值,排序过程可能会变得非常沉重,使用大量的CPU、内存和带宽。因为这个原因,我们强烈建议你不要使用深分页。(如果一定要深分页,楼主建议你采用游标查询,ES进阶系列会讲到,至于哪一篇博客,楼主还没想好)

NOTE2:在文档被检索时,已经被索引的文档可能已经存在于主分片上但是还没有复制到副本分片。 在这种情况下,副本分片可能会报告文档不存在,但是主分片可能成功返回文档。




4 Elasticsearch RestApi尝鲜

偷偷懒,还是看 ES入门系列 — 5 查询语法


 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值