中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ElasticSearch基本原理和分布式文件系統

發布時間:2020-07-15 09:35:11 來源:網絡 閱讀:3877 作者:叫我北北 欄目:開發技術

目錄

    階段一:Elasticsearch概念與架構

        Elasticsearch的功能

        Elasticsearch-Linux安裝

        Elasticsearch核心概念

        Elasticsearch基礎分布式架構

        Elasticsearch的shard和replica機制、單node環境shard分配

        橫向擴容過程,如何超出擴容極限,以及如何提升容錯性

        Elasticsearch容錯機制:master選舉,replica容錯,數據恢復

    

    階段二:ElasticSearch分布式文件架構

        1.document核心元數據

        2._source核心元數據

        3.document的全量替換、強制創建以及圖解lazy delete機制

        4.批量查詢mget

        5.bulk

        6.es并發沖突以及解決方案

        7.分布式文件系統-document各種操作內部原理



階段一:Elasticsearch概念與架構

Elasticsearch的功能

(1)分布式的搜索引擎和數據分析引擎

(2)全文檢索,結構化檢索,數據分析

(3)對海量數據進行近實時的處理


Elasticsearch-Linux安裝

    把程序放到后臺運行:    
        nohup ./your_command &

1.下載

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.0.0.tar.gz


2.解壓授權(es 規定 root 用戶不能啟動 es,所以需要使用一個其他用戶來啟動 es)

useradd esuser

passwd esuser

cd /home/esuser/

tar zxvf elasticsearch-6.0.0.tar.gz

chown -R esuser:esuser elasticsearch-6.0.0


3.啟動(切換到普通用戶)

cd elasticsearch-6.0.0

sh ./bin/elasticsearch

(如果報錯jdk版本問題,可以修改系統環境變量;但是本機環境變量使用系統自帶的jdk1.7,由于其他業務需要,不能改變,可以在bin/elasticsearch-env下配置臨時變量

JAVA_HOME=/usr/java/jdk1.8.0_144)


4.訪問測試

curl localhost:9200

注:這里不能直接使用IP,需要配置(在配置前先停了線程),下面是開始配置。


5.停止es

cd elasticsearch-6.0.0/bin

ps -ef |grep elasticsearch

kill -9 上面查出來的進程號(第一行用戶名后第一個)


6.修改

config/elasticsearch.yml文件里面的:network.host: 0.0.0.0


7.重啟

sh elasticsearch (-d后臺啟動)

發現報錯:

前三個錯誤:

ERROR: [4] bootstrap checks failed

#文件句柄太少,至少要65536

[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]

#最大線程數太少,至少2048個(經典的2048游戲)

[2]: max number of threads [1024] for user [king] is too low, increase to at least [2048]

#虛擬內存太少,至少262144

[3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

修改:

1.更改文件句柄數

[root@localhost ~]# vi /etc/security/limits.conf

在文件中加入如下內容(*表示任何用戶)

* soft nofile 65536

* hard nofile 131072

* soft nproc 2048

* hard nproc 4096


2.增加線程數

[root@localhost ~]# vi /etc/security/limits.d/90-nproc.conf 

將其中的

*          soft    nproc     1024

1

修改為

*          soft    nproc     2048


3.增加虛擬內存

[root@localhost ~]# vim /etc/sysctl.conf 

在其中添加

vm.max_map_count=655360

使配置生效(完成后最好換個客戶端重啟):

sysctl -p


第四個錯誤:

[4]system call filters failed to install; check the logs and fix your configuration or disable system call filters at your own risk

原因:

這是在因為Centos6不支持SecComp,而ES5.2.0默認bootstrap.system_call_filter為true進行檢測,所以導致檢測失敗,失敗后直接導致ES不能啟動。


解決:

在elasticsearch.yml中配置bootstrap.system_call_filter為false,注意要在Memory下面:

bootstrap.memory_lock: false

bootstrap.system_call_filter: false


8.再次重啟(最好換另外一個客戶端)

[esuser@localhost bin]$ ./elasticsearch

[root@localhost ~]# curl xxx.xx.30.27:9200


9.配置防火墻

這個時候可以在本機通過本機ip訪問,還沒有開防火墻,外網是不可以訪問的。

1) 重啟后生效

開啟: chkconfig iptables on

關閉: chkconfig iptables off


2) 即時生效,重啟后失效

開啟: service iptables start

關閉: service iptables stop

我是臨時關閉防火墻。


Elasticsearch-Windows安裝

1、安裝JDK,至少1.8.0_73以上版本,java -version

2、下載和解壓縮Elasticsearch安裝包,目錄結構

3、啟動Elasticsearchbin\elasticsearch.bates本身特點之一就是開箱即用,如果是中小型應用,數據量少,操作不是很復雜,直接啟動就可以用了

4、檢查ES是否啟動成功:http://localhost:9200/?pretty

name: node名稱

cluster_name: 集群名稱(默認的集群名稱就是elasticsearch

version.number: 5.2.0,es版本號

{

  "name" : "4onsTYV",

  "cluster_name" : "elasticsearch",

  "cluster_uuid" : "nKZ9VK_vQdSQ1J0Dx9gx1Q",

  "version" : {

    "number" : "5.2.0",

    "build_hash" : "24e05b9",

    "build_date" : "2017-01-24T19:52:35.800Z",

    "build_snapshot" : false,

    "lucene_version" : "6.4.0"

  },

  "tagline" : "You Know, for Search"

}

5、修改集群名稱:elasticsearch.yml

6、下載和解壓縮Kibana安裝包,使用里面的開發界面,去操作elasticsearch,作為我們學習es知識點的一個主要的界面入口

7、啟動Kibanabin\kibana.bat

8、進入Dev Tools界面

9、GET _cluster/health

ElasticSearch基本原理和分布式文件系統

Elasticsearch核心概念

(1)Near RealtimeNRT):近實時,兩個意思,從寫入數據到數據可以被搜索到有一個小延遲(大概1秒);基于es執行搜索和分析可以達到秒級

 

(2)Cluster:集群,包含多個節點,每個節點屬于哪個集群是通過一個配置(集群名稱,默認是elasticsearch)來決定的,對于中小型應用來說,剛開始一個集群就一個節點很正常

(3)Node:節點,集群中的一個節點,節點也有一個名稱(默認是隨機分配的),節點名稱很重要(在執行運維管理操作的時候),默認節點會去加入一個名稱為“elasticsearch”的集群,如果直接啟動一堆節點,那么它們會自動組成一個elasticsearch集群,當然一個節點也可以組成一個elasticsearch集群

 

(4)Document&field:文檔,es中的最小數據單元,一個document可以是一條客戶數據,一條商品分類數據,一條訂單數據,通常用JSON數據結構表示,每個index下的type中,都可以去存儲多個document。一個document里面有多個field,每個field就是一個數據字段。

product document

{

  "product_id": "1",

  "product_name": "高露潔牙膏",

  "product_desc": "高效美白",

  "category_id": "2",

  "category_name": "日化用品"

}

 

(5)Index:索引,包含一堆有相似結構的文檔數據,比如可以有一個客戶索引,商品分類索引,訂單索引,索引有一個名稱。一個index包含很多document,一個index就代表了一類類似的或者相同的document。比如說建立一個product index,商品索引,里面可能就存放了所有的商品數據,所有的商品document

(6)Type:類型,每個索引里都可以有一個或多個typetypeindex中的一個邏輯數據分類,一個type下的document,都有相同的field,比如博客系統,有一個索引,可以定義用戶數據type,博客數據type,評論數據type

 

商品index,里面存放了所有的商品數據,商品document

但是商品分很多種類,每個種類的document的field可能不太一樣,比如說電器商品,可能還包含一些諸如售后時間范圍這樣的特殊field;生鮮商品,還包含一些諸如生鮮保質期之類的特殊field

type,日化商品type,電器商品type,生鮮商品type

日化商品type:product_idproduct_nameproduct_desccategory_idcategory_name

電器商品type:product_idproduct_nameproduct_desccategory_idcategory_nameservice_period

生鮮商品type:product_idproduct_nameproduct_desccategory_idcategory_nameeat_period

 

每一個type里面,都會包含一堆document

{

  "product_id": "2",

  "product_name": "長虹電視機",

  "product_desc": "4k高清",

  "category_id": "3",

  "category_name": "電器",

  "service_period": "1年"

}

{

  "product_id": "3",

  "product_name": "基圍蝦",

  "product_desc": "純天然,冰島產",

  "category_id": "4",

  "category_name": "生鮮",

  "eat_period": "7天"

}

(7)shard:單臺機器無法存儲大量數據,es可以將一個索引中的數據切分為多個shard,分布在多臺服務器上存儲。有了shard就可以橫向擴展,存儲更多數據,讓搜索和分析等操作分布到多臺服務器上去執行,提升吞吐量和性能。每個shard都是一個lucene index

(8)replica:任何一個服務器隨時可能故障或宕機,此時shard可能就會丟失,因此可以為每個shard創建多個replica副本。replica可以在shard故障時提供備用服務,保證數據不丟失,多個replica還可以提升搜索操作的吞吐量和性能。primary shard(建立索引時一次設置,不能修改,默認5個),replica shard(隨時修改數量,默認1個),默認每個索引10shard5primary shard5replica shard,最小的高可用配置,是2臺服務器。

ElasticSearch基本原理和分布式文件系統

Elasticsearch基礎分布式架構

1、Elasticsearch對復雜分布式機制的透明隱藏特性

2、Elasticsearch的垂直擴容與水平擴容

3、增減或減少節點時的數據rebalance

4、master節點

5、節點對等的分布式架構

ElasticSearch基本原理和分布式文件系統

Elasticsearch的shard和replica機制、單node環境shard分配

1shard&replica機制再次梳理

(1)index包含多個shard

(2)每個shard都是一個最小工作單元,承載部分數據,lucene實例,完整的建立索引和處理請求的能力

(3)增減節點時,shard會自動在nodes負載均衡

(4)primary shardreplica shard,每個document肯定只存在于某一個primary shard以及其對應的replica shard中,不可能存在于多個primary shard

(5)replica shardprimary shard的副本,負責容錯,以及承擔讀請求負載

(6)primary shard的數量在創建索引的時候就固定了,replica shard的數量可以隨時修改

(7)primary shard的默認數量是5replica默認是1,默認有10shard5primary shard5replica shard

(8)primary shard不能和自己的replica shard放在同一個節點上(否則節點宕機,primary shard和副本都丟失,起不到容錯的作用),但是可以和其他primary shardreplica shard放在同一個節點上

------------------------------------------------------------------------------------------------

2、單node環境下創建index是什么樣子的

(1)單node環境下,創建一個index,有3primary shard3replica shard

(2)集群statusyellow

(3)這個時候,只會將3primary shard分配到僅有的一個node上去,另外3replica shard是無法分配的

(4)集群可以正常工作,但是一旦出現節點宕機,數據全部丟失,而且集群不可用,無法承接任何請求

PUT /test_index

{

   "settings" : {

      "number_of_shards" : 3,

      "number_of_replicas" : 1

   }

}

32node環境下replica shard是如何分配的

(1)replica shard分配:3primary shard3replica shard1 node

(2)primary ---> replica同步

(3)讀請求:primary/replica

橫向擴容過程,如何超出擴容極限,以及如何提升容錯性

(1)primary&replica自動負載均衡,6shard3 primary3 replica

(2)每個node有更少的shardIO/CPU/Memory資源給每個shard分配更多,每個shard性能更好

(3)擴容的極限,6shard3 primary3 replica),最多擴容到6臺機器,每個shard可以占用單臺服務器的所有資源,性能最好

(4)超出擴容極限,動態修改replica數量,9shard3primary6 replica),擴容到9臺機器,比3臺機器時,擁有3倍的讀吞吐量

(5)3臺機器下,9shard3 primary6 replica),資源更少,但是容錯性更好,最多容納2臺機器宕機,6shard只能容納0臺機器宕機

(6)這里的這些知識點,你綜合起來看,就是說,一方面告訴你擴容的原理,怎么擴容,怎么提升系統整體吞吐量;另一方面要考慮到系統的容錯性,怎么保證提高容錯性,讓盡可能多的服務器宕機,保證數據不丟失

Elasticsearch容錯機制:master選舉,replica容錯,數據恢復

19 shard3 node

(2)master node宕機,自動master選舉,red

(3)replica容錯:新masterreplica提升為primary shardyellow

(4)重啟宕機nodemaster copy replica到該node,使用原有的shard并同步宕機后的修改,green

ElasticSearch基本原理和分布式文件系統


階段二:ElasticSearch分布式文件架構

1.document核心元數據

    1、_index元數據

    2、_type元數據

    3、_id元數據

    {

      "_index": "test_index",

      "_type": "test_type",

      "_id": "1",

      "_version": 1,

      "found": true,

      "_source": {

        "test_content": "test test"

      }

    }

1.1、_index元數據

1代表一個document存放在哪個index

(2)類似的數據放在一個索引,非類似的數據放不同索引:product index(包含了所有的商品),sales index(包含了所有的商品銷售數據),inventory index(包含了所有庫存相關的數據)。如果你把比如productsaleshuman resourceemployee),全都放在一個大的index里面,比如說company index,不合適的。

(3)index中包含了很多類似的document:類似是什么意思,其實指的就是說,這些documentfields很大一部分是相同的,你說你放了3document,每個documentfields都完全不一樣,這就不是類似了,就不太適合放到一個index里面去了。

(4)索引名稱必須是小寫的,不能用下劃線開頭,不能包含逗號:productwebsiteblog

 

1.2、_type元數據

1代表document屬于index中的哪個類別(type

(2)一個索引通常會劃分為多個type,邏輯上對index中有些許不同的幾類數據進行分類:因為一批相同的數據,可能有很多相同的fields,但是還是可能會有一些輕微的不同,可能會有少數fields是不一樣的,舉個例子,就比如說,商品,可能劃分為電子商品,生鮮商品,日化商品,等等。

(3)type名稱可以是大寫或者小寫,但是同時不能用下劃線開頭,不能包含逗號

 

1.3、_id元數據

1代表document的唯一標識,與indextype一起,可以唯一標識和定位一個document

(2)我們可以手動指定documentidput /index/type/id),也可以不指定,由es自動為我們創建一個id

 

1、手動指定document id

(1)根據應用情況來說,是否滿足手動指定document id的前提:

    一般來說,是從某些其他的系統中,導入一些數據到es時,會采取這種方式,就是使用系統中已有數據的唯一標識,作為esdocumentid。舉個例子,比如說,我們現在在開發一個電商網站,做搜索功能,或者是OA系統,做員工檢索功能。這個時候,數據首先會在網站系統或者IT系統內部的數據庫中,會先有一份,此時就肯定會有一個數據庫的primary key(自增長,UUID,或者是業務編號)。如果將數據導入到es中,此時就比較適合采用數據在數據庫中已有的primary key

 

    如果說,我們是在做一個系統,這個系統主要的數據存儲就是es一種,也就是說,數據產生出來以后,可能就沒有id,直接就放es一個存儲,那么這個時候,可能就不太適合說手動指定document id的形式了,因為你也不知道id應該是什么,此時可以采取下面要講解的讓es自動生成id的方式。

 

(2)put /index/type/id

PUT /test_index/test_type/2

{

  "test_content": "my test"

}

2、自動生成document id

(1)post /index/type

POST /test_index/test_type

{

  "test_content": "my test"

}

{

  "_index": "test_index",

  "_type": "test_type",

  "_id": "AVp4RN0bhjxldOOnBxaE",

  "_version": 1,

  "result": "created",

  "_shards": {

    "total": 2,

    "successful": 1,

    "failed": 0

  },

  "created": true

}

(2)自動生成的id,長度為20個字符,URL安全,base64編碼,GUID,分布式系統并行生成時不可能會發生沖突

 

2._source核心元數據

2.1、_source元數據 

put /test_index/test_type/1

{

  "test_field1": "test field1",

  "test_field2": "test field2"

get /test_index/test_type/1

{

  "_index": "test_index",

  "_type": "test_type",

  "_id": "1",

  "_version": 2,

  "found": true,

  "_source": {

    "test_field1": "test field1",

    "test_field2": "test field2"

  }

}

_source元數據:就是說,我們在創建一個document的時候,使用的那個放在request body中的json串,默認情況下,在get的時候,會原封不動的給我們返回回來。

 

2.2、定制返回結果

定制返回的結果,指定_source中,返回哪些field

GET /test_index/test_type/1?_source=test_field1,test_field2

{

  "_index": "test_index",

  "_type": "test_type",

  "_id": "1",

  "_version": 2,

  "found": true,

  "_source": {

    "test_field2": "test field2"

  }

}

3.document的全量替換、強制創建以及圖解lazy delete機制

3.1、document的全量替換

(1)語法與創建文檔是一樣的,如果document id不存在,那么就是創建;如果document id已經存在,那么就是全量替換操作,替換documentjson串內容

(2)document是不可變的,如果要修改document的內容,第一種方式就是全量替換,直接對document重新建立索引,替換里面所有的內容

3es會將老的document標記為deleted,然后新增我們給定的一個document,當我們創建越來越多的document的時候,es會在適當的時機在后臺自動刪除標記為deleteddocument

3.2、document的強制創建

(1)創建文檔與全量替換的語法是一樣的,有時我們只是想新建文檔,不想替換文檔,如果強制進行創建呢?

(2)PUT /index/type/id?op_type=createPUT /index/type/id/_create

3.3、document的刪除

(1)DELETE /index/type/id

2不會理解物理刪除,只會將其標記為deleted,當數據越來越多的時候,在后臺自動刪除

4.批量查詢mget

4.1、批量查詢的好處 

就是一條一條的查詢,比如說要查詢100條數據,那么就要發送100次網絡請求,這個開銷還是很大的

如果進行批量查詢的話,查詢100條數據,就只要發送1次網絡請求,網絡請求的性能開銷縮減100

 

4.2、mget的語法

(1)一條一條的查詢
GET /test_index/test_type/1
GET /test_index/test_type/2
(2)mget批量查詢
GET /_mget
{
   "docs" : [
      {
         "_index" : "test_index",
         "_type" :  "test_type",
         "_id" :    1
      },
      {
         "_index" : "test_index",
         "_type" :  "test_type",
         "_id" :    2
      }
   ]
}
{
  "docs": [
    {
      "_index": "test_index",
      "_type": "test_type",
      "_id": "1",
      "_version": 2,
      "found": true,
      "_source": {
        "test_field1": "test field1",
        "test_field2": "test field2"
      }
    },
    {
      "_index": "test_index",
      "_type": "test_type",
      "_id": "2",
      "_version": 1,
      "found": true,
      "_source": {
        "test_content": "my test"
      }
    }
  ]
}
(3)如果查詢的document是一個index下的不同type種的話
GET /test_index/_mget
{
   "docs" : [
      {
         "_type" :  "test_type",
         "_id" :    1
      },
      {
         "_type" :  "test_type",
         "_id" :    2
      }
   ]
}
(4)如果查詢的數據都在同一個index下的同一個type下,最簡單了
GET /test_index/test_type/_mget
{
   "ids": [1, 2]
}

4.3、mget的重要性

    可以說mget是很重要的,一般來說,在進行查詢的時候,如果一次性要查詢多條數據的話,那么一定要用batch批量操作的api

    盡可能減少網絡開銷次數,可能可以將性能提升數倍,甚至數十倍,非常非常之重要

5.bulk

5.1、bulk語法

POST /_bulk
{ "delete": { "_index": "test_index", "_type": "test_type", "_id": "3" }}
{ "create": { "_index": "test_index", "_type": "test_type", "_id": "12" }}
{ "test_field":    "test12" }
{ "index":  { "_index": "test_index", "_type": "test_type", "_id": "2" }}
{ "test_field":    "replaced test2" }
{ "update": { "_index": "test_index", "_type": "test_type", "_id": "1", "_retry_on_conflict" : 3} }
{ "doc" : {"test_field2" : "bulk test1"} }

每一個操作要兩個json串,語法如下:

{"action": {"metadata"}}

{"data"}

舉例,比如你現在要創建一個文檔,放bulk里面,看起來會是這樣子的:

{"index": {"_index": "test_index", "_type", "test_type", "_id": "1"}}

{"test_field1": "test1", "test_field2": "test2"}

有哪些類型的操作可以執行呢?

(1)delete:刪除一個文檔,只要1json串就可以了

(2)createPUT /index/type/id/_create,強制創建

(3)index:普通的put操作,可以是創建文檔,也可以是全量替換文檔

(4)update:執行的partial update操作

 

bulk api對json的語法,有嚴格的要求,每個json串不能換行,只能放一行,同時一個json串和一個json串之間,必須有一個換行

 

bulk操作中,任意一個操作失敗,是不會影響其他的操作的,但是在返回結果里,會告訴你異常日志

POST /test_index/_bulk
{ "delete": { "_type": "test_type", "_id": "3" }}
{ "create": { "_type": "test_type", "_id": "12" }}
{ "test_field":    "test12" }
{ "index":  { "_type": "test_type" }}
{ "test_field":    "auto-generate id test" }
{ "index":  { "_type": "test_type", "_id": "2" }}
{ "test_field":    "replaced test2" }
{ "update": { "_type": "test_type", "_id": "1", "_retry_on_conflict" : 3} }
{ "doc" : {"test_field2" : "bulk test1"} }
 
POST /test_index/test_type/_bulk
{ "delete": { "_id": "3" }}
{ "create": { "_id": "12" }}
{ "test_field":    "test12" }
{ "index":  { }}
{ "test_field":    "auto-generate id test" }
{ "index":  { "_id": "2" }}
{ "test_field":    "replaced test2" }
{ "update": { "_id": "1", "_retry_on_conflict" : 3} }
{ "doc" : {"test_field2" : "bulk test1"} }

5.2、bulk size最佳大小

bulk request會加載到內存里,如果太大的話,性能反而會下降,因此需要反復嘗試一個最佳的bulk size。一般從1000~5000條數據開始,嘗試逐漸增加。另外,如果看大小的話,最好是在5~15MB之間

6.es并發沖突以及解決方案

6.1. 圖解剖析Elasticsearch并發沖突問題

ElasticSearch基本原理和分布式文件系統 

6.2.樂觀鎖和悲觀鎖并發控制方案

ElasticSearch基本原理和分布式文件系統 

6.3.es基于_version進行樂觀鎖并發控制

(1)_version元數據

PUT /test_index/test_type/6
{
  "test_field": "test test"
}
{
  "_index": "test_index",
  "_type": "test_type",
  "_id": "6",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "created": true
}
 
第一次創建一個document的時候,它的_version內部版本號就是1;以后,每次對這個document執行修改或者刪除操作,都會對這個_version版本號自動加1;哪怕是刪除,也會對這條數據的版本號加1
 
{
  "found": true,
  "_index": "test_index",
  "_type": "test_type",
  "_id": "6",
  "_version": 4,
  "result": "deleted",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  }
}

會發現,在刪除一個document之后,可以從一個側面證明,它不是立即物理刪除掉的,因為它的一些版本號等信息還是保留著的。先刪除一條document,再重新創建這條document,其實會在delete version基礎之上,再把version號加1

ElasticSearch基本原理和分布式文件系統 

6.4.external version

    es提供了一個feature,就是說,你可以不用它提供的內部_version版本號來進行并發控制,可以基于你自己維護的一個版本號來進行并發控制。舉個列子,加入你的數據在mysql里也有一份,然后你的應用系統本身就維護了一個版本號,無論是什么自己生成的,程序控制的。這個時候,你進行樂觀鎖并發控制的時候,可能并不是想要用es內部的_version來進行控制,而是用你自己維護的那個version來進行控制。

6.5、partial update

    什么是partial update

 

PUT /index/type/id,創建文檔&替換文檔,就是一樣的語法

一般對應到應用程序中,每次的執行流程基本是這樣的:

1)應用程序先發起一個get請求,獲取到document,展示到前臺界面,供用戶查看和修改

(2)用戶在前臺界面修改數據,發送到后臺

(3)后臺代碼,會將用戶修改的數據在內存中進行執行,然后封裝好修改后的全量數據

(4)然后發送PUT請求,到es中,進行全量替換

(5)es將老的document標記為deleted,然后重新創建一個新的document

 

partial update

post /index/type/id/_update

{

   "doc": {

      "要修改的少數幾個field即可,不需要全量的數據"

   }

}

看起來,好像就比較方便了,每次就傳遞少數幾個發生修改的field即可,不需要將全量的document數據發送過去


    圖解partial update實現原理以及其優點

ElasticSearch基本原理和分布式文件系統 

Partial update相比全量請求的優缺點:

    所有的查詢、修改和寫回操作,都發生在es中的一個shard內部,避免了所有的網絡數據傳輸的開銷(如果全量請求的話,會從es中找一批數據放回Java應用中,然后Java應用修改,傳回es中修改請求,這就是兩次網絡開銷,而partial update只在一個shard中操作所有)


7.分布式文件系統-document各種操作內部原理

7.1.document數據路由原理(shard為什么不可變)

    (1)document路由到shard上是什么意思?

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

    舉個例子,一個index有3個primary shard,P0,P1,P2

    每次增刪改查一個document的時候,都會帶過來一個routing number,默認就是這個document的_id(可能是手動指定,也可能是自動生成)

    routing = _id,假設_id=1

    

    會將這個routing值,傳入一個hash函數中,產出一個routing值的hash值,hash(routing) = 21

    然后將hash函數產出的值對這個index的primary shard的數量求余數,21 % 3 = 0

    就決定了,這個document就放在P0上。

    

    決定一個document在哪個shard上,最重要的一個值就是routing值,默認是_id,也可以手動指定,相同的routing值,每次過來,從hash函數中,產出的hash值一定是相同的

    

    無論hash值是幾,無論是什么數字,對number_of_primary_shards求余數,結果一定是在0~number_of_primary_shards-1之間這個范圍內的。0,1,2。

    

    (3)_id or custom routing value

    

    默認的routing就是_id

    也可以在發送請求的時候,手動指定一個routing value,比如說put /index/type/id?routing=user_id

    

    手動指定routing value是很有用的,可以保證說,某一類document一定被路由到一個shard上去,那么在后續進行應用級別的負載均衡,以及提升批量讀取的性能的時候,是很有幫助的

    

    (4)primary shard數量不可變的謎底


7.2.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都搞定之后,就返回響應結果給客戶端


7.3.寫一致性原理以及quorum機制

    (1)consistency,one(primary shard),all(all shard),quorum(default)

    

    我們在發送任何一個增刪改操作的時候,比如說put /index/type/id,都可以帶上一個consistency參數,指明我們想要的寫一致性是什么?

    put /index/type/id?consistency=quorum

    

    one:要求我們這個寫操作,只要有一個primary shard是active活躍可用的,就可以執行

    all:要求我們這個寫操作,必須所有的primary shard和replica shard都是活躍的,才可以執行這個寫操作

    quorum:默認的值,要求所有的shard中,必須是大部分的shard都是活躍的,可用的,才可以執行這個寫操作

    

    (2)quorum機制,寫之前必須確保大多數shard都可用,int( (primary + number_of_replicas) / 2 ) + 1,當number_of_replicas>1時才生效

    

    quroum = int( (primary + number_of_replicas) / 2 ) + 1

    舉個例子,3個primary shard,number_of_replicas=1,總共有3 + 3 * 1 = 6個shard

    quorum = int( (3 + 1) / 2 ) + 1 = 3

    所以,要求6個shard中至少有3個shard是active狀態的,才可以執行這個寫操作

    

    (3)如果節點數少于quorum數量,可能導致quorum不齊全,進而導致無法執行任何寫操作

    

    3個primary shard,replica=1,要求至少3個shard是active,3個shard按照之前學習的shard&replica機制,必須在不同的節點上,如果說只有2臺機器的話,是不是有可能出現說,3個shard都沒法分配齊全,此時就可能會出現寫操作無法執行的情況

    

    es提供了一種特殊的處理場景,就是說當number_of_replicas>1時才生效,因為假如說,你就一個primary shard,replica=1,此時就2個shard

    

    (1 + 1 / 2) + 1 = 2,要求必須有2個shard是活躍的,但是可能就1個node,此時就1個shard是活躍的,如果你不特殊處理的話,導致我們的單節點集群就無法工作

    

    (4)quorum不齊全時,wait,默認1分鐘,timeout,100,30s

    

    等待期間,期望活躍的shard數量可以增加,最后實在不行,就會timeout

    我們其實可以在寫操作的時候,加一個timeout參數,比如說put /index/type/id?timeout=30,這個就是說自己去設定quorum不齊全的時候,es的timeout時長,可以縮短,也可以增長

7.4.es查詢內部原理

    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就都有了


7.5.json格式

    bulk api奇特的json格式

    

    {"action": {"meta"}}\n

    {"data"}\n

    {"action": {"meta"}}\n

    {"data"}\n

    

    [{

      "action": {

     

      },

      "data": {

    

      }

    }]

    

    1、bulk中的每個操作都可能要轉發到不同的node的shard去執行

    

    2、如果采用比較良好的json數組格式

    

    允許任意的換行,整個可讀性非常棒,讀起來很爽,es拿到那種標準格式的json串以后,要按照下述流程去進行處理

    

    (1)將json數組解析為JSONArray對象,這個時候,整個數據,就會在內存中出現一份一模一樣的拷貝,一份數據是json文本,一份數據是JSONArray對象

    (2)解析json數組里的每個json,對每個請求中的document進行路由

    (3)為路由到同一個shard上的多個請求,創建一個請求數組

    (4)將這個請求數組序列化

    (5)將序列化后的請求數組發送到對應的節點上去

    

    3、耗費更多內存,更多的jvm gc開銷

    

    我們之前提到過bulk size最佳大小的那個問題,一般建議說在幾千條那樣,然后大小在10MB左右,所以說,可怕的事情來了。假設說現在100個bulk請求發送到了一個節點上去,然后每個請求是10MB,100個請求,就是1000MB = 1GB,然后每個請求的json都copy一份為jsonarray對象,此時內存中的占用就會翻倍,就會占用2GB的內存,甚至還不止。因為弄成jsonarray之后,還可能會多搞一些其他的數據結構,2GB+的內存占用。

    

    占用更多的內存可能就會積壓其他請求的內存使用量,比如說最重要的搜索請求,分析請求,等等,此時就可能會導致其他請求的性能急速下降

    另外的話,占用內存更多,就會導致java虛擬機的垃圾回收次數更多,跟頻繁,每次要回收的垃圾對象更多,耗費的時間更多,導致es的java虛擬機停止工作線程的時間更多

    

    4、現在的奇特格式

    

    {"action": {"meta"}}\n

    {"data"}\n

    {"action": {"meta"}}\n

    {"data"}\n

    

    (1)不用將其轉換為json對象,不會出現內存中的相同數據的拷貝,直接按照換行符切割json

    (2)對每兩個一組的json,讀取meta,進行document路由

    (3)直接將對應的json發送到node上去

    

    5、最大的優勢在于,不需要將json數組解析為一個JSONArray對象,形成一份大數據的拷貝,浪費內存空間,盡可能地保證性能



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

罗源县| 梨树县| 观塘区| 滨州市| 鱼台县| 大英县| 古丈县| 巨鹿县| 深州市| 教育| 镇平县| 金溪县| 从江县| 泗洪县| 呈贡县| 宁夏| 教育| 莆田市| 汝南县| 荃湾区| 镇坪县| 玛多县| 台中市| 图木舒克市| 五台县| 昔阳县| 正蓝旗| 拜城县| 宾阳县| 隆安县| 宁武县| 满城县| 布尔津县| 鄂州市| 隆德县| 交口县| 重庆市| 林州市| 察雅县| 枣庄市| 临颍县|