Elasticsearch 是一個(gè)兼有搜索引擎和NoSQL數(shù)據(jù)庫功能的開源系統(tǒng)炕泳,基于Java/Lucene構(gòu)建鹦马,可以用于全文搜索,結(jié)構(gòu)化搜索以及近實(shí)時(shí)分析物赶。可以說Lucene是當(dāng)今最先進(jìn)留晚,最高效的全功能開源搜索引擎框架酵紫。 說明: Lucene:只是一個(gè)框架,要充分利用它的功能错维,需要使用JAVA奖地,并且在程序中集成Lucene,學(xué)習(xí)成本高赋焕,Lucene確實(shí)非常復(fù)雜参歹。 Elasticsearch 是 面向文檔型數(shù)據(jù)庫,這意味著它存儲的是整個(gè)對象或者 文檔隆判,它不但會存儲它們犬庇,還會為他們建立索引僧界,這樣你就可以搜索他們了
應(yīng)用場景
-
站內(nèi)搜索:
主要和 Solr 競爭,屬于后起之秀
-
NoSQL json文檔數(shù)據(jù)庫:
主要搶占 Mongo 的市場臭挽,它在讀寫性能上優(yōu)于 Mongo 捂襟,同時(shí)也支持地理位置查詢,還方便地理位置和文本混合查詢欢峰,屬于歪打正著 (對比測試參見: http://blog.quarkslab.com/mongodb-vs-elasticsearch-the-quest-of-the-holy-performances.html )
-
監(jiān)控:
統(tǒng)計(jì)以及日志類時(shí)間序的數(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項(xiàng)目的開源企業(yè)搜索平臺。其主要功能包括全文檢索支鸡、命中標(biāo)示冬念、分面搜索、動(dòng)態(tài)聚類牧挣、數(shù)據(jù)庫集成急前,以及富文本(如Word、PDF)的處理瀑构。
- Solr是高度可擴(kuò)展的裆针,并提供了分布式搜索和索引復(fù)制。Solr是最流行的企業(yè)級搜索引擎寺晌,Solr4 還增加了NoSQL支持世吨。
- Solr是用Java編寫、運(yùn)行在Servlet容器(如 Apache Tomcat 或Jetty)的一個(gè)獨(dú)立的全文搜索服務(wù)器呻征。 Solr采用了 Lucene Java 搜索庫為核心的全文索引和搜索耘婚,并具有類似REST的HTTP/XML和JSON的API。
- Solr強(qiáng)大的外部配置功能使得無需進(jìn)行Java編碼怕犁,便可對 其進(jìn)行調(diào)整以適應(yīng)多種類型的應(yīng)用程序边篮。Solr有一個(gè)插件架構(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思杯,但在處理實(shí)時(shí)搜索應(yīng)用時(shí)效率明顯低于 Elasticsearch
- Solr 是傳統(tǒng)搜索應(yīng)用的有力解決方案胜蛉,但 Elasticsearch 更適用于新興的實(shí)時(shí)搜索應(yīng)用
核心概念
-
集群(Cluster): 包含一個(gè)或多個(gè)具有相同 cluster.name 的節(jié)點(diǎn).
- 集群內(nèi)節(jié)點(diǎn)協(xié)同工作,共享數(shù)據(jù)色乾,并共同分擔(dān)工作負(fù)荷誊册。
- 由于節(jié)點(diǎn)是從屬集群的,集群會自我重組來均勻地分發(fā)數(shù)據(jù).
- cluster Name是很重要的暖璧,因?yàn)槊總€(gè)節(jié)點(diǎn)只能是群集的一部分案怯,當(dāng)該節(jié)點(diǎn)被設(shè)置為相同的名稱時(shí),就會自動(dòng)加入群集澎办。
- 集群中通過選舉產(chǎn)生一個(gè)mater節(jié)點(diǎn)嘲碱,它將負(fù)責(zé)管理集群范疇的變更,例如創(chuàng)建或刪除索引局蚀,添加節(jié)點(diǎn)到集群或從集群刪除節(jié)點(diǎn)麦锯。master 節(jié)點(diǎn)無需參與文檔層面的變更和搜索,這意味著僅有一個(gè) master 節(jié)點(diǎn)并不會因流量增長而成為瓶頸琅绅。任意一個(gè)節(jié)點(diǎn)都可以成為 master 節(jié)點(diǎn)扶欣。我們例舉的集群只有一個(gè)節(jié)點(diǎn),因此它會扮演 master 節(jié)點(diǎn)的角色千扶。
- 作為用戶料祠,我們可以訪問包括 master 節(jié)點(diǎn)在內(nèi)的集群中的任一節(jié)點(diǎn)。每個(gè)節(jié)點(diǎn)都知道各個(gè)文檔的位置县貌,并能夠?qū)⑽覀兊恼埱笾苯愚D(zhuǎn)發(fā)到擁有我們想要的數(shù)據(jù)的節(jié)點(diǎn)术陶。無論我們訪問的是哪個(gè)節(jié)點(diǎn),它都會控制從擁有數(shù)據(jù)的節(jié)點(diǎn)收集響應(yīng)的過程煤痕,并返回給客戶端最終的結(jié)果梧宫。這一切都是由 Elasticsearch 透明管理的
節(jié)點(diǎn)(node):一個(gè)節(jié)點(diǎn)是一個(gè)邏輯上獨(dú)立的服務(wù),可以存儲數(shù)據(jù)摆碉,并參與集群的索引和搜索功能, 一個(gè)節(jié)點(diǎn)也有唯一的名字塘匣,群集通過節(jié)點(diǎn)名稱進(jìn)行管理和通信.
索引(Index): 索引與關(guān)系型數(shù)據(jù)庫實(shí)例(Database)相當(dāng)。索引只是一個(gè) 邏輯命名空間巷帝,它指向一個(gè)或多個(gè)分片(shards)忌卤,內(nèi)部用Apache Lucene實(shí)現(xiàn)索引中數(shù)據(jù)的讀寫
文檔類型(Type):相當(dāng)于數(shù)據(jù)庫中的table概念。每個(gè)文檔在ElasticSearch中都必須設(shè)定它的類型楞泼。文檔類型使得同一個(gè)索引中在存儲結(jié)構(gòu)不同文檔時(shí)驰徊,只需要依據(jù)文檔類型就可以找到對應(yīng)的參數(shù)映射(Mapping)信息笤闯,方便文檔的存取
-
文檔(Document):相當(dāng)于數(shù)據(jù)庫中的row, 是可以被索引的基本單位棍厂。例如颗味,你可以有一個(gè)的客戶文檔,有一個(gè)產(chǎn)品文檔牺弹,還有一個(gè)訂單的文檔浦马。文檔是以JSON格式存儲的。在一個(gè)索引中张漂,您可以存儲多個(gè)的文檔晶默。請注意,雖然在一個(gè)索引中有多分文檔航攒,但這些文檔的結(jié)構(gòu)是一致的磺陡,并在第一次存儲的時(shí)候指定, 文檔屬于一種 類型(type),各種各樣的類型存在于一個(gè) 索引 中屎债。你也可以通過類比傳統(tǒng)的關(guān)系數(shù)據(jù)庫得到一些大致的相似之處:
關(guān)系數(shù)據(jù)庫 ? 數(shù)據(jù)庫 ? 表 ? 行 ? 列(Columns) Elasticsearch ? 索引 ? 類型 ? 文檔 ? 字段(Fields)
Mapping: 相當(dāng)于數(shù)據(jù)庫中的schema仅政,用來約束字段的類型垢油,不過 Elasticsearch 的 mapping 可以自動(dòng)根據(jù)數(shù)據(jù)創(chuàng)建
-
分片(shard) :是 工作單元(worker unit) 底層的一員盆驹,用來分配集群中的數(shù)據(jù),它只負(fù)責(zé)保存索引中所有數(shù)據(jù)的一小片滩愁。
- 分片是一個(gè)獨(dú)立的Lucene實(shí)例躯喇,并且它自身也是一個(gè)完整的搜索引擎。
- 文檔存儲并且被索引在分片中硝枉,但是我們的程序并不會直接與它們通信廉丽。取而代之,它們直接與索引進(jìn)行通信的
- 把分片想象成一個(gè)數(shù)據(jù)的容器妻味。數(shù)據(jù)被存儲在分片中正压,然后分片又被分配在集群的節(jié)點(diǎn)上。當(dāng)你的集群擴(kuò)展或者縮小時(shí)责球,elasticsearch 會自動(dòng)的在節(jié)點(diǎn)之間遷移分配分片焦履,以便集群保持均衡
- 分片分為 主分片(primary shard) 以及 從分片(replica shard) 兩種。在你的索引中雏逾,每一個(gè)文檔都屬于一個(gè)主分片
- 從分片只是主分片的一個(gè)副本嘉裤,它用于提供數(shù)據(jù)的冗余副本,在硬件故障時(shí)提供數(shù)據(jù)保護(hù)栖博,同時(shí)服務(wù)于 搜索和檢索這種只讀請求
- 索引中的主分片的數(shù)量在索引創(chuàng)建后就固定下來了屑宠,但是從分片的數(shù)量可以隨時(shí)改變。
- 一個(gè)索引默認(rèn)設(shè)置了5個(gè)主分片仇让,每個(gè)主分片有一個(gè)從分片對應(yīng)
ES模塊結(jié)構(gòu)
模塊結(jié)構(gòu)圖如下
-
Gateway: 代表ES的持久化存儲方式典奉,包含索引信息躺翻,ClusterState(集群信息),mapping卫玖,索引碎片信息获枝,以及transaction log等
- 對于分布式集群來說,當(dāng)一個(gè)或多個(gè)節(jié)點(diǎn)down掉了骇笔,能夠保證我們的數(shù)據(jù)不能丟省店,最通用的解放方案就是對失敗節(jié)點(diǎn)的數(shù)據(jù)進(jìn)行復(fù)制,通過控制復(fù)制的份數(shù)可以保證集群有很高的可用性笨触,復(fù)制這個(gè)方案的精髓主要是保證操作的時(shí)候沒有單點(diǎn)懦傍,對一個(gè)節(jié)點(diǎn)的操作會同步到其他的復(fù)制節(jié)點(diǎn)上去。
- ES一個(gè)索引會拆分成多個(gè)碎片芦劣,每個(gè)碎片可以擁有一個(gè)或多個(gè)副本(創(chuàng)建索引的時(shí)候可以配置)粗俱,這里有個(gè)例子,每個(gè)索引分成3個(gè)碎片虚吟,每個(gè)碎片有2個(gè)副本寸认,如下:
$ curl -XPUT http://localhost:9200/twitter/ -d ' index : number_of_shards : 3 number_of_replicas : 2
- 每個(gè)操作會自動(dòng)路由主碎片所在的節(jié)點(diǎn),在上面執(zhí)行操作串慰,并且同步到其他復(fù)制節(jié)點(diǎn)偏塞,通過使用“non blocking IO”模式所有復(fù)制的操作都是并行執(zhí)行的,也就是說如果你的節(jié)點(diǎn)的副本越多邦鲫,你網(wǎng)絡(luò)上的流量消耗也會越大灸叼。復(fù)制節(jié)點(diǎn)同樣接受來自外面的讀操作,意義就是你的復(fù)制節(jié)點(diǎn)越多庆捺,你的索引的可用性就越強(qiáng)古今,對搜索的可伸縮行就更好,能夠承載更多的操作
- 第一次啟動(dòng)的時(shí)候滔以,它會去持久化設(shè)備讀取集群的狀態(tài)信息(創(chuàng)建的索引捉腥,配置等)然后執(zhí)行應(yīng)用它們(創(chuàng)建索引,創(chuàng)建mapping映射等)你画,每一次shard節(jié)點(diǎn)第一次實(shí)例化加入復(fù)制組抵碟,它都會從長持久化存儲里面恢復(fù)它的狀態(tài)信息
-
Discovery
- 節(jié)點(diǎn)啟動(dòng)后先ping(這里的ping是 Elasticsearch 的一個(gè)RPC命令。如果 discovery.zen.ping.unicast.hosts 有設(shè)置撬即,則ping設(shè)置中的host立磁,否則嘗試ping localhost 的幾個(gè)端口, Elasticsearch 支持同一個(gè)主機(jī)啟動(dòng)多個(gè)節(jié)點(diǎn))
- Ping的response會包含該節(jié)點(diǎn)的基本信息以及該節(jié)點(diǎn)認(rèn)為的master節(jié)點(diǎn)
- 選舉開始剥槐,先從各節(jié)點(diǎn)認(rèn)為的master中選唱歧,規(guī)則很簡單,按照id的字典序排序,取第一個(gè)
- 如果各節(jié)點(diǎn)都沒有認(rèn)為的master颅崩,則從所有節(jié)點(diǎn)中選擇几于,規(guī)則同上。這里有個(gè)限制條件就是 discovery.zen.minimum_master_nodes沿后,如果節(jié)點(diǎn)數(shù)達(dá)不到最小值的限制沿彭,則循環(huán)上述過程,直到節(jié)點(diǎn)數(shù)足夠可以開始選舉
- 最后選舉結(jié)果是肯定能選舉出一個(gè)master尖滚,如果只有一個(gè)local節(jié)點(diǎn)那就選出的是自己
- 如果當(dāng)前節(jié)點(diǎn)是master喉刘,則開始等待節(jié)點(diǎn)數(shù)達(dá)到 minimum_master_nodes,然后提供服務(wù), 如果當(dāng)前節(jié)點(diǎn)不是master漆弄,則嘗試加入master.
- ES支持任意數(shù)目的集群(1-N),所以不能像 Zookeeper/Etcd 那樣限制節(jié)點(diǎn)必須是奇數(shù)睦裳,也就無法用投票的機(jī)制來選主,而是通過一個(gè)規(guī)則撼唾,只要所有的節(jié)點(diǎn)都遵循同樣的規(guī)則廉邑,得到的信息都是對等的,選出來的主節(jié)點(diǎn)肯定是一致的. 但分布式系統(tǒng)的問題就出在信息不對等的情況倒谷,這時(shí)候很容易出現(xiàn)腦裂(Split-Brain)的問題蛛蒙,大多數(shù)解決方案就是設(shè)置一個(gè)quorum值,要求可用節(jié)點(diǎn)必須大于quorum(一般是超過半數(shù)節(jié)點(diǎn))渤愁,才能對外提供服務(wù)牵祟。而 Elasticsearch 中,這個(gè)quorum的配置就是 discovery.zen.minimum_master_nodes 猴伶。
-
memcached
- 通過memecached協(xié)議來訪問ES的接口,支持二進(jìn)制和文本兩種協(xié)議.通過一個(gè)名為transport-memcached插件提供
- Memcached命令會被映射到REST接口课舍,并且會被同樣的REST層處理汁果,memcached命令列表包括:get/set/delete/quit
River : 代表es的一個(gè)數(shù)據(jù)源污秆,也是其它存儲方式(如:數(shù)據(jù)庫)同步數(shù)據(jù)到es的一個(gè)方法牺陶。它是以插件方式存在的一個(gè)es服務(wù),通過讀取river中的數(shù)據(jù)并把它索引到es中办桨,官方的river有couchDB的,RabbitMQ的站辉,Twitter的呢撞,Wikipedia的,river這個(gè)功能將會在后面的文件中重點(diǎn)說到