Cluster(叢集)
Elasticsearch 叢集由一個或多個節點組成,可通過其叢集名稱進行標識。在預設的情況下,如我們的 Elasticsearch已經開始執行,那麼它會自動生成一個叫做 “Elasticsearch” 的叢集。當然我們可以在 config/elasticsearch.yml 裡定製我們的叢集的名字:
[root@cb71f81b72b7 config]# cat elasticsearch.yml
cluster.name: "docker-cluster"
network.host: 0.0.0.0
[root@cb71f81b72b7 config]#
一個 Elasticsearch 的叢集就像是下面的一個佈局:
帶有 NginX 代理及 Balancer 的架構圖是這樣的:
我們可以通過:
GET _cluster/state
來獲取整個 cluster 的狀態。這個狀態只能被 master node 所改變。上面的介面 返回的結果是:
{
"cluster_name" : "docker-cluster",
"cluster_uuid" : "Lmv7APZ4QemXB88AGZZfcA",
"version" : 163,
"state_uuid" : "7nh2_aWaT9aJHiVaOo5UjQ",
"master_node" : "bhsEXqpaT7K2PEmXSYlbsg",
"blocks" : { },
"nodes" : {...},
"metadata" : {...},
"routing_table" : {...},
"routing_nodes" : {...}
}
Node(節點)
節點就是單個 Elasticsearch 例項。在大多數環境中,每個節點都在單獨的盒子或虛擬機器上執行。一個叢集由一個或多 個 node 組成。在測試的環境中,我可以把多個 node 執行在一個 server 上。在實際 的部署中,大多數情況還是需要一個 server 上執行一個 node。
節點分類:
- master-eligible:可以作為主node。一旦成為主node,它可以管理整個 cluster 的設定及變化:建立,更新,刪除 index;新增或刪除 node;為 node 分配 shard
- data:資料 node
- ingest: 資料接入(比如 pipepline)
- machine learning (Gold/Platinum License)
一般來說,一個 node 可以具有上面的一種或幾種功能。我們可以在命令列或者 Elasticsearch 的配置檔案(Elasticsearch.yml)來定義:
Node型別 | 配置引數 | 預設值 |
---|---|---|
master-eligible | Node.master | True |
data | Node.data | True |
ingest | Node.ingest | True |
machine learning | Node.ml | true (除了 OSS 釋出版) |
你也可以讓一個 node 做專有的功能及角色。如果上面 node 配置引數沒有任何 配置,那麼我們可以認為這個 node 是作為一個 coordination node。在這種情況下。
它可以接受外部的請求,並轉發到相應的節點來處理。針對 master node,有時我們需 要設定 cluster.remote.connect: false。
在實際的使用中,我們可以把請求傳送給 data 節點,而不能傳送給 master 節點。我們可以通過對 config/elasticsearch.yml 檔案中配置來定義一個 node 在叢集 中的角色:
在有些情況中,我們可以通過設定 node.voting_only 為 true 從而使得一個 node 在 node.master 為真的情況下,只作為參加 voting 的功能,而不當選為 master node。這種情況為了避免腦裂情況發生。它通常可以使用一個 CPU 效能較低的 node 來擔當。
我們可以使用如下的一個命令來獲取當前可以進行 vote 的所有 master-eligible 節點:
GET /_cluster/state?filter_path=metadata.cluster_coordination.last_committed_config
得類似如下列表的結果:
{
"metadata" : {
"cluster_coordination" : {
"last_committed_config" : [
"bhsEXqpaT7K2PEmXSYlbsg",
"chsEXqpaT7K2PEmXSYlbsg",
"dhsEXqpaT7K2PEmXSYlbsg"
]
}
}
}
在整個 Elastic 的架構中,Data Node 和 Cluster 的關係表述如下:
Document(文件)
Elasticsearch 是面向文件的,這意味著你索引或搜尋的最小資料單元是文件。
文件在 Elasticsearch 中有一些重要的屬性:
獨立的:
文件包含欄位(名稱)及其值。
可以是分層的:
可以將其視為文件中的文件,它還可以包含其他欄位和值。
結構靈活
文件不依賴於預定義的架構。
Document 相比較於關聯式資料庫,它相應於其中每個 record。
Type(型別)
型別是文件的邏輯容器,類似於表是行的容器。
你將具有不同結構(模式)的文件放在不同型別中。 例如,你可以使用一種型別來 定義聚合組,並在人們聚集時為事件定義另一種型別。
在 Elasticsearch 中,我們開始可以不定義一個 mapping,而直接寫入到我們指定 的 index 中。這個 index 的 mapping 是動態生成的 (當然我們也可以禁止這種行 為)。其中的資料項的每一個資料型別是動態識別的。比如時間,字串等,雖然有些 資料型別,還是需要我們手動調整,比如 geo_point 等地理位置資料。
Index(索引)
在 Elasticsearch 中,索引是文件的集合。
每個 Index 由一個或多個 documents 組成,並且這些 document 可以分佈於不 同的 shard 之中。
很多人認為 index 類似於關聯式資料庫中的 database。這中說法是有些道理,但是 並不完全相同。其中很重要的一個原因是,在 Elasticsearch 中的文件可以有 object 及 nested 結構。一個 index 是一個邏輯名稱空間,它對映到一個或多個主分片,並且可 以具有零個或多個副本分片。
每當一個文件進來後,根據文件的 id 會自動進行 hash 計算,並存放於計算出來 的 shard 例項中,這樣的結果可以使得所有的 shard 都比較有均衡的儲存,而不至於 有的 shard 很忙。
shard_num = hash(_routing) % num_primary_shards
上面的公式我們也可以看出來,我們的 shard 數目是不可以動態修改的,否則之 後也找不到相應的 shard 號碼了。必須指出的是,replica 的數目是可以動態修改的。
Shard
Elasticsearch 是一個分散式搜尋引擎,因此索引通常會拆分為分佈在多個節 點上的稱為分片的元素。 Elasticsearch 自動管理這些分片的排列。 它還根據需要重新 平衡分片,因此使用者無需擔心細節。
由於分片的作用,一個索引可以儲存單個節點硬體限制的大量資料。比如一個具備20億,大小為2TB的磁碟空間,而任一節點都沒有這樣大的磁碟空間;或者單個節點處理 搜尋請求,響應太慢。為了解決這個問題,Elasticsearch 提供了將索引劃分成多份的能力,這些份就叫做 分片(shard)。當你建立一個索引的時候,你可以指定你想要的分片 (shard) 的數量。 每個分片本身也是一個功能完善並且獨立的“索引”,這個“索引”可以被放置到叢集 中的任何節點上。
分片作用:
- 允許你水平分割/擴充套件你的內容容量。
允許你在分片(潛在地,位於多個節點上)之上進行分散式的、並行的操作,進而 提高效能/吞吐量。
分片種類:
Primary shard
每個文件都儲存在一個 Primary shard。 索引文件時,它首先在 Primary shard 上編制索引,然後在此分片的所有副本上(replica)編制索引。索 引可以包含一個或多個主分片。 此數字確定索引相對於索引資料大小的可伸縮性。 建立索引後,無法更改索引中的主分片數。
Replica shard
每個主分片可以具有零個或多個副本。 副本是主分片的副本,有兩 個目的:
增加故障轉移:如果主分片故障,可以將副本分片提升為主分片。
提高效能:get 和 search 請求可以由主 shard 或副本 shard 處理。
預設情況下,每個主分片都有一個副本,但可以在現有索引上動態更改副本數。 永遠不會在與其主分片相同的節點上啟動副本分片。
如一個索引:index 有 5 個 shard 及 1 個 replica的情況如下:
這些 Shard 分佈於不同的物理機器上:
可以為每個 Index 設定相應的 Shard 數值:
curl -XPUT http://localhost:9200/wechat?pretty -H 'Content-Type: application/json' - d ' { "settings" : { "index.number_of_shards" : 2, "index.number_of_replicas" : 1
}
}
上面的 REST 介面中,我們為 wechat 這個 index 設定了 2 個 shards,並且有一個 replica。一旦設定好 primary shard 的數量,我們就不可以修改 了。這是因為 Elasticsearch 會依據每個 document 的 id 及 primary shard的數量來把相應的document 分配到相應的shard中。如果這個數量以後修改的話,那麼每 次搜尋的時候,可能會找不到相應的 shard。
我們可以通過如下的介面來檢視我們的 index 中的設定:
curl -XGET http://localhost:9200/wechat/_settings?pretty
Replica(副本)
預設情況下,Elasticsearch 為每個索引建立一個主分片和一個副本。這意味著每個 索引將包含一個主分片,每個分片將具有一個副本。
分配多個分片和副本是分散式搜尋功能設計的本質,提供高可用性和快速訪問索引中的文件。主分片和副本分片之間的主要區別在於,只有主分片可以接受索引請求。副本和主分片都可以提供查詢請求。
注意:number_of_shards 值與索引有關,而與整個叢集無關。此值指定每個索引的分片數(不是叢集中的主分片總數)。
通過如下的介面來獲得一個index的健康情況:
http://localhost:9200/_cat/indices/twitter
更進一步的查詢,我們可以看出:
如果一個 index 顯示的是紅色,表面這個 index 至少有一個 primary shard 沒有 被正確分配,並且有的 shard 及其相應的 replica 已經不能正常訪問。 如果是綠色, 表明 index 的每一個 shard 都有備份 (replica),並且其備份也成功複製在相應的 replica shard 之中。如果其中的一個 node 壞了,相應的另外一個 node 的 replica 將起作用,從而不會造成資料的丟失。
shard 健康
- 紅色:叢集中未分配至少一個主分片 。
- 黃色:已分配所有主副本,但未分配至少一個副本 。
- 綠色:分配所有分片。