Elastic Stack学习笔记5-分布式特性介绍

  1. 分布式特性

  • es支持集群模式,是一个分布式系统,其好处主要有两个:

  • 增大系统容量,如内存、硬盘,使得es集群可以支持PB级的数据。

  • 提高系统的可用性,即使部分节点停止服务,整个集群仍然可以正常服务。

  • es集群由多个es实例组成

  • 不同集群通过集群名称进行区分,可以通过cluster.name进行修改,默认名称为elasticsearch。

  • 每个es实例本质上是一个JVM进程,且有自己的名字,通过node.name进行修改。

  1. cerebro安装与运行

通过cerebro可以可视化的监控elasticsearch集群的状态。

  • 下载地址

https://github.com/lmenezes/cerebro

下载https://github.com/lmenezes/cerebro/releases/tag/v0.7.1

  • 解压安装包并运行

tar zxvf cerebro-0.7.1.tgz
cd cerebro-0.7.1
cd bin
./cerebro

jdk9+安装不成功可参考:https://blog.csdn.net/ilwoziji/article/details/129230044

  1. es集群的构建

  • es的安装与下载

可参见:https://blog.csdn.net/ilwoziji/article/details/129227381?spm=1001.2014.3001.5501

  • 启动一个节点

./elasticsearch -Ecluster.name=my_cluster -Epath.data=my_cluster_node1 -Enode.name=node1 -Ehttp.port=5200 -d 
  • cluster state

  • es集群相关的数据被称为cluster state,主要记录如下信息

  • 节点信息,比如节点名称、链接地址等。

  • 索引信息,比如索引名称配置等。

...

  • master node

  • 可以修改cluster state的节点称为master节点,一个集群只能有一个

  • cluster state存储在每一个节点上,master节点维护最新版本并同步给其他节点。

  • master节点是通过集群中所有节点选举产生的,可以被选举的节点称为master-eligible节点,相关配置如下:

node.master:true默认就是true。是可以被选举为master的节点。

  • 创建一个索引

  • 我们通过如下API创建一个索引

  • PUT test_index

  • Coordinating Node

  • 处理请求的节点被称为coordinating节点,该节点为所有节点的默认角色,不能取消

  • 路由请求到正确的节点进行处理,比如创建索引的请求到master节点。

  • Data Node

  • 存储数据的节点Data Node,默认节点都是data类型,相关配置如下:

  • data.node:true

  • 新增一个节点

  • 新增node2节点,命令如下:

./elasticsearch -Ecluster.name=my_cluster -Epath.data=my_cluster_node2 -Enode.name=node2 -Ehttp.port=5300 -d 
  1. 提高系统可用性-副本与分片

  • 服务可用性

  • 两个节点的情况下,允许其中一个节点停止服务。

  • 数据可用性

  • 引入副本(Replication)解决。

  • 每个节点上都有完备的数据。

  • 增大系统容量

  • 如何将数据分布到所有节点上?

  • 引入分片(shard)解决问题。

  • 分片是es支持PB级数据的基石。

  • 分片存储了部分数据,可以分布于任意节点上。

  • 分片数在索引创建时指定,且后续不允许在修改,默认为5个。

  • 分片有主分片和副本分片之分,以实现数据的高可用。

  • 副本分片的数据由主分片同步,可以有多个,从而提高读取的吞吐量。

  • 两个问题

  • 此时增加节点是否能提高test_index的容量?

  • 答案是不能,因为只有3个分片,已经分布在3个节点上,新增节点无法利用。

  • 此时增加副本数是否能提高test_index的读取吞吐量?

  • 答案是不能,因为新增的副本也是分步在当前的3个节点上,还是利用了同样的资源。如果要增加吞吐量,还需要新增节点。

  • 分片设定很重要,需要提前规划好

  • 过小会导致后续无法通过增加节点来提高查询的吞吐量。

  • 过大会导致一个节点上的分片过多,此时也就影响查询的性能。

  1. 集群状态cluster health

  • 通过_cluster/health API可以查看集群的健康状态,包括以下三种:

  • green 健康状态,指所有主副分片都分配正常。

  • yellow所有主分片都正常,但是副本分片未分配正常。

  • red 有主分片未分配。

http://localhost:5200/_cluster/health

  1. 故障转移

  • node1所在机器宕机导致服务终止,此时集群会如何处理?

  • node2和node3发现node1无法响应一段时间后会发起master选举,比如这里选择node2为master节点。此时由于主分片P0下线,集群状态变为red。

  • node2发现主分片P0未分配,此时将R0提升为主分片。此时由于所有主分片都正常分配,集群状态变为yellow。

  • node2为P0和P1生成新的副本,集群状态变为绿色。

  1. 文档分布式存储

  • 文档最终会存储到分片上,如下图所示:

  • Document1是如何存储到分片P1上的?选择P1的依据是什么?

  • 需要文档到分片的映射算法。

  • 目的

  • 使得文档均匀的分布在所有的分片上,以充分利用资源。

  • 文档到分片的映射算法

  • 随机选择或round-robin算法?

  • 不可取,因为需要维护文档到分片的映射关系,成本巨大。

  • 根据文档值时时的计算对应的分片

  • shard = hash(routing)%number_of_primary_shards。

  • hash算法保证可以将数据均匀地分散在分片中。

  • routing是一个关键参数,默认是文档id,也可以自行指定。

  • number_of_primary_shards主分片数

  • 该算法与主分片数相关,这也是分片数一旦确定后便不能修改的原因。

  • 文档创建的流程

  • 文档读取的流程

  • 文档批量创建流程

  • 文档批量读取流程

  1. 脑裂问题

  • 脑裂问题,英文为split-brain,是分布式系统中的经典网络问题,如下图所示:

  • node2和node3会重新选举master,比如node2成为新的master,此时会更新cluster state。

  • node1自己组成集群后也会更新cluster state。

  • 同一个集群有两个master,而且维护不同的cluster state,网络恢复后无法选择正确的master。

  • 接解决方案

  • 仅在可选举master-eligible节点数大于等于quorum时才可以进行选举。

  • quorum=(master-eligible节点数)/ 2 + 1,例如3个master-eligible,quorum为2。

  • 设定discovery.zen.minimum_master_nodes为quorum即可避免脑裂问题。

  1. shard详解

  • 倒排索引的不可变更

  • 倒排索引一旦生成,不能更改。

  • 其好处如下:

  • 不用考虑并发写文件的问题,杜绝了锁机制带来的性能问题。

  • 由于文件不在更改,可以充分利用文件系统缓存,只需载入一次,只要内存足够,对该文件的读取都会从内存读取,性能高。

  • 利于生成缓冲数据。

  • 利于对文件进行压缩存储,节省磁盘和内存存储空间。

  • 坏处

  • 需要写入新文档时,必须重新构建倒排索引,然后替换老文件后,新文档才能被检索,导致文档实时性差。

  • 方案一:新增文档时,针对所有文档重新构建索引。

  • 缺点开销太大,实时性差。不可取。

  • 方案二:新文档直接生成新的倒排索引文件,查询时同时查询所有的倒排索引文件,然后做结果的汇总计算即可。

  • Lucene的实现方案,采用的事方案二,它构建的单个倒排索引称为segment,合一起称为Index,与es中的Index不同,es中的一个shard对应一个Lucene Index。

  • Lucene会有一个专门的文件来记录所有的segment信息,成为commit point。

  • 文档搜索实时性-refresh

  • segment写入磁盘的过程依然很耗时,可以借助文件系统缓存的特性,先将segment在缓存中创建并开放查询来进一步提升实时性,该过程在es中被称为refresh。

  • 在refresh之前文档会先存储在一个buffer中,refresh时会将buffer中的所有文档清空并生成segment。

  • es默认每一秒执行一次refresh,因此文档的实时性被提高到1秒,这也是es被称为近实时(near real time)的原因。

  • refresh发生的时机

  • 间隔时间达到时,通过index.settings.refresh_interval来设定,默认为1秒。

  • index_buffer占满时,其大小通过indices.memery.index_buffer_size设置,默认时JVM heap的10%,所有shard共享。

  • flush时也会发生refresh。

  • 文档搜索实时性-translog

  • 如果内存中的segment还没写入到磁盘前发生宕机,那么其中的文档就无法恢复了。如何解决此问题?

  • es引入translog的机制,写入文档到buffer时,同时写入文档到translog。

  • translog文件会即时写入到磁盘(fsync),6.x默认每次都会落盘。可以修改为每5秒写入一次,来提高写入性能,这样同时会带来可能会丢失5秒内的数据,相关配置为index.translog.*。

  • es启动时会检查translog文件,并从中恢复数据。

  • 文档搜索实时性-flush

  • 负责将内存中的segment写入磁盘,主要工作如下:

  • 将translog写入磁盘。

  • 将index buffer清空,其中的文档生成一个新的segment,相当于一个refresh操作。

  • 更新commit point并写入磁盘。

  • 删除旧的translog文件。

  • flush发生的时机

  • 间隔时间达到时,默认30分钟,5.x之前的版本可以修改,之后的版本不可修改。

  • translog占满时,其大小可以通过index.translog.flush_threshold_size控制,默认时512m,每个index都有自己的translog。

  • 删除与更新文档

  • segment一旦生成就不能修改,那么你要删除文档要如何操作?

  • Lucene专门维护一个.del文件,记录所有已删除的文档,注意.del文档上记录的是文档在lucene内部的id。

  • 在查询返回结果前会过滤掉.del文件中的文档。

  • 更新文档如何进行

  • 首先删除文档,在创建新文档。

  • es index 与 lucene index的对照,如下图:

  • segment merging

  • 随着segment的增多,由于一次查询的segment的增多,查询速度会变慢。

  • es会定时后台惊喜segment merging,减少segment数量。

  • 通过force_merge api可以手动强行做segment merge的操作。

来源:https://coding.imooc.com/learn/list/181.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值