把ElasticSearch當(dāng)成是NoSQL數(shù)據(jù)庫
Elasticsearch 可以被當(dāng)成一個 "NoSQL"-數(shù)據(jù)庫來使用么? NoSQL 意味著在不同的環(huán)境下存在不同的東西, 而erestingly 它并不是真的跟 SQL 有啥關(guān)系. 我們開始只會覺得 "可能"而已, 所以細(xì)細(xì)研究了 Elasticsearch 的各種屬性,包括它已經(jīng)為了成就最具靈活性,可伸縮性和性能優(yōu)異的分析查詢引擎的那些屬性。
NoSQL 數(shù)據(jù)庫是什么?
NoSQL-數(shù)據(jù)庫 將 NoSQL 定義為“下一代主要解決如下問題的數(shù)據(jù)庫: 非關(guān)系型的,分布式的,開元的并且可以扁平擴展.”. 換言之,它并不是一個精確的定義.
它尤其與SQL無關(guān). 比方說, Hive 查詢語言的靈感顯然來自 SQL. Esper查詢語言同樣如此, 只是它操作的是流而不是關(guān)系. 還有你知道 PostgreSQL 過去被命名為 “Postgres” 并使用 “Quel” 作為它的查詢語言么? 而首先作為一個關(guān)系型數(shù)據(jù)庫管理系統(tǒng)( ORDBMS), 它現(xiàn)在同樣有許多的特性使其具備無模式文檔存儲的能力.
它同樣也和ACID-特性無關(guān). Hyperdex 就是一個 NoSQL-數(shù)據(jù)庫的例子,它的目標(biāo)就是提供 ACID-事務(wù)能力. MySQL, 確實是一個 SQL-數(shù)據(jù)庫, 歷史上它有一段解釋 ACID 的真正意義的曖昧?xí)r期.
關(guān)系型的? 雖然大多數(shù)的 NoSQL-數(shù)據(jù)庫并不支持加入傳統(tǒng)關(guān)系型數(shù)據(jù)意義相同的功能,但還是有一些那樣做了,并將其留給用戶當(dāng)做練習(xí)使用. RethinkDB, Hive 還有 Pig, 等等. Neo4j, 面向圖形的數(shù)據(jù)庫, 確實是處理關(guān)系用的 - 它擅于遍歷圖中的關(guān)系 (比如,圖中的邊) . Elasticsearch 有一個概念叫做加入父子關(guān)系的“查詢時間”和加入嵌套類型的“索引時間“.
分布式的? 已經(jīng)有一些分布式的 SQL-數(shù)據(jù)庫 了, 并以 一些項目 旨在做一些像一個NoSQLite那樣的事情, 更新一代的數(shù)據(jù)庫趨向于在某些方式上具備分布式能力.
總而言之, 既沒有道理給 NoSQL 做出精確的定義, 也不能簡單的說 Elasticsearch 是一個“文檔存儲”-類型的NoSQL-數(shù)據(jù)庫. 在我寫這篇文章的時候, nosql-database.org 列出了超過20 個那樣的東西.
在下一節(jié),我們將關(guān)注一些重要的屬性并且看看 Elasticsearch 為什么要實現(xiàn)或者不去實現(xiàn)它們。
無事務(wù)
Lucene, 是 Elasticsearch 的構(gòu)建的基礎(chǔ), 它是由一個事務(wù)的概念的. 而Elasticsearch在另外的方面, 并沒有典型意義的事務(wù). 對于已經(jīng)提交的文檔并沒有辦法回滾, 而你也不能提交一組文檔并且為它們所有或者其中一些建立索引. 然而它所具備的, 是一個用來確保業(yè)務(wù)過程持久性而不用做昂貴的Lucene提交的預(yù)寫日志. 你也可以指定索引操作的一致性級別, 以確保在返回之前有多少副本可以拿來確認(rèn)操作條件. 默認(rèn)的是法定人數(shù), 例如 ⌊n2⌋
在逐個切片進行處理的方式中,當(dāng)一個索引被刷新時,默認(rèn)是一秒鐘一次,就需要對變更的可見性進行控制。
通過制定提交文檔的版本,可以進行樂觀并發(fā)控制。
Elasticsearch追求的是速度。支持分布式事務(wù)是一大塊工作。不支持分布式事務(wù)會使得很多事情變得容易起來。只要我們能接受讀取到的數(shù)據(jù) 有些陳舊,而且所有人看到的是同一時間點的數(shù)據(jù),那么Elasticsearch就可以利用緩存提供很多服務(wù) - 這對于我們鐘愛的極速性能來說是至關(guān)重要的。
模式靈活
Elasticsearch 不要求你先指定模式。扔給它一個 JSON 文檔,它就會進行一些訓(xùn)練有素的猜測來推斷其類型。對于數(shù)值、布爾、時間戳它可以做的很好。對于字符串,它會使用“標(biāo)準(zhǔn)化”的分析,這通常是良好的開始。
它是有商榷的“無模式”,在這個意義上你不必指定一個模式,我們更愿意把它認(rèn)做是“模式靈活”。為了開發(fā)大規(guī)模的搜索、分析,你確實需要對模式進行 微調(diào)。Elasticsearch 有大量的強大工具可以幫助你,例如動態(tài)模板、多字段對象等。這在我們關(guān)于映射的文章里會談及更多。
關(guān)系和約束
Elasticsearch是一種面向文檔的數(shù)據(jù)庫。你想要對之進行搜索的整個對象關(guān)系圖,都需要進行索引,在對文檔進行索引之前,它們必須先被反規(guī)范化。反規(guī)范化提升了查詢性能(因為不再需要進行關(guān)聯(lián)查詢),使用了更多存儲空間(因為數(shù)據(jù)必須被存儲多次),但是,要保持?jǐn)?shù)據(jù)一致性和實時性則更加困難(因為任何數(shù)據(jù)改變都必須被寫入到所有實例中去)。不過,對于一次寫入頻繁讀取的工作場景,它的表現(xiàn)相當(dāng)優(yōu)異。
舉例來說,假設(shè)你在數(shù)據(jù)庫中存儲了客戶、訂單和產(chǎn)品等數(shù)據(jù),現(xiàn)在你想要通過產(chǎn)品名字和客戶姓名來查找訂單??梢赃@樣來解決這個問題:在對訂單進行索引時, 把客戶和產(chǎn)品的所有必要信息都加進來。這樣的話,查詢就非常簡單,但是當(dāng)你想要改變某個產(chǎn)品的名字時會出現(xiàn)什么情況呢? 在進行了良好規(guī)范化的關(guān)系型模型中,你只需要修改該產(chǎn)品對應(yīng)的單條記錄就搞定了。這是關(guān)系型數(shù)據(jù)庫所擅長的。而在反規(guī)范化的文檔數(shù)據(jù)庫中,將不得不更新與 該產(chǎn)品有關(guān)的所有訂單。
換句話說,在面向文檔類型的數(shù)據(jù)庫中,比如Elasticsearch, 我們對文檔進行映射和存儲設(shè)計只是為了優(yōu)化查詢和信息獲取的性能。
在介紹中已經(jīng)提到,Elasticsearch中可以使用父/子-關(guān)系進行“查詢時”連結(jié),也可以使用內(nèi)嵌類型進行“索引時”連結(jié)。我們會在以后的文章中對該主題進行深入介紹。我們推薦Martijn van Groningen的一篇文章“Document relations with Elasticsearch”.
大多數(shù)關(guān)系型數(shù)據(jù)庫也會允許你指定約束關(guān)系,來定義什么需要保持一致性,什么不需要保持一致性。比如,參照完整性和唯一性都是強制性的。你可以要求賬戶變更金額必須是正數(shù),等等。而面向文檔的數(shù)據(jù)庫不傾向于這么做,Elasticsearch就是如此。
魯棒性
一個數(shù)據(jù)庫應(yīng)當(dāng)是魯棒的,尤其是當(dāng)它是你權(quán)威的記錄系統(tǒng)時。理想情況下,一個耗費資源的查詢應(yīng)當(dāng)可以被撤銷,你肯定不希望數(shù)據(jù)庫停止工作,除非你命令它停下來。
不幸的是,Elasticsearch (以及它的組件)目前并沒有很好的處理OutOfMemory錯誤。我們在Elasticsearch in Production, OutOfMemory-Caused Crashes一文中進行了更加深入的討論。所以,給Elasticsearch配置足夠多的內(nèi)存就顯得非常重要,而且在生產(chǎn)集群中要謹(jǐn)慎運行那些無法預(yù)知將會耗費多少內(nèi)存的查詢。
不過,隨著Elasticsearch越來越成熟,這個問題很可能會得到改善,記住Elasticsearch的目標(biāo)是追求速度,所以它假設(shè)內(nèi)存永遠(yuǎn)是充足的。
分布式
另請參考: Elasticsearch in Production, Networking.
Shay Banon在創(chuàng)建Elasticsearch之前,在Compass工作過。由于意識到它很難轉(zhuǎn)變成一個分布式的搜索引擎,他就從頭開始創(chuàng)建了Elasticsearch1。 Elasticsearch被設(shè)計成分布式的且易于擴展,用來在商用硬件上處理海量數(shù)據(jù)。
作為一個分布式的系統(tǒng),Elasticsearch的上手和使用都令人難以置信的簡單,但是分布式系統(tǒng)本身是很復(fù)雜的。關(guān)于這一點,我們在Elasticsearch in Production, Networking有更多討論,所以下面只是一個簡短的摘要。
分布式系統(tǒng)天生的特性,意味著很多事情都可能會出錯。同樣的,不同的數(shù)據(jù)庫系統(tǒng)致力于擁有不同強項: 有些力爭強大的安全保證,另外一些則致力于高可用性,即使某些時候(甚至多數(shù)時候)出現(xiàn)錯誤也在所不惜。而且,正如Kyle Kingsbury在他杰出的網(wǎng)絡(luò)分區(qū)的風(fēng)險系列文章中所指出的那樣,當(dāng)問題發(fā)生時,實際上數(shù)據(jù)庫系統(tǒng)并沒有像它們所宣稱的那樣來處理問題。簡言之,他發(fā)現(xiàn)當(dāng)分布式數(shù)據(jù)庫運行良好晴空萬里時,絕大部分?jǐn)?shù)據(jù)庫在遭受到大量可能的問題時所做的努力,都會以失敗而告終。
在一致性,可用性,以及分區(qū)容錯性方面,Elasticsearch 是一個CP系統(tǒng),一個相當(dāng)不靠譜的“一致性”定義。如果你有一個只讀的工作負(fù)載, Elasticsearch 允許你通過不嚴(yán)格的“最小主節(jié)點”要求(如不需要quorum)實現(xiàn)AP行為。然而,通常你需要集群中大量節(jié)點是可用的。寫入一個配置錯誤的沒有大量節(jié)點 的集群,像“split brain”集群,可能引起無法恢復(fù)的數(shù)據(jù)丟失。這不只是特定于Elasticsearch的。
Elasticsearch 選擇自己的主節(jié)點。然而這是一個相當(dāng)簡單但不是非??煽康乃惴?,這在現(xiàn)實世界的網(wǎng)絡(luò)壓力下可能導(dǎo)致很多問題。事實上,我們管理成百上千的集群,經(jīng)??吹街鞴?jié)點選擇問題,因此我們主動將主節(jié)點移入ZooKeeper, 當(dāng)然我們也有其他目的。
在拓展性方面,索引被分到了一個或多個碎片中。這在索引創(chuàng)建時就指定了并且不能改變。因此,隨著預(yù)期的增長,一個索引應(yīng)該被合理的分割。隨著越來越 多的節(jié)點添加到Elasticsearch集群中來,它在重新分配和移動碎片上表現(xiàn)良好。因此,Elasticsearch很容易拓展。
安全
另請參閱: Elasticsearch in Production, Security.
Elasticsearch沒有提供授權(quán)和認(rèn)證特性。你可以認(rèn)為,任何人只要能連接到你的Elasticsearch集群,就擁有了“超級用戶”權(quán)限,尤其是當(dāng)Elasticsearch的強大腳本功能被激活時。
總結(jié)
如果本文描述的這些限制都不能阻止你,你當(dāng)然可以使用Elasticsearch作為主存儲庫。一個不錯的例子是,當(dāng)你使用Logstash時。Logstash是一個神奇的工具,用來管理日志并把它們導(dǎo)入到Elasticsearch中,你可以只是對日志進行備份以防萬一。日志都是一次寫入,多次讀取的。不需要升級,不需要事務(wù)支持,沒有完整性約束,等等。
那么像Postgres那樣的系統(tǒng)怎么樣呢,它有全文檢索和ACID-事務(wù)。 (其它例子包括MySQL, MongoDB, Riak等等的全文檢索能力) 你當(dāng)然可以通過Postgres來實現(xiàn)基本的檢索,但是在性能上和功能上與ElasticSearch都有巨大的差距。正如我們在事務(wù)那 一節(jié)中所提到的,Elasticsearch會做很多緩存,所以有可能會“欺騙”我們,而且不關(guān)心多版本之間的并發(fā)控制以及其它復(fù)雜的事情。搜索遠(yuǎn)不止在 一段文本中找到一個關(guān)鍵字那么簡單:它是利用領(lǐng)域特定知識來實現(xiàn)良好的相關(guān)度模型,由此給出整個結(jié)果空間的一個全貌,并且能做拼寫檢查和自動補全之類的工 作。而且所有這些工作都要保證速度。
Elasticsearch通常被用作其它數(shù)據(jù)庫的補充。那樣的數(shù)據(jù)庫系統(tǒng)要有強大的數(shù)據(jù)約束保證、容錯性和魯棒性、高可用性和帶事務(wù)支持的數(shù)據(jù)更 新能力,它維護著核心數(shù)據(jù) - 這些數(shù)據(jù)隨后會被異步推送到Elasticsearch中去(也可能是抽取,前提是你使用了Elasticsearch的某一種“rivers”)。 保持?jǐn)?shù)據(jù)同步是我們打算將來撰文深入探討的話題。這里,在Found網(wǎng)站的文章中,我們使用具有代表性的PostgreSQL和ZooKeeper來提供 源數(shù)據(jù),并把這些數(shù)據(jù)輸入給Elasticsearch來提供強大的搜索。
像其它所有事情一樣,沒有包治百病的靈丹妙藥,沒有一個數(shù)據(jù)庫可以做到所有的事情。也許這種情況會永遠(yuǎn)持續(xù)下去,所以一定要了解你的數(shù)據(jù)庫的優(yōu)點和弱點!
原文鏈接:https://www.found.no/foundation/elasticsearch-as-nosql/
譯文鏈接:http://www.oschina.net/translate/elasticsearch-as-nosql