Elasticsearch的由來
思考:大規模數據如何檢索?
如:當系統數據量上了10億、100億條的時候,我們在做系統架構的時候通常會從以下角度去考慮問題:
1)用什么數據庫好?(mysql、sybase、oracle、達夢、神通、mongodb、hbase…)
2)如何解決單點故障;(lvs、F5、A10、Zookeep、MQ)
3)如何保證數據安全性;(熱備、冷備、異地多活)
4)如何解決檢索難題;(數據庫代理中間件:mysql-proxy、Cobar、MaxScale等;)
5)如何解決統計分析問題;(離線、近實時)
傳統數據庫的應對解決方案
解決要點:
1)通過主從備份解決數據安全性問題;
2)通過數據庫代理中間件心跳監測,解決單點故障問題;
3)通過代理中間件將查詢語句分發到各個slave節點進行查詢,并匯總結果
非關系型數據庫的解決方案
對于Nosql數據庫,以mongodb為例,其它原理類似:
解決要點:
1)通過副本備份保證數據安全性;
2)通過節點競選機制解決單點問題;
3)先從配置庫檢索分片信息,然后將請求分發到各個節點,最后由路由節點合并匯總結果
ES定義
ES=elaticsearch簡寫, Elasticsearch是一個開源的高擴展的分布式全文檢索引擎,它可以近乎實時的存儲、檢索數據;本身擴展性很好,可以擴展到上百臺服務器,處理PB級別的數據。
Elasticsearch也使用Java開發并使用Lucene作為其核心來實現所有索引和搜索的功能,但是它的目的是通過簡單的RESTful API來隱藏Lucene的復雜性,從而讓全文搜索變得簡單。
ES主要解決問題:
1)檢索相關數據;
2)返回統計結果;
3)速度要快。
ES核心概念
1)Cluster:集群。
ES可以作為一個獨立的單個搜索服務器。不過,為了處理大型數據集,實現容錯和高可用性,ES可以運行在許多互相合作的服務器上。這些服務器的集合稱為集群。
2)Node:節點。
形成集群的每個服務器稱為節點。
3)Shard:分片。
當有大量的文檔時,由于內存的限制、磁盤處理能力不足、無法足夠快的響應客戶端的請求等,一個節點可能不夠。這種情況下,數據可以分為較小的分片。每個分片放到不同的服務器上。
當你查詢的索引分布在多個分片上時,ES會把查詢發送給每個相關的分片,并將結果組合在一起,而應用程序并不知道分片的存在。即:這個過程對用戶來說是透明的。
4)Replia:副本。
為提高查詢吞吐量或實現高可用性,可以使用分片副本。
副本是一個分片的精確復制,每個分片可以有零個或多個副本。ES中可以有許多相同的分片,其中之一被選擇更改索引操作,這種特殊的分片稱為主分片。
當主分片丟失時,如:該分片所在的數據不可用時,集群將副本提升為新的主分片。
5)全文檢索。
全文檢索就是對一篇文章進行索引,可以根據關鍵字搜索,類似于mysql里的like語句。
全文索引就是把內容根據詞的意義進行分詞,然后分別創建索引,例如”你們的激情是因為什么事情來的” 可能會被分詞成:“你們“,”激情“,“什么事情“,”來“ 等token,這樣當你搜索“你們” 或者 “激情” 都會把這句搜出來。
ES數據架構的主要概念(與關系數據庫Mysql對比)
(1)關系型數據庫中的數據庫(DataBase),等價于ES中的索引(Index)
(2)一個數據庫下面有N張表(Table),等價于1個索引Index下面有N多類型(Type),
(3)一個數據庫表(Table)下的數據由多行(ROW)多列(column,屬性)組成,等價于1個Type由多個文檔(Document)和多Field組成。
(4)在一個關系型數據庫里面,schema定義了表、每個表的字段,還有表和字段之間的關系。 與之對應的,在ES中:Mapping定義索引下的Type的字段處理規則,即索引如何建立、索引類型、是否保存原始索引JSON文檔、是否壓縮原始JSON文檔、是否需要分詞處理、如何進行分詞處理等。
(5)在數據庫中的增insert、刪delete、改update、查search操作等價于ES中的增PUT/POST、刪Delete、改_update、查GET.
Elasticsearch與關系數據的類比對應關系如下:
Relational DB ? Databases ? Tables ? Rows ? Columns
Elasticsearch ? Indices ? Types ? Documents ? Fields
實例:新浪是如何分析處理32億條實時日志的
http://dockone.io/article/505
什么是一個Shard?
Shard就是一個Lucene Index
Index需要多少個Shard?
Shard數 = Node數?
總體上說,當我們節點數和Shard數相等時,ElasticSearch集群的性能可以達到最優。即,對于一個3節點集群,我們為每個集群節點分配一個Shard,總共3個Shard。但是由于ElasticSearch的不可變性(Immutable)的限制,系統無法對Shard進行重新拆分分配,除非重新索引這個文件集合。所以,當我們需要增加更多節點的時候,又希望Shard能利用到增加節點帶來的系統性能提升時,我們就不得不進行重新索引,由于重索引開銷巨大,這是我們不希望看到的。
如果需要重新建立索引,將會是一個巨大的開銷,為了支持未來可能的水平擴展,我們會為集群分配比node數更多的shard數,也就是說每個節點會有多個Shard。
如果單個node分配多個shard,就會引入另外一系列的性能問題,我們知道對于任意一次完整的搜索,ElasticSearch會分別對每個shard進行查詢,最后進行匯總。當節點數和shard數是一對一的時候,所有的查詢可以并行運行。但是,對于具有多個shard的節點,如果磁盤是15000RPM或SSD,可能會相對較快,但是這也會存在等待響應的問題,所以通常不推薦一個節點超過2個shard。
3節點6shard,即每個節點2shard,這可以使我們在未來輕松的橫向擴展到6個節點,應對許多極端的場景。
Replicas數呢?
Replica也是Shard,與shard不同的是,replica只會參與讀操作,同時也能提高集群的可用性。對于Replica來說,它的主要作用就是提高集群錯誤恢復的能力,所以replica的數目與shard的數目以及node的數目相關,與shard不同的是,replica的數目可以在集群建立之后變更,切代價較小,所以相比shard的數目而言,沒有那么重要。
例子:
3 node, 3 shard, 1 replica (each)
一個節點宕機