zoukankan      html  css  js  c++  java
  • ElasticSearch图解

    1. 图解es内部机制

    1.1. 图解es分布式基础

    1.1.1es对复杂分布式机制的透明隐藏特性

    • 分布式机制:分布式数据存储及共享。
    • 分片机制:数据存储到哪个分片,副本数据写入。
    • 集群发现机制:cluster discovery。新启动es实例,自动加入集群。
    • shard负载均衡:大量数据写入及查询,es会将数据平均分配。
    • shard副本:新增副本数,分片重分配。

    0201-图解es分布式基础

    1.1.2Elasticsearch的垂直扩容与水平扩容

    垂直扩容:使用更加强大的服务器替代老服务器。但单机存储及运算能力有上线。且成本直线上升。如10t服务器1万。单个10T服务器可能20万。

    水平扩容:采购更多服务器,加入集群。大数据。

    1.1.3增减或减少节点时的数据rebalance

    新增或减少es实例时,es集群会将数据重新分配。

    1.1.4master节点

    功能:

    • 创建删除节点
    • 创建删除索引

    1.1.5节点对等的分布式架构

    • 节点对等,每个节点都能接收所有的请求
    • 自动请求路由
    • 响应收集

    1.2. 图解分片shard、副本replica机制

    1.2.1shard&replica机制

    (1)每个index包含一个或多个shard

    (2)每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整的建立索引和处理请求的能力

    (3)增减节点时,shard会自动在nodes中负载均衡

    (4)primary shard和replica shard,每个document肯定只存在于某一个primary shard以及其对应的replica shard中,不可能存在于多个primary shard

    (5)replica shard是primary shard的副本,负责容错,以及承担读请求负载

    (6)primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改

    (7)primary shard的默认数量是1,replica默认是1,默认共有2个shard,1个primary shard,1个replica shard

    注意:es7以前primary shard的默认数量是5,replica默认是1,默认有10个shard,5个primary shard,5个replica shard

    (8)primary shard不能和自己的replica shard放在同一个节点上(否则节点宕机,primary shard和副本都丢失,起不到容错的作用),但是可以和其他primary shard的replica shard放在同一个节点上

    0202-图解分片shard、副本replica机制

    1.3图解单node环境下创建index是什么样子的

    (1)单node环境下,创建一个index,有3个primary shard,3个replica shard
    (2)集群status是yellow
    (3)这个时候,只会将3个primary shard分配到仅有的一个node上去,另外3个replica shard是无法分配的
    (4)集群可以正常工作,但是一旦出现节点宕机,数据全部丢失,而且集群不可用,无法承接任何请求

    PUT /test_index1
    {
       "settings" : {
          "number_of_shards" : 3,
          "number_of_replicas" : 1
       }
    }
    

    0203-图解单node环境下创建index是什么样子的

    1.4图解2个node环境下replica shard是如何分配的

    (1)replica shard分配:3个primary shard,3个replica shard,1 node
    (2)primary ---> replica同步
    (3)读请求:primary/replica

    ![0204-图解2个node环境下replica shard是如何分配的](https://typora-oss.oss-cn-beijing.aliyuncs.com/0204-图解2个node环境下replica shard是如何分配的.jpg)

    1.5图解横向扩容

    • 分片自动负载均衡,分片向空闲机器转移。
    • 每个节点存储更少分片,系统资源给与每个分片的资源更多,整体集群性能提高。
    • 扩容极限:节点数大于整体分片数,则必有空闲机器。
    • 超出扩容极限时,可以增加副本数,如设置副本数为2,总共3*3=9个分片。9台机器同时运行,存储和搜索性能更强。容错性更好。
    • 容错性:只要一个索引的所有主分片在,集群就就可以运行。

    0205-图解横向扩容

    1.6 图解es容错机制 master选举,replica容错,数据恢复

    以3分片,2副本数,3节点为例介绍。

    • master node宕机,自动master选举,集群为red
    • replica容错:新master将replica提升为primary shard,yellow
    • 重启宕机node,master copy replica到该node,使用原有的shard并同步宕机后的修改,green

    ![0206-图解es容错机制 master选举,replica容错,数据恢复](https://typora-oss.oss-cn-beijing.aliyuncs.com/0206-图解es容错机制 master选举,replica容错,数据恢复.jpg)

    2. 图解文档存储机制

    2.1. 数据路由

    2.1.1文档存储如何路由到相应分片

    一个文档,最终会落在主分片的一个分片上,到底应该在哪一个分片?这就是数据路由。

    2.1.2路由算法

    shard = hash(routing) % number_of_primary_shards
    

    哈希值对主分片数取模。

    举例:

    对一个文档经行crud时,都会带一个路由值 routing number。默认为文档_id(可能是手动指定,也可能是自动生成)。

    存储1号文档,经过哈希计算,哈希值为2,此索引有3个主分片,那么计算2%3=2,就算出此文档在P2分片上。

    决定一个document在哪个shard上,最重要的一个值就是routing值,默认是_id,也可以手动指定,相同的routing值,每次过来,从hash函数中,产出的hash值一定是相同的

    无论hash值是几,无论是什么数字,对number_of_primary_shards求余数,结果一定是在0~number_of_primary_shards-1之间这个范围内的。0,1,2。

    2.1.3手动指定 routing number

    PUT /test_index/_doc/15?routing=num
    {
      "num": 0,
      "tags": []
    }
    

    场景:在程序中,架构师可以手动指定已有数据的一个属性为路由值,好处是可以定制一类文档数据存储到一个分片中。缺点是设计不好,会造成数据倾斜。

    所以,不同文档尽量放到不同的索引中。剩下的事情交给es集群自己处理。

    2.1.4主分片数量不可变

    涉2及到以往数据的查询搜索,所以一旦建立索引,主分片数不可变。

    0207-数据路由

    2.2. 图解文档的增删改内部机制

    增删改可以看做update,都是对数据的改动。一个改动请求发送到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都搞定之后,就返回响应结果给客户端。

    0208-图解文档的增删改内部机制

    2.3.图解文档的查询内部机制

    1、客户端发送请求到任意一个node,成为coordinate node

    2、coordinate node对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard以及其所有replica中随机选择一个,让读请求负载均衡

    3、接收请求的node返回document给coordinate node

    4、coordinate node返回document给客户端

    5、特殊情况:document如果还在建立索引过程中,可能只有primary shard有,任何一个replica shard都没有,此时可能会导致无法读取到document,但是document完成索引建立之后,primary shard和replica shard就都有了。

    0209-图解文档的查询内部机制

    2.4.bulk api奇特的json格式

    POST /_bulk
    {"action": {"meta"}}
    
    {"data"}
    
    {"action": {"meta"}}
    
    {"data"}
    
    
    [
        {
            "action":{
                "method":"create"
            },
            "data":{
                "id":1,
                "field1":"java",
                "field1":"spring",
            }
        },
          {
            "action":{
                "method":"create"
            },
            "data":{
                "id":2,
                "field1":"java",
                "field1":"spring",
            }
        }       
    ]
    
    

    1、bulk中的每 node的shard去执行

    2、如果采用比较良好的json数组格式

    允许任意的换行,整个可读性非常棒,读起来很爽,es拿到那种标准格式的json串以后,要按照下述流程去进行处理

    (1)将json数组解析为JSONArray对象,这个时候,整个数据,就会在内存中出现一份一模一样的拷贝,一份数据是json文本,一份数据是JSONArray对象

    (2)解析json数组里的每个json,对每个请求中的document进行路由

    (3)为路由到同一个shard上的多个请求,创建一个请求数组。100请求中有10个是到P1.

    (4)将这个请求数组序列化

    (5)将序列化后的请求数组发送到对应的节点上去

    3、耗费更多内存,更多的jvm gc开销

    我们之前提到过bulk size最佳大小的那个问题,一般建议说在几千条那样,然后大小在10MB左右,所以说,可怕的事情来了。假设说现在100个bulk请求发送到了一个节点上去,然后每个请求是10MB,100个请求,就是1000MB = 1GB,然后每个请求的json都copy一份为jsonarray对象,此时内存中的占用就会翻倍,就会占用2GB的内存,甚至还不止。因为弄成jsonarray之后,还可能会多搞一些其他的数据结构,2GB+的内存占用。

    占用更多的内存可能就会积压其他请求的内存使用量,比如说最重要的搜索请求,分析请求,等等,此时就可能会导致其他请求的性能急速下降。

    另外的话,占用内存更多,就会导致java虚拟机的垃圾回收次数更多,跟频繁,每次要回收的垃圾对象更多,耗费的时间更多,导致es的java虚拟机停止工作线程的时间更多。

    4、现在的奇特格式

    POST /_bulk
    { "delete": { "_index": "test_index",  "_id": "5" }} 
    
    { "create": { "_index": "test_index",  "_id": "14" }}
    
    { "test_field": "test14" }
    
    { "update": { "_index": "test_index",  "_id": "2"} }
    
    { "doc" : {"test_field" : "bulk test"} }
    
    

    (1)不用将其转换为json对象,不会出现内存中的相同数据的拷贝,直接按照换行符切割json

    (2)对每两个一组的json,读取meta,进行document路由

    (3)直接将对应的json发送到node上去

    5、最大的优势在于,不需要将json数组解析为一个JSONArray对象,形成一份大数据的拷贝,浪费内存空间,尽可能地保证性能。

  • 相关阅读:
    Linux之find命令
    Android WebView如何加载assets下的html文件
    Android 静默安装
    Android listview下拉刷新 SwipeRefreshLayout
    AndroidManifest.xml 详解
    Android 查看内存使用状况
    Android invalidate() 和 postInvalidate()的区别
    Android动画之Interpolator和AnimationSet
    实现Fragment的切换和ViewPager自动循环设置切换时间
    android 实现橡皮擦效果以及保存涂鸦的功能
  • 原文地址:https://www.cnblogs.com/dalianpai/p/13885500.html
Copyright © 2011-2022 走看看