關於分布式架構
首先將ES默認每個索引是5個分片,這樣做得目的是兩個一個索引的時候速度更快(將數據寫到小分片的尾部比寫入大分片尾部更加快);另外一個是當數據量達到一定程度之后,分片查詢,在匯總(scater-gathter)這種模式更加簡單一些。
ES的分片奠定了ES在分布式存儲的地位,也意味着ES天生就是多節點部署的,節點數=分片數*(副本數 + 1)。這里有個問題,到底是多分片還是多索引,還是多索引優於多分片;但是差別都不大,為什么這么說,你要明白每個分片本質上是Lucene的一個索引,這個才是真正的索引計算單元;所以在ES里面的索引其實是對於分布式Lucene里面的索引的一個封裝,或者說是master;關於查詢套路,索引可以通過名稱定位,分片可以通過路由定位;
ES為了保證持續提供服務,提供了副本(replica)機制,就是數據的部分,副本是基於分片的,一旦主分片掛了,那么會自動切換到副本進行查詢。但是缺點就是占用空間,尤其對於海量數據而言,硬盤壓力會比較大,所以副本數需要考慮。默認是1副本。
路由查詢策略
剛才在比較分片和索引的時候,提到了多分片場景下可以指定路由來進行地位,避免向所有分片下發查詢,導致查詢速度下降。使用路由的套路是這樣的,首先在創建索引的時候就要指定路由,像下面這樣:
curl -XPUT localhost:9200/books/doc/1?routing=A -d '{ "title" : "Document"}'
在創建的時候,就記錄了路由器為A,此時在索引完成后,將會在路由表(Route Table)中記錄一條路由名稱"A"所指向的分片。之后,在你進行查詢的時候也要指定同名路由即可定位到指定的分片進行查詢:
curl -XGET 'localhost:9200/documents/_search?pretty&q=*&routing=A'
這樣查詢首先會去路由表中查詢路由A對應的分片,然后再去對應的分片中進行查詢。
那么現在有一個問題:如果分片大小滿了怎么辦,如果ES的機制自動進行存儲的平衡,我們再次通過路由A查找數據,但是此時數據已經分配到別的機器上面怎么辦?這個問題還有待研究。
我們知道分片是Lucene的一個索引,路由定位也是分片級別,但是一個分片其實是可以對應多個路由信息,所以不能依賴於分片而放棄查詢條件,這個還是要有的。這樣,我們在一次查詢中可以指定多個路由進行查詢(如下所示),但是,索引的時候只能指定一個路由。
curl -XGET 'localhost:9200/documents/_search?routing=A,B'
分配意識
那么下面介紹一下ES里面的分片的自動優化部署的特性:分配意識(Allocation Awareness);簡單地講,就是ES將會自動將主分片和副本分布到兩台不同的機器,避免要掛一起掛的場景。
自動部署里面有很多配置,就不多說了,這里要明白的是ES里面的部署機制,其實這些配置都是默認,從理解ES的角度來講是有價值,但是從操作層面來講大多數時候不需要關注。
(分布式)查詢偏好策略
最后說一下查詢偏好,通過設置查詢偏好,可以指定分布式查詢的模式,或者優先策略:
_primary:只在主節點查;
_primary_firest:只有主節點掛了,再查副本;
_local:優先本地查;
_only_node:XXX:指定節點查詢;
_prefer_node:XXX:優先指定節點查詢;
_shard:0,1,2:指定分片查詢。