shard 和 replica 機制
- 一個 index 包含多個 shard,primary shard 的數(shù)量是在建立 index 的時候就確定的,不可修改,但是 replica 是可隨時修改的
- 新建 index 的時候,primary shard 的默認數(shù)量是 5,replica 默認是 1,默認有 10 個 shard,5 個 primary shard,5 個 replica shard
- 每個 shard 是最小的工作單元,擁有部分的數(shù)據(jù),是一個 Lucene 實例,有建立索引和處理請求的能力
- 當 node 變化的時候,shard 會在 node 上自動進行負載均衡
- replica shard 是 primary shard 的副本,負責容錯,以及承擔讀請求負載
- primary shard 不能和自己的 replica shard 放在同一個節(jié)點上,但是可以和其他 primary shard 的 replica shard 放在同一個節(jié)點上
擴容和容錯性
假設(shè)現(xiàn)在我們有3個node,6個shard,則每個node上分配2個shard,此時最多容忍1臺機器掛了,因為2臺機器有4個shard,能存放下3個primary shard。此時如果我們進行水平擴容,將node變?yōu)?個,則每個node有1個shard,每個shard能使用的IO/CPU/Memory資源更多,性能會更好。
另外假設(shè)我們現(xiàn)在還是3個node,但是將shard變?yōu)?個,則每個node有3個shard,此時雖然每個shard使用的資源少了,但是容錯性提高了,最多能容忍2個node故障,因為剩余的1個node還有3個shard,能包含所有數(shù)據(jù)。
容錯過程分析
- 假設(shè)某個master node掛了,此時es通過選舉選舉中新的master節(jié)點,并將丟失的primary shard對應的replica shard提升為primary shard
- 重啟故障的node,重啟后,新的master node將數(shù)據(jù)復制到該節(jié)點上,原先的primary node變?yōu)閞eplica node,同步是增量同步
創(chuàng)建index注意
index類似于mysql中的database,mysql中會將不同用途的數(shù)據(jù)放到不同的database中,es也一樣,將同類的(fields基本相同)的document放到一起,這樣帶來的好處是不同index不會相互影響,因為不同index的shard是分類的,這就意味著彼此的shard操作不會影響。舉個例子:
假設(shè)我們有一個book_index,存放了所有的書籍信息,供用戶在線檢索,另外還有一個需求是后臺人員對book信息進行一些統(tǒng)計分析操作,由于這些操作都是非常耗時的,因此如果放在同一個index中,勢必會影響線上瀏覽。
文檔id生成
文檔id的生成有兩種方式:自動和手動。
手動的場景適合:假設(shè)數(shù)據(jù)來源是mysql系統(tǒng),里面有自己的唯一id了,此時es只是輔助mysql進行一些檢索操作,此時就用外部系統(tǒng)的id即可
自動:數(shù)據(jù)就是存在于es中,通過es的GUUID算法保證id的唯一,自動生成的id,長度為20個字符,URL安全,base64編碼,GUID,分布式系統(tǒng)并行生成時不可能會發(fā)生沖突
source元字段
source元字段的內(nèi)容是在我們創(chuàng)建一個document的時候,使用的那個放在request body中的json串,默認情況下,在get的時候,會原封不動的給我們返回回來。
在我們查詢的時候,如果帶上_source參數(shù),就可以定制返回的結(jié)果了。
document的替換、刪除操作
1、document的全量替換
(1)語法與創(chuàng)建文檔是一樣的,如果document id不存在,那么就是創(chuàng)建;如果document id已經(jīng)存在,那么就是全量替換操作,替換document的json串內(nèi)容
(2)document是不可變的,如果要修改document的內(nèi)容,第一種方式就是全量替換,直接對document重新建立索引,替換里面所有的內(nèi)容
(3)es會將老的document標記為deleted,然后新增我們給定的一個document,當我們創(chuàng)建越來越多的document的時候,es會在適當?shù)臅r機在后臺自動刪除標記為deleted的document
2、document的強制創(chuàng)建
(1)創(chuàng)建文檔與全量替換的語法是一樣的,有時我們只是想新建文檔,不想替換文檔,如果強制進行創(chuàng)建呢?
(2)PUT /index/type/id?op_type=create,PUT /index/type/id/_create
3、document的刪除
(1)DELETE /index/type/id
(2)不會理解物理刪除,只會將其標記為deleted,當數(shù)據(jù)越來越多的時候,在后臺自動刪除
(3)當我們刪除完一個document后,再次PUT新建的時候,會在原來deleteverion基礎(chǔ)上再加一
version并發(fā)控制
es通過version來進行樂觀鎖控制,語法是通過在參數(shù)version實現(xiàn)
?version=1
?version=1&version_type=external
version_type=external,唯一的區(qū)別在于,_version,只有當你提供的version與es中的_version一模一樣的時候,才可以進行修改,只要不一樣,就報錯;當version_type=external的時候,只有當你提供的version比es中的_version大的時候,才能完成修改
es,_version=1,?version=1,才能更新成功
es,_version=1,?version>1&version_type=external,才能成功,比如說?version=2&version_type=external
partial update
partial update不需要傳遞整個json對象,而是只需要修改的filed,但是在服務(wù)端執(zhí)行partial update的時候,其實和PUT還是一樣的,都是先去讀document,更新字段后,將老的document標記為刪除,然后創(chuàng)建一個新的document,與全量update不同的是將get。modify。update操作放在了服務(wù)端,這樣子減少了網(wǎng)絡(luò)開銷,提高性能。
partial update的時候是在server進行了樂觀鎖控制,1. 取到version 2.修改后更新,我們可以通過指定retry來聲明重復1,2步驟的次數(shù)。