Elasticsearch 是一個兼有搜索引擎和NoSQL數(shù)據(jù)庫功能的開源系統(tǒng),基于Java/Lucene構(gòu)建,可以用于全文搜索,結(jié)構(gòu)化搜索以及近實時分析??梢哉fLucene是當(dāng)今最先進(jìn),最高效的全功能開源搜索引擎框架。 說明: Lucene:只是一個框架,要充分利用它的功能,需要使用JAVA,并且在程序中集成Lucene,學(xué)習(xí)成本高,Lucene確實非常復(fù)雜。 Elasticsearch 是 面向文檔型數(shù)據(jù)庫,這意味著它存儲的是整個對象或者 文檔,它不但會存儲它們,還會為他們建立索引,這樣你就可以搜索他們了
應(yīng)用場景
-
站內(nèi)搜索:
主要和 Solr 競爭,屬于后起之秀
-
NoSQL json文檔數(shù)據(jù)庫:
主要搶占 Mongo 的市場,它在讀寫性能上優(yōu)于 Mongo ,同時也支持地理位置查詢,還方便地理位置和文本混合查詢,屬于歪打正著 (對比測試參見: http://blog.quarkslab.com/mongodb-vs-elasticsearch-the-quest-of-the-holy-performances.html )
-
監(jiān)控:
統(tǒng)計以及日志類時間序的數(shù)據(jù)的存儲和分析以及可視化,這方面是引領(lǐng)者
-
國外:Wikipedia使用 ES 提供全文搜索并高亮關(guān)鍵字、StackOverflow結(jié)合全文搜索與地理位置查詢、
Github使用Elasticsearch檢索1300億行的代碼
-
國內(nèi):
百度(在casio、云分析、網(wǎng)盟、預(yù)測、文庫、直達(dá)號、錢包、風(fēng)控等業(yè)務(wù)上都應(yīng)用了ES,單集群每天導(dǎo)入30TB+數(shù)據(jù),總共每天60TB+)、新浪 **,阿里巴巴、騰訊等公司均有對ES的使用
使用比較廣泛的平臺ELK(ElasticSearch, Logstash, Kibana)
solr VS ES
- Solr是Apache Lucene項目的開源企業(yè)搜索平臺。其主要功能包括全文檢索、命中標(biāo)示、分面搜索、動態(tài)聚類、數(shù)據(jù)庫集成,以及富文本(如Word、PDF)的處理。
- Solr是高度可擴展的,并提供了分布式搜索和索引復(fù)制。Solr是最流行的企業(yè)級搜索引擎,Solr4 還增加了NoSQL支持。
- Solr是用Java編寫、運行在Servlet容器(如 Apache Tomcat 或Jetty)的一個獨立的全文搜索服務(wù)器。 Solr采用了 Lucene Java 搜索庫為核心的全文索引和搜索,并具有類似REST的HTTP/XML和JSON的API。
- Solr強大的外部配置功能使得無需進(jìn)行Java編碼,便可對 其進(jìn)行調(diào)整以適應(yīng)多種類型的應(yīng)用程序。Solr有一個插件架構(gòu),以支持更多的高級定制
- Elasticsearch 與 Solr 的比較總結(jié)
- 二者安裝都很簡單
- Solr 利用 Zookeeper 進(jìn)行分布式管理,而 Elasticsearch 自身帶有分布式協(xié)調(diào)管理功能
- Solr 支持更多格式的數(shù)據(jù),而 Elasticsearch 僅支持json文件格式
- Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高級功能多有第三方插件提供
- Solr 在傳統(tǒng)的搜索應(yīng)用中表現(xiàn)好于 Elasticsearch,但在處理實時搜索應(yīng)用時效率明顯低于 Elasticsearch
- Solr 是傳統(tǒng)搜索應(yīng)用的有力解決方案,但 Elasticsearch 更適用于新興的實時搜索應(yīng)用
核心概念
-
集群(Cluster): 包含一個或多個具有相同 cluster.name 的節(jié)點.
- 集群內(nèi)節(jié)點協(xié)同工作,共享數(shù)據(jù),并共同分擔(dān)工作負(fù)荷。
- 由于節(jié)點是從屬集群的,集群會自我重組來均勻地分發(fā)數(shù)據(jù).
- cluster Name是很重要的,因為每個節(jié)點只能是群集的一部分,當(dāng)該節(jié)點被設(shè)置為相同的名稱時,就會自動加入群集。
- 集群中通過選舉產(chǎn)生一個mater節(jié)點,它將負(fù)責(zé)管理集群范疇的變更,例如創(chuàng)建或刪除索引,添加節(jié)點到集群或從集群刪除節(jié)點。master 節(jié)點無需參與文檔層面的變更和搜索,這意味著僅有一個 master 節(jié)點并不會因流量增長而成為瓶頸。任意一個節(jié)點都可以成為 master 節(jié)點。我們例舉的集群只有一個節(jié)點,因此它會扮演 master 節(jié)點的角色。
- 作為用戶,我們可以訪問包括 master 節(jié)點在內(nèi)的集群中的任一節(jié)點。每個節(jié)點都知道各個文檔的位置,并能夠?qū)⑽覀兊恼埱笾苯愚D(zhuǎn)發(fā)到擁有我們想要的數(shù)據(jù)的節(jié)點。無論我們訪問的是哪個節(jié)點,它都會控制從擁有數(shù)據(jù)的節(jié)點收集響應(yīng)的過程,并返回給客戶端最終的結(jié)果。這一切都是由 Elasticsearch 透明管理的
節(jié)點(node):一個節(jié)點是一個邏輯上獨立的服務(wù),可以存儲數(shù)據(jù),并參與集群的索引和搜索功能, 一個節(jié)點也有唯一的名字,群集通過節(jié)點名稱進(jìn)行管理和通信.
索引(Index): 索引與關(guān)系型數(shù)據(jù)庫實例(Database)相當(dāng)。索引只是一個 邏輯命名空間,它指向一個或多個分片(shards),內(nèi)部用Apache Lucene實現(xiàn)索引中數(shù)據(jù)的讀寫
文檔類型(Type):相當(dāng)于數(shù)據(jù)庫中的table概念。每個文檔在ElasticSearch中都必須設(shè)定它的類型。文檔類型使得同一個索引中在存儲結(jié)構(gòu)不同文檔時,只需要依據(jù)文檔類型就可以找到對應(yīng)的參數(shù)映射(Mapping)信息,方便文檔的存取
-
文檔(Document):相當(dāng)于數(shù)據(jù)庫中的row, 是可以被索引的基本單位。例如,你可以有一個的客戶文檔,有一個產(chǎn)品文檔,還有一個訂單的文檔。文檔是以JSON格式存儲的。在一個索引中,您可以存儲多個的文檔。請注意,雖然在一個索引中有多分文檔,但這些文檔的結(jié)構(gòu)是一致的,并在第一次存儲的時候指定, 文檔屬于一種 類型(type),各種各樣的類型存在于一個 索引 中。你也可以通過類比傳統(tǒng)的關(guān)系數(shù)據(jù)庫得到一些大致的相似之處:
關(guān)系數(shù)據(jù)庫 ? 數(shù)據(jù)庫 ? 表 ? 行 ? 列(Columns) Elasticsearch ? 索引 ? 類型 ? 文檔 ? 字段(Fields) Mapping: 相當(dāng)于數(shù)據(jù)庫中的schema,用來約束字段的類型,不過 Elasticsearch 的 mapping 可以自動根據(jù)數(shù)據(jù)創(chuàng)建
-
分片(shard) :是 工作單元(worker unit) 底層的一員,用來分配集群中的數(shù)據(jù),它只負(fù)責(zé)保存索引中所有數(shù)據(jù)的一小片。
- 分片是一個獨立的Lucene實例,并且它自身也是一個完整的搜索引擎。
- 文檔存儲并且被索引在分片中,但是我們的程序并不會直接與它們通信。取而代之,它們直接與索引進(jìn)行通信的
- 把分片想象成一個數(shù)據(jù)的容器。數(shù)據(jù)被存儲在分片中,然后分片又被分配在集群的節(jié)點上。當(dāng)你的集群擴展或者縮小時,elasticsearch 會自動的在節(jié)點之間遷移分配分片,以便集群保持均衡
- 分片分為 主分片(primary shard) 以及 從分片(replica shard) 兩種。在你的索引中,每一個文檔都屬于一個主分片
- 從分片只是主分片的一個副本,它用于提供數(shù)據(jù)的冗余副本,在硬件故障時提供數(shù)據(jù)保護(hù),同時服務(wù)于 搜索和檢索這種只讀請求
- 索引中的主分片的數(shù)量在索引創(chuàng)建后就固定下來了,但是從分片的數(shù)量可以隨時改變。
- 一個索引默認(rèn)設(shè)置了5個主分片,每個主分片有一個從分片對應(yīng)
ES模塊結(jié)構(gòu)
模塊結(jié)構(gòu)圖如下
-
Gateway: 代表ES的持久化存儲方式,包含索引信息,ClusterState(集群信息),mapping,索引碎片信息,以及transaction log等
- 對于分布式集群來說,當(dāng)一個或多個節(jié)點down掉了,能夠保證我們的數(shù)據(jù)不能丟,最通用的解放方案就是對失敗節(jié)點的數(shù)據(jù)進(jìn)行復(fù)制,通過控制復(fù)制的份數(shù)可以保證集群有很高的可用性,復(fù)制這個方案的精髓主要是保證操作的時候沒有單點,對一個節(jié)點的操作會同步到其他的復(fù)制節(jié)點上去。
- ES一個索引會拆分成多個碎片,每個碎片可以擁有一個或多個副本(創(chuàng)建索引的時候可以配置),這里有個例子,每個索引分成3個碎片,每個碎片有2個副本,如下:
$ curl -XPUT http://localhost:9200/twitter/ -d ' index : number_of_shards : 3 number_of_replicas : 2- 每個操作會自動路由主碎片所在的節(jié)點,在上面執(zhí)行操作,并且同步到其他復(fù)制節(jié)點,通過使用“non blocking IO”模式所有復(fù)制的操作都是并行執(zhí)行的,也就是說如果你的節(jié)點的副本越多,你網(wǎng)絡(luò)上的流量消耗也會越大。復(fù)制節(jié)點同樣接受來自外面的讀操作,意義就是你的復(fù)制節(jié)點越多,你的索引的可用性就越強,對搜索的可伸縮行就更好,能夠承載更多的操作
- 第一次啟動的時候,它會去持久化設(shè)備讀取集群的狀態(tài)信息(創(chuàng)建的索引,配置等)然后執(zhí)行應(yīng)用它們(創(chuàng)建索引,創(chuàng)建mapping映射等),每一次shard節(jié)點第一次實例化加入復(fù)制組,它都會從長持久化存儲里面恢復(fù)它的狀態(tài)信息
-
Discovery
- 節(jié)點啟動后先ping(這里的ping是 Elasticsearch 的一個RPC命令。如果 discovery.zen.ping.unicast.hosts 有設(shè)置,則ping設(shè)置中的host,否則嘗試ping localhost 的幾個端口, Elasticsearch 支持同一個主機啟動多個節(jié)點)
- Ping的response會包含該節(jié)點的基本信息以及該節(jié)點認(rèn)為的master節(jié)點
- 選舉開始,先從各節(jié)點認(rèn)為的master中選,規(guī)則很簡單,按照id的字典序排序,取第一個
- 如果各節(jié)點都沒有認(rèn)為的master,則從所有節(jié)點中選擇,規(guī)則同上。這里有個限制條件就是 discovery.zen.minimum_master_nodes,如果節(jié)點數(shù)達(dá)不到最小值的限制,則循環(huán)上述過程,直到節(jié)點數(shù)足夠可以開始選舉
- 最后選舉結(jié)果是肯定能選舉出一個master,如果只有一個local節(jié)點那就選出的是自己
- 如果當(dāng)前節(jié)點是master,則開始等待節(jié)點數(shù)達(dá)到 minimum_master_nodes,然后提供服務(wù), 如果當(dāng)前節(jié)點不是master,則嘗試加入master.
- ES支持任意數(shù)目的集群(1-N),所以不能像 Zookeeper/Etcd 那樣限制節(jié)點必須是奇數(shù),也就無法用投票的機制來選主,而是通過一個規(guī)則,只要所有的節(jié)點都遵循同樣的規(guī)則,得到的信息都是對等的,選出來的主節(jié)點肯定是一致的. 但分布式系統(tǒng)的問題就出在信息不對等的情況,這時候很容易出現(xiàn)腦裂(Split-Brain)的問題,大多數(shù)解決方案就是設(shè)置一個quorum值,要求可用節(jié)點必須大于quorum(一般是超過半數(shù)節(jié)點),才能對外提供服務(wù)。而 Elasticsearch 中,這個quorum的配置就是 discovery.zen.minimum_master_nodes 。
-
memcached
- 通過memecached協(xié)議來訪問ES的接口,支持二進(jìn)制和文本兩種協(xié)議.通過一個名為transport-memcached插件提供
- Memcached命令會被映射到REST接口,并且會被同樣的REST層處理,memcached命令列表包括:get/set/delete/quit
River : 代表es的一個數(shù)據(jù)源,也是其它存儲方式(如:數(shù)據(jù)庫)同步數(shù)據(jù)到es的一個方法。它是以插件方式存在的一個es服務(wù),通過讀取river中的數(shù)據(jù)并把它索引到es中,官方的river有couchDB的,RabbitMQ的,Twitter的,Wikipedia的,river這個功能將會在后面的文件中重點說到