浅谈Elasticsearch 5.6.10_理论篇

2020-05-29 00:00:00 数据 文档 节点 请求 写入

写在前面:历经一年,终于从电子实验台转战到服务器机房了,不变的依然是一线搬砖能手。以大数据运维的名头进入互联网已有半年,从零开始接触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

相关文章