jjzjj

ELK之Elasticsearch分片/副本与数据操作流程

焱齿 2024-05-05 原文

1、前言 

        一台服务器上无法存储大量数据,ES把一个index里面的数据分成多个shard分布式的存储在多个服务器上(对大的索引分片,拆成多个,分不到不同的节点上)。ES就是通过shard来解决节点的容量上限问题的,通过主分片可以将数据分布到集群内的所有节点上。主分片数是在索引创建时指定的,一般不允许修改,除非Reindex。一个索引中的数据保存在多个分片中(默认为一个)相当于水平分表。一个分片表示一个Lucene的实例,它本身就是一个完整的搜索引擎。我们的文档被存储和索引到分片内,这些对应用程序是透明的,即应用程序直接与索引交互而不是分片。

        首先看一下一个ES集群大概的组织形式图。非常直观!!!!!

由上图可以看到shard可以分为主分片(primary shard)和副分片(replaca shard)。

图示为三个节点。其中任何一个都是有可能故障或者宕机的,此时其承载的shard的数据就会丢失;通过设置一个或者多个replica shard就可以在发生故障的时候提供备份服务。一方面可以保证数据不丢失,另一方面还可以提升操作的吞吐量和性能。

2、解读shard

        我们可以通过shards查看分片的具体信息。命令会列出详细的列出哪些节点包含哪些分片。也会告诉你这个分片的主/副信息、每个分片的文档数和这些文档在磁盘上占用的字节数。同时也会告诉你这些节点位于那个ip。 

#查看所有分片的情况
GET /_cat/shards?v
#指定查看某个索引的分片的情况
GET /_cat/shards/es_qidian_flow_online_v2_202202?v

GET /_cat/shards/es_qidian_flow_online_v2_202202?pretty&v  

注:GET /_cat/shards?v  这里"v"而不是"?v",如上这里是url链接参数的语法而已。他的的作用就是列出表头(还是要比较好,不熟悉的情况至少知道每个字段的含义)。如下为一个实例。

下图 为消息记录搜索功能对应的一个索引的具体分片信息,结合前面的示意图进行解读。

①可以看到node节点号和ip是完全能对应上的;也可以看到对于消息记录搜索这个case总共有三个节点和腾讯云上能看到的配置相同。

②shard列为分片号,分别为0~8;针对其中任一分片例如4,可以看到其有一个主分片(p)和一个副分片(r)。其中每一个分片有点像是mongodb的1主1从的一份副本集,不过在具体组织上还是有区别的。即mongodb任一个主or从其实都是对应一个mongod实例;但是对于这里的es而言总共只有三个node,2*9=18个主副分片都是分布在这三个node上,只不过在组织的时候尽量让主副分片不落在同一个node上就可以了。和前面的示意图也完全一致。

③docs可以看到每个分片的文档数,可以留意到同一分片的主副节点的文档数是完全一致的。这从侧面也说明了主副节点之间"副本集"的关系(一份数据冗余存储)。

④store可以看到磁盘存储空间的占用情况。

⑤增减节点(node)的时候shard会自动在nodes中负载均衡;其实从上面截图中我们也可以看到三个节点承载的分片数是差不多的。

⑥primary shard的数量在建立索引的时候设置,后续不能修改。replica shard数量应该是可以修改的。默认情况会分别创建5个primary shard和5个replica shard。关于截图这个case的9个分片就是创建索引的时候指定的,如下模板和索引中都能看到相关设置。

注:当然硬要修改分片数也是可以的,es也提供了相应的api来进行reindex。不过这个代价有点高,要重建整个索引。

思考:其实之所以代价高是es的路由机制决定的,分片数变化后就routing不到原来的数据了。当然我们可以进行更深层次的思考,尤其是和mongodb这种可以任意扩充分片的数据库进行对比。会发现本质原因对于ES来说shard就是承载数据的最小单位,写入的时候也完全是按照shard的数量进行的路由;而mongodb最小承载单位是chunk,chunk不是固定在某个shard一成不变,而是在balancer的控制下动态地游走于各个shard之间。

⑦primary shard不能和自己的replica shard放到同一个节点上(否则该节点挂了后这个分片的数据就彻底丢失了,起不到容错作用),但是可以和其他shard的replica节点放到一个节点上。

⑧每个doc肯定只存在于某一个primary shard以及其对应的replica shard中,不可能存在于多个primary shard上。

⑨replica的容错。举个例子master节点(node)宕机后,其上存在的primary shard也一并异常。这个时候会选举产生一个新的master,它会将异常primary shard对应的replica shard提升为primary shard。重启宕机node,master copy备份的数据到重启后的node,然后还会同步宕机所落后的数据,并将这个shard降级为replica。注:关于node下面会讲到。

注:统计数据量的时候副本集只能算一份数据,不要重复统计了哦!(大概8亿/月)

3、ES集群的各节点(client/master/data)

前面第⑨点提到了发生宕机时master会参与恢复,这里简要的介绍下master。其实除了master ES集群中的节点根据其被配置后所实际执行的功能可以大致分为 client/master/data三种。

查看节点信息(谁是master节点),如下图有"*"号的就是master节点。 

GET _cat/nodes?v

前面所说的配置无非就是主节点和数据节点的配置,如下:

node.master: true
node.data: false

3.1 主节点(master node)

elasticsearch.yml

node.master: true
node.data: false

主要功能:维护元数据,管理集群节点状态;不负责数据写入和查询。
配置要点:内存可以相对小一些,但是机器一定要稳定,最好是独占的机器。

        当node.master被设置为true的时候就为主节点。理想情况下这个master节点就干一些管理性质的工作,比如维护索引元数据(创建删除索引)、负责切换primary shard和replica shard身份等。主节点的稳定性非常重要。默认情况集群中任何一个node.master没有被设为false的节点都有可能被选为主节点,为了让集群更加稳定分离主节点和数据节点是一个比较好的选择。

        要是master节点宕机了,那么会自动重新选举一个节点为master。

        如果非master节点宕机了,会有master节点让宕机节点上的primary shard的身份转移到其他机器上的replica shard。等到宕机机器重启恢复后,master节点会控制将缺失的replica shard分片补充过去,同步后续修改数据之类的,让集群恢复到有容错保障的状态。

        稳定的主节点对集群的健康是非常重要的。默认情况下任何一个集群中的节点都有可能被选为主节点。索引数据和搜索查询等操作会占用大量的CPU、内存、IO资源,为了确保一个集群的稳定,分离主节点和数据节点是一个比较好的选择。我们可以通过配置指定一个节点应该是数据节点还是master节点。

3.2 客户端节点(client node)

elasticsearch.yml

node.master: false
node.data: false
 
主要功能:负责任务分发和结果汇聚,分担数据节点压力。
配置要点:大内存,最好是独占的机器

        当node.master/data都被设置为false的时候即为客户端节点。此时该节点只能处理路由请求、处理搜索、分片索引操作等。独立的客户端节点在大型集群中是非常有用的,它协调主节点和数据节点。

3.3  数据节点(data node)

elasticsearch.yml

node.master: false
node.data: true


主要功能:负责数据的写入与查询,压力大。
配置要点:大内存,最好是独占的机器。

        node.master未设置为false、data被设置为true即为数据节点。数据节点的作用就是实际承载数据的节点,也是执行增删改查、聚合操作的节点。数据节点对cpu、内存、io要求较高。注意当资源不够用的时候需要向集群中添加新的节点。        

3.4 混合节点(mixed node)  不建议


elasticsearch.yml

node.master: true
node.data: true

4、ES的扩容

ES的扩容就是新增节点(node),然后在将所有的shard在节点之间进行一个重新的分配(负载均衡)就可以了。

5、ES集群数据写入拉取流程

相关参考

​​​​​​ElasticSearch学习之数据写入及查询流程分析_Charles Yan的博客-CSDN博客_elasticsearch接口写入数据

 【分布式搜索引擎】Elasticsearch写入和读取数据过程_NICE波的技术博客_51CTO博客

Elasticsearch分布式架构思考 - 知乎

5.1  ES数据写入流程

1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点);
2)coordinating node,对document进行路由,将请求转发给对应的node(有primary shard);
3)实际的node上的primary shard处理请求,然后将数据同步到replica node;
4)coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端。
 

5.2  ES数据拉取流程

1)客户端发送请求到任意一个node,成为coordinate node;
2)coordinate node对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard以及其所有replica中随机选择一个,让读请求负载均衡;
3)接收请求的node返回document给coordinate node;
4)coordinate node返回document给客户端。
 

1.写入document时,每个document会自动分配一个全局唯一的id即doc id,同时也是根据doc id进行hash路由到对应的primary shard上。也可以手动指定doc id,比如用订单id,用户id。

2.读取document时,你可以通过doc id来查询,然后会根据doc id进行hash,判断出来当时把doc id分配到了哪个shard上面去,从那个shard去查询

6、ES同mongodb分片集群比较

(0)MongoDB就是一个个的节点先组成副本集,一个个的副本集在mongos/configserver的组织下成为一个完整的分片集群;其逻辑组织(主副关系)形式和物理实体(ip)组织形式是完全一样的。ES更像是实现约定好固定的shard数量(主副),这些shard尽量均匀的分布在N个节点(node)上;其逻辑组织形式(主副关系)和物理实体(ip)组织形式是完全独立的。

(1)最大的不同就是ES各个节点的角色更加平等。对于ES而言,无论是写入还是查询客户端的请求可以作用与任意一个node。这个node就是协调节点,它的角色有点像是mongos了;负责路由、聚合等。其实从这个实现我们知道ES的每一个node都是要维护一个routing table的。

(2)比对mongodb和ES后发现,两者对于一个副本集在命令上存在差异,但意思是差不多的。ES把主、副称为primary shard和replica shard,但是mongodb里面称为primary节点和secondary节点。简单理解节点可以认为为一个ip实例(一台机器);对于ES来说一个节点通常包括多个shard,所以意思还是那个意思但是你不能用节点。但是对于mongodb来说一个mongod就是一个实例,所以直接称为节点就好了。

(3)对于写入操作。mongos的角色可能由任一个node承担,但是真正往某个shard写数据的时候其实还是优先作用与primary shard然后在同步到replica shard,这一点和mongodb差不多;只不过mongodb的一个副本集里面叫主从节点罢了。

(4)对于查询操作。mongos的角色可能由任一个node承担,但是具体进行查询的时候则是在对应分片的primary和replica中进行轮询;而mongodb则是提供了不同的选项。

下面也贴一个mongodb分片集的示意图,方便对比。

有关ELK之Elasticsearch分片/副本与数据操作流程的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  3. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  4. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  5. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  6. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  7. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  8. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  9. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

  10. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

随机推荐