浅谈Elasticsearch 5.6.10_理论篇

写在前面:历经一年,终于从电子实验台转战到服务器机房了,不变的依然是一线搬砖能手。以大数据运维的名头进入互联网已有半年,从零开始接触Elasticsearch,入门到进阶,还未到放弃,闲来做个自我总结。

一、Elasticsearch简介

Elasticsearch是一个基于Apache Lucene(TM)的分布式可扩展的实时搜索和分析引擎。

优点:

1)开箱即用。安装步骤非常简单,集群默认配置成熟稳定。

2)近实时。从写入到可被读取只需秒级以内,效率高。

3)分布式。自动维护数据并行写入多个节点,搜索请求自动路由到多个节点执行;支持横向扩展,轻松解决TB乃至PB级别的数据量;自动维护数据的冗余副本。

4)丰富的API。使用Restful API能够满足日常运维需求,调用Java API能够开发很多复杂的搜索功能、聚合分析功能。

应用场景:

BI商业智能,离线分析+实时查询。

离线分析:主要作为Nosql数据库存储TB级别较大数据量的文档数据,供大数据平台作数据分析用,或者供业务部门做模糊搜索使用。

实时查询:用户的开卡信息通过Storm近实时写入到ES,供业务部门查询。

二、Elasticsearch集群特性

分布式机制下的隐藏特性:

1)自动分片:当一条文档写入到ES集群中,不必关心数据是如何分片、存到哪个shard,ES会自动完成。

2)自动发现集群:在新节点完成相关配置并启动进程后,会自动加入到集群,并接受部分数据。

3)节点负载均衡:比如10个node,100个shard,ES会自动进行均匀分配,以保持每个节点接收均匀的读写负载请求。

4)节点对等:每个节点都能接收所有请求,自动路由请求到对应节点执行,处理完成后收集响应,返回给客户端。

5)Rebalance机制:增加或减少节点/索引时,数据自动保持负载均衡。

shard & replica的特性:

1)每个索引包含多个shard。其中primary shard在创建索引时设置,从此不可修改;replica shard可以动态修改。

2)shard是最小的工作单元。承载部分数据及Lucene实例,具有完整的处理请求能力。

3)一条document必须而且只存在于一个shard及其replica中,不可能存在于多个。

4)replica是shard的副本,用于冗余,且能承担都请求的负载。

5)shard、replica都有默认值。ES5.6版本默认total shard = 5 * shard + 5 * replica = 10

6)shard不能与自己的replica放在同一个节点,但是可以和别人的replica放在同一个节点。

三、Elasticsearch读写原理

Elasticsearch写入数据过程:

  • 客户端选择一个node发送写入请求,该节点成为coordinating node(协调节点)。
  • 协调节点会计算新文档应该加入到哪个shard中,由于每个节点都存储有所有分片存储在哪个节点的信息,因此协调节点会将请求发送给对应主分片所在的节点。
  • 主分片完成新文档写入,会将请求并行发送到其所有副本分。
  • 协调节点收集所有分片所在节点的响应信息,然后返回相应结果给客户端。

图1、写入数据过程

Elasticsearch读取数据过程:

  • 客户端发送读取请求到coordinate node(协调节点)。
  • 首先,协调节点会广播请求到各个节点的不同分片,查询请求可以被某个主分片或某个副本分片处理,协调节点路由的依据是round-robin随机轮询算法,以此达到主分片/副本分片对查询请求的负载均衡。
  • query phase(查询阶段):每个 shard 将自己的查询结果(其实是一些轻量级的结果比如doc id、排序信息)返回给协调节点,由协调节点进行全局的合并、排序、分页等操作,产出最终的查询排序结果。
  • fetch phase(取回阶段):协调节点会根据最终的查询排序结果,向含有对应doc id 的节点上去拉取实际的 document 数据,最终返回给客户端。

Tips:如果是简单地读取某个doc id对应的文档值,则直接按照fetch phase(取回阶段)的过程获取结果。

图2、分布式搜索的查询阶段

图3、分布式搜索的取回阶段

深度剖析数据写入的底层原理:

1)每次写入新文档时,都会先写入内存buffer中,并将这一操作写入一个translog文件(transaction log)中。此时如果执行搜索操作,这个新文档还不能被索引到。

图4、新文档写入buffer,操作写入translog

2)当buffer中有数据,ES默认每隔1秒时间(这个时间可修改)进行一次refresh操作。此时在这1秒内写入buffer的文档会被写入一个文件系统缓存(filesystem cache)中,如是真如并构成一个分段(segment),然后清空buffer。此时这个segment里的文档可以被搜索到,但是尚未写入硬盘,即如果此时发生断电,则这些文档可能会丢失。 (过程1~2叫refresh)

图5、在执行刷新后清空内存,新文档写入文件系统缓存

3)不断有新的文档写入,则过程1~2不断重复执行。每隔一秒生成一个新的segment,而translog文件将越来越大。

图6、translog不断加入新文档记录

4)每隔30分钟或者translog文件变得很大,则执行一次fsync操作。此时立刻执行一次refresh操作,然后将所有在文件系统缓存中的segment写入磁盘,而translog将被删除(此后会生成新的translog)。 (此过程叫flush)

curl -XPOST 'http://es01:9200/_flush/synced'              #手工flush所有translog
curl -XPOST 'http://es01:9200/my_idxname/_flush/synced'   #手工flush某个索引的translog

图7、将segment强制fsync到磁盘,清空内存和translog

由上面的流程可以看出,在两次fsync操作之间,存储在内存和文件系统缓存中的文档是不安全的,一旦出现断电这些文档就会丢失。所以ES引入了translog来记录两次fsync之间所有的操作,这样机器从故障中恢复或者重新启动,ES便可以根据translog进行还原。

当然,translog本身也是文件,存在于内存当中,如果发生断电一样会丢失。但是,ES会在每隔5秒时间或是一次写入请求完成后将translog写入磁盘。可以认为一个对文档的操作一旦写入磁盘便是安全的可以复原的,因此只有在当前操作记录被写入磁盘,ES才会将操作成功的结果返回发送此操作请求的客户端。

此外,由于每一秒就会生成一个新的segment,很快将会有大量的segment。对于一个分片进行查询请求,将会轮流查询分片中的所有segment,这将降低搜索的效率。因此ES会自动启动合并segment的工作,将一部分相似大小的segment合并成一个新的大segment。合并的过程实际上是创建了一个新的segment,当新segment被写入磁盘,所有被合并的旧segment被清除。

图8、合并segment

Elasticsearch更新和删除文档:

ES的索引是不能修改的,因此更新和删除操作并不是直接在原索引上直接执行。

每一个磁盘上的segment都会维护一个del文件,用来记录被删除的文件。每当用户提出一个删除请求,文档并没有被真正删除,索引也没有发生改变,而是在del文件中标记该文档已被删除。因此,被删除的文档依然可以被检索到,只是在返回检索结果时被过滤掉了。每次在启动segment合并工作时,那些被标记为删除的文档才会被真正删除。

更新文档会首先查找原文档,得到该文档的版本号。然后将修改后的文档写入内存,此过程与写入一个新文档相同。同时,旧版本文档被标记为删除,同理,该文档可以被搜索到,只是最终被过滤掉。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值