ES是一个分布式全文检索框架,隐藏了复杂的处理机制,核心数据分片机制、集群发现、分片负载均衡请求路由

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

ES是一个分布式框架隐藏了复杂的处理机制核心数据分片机制、集群发现、分片负载均衡请求路由。

ES的高可用架构总体如下图


说明本文会以pdf格式持续更新更多最新尼恩3高pdf笔记请从下面的链接获取语雀 或者 码云

ES基本概念名词
Cluster

代表一个集群集群中有多个节点其中有一个为主节点这个主节点是可以通过选举产生的主从节点是对于集群内部来说的。

es的一个概念就是去中心化字面上理解就是无中心节点这是对于集群外部来说的因为从外部来看es集群在逻辑上是个整体你与任何一个节点的通信和与整个es集群通信是等价的。

Shards

代表索引分片es可以把一个完整的索引分成多个分片这样的好处是可以把一个大的索引拆分成多个分布到不同的节点上。构成分布式搜索。

分片的数量只能在索引创建前指定并且索引创建后不能更改。why大家可以独立思考一下!

分片数由index.number_of_shards在索引创建的时候指定如果需要修改主分片数需要重建索引
1 按照需要创建一个新的索引
2 reindex把索引现有的数据同步到新索引中
3 别名绑定新创建的索引上

规避主分片不能修改的问题的方法官方的说明

我们当前的选择只有一个就是将数据重新索引至一个拥有更多分片的一个更大的索引但这样做将消耗的时间是我们无法提供的。

通过事先规划我们可以使用 预分配 的方式来完全避免这个问题。

注意ES在不断升级在ES6.1开始已经%50支持修改主分片的操作。

在老版本的ES例如2.3版本中 index的shard数量定好后就不能再修改除非重建数据才能实现。

从ES6.1开始ES 支持split操作可以在线操作扩大shard的数量注意操作期间也需要对index锁写

从ES7.0开始split时候不再需要加参数 index.number_of_routing_shards

在 这个split的过程中 它会先复制全量数据然后再去做删除多余数据的操作需要注意磁盘空间的占用。

所以可以理解为ES还是没有完全 支持修改主分片的操作。 不到万不得已不建议在线修改主分片。

replicas

代表索引副本es可以设置多个索引的副本。

副本的作用

一是提高系统的容错性当某个节点某个分片损坏或丢失时可以从副本中恢复。

二是提高es的查询效率es会自动对搜索请求进行负载均衡。

Recovery

代表数据恢复或叫数据重新分布es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配;

挂掉的节点重新启动时也会进行数据恢复。

总览ES集群中的五大角色
在Elasticsearch中有五大角色主要如下

Master Node主节点

主节点该节点不和应用创建连接每个节点都保存了集群状态.

master节点控制整个集群的元数据。

只有Master Node节点可以修改节点状态信息及元数据(metadata)的处理比如索引的新增、删除、分片路由分配、所有索引和相关 Mapping 、Setting 配置等等。

从资源占用的角度来说master节点不占用磁盘IO和CPU内存使用量一般 没有data 节点高

Master eligible nodes合格主节点

合格节点每个节点部署后不修改配置信息默认就是一个 eligible 节点.

有资格成为Master节点但暂时并不是Master的节点被称为 eligible 节点该节点可以参加选主流程成为Mastere节点.

该节点只是与集群保持心跳判断Master是否存活如果Master故障则参加新一轮的Master选举。

从资源占用的角度来说eligible节点比Master节点更节省资源因为它还未成为 Master 节点只是有资格成功Master节点。

Data Node数据节点

数据节点改节点用于建立文档索引 接收 应用创建连接、接收索引请求接收用户的搜索请求

data节点真正存储数据ES集群的性能取决于该节点的个数(每个节点最优配置的情况下)

data节点的分片执行查询语句获得查询结果后将结果反馈给Coordinating节点在查询的过程中非常消耗硬件资源如果在分片配置及优化没做好的情况下进行一次查询非常缓慢(硬件配置也要跟上数据量)。

数据节点保存包含索引文档的分片数据执行CRUD、搜索、聚合相关的操作。属于内存、CPU、IO密集型对硬件资源要求高。

从资源占用的角度来说data节点会占用大量的CPU、IO和内存

Coordinating Node协调节点(/路由节点/client节点)

协调节点该节点专用与接收应用的查询连接、接受搜索请求但其本身不负责存储数据

协调节点的职责

接受客户端搜索请求后将请求转发到与查询条件相关的多个data节点的分片上然后多个data节点的分片执行查询语句或者查询结果再返回给协调节点协调节点把各个data节点的返回结果进行整合、排序等一系列操作后再将最终结果返回给用户请求。

搜索请求在两个阶段中执行query 和 fetch这两个阶段由接收客户端请求的节点 - 协调节点协调。

在请求query 阶段协调节点将请求转发到保存数据的数据节点。 每个数据节点在本地执行请求并将其结果返回给协调节点。
在收集fetch阶段协调节点将每个数据节点的结果汇集为单个全局结果集。
从资源占用的角度来说协调节点可当负责均衡节点该节点不占用io、cpu和内存

Ingest Nodeingest节点

ingest 节点可以看作是数据前置处理转换的节点支持 pipeline管道 设置可以使用 ingest 对数据进行过滤、转换等操作类似于 logstash 中 filter 的作用功能相当强大。

Ingest节点处理时机——在数据被索引之前通过预定义好的处理管道对数据进行预处理。默认情况下所有节点都启用Ingest因此任何节点都可以处理Ingest任务。

我们也可以创建专用的Ingest节点。

详解Coordinating Only Nodes
ES 本身是一个分布式的计算集群每个 Node 都可以响应用户的请求包括 Master Node、Data Node它们都有完整的 Cluster State 信息。

正如我们知道的一样在某个 Node 收到用户请求的时候会将请求转发到集群中所有索引相关的 Node 上之后将每个 Node 的计算结果合并后返回给请求方。

我们暂且将这个 Node 称为查询节点整个过程跟分布式数据库原理类似。那问题来了这个查询节点如果在并发和数据量比较大的情况下由于数据的聚合可能会让内存和网络出现瓶颈。

因此在职责分离指导思想的前提下这些操作我们也应该从这些角色中剥离出来官方称它是 Coordinating Nodes只负责路由用户的请求包括读、写等操作对内存、网络和 CPU 要求比较高。

本质上Coordinating Only Nodes 可以笼统的理解为是一个负载均衡器或者反向代理只负责读本身不写数据。

它的配置是

node.master: false
node.data: false
node.ingest: false
search.remote.connect: false
增加 Coordinating Nodes 的数量可以提高 API 请求响应的性能 提升集群的吞吐量

我们也可以针对不同量级的 Index 分配独立的 Coordinating Nodes 来满足请求性能。

那是不是越多越好呢

在一定范围内是肯定的但凡事有个度过了负作用就会突显太多的话会给集群增加负担。

说明本文会以pdf格式持续更新更多最新尼恩3高pdf笔记请从下面的链接获取语雀 或者 码云

详解Ingest Nodeingest节点
由于其他几种类型节点和用途都很好理解无非主节点、数据节点、路由节点。

但是Ingest不好理解。

Ingest的用途
可以把Ingest节点的功能抽象为大数据处理环节的“ETL”——抽取、转换、加载。

Ingest的用途
1ingest 节点可以看作是数据前置处理转换的节点支持 pipeline管道 设置可以使用 ingest 对数据进行过滤、转换等操作类似于 logstash 中 filter 的作用功能相当强大。

2Ingest节点 可用于执行常见的数据转换和丰富。 处理器配置为形成管道。 在写入时Ingest Node有20个内置处理器例如grokdategsub小写/大写删除和重命名。

3在批量请求或索引操作之前Ingest节点拦截请求并对文档进行处理。

Ingest的例子

一个例子是可以是日期处理器其用于解析字段中的日期。
另一个例子是转换处理器它将字段值转换为目标类型例如将字符串转换为整数。

ingest 节点能解决什么问题
上面的Ingest节点介绍太官方看不大懂怎么办来个实战场景例子吧。

思考问题1线上写入数据改字段需求

如何在数据写入阶段修改字段名不是修改字段值

思考问题2线上业务数据添加特定字段需求

如何在批量写入数据的时候每条document插入实时时间戳

这时脑海里开始对已有的知识点进行搜索。
针对思考问题1字段值的修改无非update,update_by_query但是字段名呢貌似没有相关接口或实现。
针对思考问题2插入的时候业务层面处理读取当前时间并写入貌似可以有没有不动业务层面的字段的方法呢

答案是有的这就是Ingest节点的妙处。

Ingest的实操体验
针对问题1

如何在数据写入阶段修改字段名不是修改字段值

PUT _ingest/pipeline/rename_hostname
{
  "processors": [
    {
        "field": "hostname",
        "target_field": "host",
        "ignore_missing": true
      }
    }
  ]
}
 
 
PUT server
 
POST server/values/?pipeline=rename_hostname
{
  "hostname": "myserver"
}

如上借助Ingest节点的 rename_hostname管道的预处理功能实现了字段名称的变更由hostname改成host。

针对问题2

线上业务数据添加特定字段需求**

PUT _ingest/pipeline/indexed_at
{
  "description": "Adds indexed_at timestamp to documents",
  "processors": [
    {
      "set": {
        "field": "_source.indexed_at",
        "value": "{{_ingest.timestamp}}"
      }
    }
  ]
}
 
PUT ms-test
{
  "settings": {
    "index.default_pipeline": "indexed_at"
  }
}
 
POST ms-test/_doc/1
{"title":"just testing"}

如上通过indexed_at管道的set处理器与ms-test的索引层面关联操作 ms-test索引每插入一篇document都会自动添加一个字段index_at=最新时间戳。

6.5版本ES验证ok。

Ingest节点的核心原理
在实际文档索引发生之前使用Ingest节点预处理文档。Ingest节点拦截批量和索引请求它应用转换然后将文档传递回索引或Bulk API。

强调一下 Ingest节点处理时机——在数据被索引之前通过预定义好的处理管道对数据进行预处理。

默认情况下所有节点都启用Ingest因此任何节点都可以处理Ingest任务。我们也可以创建专用的Ingest节点。

要禁用节点的Ingest功能需要在elasticsearch.yml 设置如下

node.ingestfalse
Ingest节点的核心原理, 涉及几个知识点

1、预处理 pre-process
要在数据索引化(indexing)之前预处理文档。

2、管道 pipeline
每个预处理过程可以指定包含一个或多个处理器的管道。

管道的实际组成

{
  "description" : "...",
  "processors" : [ ... ]
}
description管道功能描述。
processors注意是数组可以指定1个或多个处理器。

3、处理器 processors
每个处理器以某种特定方式转换文档。
例如管道可能有一个从文档中删除字段的处理器然后是另一个重命名字段的处理器。
这样再反过来看第4部分就很好理解了。

Ingest API
Ingest API共分为4种操作分别对应

PUT新增、
GET获取、
DELETE删除、
Simulate 仿真模拟。
模拟管道AP Simulate 针对请求正文中提供的文档集执行特定管道。
除此之外高阶操作包括

1、支持复杂条件的Nested类型的操作
2、限定条件的管道操作
3、限定条件的正则操作等。
详细内容参见官网即可。

常见的处理器有如下28种举例

append处理器添加1个或1组字段值
convert处理器支持类型转换。

建议没必要都过一遍根据业务需求反查文档即可。
Ingest节点和Logstash Filter 啥区别
业务选型中肯定会问到这个问题。

区别一支持的数据源不同。
Logstash大量的输入和输出插件比如kafkaredis等可供使用还可用来支持一系列不同的架构。
Ingest节点不能从外部来源例如消息队列或数据库提取数据必须批量bulk或索引index请求将数据推送到 Elasticsearch.
区别二应对数据激增的能力不同。
LogstashLogstash 可在本地对数据进行缓冲以应对采集骤升情况。如前所述Logstash 同时还支持与大量不同的消息队列类型进行集成。
Ingest节点极限情况下会出现在长时间无法联系上 Elasticsearch 或者 Elasticsearch 无法接受数据的情况下均有可能会丢失数据。
区别三处理能力不同。
Logstash支持的插件和功能点较Ingest节点多很多。
Ingest节点支持28类处理器操作。Ingest节点管道只能在单一事件的上下文中运行。Ingest通常不能调用其他系统或者从磁盘中读取数据。
说明本文会以pdf格式持续更新更多最新尼恩3高pdf笔记请从下面的链接获取语雀 或者 码云

详解一次ES搜索的两阶段
ES的搜索过程目标是符合搜索条件的文档这些文档可能散落在各个node、各个shard中

ES的搜索需要找到匹配的文档并且把从各个node各个shard返回的结果进行汇总、排序组成一个最终的结果排序列表才算完成一个搜索过程。

一次搜索请求在两个阶段中执行query 和 fetch这两个阶段由接收客户端请求的节点 (协调节点)协调。

在请求query 阶段协调节点将请求转发到保存数据的数据节点。 每个数据节点在本地执行请求并将其结果返回给协调节点。
在收集fetch阶段协调节点将每个数据节点的结果汇集为单个全局结果集。
我们将按两阶段的方式对这个过程进行讲解。

phase 1: query 查询阶段

假定我们的ES集群有三个nodenumber_of_primary_shards为3replica shard为1我们执行一个这样的查询请求

GET /music/children/_search
{
  "from": 980,
  "size": 20
}
query 查询阶段的过程示意图如下

query 查询阶段的过程示如下

Java客户端发起查询请求接受请求的node-1成为Coordinate Node协调者该node会创建一个priority queue长度为from + size即1000。
Coordinate Node将请求分发到所有的primary shard或replica shard中每个shard在本地创建一个同样大小的priority queue长度也为from + size用于存储该shard执行查询的结果。
每个shard将各自priority queue的元素返回给Coordinate Node元素内只包含文档的ID和排序值如_scoreCoordinate Node将合并所有的元素到自己的priority queue中并完成排序动作最终根据from、size值对结果进行截取。
补充说明

哪个node接收客户端的请求该node就会成为Coordinate Node。

Coordinate Node转发请求时会根据负载均衡算法分配到同一分片的primary shard或replica shard上注意这里是或不是与。

为什么说replica值设置得大一些, 可以增加系统吞吐量呢

原理就在这里

Coordinate Node的查询请求负载均衡算法会轮询所有的可用shard并发场景时就会有更多的硬件资源CPU、内存IO会参与其中系统整体的吞吐量就能提升。

此查询过程Coordinate Node得到是轻量级的文档元素信息只包含文档ID和_score这些信息这样可以减轻网络负载因为分页过程中大部分的数据是会丢弃掉的。

phase 2: fetch取回阶段

在完成了查询阶段后此时Coordinate Node已经得到查询的列表但列表内的元素只有文档ID和_score信息并无实际的_source内容取回阶段就是根据文档ID取到完整的文档对象的过程。

如下图所示

fetch取回阶段的过程示意图如下

Coordinate Node根据from、size信息截取要取回文档的ID如{"from": 980, "size": 20}则取第981到第1000这20条数据其余丢弃from/size为空则默认取前10条向其他shard发出mget请求。
shard接收到请求后根据_source参数可选加载文档信息返回给Coordinate Node。
一旦所有的shard都返回了结果Coordinate Node将结果返回给客户端。
注意

使用from和size进行分页时传递信息给Coordinate Node的每个shard都创建了一个from + size长度的队列并且Coordinate Node需要对所有传过来的数据进行排序工作量为number_of_shards * (from + size)然后从里面挑出size数量的文档如果from值特别大那么会带来极大的硬件资源浪费鉴于此原因强烈建议不要使用深分页。

不过深分页操作很少符合人的行为翻几页还看不到想要的结果人的第一反应是换一个搜索条件

只有机器人或爬虫才这么不知疲倦地一直翻页 直到服务器崩溃。

说明本文会以pdf格式持续更新更多最新尼恩3高pdf笔记请从下面的链接获取语雀 或者 码云

ES的副本高可用架构
ES核心存放的核心数据是索引。

ES集群中索引可能由多个分片构成并且每个分片可以拥有多个副本。

通过将一个单独的索引分为多个分片解决单一索引的大小过大导致的搜索效率问题。

分片之后由于每个分片可以有多个副本通过将副本分配到多个服务器可以提高查询的负载能力。

每个索引会被分成多个分片shards进行存储默认创建索引是分配5个分片进行存储。

每个分片都会分布式部署在多个不同的节点上进行部署该分片成为primary shards。

如果ES实现了集群的话会将单台服务器节点的索引文件使用分片技术分布式存放在多个不同的物理机器上。

分片就是将数据拆分成多台节点进行存放这样做是为了提升索引、搜索效率。

通过 _setting API可以查询到索引的元数据

两个很重要的数据

5 每个索引拆分5片存储

1备份一份

注意索引的主分片primary shards定义好后后面不能做修改。

分片的副本
在ES分片技术中分为主primary分片、副(replicas)分片。

为了实现高可用数据的高可用、高并发主分片可以有对应的副本分片replics shards。

replic shards分片承载了负责容错、以及请求的负载均衡。

**注意: **

每一个主分片为了实现高可用都会有自己对应的副本分片

分片对应的副本分片不能存放同一台服务器上单台ES没有副本用分片的。

主分片primary shards可以和其他replics shards存放在同一个node节点上。

在往主分片服务器存放数据时候会对应实时同步到备用分片服务器

但是查询时候所有主、备分片都参与查询。由协调节点进行负载均衡。

分片的存放
假设一个索引

number_of_shards=3

number_of_replicas=3

3个分片每个分片一个 副本总共6个shard。

放在一个3个data node的集群中具体的存放方式为

三个节点 6/3 为 2 每个节点存放两个分片

在创建索引时候主分片数量定义好后是不能修改的

修改副的分片 number_of_replica =2

3个主分片6个备分片 一共9个分片具体的存放方式为

从高可用/高并发的角度出发官方建议 shard为 节点的平方数

节点的扩容
假设data node由2个节点扩容到3个节点。

主分片3 备份1 主分片3个 每个主分片对应的1个备分片

总的shard数=3*2=6

那么官方达到建议 shard为 节点的平方数。

按照官方的建议如果每个主分片可以对应的2个备分片总共的分片数=3*3=9。

百亿数据的分片和节点规划
百亿数据放在数据库的量是多少

假设 1T 。

实际的生产经验一个shard应该是30-50G比较合理机械硬盘不建议大于50G

磁盘好的话比如SSD固态硬盘这个可以大点比如100G

如果是1T一个分片50G建议你最少primary shards 20个

从高可用/高并发的角度出发官方建议 shard为 节点的平方数

所以replicas 可以根据节点数来推算。

比如10 个Data node10 X 10=100, 则副本数可以为 4 4+1*20=100

注意副本太多有很大的副作用集群内部的需要保障primary 和 replica 的数据一致性需要的网络流量消耗与 CPU消耗会大大提升。

数据路由
documnet routing数据路由

当客户端发起创建document的时候es需要确定这个document放在该index哪个shard上。这个过程就是数据路由。

路由算法shard = hash(routing) % number_of_primary_shards

如果number_of_primary_shards在查询的时候取余发生的变化无法获取到该数据


注意索引的主分片数量定义好后不能被修改

已知主分片数量为3

路由算法: shard = hash(routing) % 主分片数量3

分片位置 p1 = % 3 p2 =2%3 , p0=3%3

routing 就是采用 id

在查询时候底层根据文档 id % 主分片数量获取分片位置

计算的算法 取模时候 除数改变了 查询时候 怎么办

所以 不能乱改啊~

说明本文会以pdf格式持续更新更多最新尼恩3高pdf笔记请从下面的链接获取语雀 或者 码云

ES集群的架构规划
首先是集群节点的角色规划。

一个节点在默认角色
Elasticsearch的员工 Christian_Dahlqvist解读如下

一个节点的缺省配置是主节点+数据节点两属性为一身。

对于3-5个节点的小集群来讲通常让所有节点存储数据和具有获得主节点的资格。你可以将任何请求发送给任何节点并且由于所有节点都具有集群状态的副本它们知道如何路由请求。

通常只有较大的集群才能开始分离专用主节点、数据节点。 对于许多用户场景路由节点根本不一定是必需的。

专用协调节点也称为client节点或路由节点从数据节点中消除了聚合/查询的请求解析和最终阶段并允许他们专注于处理数据。
在多大程度上这对集群有好处将因情况而异。 通常我会说在查询大量使用情况下路由节点更常见。

实际上一个节点在默认情况下会同时扮演Master NodeData Node 和 Ingest Node。

节点类型    配置参数    默认值
Master Eligible    node.master    true
Data    node.data    true
Ingest    node.ingest    true
Coordinating only    无    设置上面 3 个参数全为 false节点为协调节点
节点的角色建议
分环境

在开发环境一个节点可以承担多种角色

生产环境中需要根据数据量写入和查询的吞吐量选择合适的部署方式建议设置单一角色的节点dedicated node)

ES2.X及之前版本节点角色概述
注意在ES2.X及之前 节点的角色有点不一样具体如下


ES5.X节点角色清单
注意在ES5.X及之后 节点的角色基本稳定下来了具体如下

配置节点类型
开发环境中一个节点可以承担多种角色

生产环境中应该设置单一的角色

节点类型    配置参数    默认值
Master    node.master    true
Master eligible    node.master    true
Data    node.data    true
Coordinating    无    每个节点都是协调节点,设置其它节点全部为false则为协调节点
Ingest    node.ingest    true
两个属性的四种组合
Master和Data两个角色这些功能是由三个属性控制的。

  1. node.master
node.data
3. node.ingest
默认情况下这三个属性的值都是true。

默认情况下elasticsearch 集群中每个节点都有成为主节点的资格也都存储数据还可以提供查询服务做预处理。

node.master这个属性表示节点是否具有成为主节点的资格
注意此属性的值为 true并不意味着这个节点就是主节点。因为真正的主节点是由多个具有主节点资格的节点进行选举产生的。所以这个属性只是代表这个节点是不是具有主节点选举资格。

node.data这个属性表示节点是否存储数据。

组合1

node.master: true AND node.data: true AND node.ingest: true

这种组合表示这个节点既有成为主节点的资格又可以存储数据还可以作为预处理节点

这个时候如果某个节点被选举成为了真正的主节点那么他还要存储数据这样对于这个节点的压力就比较大了。

elasticsearch 默认是每个节点都是这样的配置在测试环境下这样做没问题。实际工作中建议不要这样设置这样相当于 主节点 和 数据节点 的角色混合到一块了。

组合2

node.master: false AND node.data: **true **AND node.ingest: false

这种组合表示这个节点没有成为主节点的资格也就不参与选举只会存储数据。

这个节点我们称为 data(数据)节点。在集群中需要单独设置几个这样的节点负责存储数据。

后期提供存储和查询服务

组合3

node.master: true AND node.data: falseAND node.ingest: false

这种组合表示这个节点不会存储数据有成为主节点的资格可以参与选举有可能成为真正的主节点。这个节点我们称为master节点

组合4

node.master: false AND node.data: falseAND node.ingest: true

这种组合表示这个节点即不会成为主节点也不会存储数据这个节点的意义是作为一个 client(客户端)节点主要是针对海量请求的时候可以进行负载均衡。

在新版 ElasticSearch5.x 之后该节点称之为coordinate 节点其中还增加了一个叫ingest 节点用于预处理数据索引和搜索阶段都可以用到。
当然作为一般应用是不需要这个预处理节点做什么额外的预处理过程那么这个节点和我们称之为 client 节点之间可以看做是等同的我们在代码中配置访问节点就都可以配置这些 ingest 节点即可。

不同角色节点 的配置选择
Dedicated Master Eligible Node

负责集群状态的管理
使用低配置的 CPURAM 和磁盘
Dedicated Data Node

负责数据存储及处理客户端请求
使用高配置的 CPURAM 和磁盘
Dedicated Ingest Node

负责数据处理
使用高配置的 CPU中等配置的 RAM低配置的磁盘
Coordinating only Node

高配或中配的 CPU高配或中配的 RAM低配的磁盘
生产环境中建议为一些大的集群配置 Coordinating Only Node其扮演的角色
Load Balancer降低 Master 和 Data Nodes 的负载
负责搜索结果的 Gather 和 Reduce
有时无法预知客户端会发送怎样的请求大量占用内存的聚合操作比如一个深度聚合可能会发生 OOM
高可用ES部署的基本原则
配置 多个Dedicated Master Node
为什么要配置 多个Dedicated Master Node

从高可用 & 避免脑裂的角度出发需要配置多个 Dedicated Master Node

一般在生产环境中配置 3 台当有1 台丢失的时候其余的节点会被提升成活跃主节点
一个集群必须有一台活跃的主节点负责分片管理索引创建集群管理等操作
Elasticsearch集群至少三个Master实例并且生产建议每个es实例部署在不同的设备上三个Master节点最多只能故障一台Master节点数据不会丢失; 如果三个节点故障两个节点则造成数据丢失并无法组成集群。

三台Master做集群其中一台被真正选为了Master那么其它两台就是 eligible 节点。

Master Node 和 Data Node 或 Coordinating Node 分开部署
如果 Master Node 和 Data Node 或 Coordinating Node 混合部署

Data Node 相对有比较大的内存占用
Coordinating Node 有时候会有开销很高的查询导致 OOM
这些都有可能影响 Master 节点导致集群的不稳定
Data Node 水平扩展
在Elasticsearch集群中此节点应该是最多的。

Data Node 在以下两种场景可以不断扩展

当磁盘容量无法满足时可以增加 Data Node
当磁盘读写压力大时可以增加 Data Node
内存建议

假如一台机器部署了一个ES实例则ES最大可用内存不要超过物理内存的50%

ES最大可用内存最多不可超过32G

如果单台机器上部署了多个ES实例则多个ES实例内存相加等于物理内存的50%。

每1GB堆内存对应集群的分片建议保持在20个以内

分片建议

每个分片大小不要超过30G硬盘条件好的话不建议超过100G.

Coordinating Node 水平扩展
当系统中有大量复杂查询及聚合的时候增加 Coordinating Node提升查询和聚合的性能
可以在 Coordinating Node 前配置 LB软件或硬件实现此时 Application 只需要和 LB 交互
读写分离与LB负载均衡
读请求发到 Coordinating Node
写请求发到 Ingest Node
Coordinating Node 和 Ingest Node 前都可以配置 LB
高可用ES的部署源规划
小型的ES集群的节点架构
小型的ES集群就是3/5/7这种少于10个节点的集群。

对于3个节点、5个节点甚至更多节点角色的配置Elasticsearch官网、国内外论坛、博客都没有明确的定义。

小型的ES集群的节点角色规划

1对于Ingest节点如果我们没有格式转换、类型转换等需求直接设置为false。
23-5个节点属于轻量级集群要保证主节点个数满足((节点数/2)+1)。
3轻量级集群节点的多重属性如Master&Data设置为同一个节点可以理解的。
4如果进一步优化5节点可以将Master和Data再分离。

大型的ES集群的节点架构
ES数据库最好的高可用集群部署架构为

三台服务器做master节点
N比如20台服务器作为data节点存储资源要大
N比如2台做ingest节点用于数据转换可以提高ES查询效率


说明本文会以pdf格式持续更新更多最新尼恩3高pdf笔记请从下面的链接获取语雀 或者 码云 

高可用进阶异地多活部署场景(多个data center)
异地多活部署场景, 可以在多个data center 部署多套ES集群。

在多个data center的部署场景。 如何进一步保证ES集群的高可用呢

读高可用架构
这几个集群需要确保有相同的数据。通过gtm进行流量路由将用户的读请求路由到最优的集群。

GTM主要用来做数据的读取。

具体的读高可用架构图如下

如何保证数据一致性
两种方案

需要程序分别写入这几个集群保持数据一致。

或者就写入一个集群 ,使用es的跨集群复制确保数据一致

一致性保障策略1集群多写
需要程序分别写入这几个集群保持数据一致

由于建立索引的及时性没有那么高更多的情况是写入消息队列。

各个数据中心的程序去消费消息队列中的数据。

一致性保障策略2ES的跨集群复制
Elasticsearch后面统称ES cross-cluster replication (后面统称CCR)是ES 6.5的一个测试特性是ES 6.7的的一个全局高可用特性。

CCR将索引复制到其他ES集群可以解决多个用例包括跨数据中心高可用(HA)灾难恢复(DR)和CDN样体系结构最终实现ES集群的高可用。

CCR没有所谓的冲突监测如果要独立flower只需要暂定同步关闭索引取消对leader的关注重新打开索引即可。

CCR 是双向的

CCR 这个特性可以让你将一个集群的索引数据同步复制到远程的另外一个集群上面去。或者反过来将一个远程的集群的索引数据同步的复制到本地 Elasticsearch 集群中来。

CCR 可以复制到多个集群

CCR允许不同的索引复制到一个或多个ES 集群中。

集群复制类似于数据订阅的方式一个集群的数据可以被多个集群订阅也就是可以被复制到多个集群上面去。

CCR 工作在索引层面

CCR 工作在索引层面使用 Pull 的模式Follower 索引主动的去 Pull Leader 的数据。

CCR 有两个角色一个是 Leader表示数据的源头另外一个Follower表示数据的订阅方得到的是数据副本。

CCR是一个leader/fllower架构leader可以进行任何操作但是fllower则不能进行写入操作fllower的mapping和setting也是跟随leader的变化而变化无需进行单独的修改。

CCR不是免费的特性

这个特性是 Elasticsearch 的商业特性需要白金订阅。

CCR的使用场景

异地多活多data center 集群高可用以及灾难恢复
全球化多data center 实现数据的就近访问地理
集中式的报告集群
第一个场景关于保证 Elasticsearch 集群的高可用和灾难恢复。

通过部署多套 Elasticsearch 集群并且分布在不同地域的数据中心然后接着 CCR将数据做一个实时的同步假如其中一个数据中心失联或者因为不可抗力的因素如台风、地震我们照样还能通过访问剩下的集群来获取完整的数据如下图示意

当 Production DC 失联之后我们可以立即切换到 Disaster Recovery DC。

第二个场景数据的就近访问。

假设是一个大集团有总公司和分公司通过按地理位置来划分分公司自己的业务集群不同城市的业务数据可以使用各自的集群这样能够更快的进行当地业务的处理不过也有一些数据可能是总公司下发的数据各个分公司都只能读比如一些元数据我们借助 CCR可以把这部分数据下发到各个分公司的 Elasticsearch 集群这样每个分公司都能实时的获取到最新的数据并且直接访问各自的本地集群就可以了大大提升访问速度。

上图中Central DC 借助 CCR 实时的同步下发数据到 Singapore DC、Canada DC 和 Ireland DC。

第三个场景就是做集中式的报告分析。

接上面的案例我们反过来处理我们的业务数据我们将每个分公司的业务数据实时的同步到总公司的 Elasticsearch 集群这样总公司就有了每个分公司的完整数据这样进行报告分析的时候就可以直接的在总公司的 Elasticsearch 集群里面进行快速的可视化分析了。

CCR 如何使用
说了这么多 CCR 的适用场景那接下来我们来看一下具体如何使用吧。

假设我有两个机器北京集群192.168.1.100:9300和深圳集群192.168.3.100:9300这俩个集群之间的网络是互通的。现在我们希望把北京集群的销售数据同步到深圳集群上去。

第一步在北京集群上设置 Leader 索引

这个 Leader Index 需要设置好允许 Soft Deletes这个参数非常重要CCR 依赖这个特性来如果这个索引之前没有开启过这个参数需要重新创建索引才行。
比如我创建一个 bj_sales 这个索引

PUT bj_sales
{
  "settings": {
    "index.soft_deletes.retention.operations": 2000,
    "index.soft_deletes.enabled": true
  }
}
现在这个 bj_sales 就已经具备跨集群复制的能力了。

第二步北京集群创建几条销售数据。

POST bj_sales/doc/
{
  "name":"Jack Ma",
  "age":40
}
 
POST bj_sales/doc/
{
  "name":"Pony Ma",
  "age":40
}
第三步在深圳集群上把北京集群的信息加到远程集群里面去。

PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "remote": {
        "bj": {
          "seeds": [
            "192.168.1.100:9300"
          ]
        }
      }
    }
  }
}
bj 是我们能够在深圳集群里面访问北京集群的命名空间。

第四步我们在深圳集群里面通过 CCR API 创建一个索引并订阅北京机器的 bj_sales 这个索引。

PUT /bj_sales_replica/_ccr/follow
{
  "remote_cluster" : "bj",
  "leader_index" : "bj_sales"
}
bj_sales_replica 是我们将要创建在深圳集群上的索引名称remote 集群是 bj订阅了对方的 bj_sales 索引。

第五步验证

如果不出意外我们在深圳集群上应该就会创建一个新的 bj_sales_replica 的索引并且里面会有两条数据我们可以验证一下如下

GET bj_sales_replica/_search
返回结果如下

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "bj_sales_replica",
        "_type" : "doc",
        "_id" : "iNZYymcBGbeu9hnEe7-G",
        "_score" : 1.0,
        "_source" : {
          "name" : "Pony Ma",
          "age" : 40
        }
      },
      {
        "_index" : "bj_sales_replica",
        "_type" : "doc",
        "_id" : "QdZYymcBGbeu9hnEJb-Z",
        "_score" : 1.0,
        "_source" : {
          "name" : "Jack Ma",
          "age" : 40
        }
      }
    ]
  }
}

果然自动将远程集群的数据复制过来了。

继续验证数据同步

我们在北京集群上继续新增数据和删除数据看看深圳集群是否都能正常同步。

POST bj_sales/doc/5
{
  "name":"Tony",
  "age":30
}
DELETE bj_sales/doc/5

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

“ES是一个分布式全文检索框架,隐藏了复杂的处理机制,核心数据分片机制、集群发现、分片负载均衡请求路由” 的相关文章