概覽一下大數(shù)據(jù)項目中可以使用的數(shù)據(jù)存儲技術(shù),聚焦于Couchbase 和 ElasticSearch,展示如何使用以及它們的區(qū)別,先理解一下NoSQL領(lǐng)域中各種不同的技術(shù)。
NoSQL
關(guān)系型數(shù)據(jù)庫是過去的選擇,幾乎是許多開發(fā)者和DBA對于傳統(tǒng)三層架構(gòu)應(yīng)用的唯一選擇。使用這一場景有很多原因,數(shù)據(jù)建模方法,查詢語言與數(shù)據(jù)交互,保證數(shù)據(jù)的一致性部署,并能夠為復(fù)雜的應(yīng)用服務(wù)。
然而,這不是解決所有數(shù)據(jù)存儲問題的唯一方案,也是NoSQL 產(chǎn)生的原因。NoSQL 提供了新的方法而不是采用面向標準SQL的范式。
NoSQL 技術(shù)與高伸縮性無縫融合,很多技術(shù)同時具備了高分布性和高性能。大多數(shù)時間里,它們使 現(xiàn)有RDBMS 技術(shù)所實現(xiàn)的架構(gòu)更加完整,例如 作為緩存服務(wù)器,搜索引擎,非結(jié)構(gòu)化存儲,易變信息存儲等。主要分為4類:
Key/value
列存儲
面向文檔的存儲
圖存儲
現(xiàn)在深入到各種技術(shù),選擇最適用我們場景的技術(shù)。
Key/Value
第一個也是最早的 NoSQL 數(shù)據(jù)存儲就是key/value. 這些數(shù)據(jù)就像字典一樣根據(jù)key來匹配value,通常使用在需要高性能的基本信息存儲,例如需要快速讀寫的session信息,這些存儲在這樣的情景非常高效,也通常具有高伸縮性。
Key/value也經(jīng)常被用于上下文的隊列化來保證數(shù)據(jù)不丟失,例如日志架構(gòu)或搜索引擎的索引架構(gòu)。Redis 和Riak KV 是非常有名的key/value數(shù)據(jù)存儲; Redis 使用的更加廣泛,因為它有著一個內(nèi)存型 K/V 存儲,并且持久化是可選的。Redis 經(jīng)常用于web應(yīng)用中來存儲session相關(guān)的數(shù)據(jù),例如node或者-
PHP的 web應(yīng)用 ; 每秒鐘可以提取成千上萬的session信息而沒有性能損失。另一個典型場景是后面要講到的序列化:Redis位于 Logstash 和 ElasticSearch 之間來存儲t ElasticSearch 查詢中的索引。
Column
由于要存儲超大量的記錄信息 到達了key/value存儲限制的時候就需要用到列存儲。列存儲技術(shù)對于RDBMS世界的工程師可能不太容易理解,但事實上非常簡單。RDBMS 中數(shù)據(jù)是按行存儲的,而列存儲中是按列的。使用列數(shù)據(jù)庫的主要好處是能高速訪問海量數(shù)據(jù)。 RDBMS的一行在硬盤上是一個連續(xù)的存儲,多行可能存儲在硬盤不同的位置,使訪問稍顯復(fù)雜,在列數(shù)據(jù)庫中的一列數(shù)據(jù)是連續(xù)存儲的。
舉個例子,考慮在RDBMS中查詢索引博客的標題,尤其是有數(shù)百萬數(shù)據(jù)的時候,需要大量的IO操作,而在列數(shù)據(jù)庫中,這樣的查詢只是一次訪問。這樣的數(shù)據(jù)庫在從特定簇提取海量數(shù)據(jù)中非常順手,但此消彼長的是缺乏靈活性。使用最多的列存儲數(shù)據(jù)庫是
Google Cloud Bigtable, 但開源的列存儲數(shù)據(jù)庫是Apache HBase 和Cassandra.
列存儲數(shù)據(jù)庫的另一個好處是容易伸縮,這些列在海量存儲時具有高伸縮性。這就是為什么它們主要用于保存非易變且長久保留信息的原因。
Document
列存儲數(shù)據(jù)庫對于含有比較深嵌套結(jié)構(gòu)的結(jié)構(gòu)化數(shù)據(jù)的存儲不是最好的,這種場景需要使用面向文檔的數(shù)據(jù)存儲。數(shù)據(jù)實際上以key/value 存儲,但是所有壓縮的數(shù)據(jù)叫做文檔。 文檔依賴于一個結(jié)構(gòu)或者編碼例如XML, 但更多時候是 JSON (JavaScript Object Notation).
盡管文檔型數(shù)據(jù)庫對于數(shù)據(jù)的結(jié)構(gòu)化存儲和表達都非常有用,但也有其脆弱的一面,特別是與數(shù)據(jù)的交互性操作。它們基本上要遍歷整個文檔,例如當讀取某個特定字段的時候,遍歷可能會影響性能。
當需要存儲嵌套信息的時候,可以采用文檔型數(shù)據(jù)庫。例如,考慮怎樣表達應(yīng)用中的一個賬戶,大概有以下信息:
基礎(chǔ)信息:姓名,生日,照片 ,URL, 創(chuàng)建日期等等
復(fù)雜信息: 地址,認證方法(password, Facebook, 等第三方認證),興趣等等。
這也是NoSQL 文檔型數(shù)據(jù)庫經(jīng)常用到web應(yīng)用的原因: 表達嵌套對象非常容易,由于都使用JSON,還可以與前端的JavaScript技術(shù)無縫集成。
使用最多的文檔型數(shù)據(jù)庫是MongoDB, Couchbase, 和 Apache CouchDB,都非常容易安裝和啟動,有很好的文檔說明,而且都是可伸縮的,除此之外,它們也是開放現(xiàn)代web應(yīng)用的明確選擇。
Couchbase 是我們架構(gòu)中選擇的技術(shù),使用它來存儲,查詢和組織數(shù)據(jù)。原因是基于它的性能基準測試,它的高吞吐量操作時延低于MongoDB.
還有一個值得關(guān)注的是,Couchbase 今天是 CouchDB 和Memcached的結(jié)合體。從支持的角度上看,使用CouchBase更顯得有意義。
Graph
Graph 數(shù)據(jù)庫與其它數(shù)據(jù)庫有著本質(zhì)的區(qū)別。它使用了不同的范式來表達數(shù)據(jù)——樹結(jié)構(gòu),節(jié)點和邊連接起來叫做關(guān)系。這些數(shù)據(jù)庫是隨著社交網(wǎng)絡(luò)而誕生的,例如表達用戶的好友網(wǎng)絡(luò),他們的好友關(guān)系等等。對于其它類型的數(shù)據(jù)存儲,可能把一個用戶的好友關(guān)系存儲在一個文檔中,但是,存儲好友關(guān)系還依然非常復(fù)雜;使用圖數(shù)據(jù)庫就非常簡單,為每個好友創(chuàng)建節(jié)點,通過關(guān)系連接他們,依賴查詢的需要和范圍瀏覽圖。
最著名的圖數(shù)據(jù)庫是Neo4j, 象前面所說的,主要使用場景是處理復(fù)雜的關(guān)系信息,例如實體間的連接,也可以用于分類的場景。
Figure 2-1 展示了在圖數(shù)據(jù)庫中3個實體是如何連接的。
Figure 2-1. Graph database example
圖中的兩天賬戶節(jié)點Jane 和 John, 它們之間的每一條邊定義了他們的關(guān)系,在某天相互認識,另一組節(jié)點連接的兩個賬戶展示了Jane 和 Joh在某天后都成為了足球組的成員。
我們使用場景中的NoSQL
根據(jù)我們的使用場景,首先需要一個文檔型的 NoSQL數(shù)據(jù)庫,將存儲在關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)結(jié)構(gòu)化的一個 JSON 文檔. 如前所述,傳統(tǒng)的RDBMSs 將數(shù)據(jù)存儲到多個有關(guān)系的表,當?shù)玫揭粋€完整對象時變得比較復(fù)雜和低效。讓我們在Figure 2-2. 中看一個賬戶被分割成多個表的例子。
Figure 2-2. Account tables
如果要獲得所有的賬戶信息,基本上需要join兩到三個表。現(xiàn)在考慮這樣的情形: 需要處理所有用戶在應(yīng)用中的每一次連接,這些連接有著不同的商業(yè)邏輯。 最后,想要賬戶自身的視圖。通過傳遞一個賬戶標識通過API從全部用戶視圖中得到一個怎樣的文檔呢?
{
"id": "account_identifier",
"email": "account@email.com",
"firstname": "account_firstname",
"lastname": "account_lastname",
"birthdate": "account_birthdate",
"authentication": [{
"token": "authentication_token_1",
"source": "authenticaton_source_1",
"created": "12-12-12"
}, {
"token": "authentication_token_2",
"source": "authenticaton_source_2",
"created": "12-12-12"
}],
"address": [{
"street": "address_street_1",
"city": "address_city_1"
"zip": "address_zip_1"
"country": "address_country_1"
"created": "12-12-12"
}]
}
好處顯而易見: 通過保持一個實體的 JSON 表達,可以更快更好的訪問數(shù)據(jù)。進一步,將這一方法通用化,從NoSQL數(shù)據(jù)庫讀取所有的讀操作,而讓所有的寫操作 (create, update,delete) 還在RDBMS上 .但我們必須實現(xiàn)一個邏輯來維持 RDBMS到NoSQL 的數(shù)據(jù)同步,如果沒在緩存中的話還要創(chuàng)建一個關(guān)系型數(shù)據(jù)庫的對象。
當我們在NoSQL高效可伸縮地創(chuàng)建文檔時問什么還要保持 RDBMS呢?因為這不是我們應(yīng)用的真正目的。我門不想產(chǎn)生一個Big Bang 的影響. 假設(shè)RDBMS已經(jīng)準備好了,但因為RDBMS缺乏靈活性而集成了一個NoSQL存儲。希望充分利用兩個最好的技術(shù) —特別是RDBMS的數(shù)據(jù)一致性和NoSQL的伸縮性 。
除此之外,這是一個簡單查詢的例子,但是希望更進一步,例如文檔中任意字段的全文檢索。那么,在關(guān)系型數(shù)據(jù)庫中如何做的呢?是索引,但是要索引表中所有的列么?實際上,這是不可能的,但可以輕松地使用NoSQL技術(shù)做這件事,例如ElasticSearch. 在我們深入一個NoSQL 緩存系統(tǒng)之前,先看一下如何使用 Couchbase 這一文檔型數(shù)據(jù)庫,然后回顧它的局限再切換到ElasticSearch。
先看一下Couchbase這一可伸縮架構(gòu), 但因為Couchbase 的一些嚴重局限, 還是在遷移前看一下?lián)碛蠩lasticSearch的完整架構(gòu)。
Couchbase 介紹
Couchbase是一個開源的文檔型數(shù)據(jù)庫,有著靈活的數(shù)據(jù)模型,性能和伸縮性都適合我們的使用場景,將關(guān)系型數(shù)據(jù)庫的數(shù)據(jù)存儲到一個結(jié)構(gòu)化的 JSON 文檔.大多數(shù)NoSQL技術(shù)有著類似的架構(gòu)—首先看 Couchbase 架構(gòu)師如何組織的,然后介紹 Couchbase中命名約定, 再深入到存儲數(shù)據(jù)是如何查詢的,最后討論跨數(shù)據(jù)中心的復(fù)制。
架構(gòu)
Couchbase是一個真正的無共享架構(gòu),這意味著沒有單點故障,因為集群中的每個節(jié)點都是自給自足而且獨立的。分布式技術(shù)工作的方式如何?——各節(jié)點不共享任何內(nèi)存或硬盤存儲。文檔以JSON或者二進制形式存儲在Couchbase中,在集群間復(fù)制,所組織的單元叫buckets. 一個bucket 通過設(shè)置RAM緩存來根據(jù)存儲和訪問需求完成伸縮,還可以設(shè)置彈性副本的數(shù)量。 從底層看, bucket 被分割成叫做vBuckets 的小單元,實際上是數(shù)據(jù)分區(qū)。 Couchbase 使用一個集群映射將分區(qū)和服務(wù)器關(guān)聯(lián)起來。一個Couchbase服務(wù)器在一個集群內(nèi)對一個bucket有3個副本,每個 Couchbase 管理vbucket 激活或副本的子集。 這就是Couchbase的彈性原理; 每個文檔的每次索引,都有副本,如果集群中的一個節(jié)點掛了,集群將激活副本分區(qū)來保證連續(xù)的服務(wù)。
Figure 2-3 解釋了集群中只有一個激活的數(shù)據(jù)拷貝同時有一個或多個副本。
Figure 2-3. Couchbase active document and replicas
從客戶端視角看,如果使用智能客戶端(Java, C, C++,Ruby等.), 然后這些客戶端連接集群映射; 客戶端從應(yīng)用發(fā)送請求到合適的服務(wù)器. 就交互而言,有非常重要的一點: 文檔操作默認是異步的。這意味著當你更新文檔的時候,Couchbase 不能在硬盤上立即更新數(shù)據(jù)。Figure 2-4. 呈現(xiàn)了真實的處理過程。
Figure 2-4. Couchbase data flow
如 Figure2-4 所示, 智能客戶端連接到一個 Couchbase 實例,首先異步將文檔寫到緩存中,客戶端立即得到響應(yīng)而不是阻塞到數(shù)據(jù)流處理完,當寫操作完成時由客戶端改變行為狀態(tài)。然后,文檔被放入集群那邊的寫隊列,所以在集群間復(fù)制; 此后, 文檔被放入硬盤存儲的寫隊列來持久化到相關(guān)節(jié)點。如果部署了多集群,Cross Data Center Replication (XDCR) 特性可以在不同集群間傳播這種數(shù)據(jù)改變,集群可以位于不同的數(shù)據(jù)中心。
Couch base有自己的數(shù)據(jù)查詢方法; 實際上, 簡單地使用文檔ID就可以查詢文檔,Couchbase的強大在視圖特性的內(nèi)部. Couchbase 中, 有一個二級索引叫做設(shè)計文檔,是在bucket內(nèi)部創(chuàng)建的. bucket可以包含文檔的多個類型,例如一個簡單的電子商務(wù)應(yīng)用的bucket 包含如下內(nèi)容:
- Account
- Product
- Cart
- Orders
- Bills
Couchbase 使用設(shè)計文檔來完成它們的邏輯分割. 一個bucket 可以包含多設(shè)計文檔 , 也包含了多視圖. 一個視圖是由用戶定義bucket內(nèi)的索引文檔的函數(shù)。該函數(shù)是用戶定義的map/reduce 函數(shù)將文檔映射到集群中,輸出 key/value 對, 存儲在索引中用于將來的信息提取。回顧電商網(wǎng)站的例子,嘗試從帳戶標識的所有訂單中建立索引. map/reduce 函數(shù)如下所示:
function(doc, meta) {
if (doc.order_account_id)
emit(doc.order_account_id, null);
}
if 判斷語句允許函數(shù)聚焦在一個文檔,它包含了order_account_id 字段然后索引這一標識。因此,任何客戶端都可以根據(jù)這一標識從Couchbase中查詢數(shù)據(jù)。
Cluster Manager 和管理控制臺
Cluster manager 是集群中一個特殊的節(jié)點。在任何時候,如果集群內(nèi)的一個節(jié)點掛了, orchestrator 通過通知集群內(nèi)所有其它節(jié)點來處理故障切換, 定位故障節(jié)點的副本分區(qū)來使之處于激活狀態(tài). Figure 2-5 描述了故障切換處理。
Figure 2-5. Couchbase failover
如果 orchestrator 節(jié)點掛了,所有節(jié)點都可以通過心跳監(jiān)控檢測到,這個 watchdog 運行在集群中的所有節(jié)點上。所有集群相關(guān)的特性都可以通過API形式來管理Couchbase, 但是有現(xiàn)成的管理控制臺。Couchbase 有一個安全控制臺來管理和監(jiān)控集群; 可以選擇可用的操作包括服務(wù)器搭建,創(chuàng)建buckets, 瀏覽和更新文檔, 實現(xiàn)新的視圖,以及監(jiān)控 vBucket 和硬盤寫隊列.
Figure 2-6 展示了Couchbase 控制臺主頁,有現(xiàn)存buckets所使用的內(nèi)存, 數(shù)據(jù)使用的硬盤, 以及buckets的活動.
Figure 2-6. Couchbase console home
在 Server Nodes 中執(zhí)行集群管理,讓用戶配置故障切換和復(fù)制以防止數(shù)據(jù)丟失。 Figure 2-7 展示了單節(jié)點安裝故障切換的不安全型。
Figure 2-7. Couchbase server nodes
任何時候,都可以通過點擊Add Server 按鈕來增加一個新的Couchbase 服務(wù)器,這一操作的時候,數(shù)據(jù)就開始在節(jié)點間復(fù)制來保證故障切換。通過點擊
服務(wù)器IP, 可用訪問一個bucket的監(jiān)控數(shù)據(jù), 如 Figure 2-8.
Figure 2-8. Couchbase bucket monitoring
該圖展示了一個叫做DevUser的數(shù)據(jù) bucket,包含了用戶相關(guān)的JSON文檔.如前所述 ,新文檔索引的處理是復(fù)雜的底層處理的一部分。當處理高索引吞吐量的海量數(shù)據(jù)時,可用從監(jiān)控控制臺看到基本的測量信息。例如,當寫操作時統(tǒng)計磁盤寫隊列的瓶頸。
Figure 2-9 中, 可用看的drain rate—從磁盤寫隊列中寫入磁盤的數(shù)據(jù)數(shù)量——在寫入副本時活躍節(jié)點時平滑的,而且在平滑區(qū)間內(nèi)增長相對平均。一個改變的行為將是看到活動項目的平均年齡保持增長,這意味著,寫操作是與數(shù)據(jù)推入寫磁盤隊列的數(shù)量相比太慢了。
Figure 2-9. Couchbase bucket disk queue
管理文檔
通過bucket視圖,可以從管理控制臺管理所有的文檔. 這一視圖允許用戶瀏覽buckets, 設(shè)計文檔以及視圖.文檔存儲在Couchbase的一個bucket中,可以通過管理控制臺的 Data Bucket 欄目訪問,如Figure 2-10 所示.
Figure 2-10. Couchbase console bucket view
從服務(wù)器來看 , 控制臺給出了bucket的統(tǒng)計數(shù)據(jù)如 RAM 和存儲大小以及每秒操作的數(shù)量。但真正的好處是這個視圖可以瀏覽文檔并通過ID來提取它們,如 Figure 2-11 所示.
Figure 2-11. Couchbase document by ID
同時,可以通過這一視圖創(chuàng)建設(shè)計文檔和索引文檔的視圖如Figure 2-12 所示.
Figure 2-12. Couchbase console view implementation
在Figure 2-12 中, 實現(xiàn)了一個視圖,它基于公司名稱提取文檔。管理控制臺可用非常方便的管理文檔,但在真實世界中,需要在管理控制臺開始實現(xiàn)一個設(shè)計文檔,并且創(chuàng)建一個工業(yè)化部署的備份。所有的設(shè)計文檔都存儲在一個JSON 文件中,有著一個簡單的結(jié)構(gòu)來描繪上所有的視圖,如表 2-1 所示.
Listing 2-1. Designing a Document JSON Example
[{
...
"doc": {
"json": {
"views": {
"by_Id": {"map": "function (doc, meta)
{\n emit(doc.id, doc);\n}"},
"by_email": {"map": "function (doc, meta)
{\n emit(doc.email, doc);\n}"},
"by_name": {"map": "function (doc, meta)
{\n emit(doc.firstname, null);\n}"},
"by_company": {"map": "function (doc, meta)
{\n emit(doc.company, null);\n}"},
"by_form": {"map": "function (doc, meta)
{\n emit(meta.id, null);\n}"}
}
}
...
}
}]
已經(jīng)看到,可以通過管理控制臺執(zhí)行文檔的管理,但是在商用架構(gòu)中,大量這樣的操作是通過使用Couchbase API 的腳本完成的。
介紹ElasticSearch
已經(jīng)了解了Couchbase這樣的一個NoSQL; ElasticSearch 也是一個NoSQL技術(shù),但與 Couchbase完全不同. 這是由Elastic公司命名的分布式數(shù)據(jù)庫。
架構(gòu)
它是一個建立于Apache Lucene(一個Java寫的全文搜素引擎)之上的索引/搜索引擎。從一開始, ElasticSearch 就是分布式可伸縮的,可以通過增加節(jié)點資源來垂直擴展,也可以通過增加節(jié)點來水平擴展增加高可用性同時保持彈性。如果一個節(jié)點掛了,由于在集群間的復(fù)制,由其它節(jié)點提供服務(wù)。
ElasticSearch 是一個無縫引擎;數(shù)據(jù)以JSON存儲,分區(qū)叫做shards. 一個 shard 實際上是一個Lucene的索引,是 ElasticSearch中最小的可擴展單元. Shards 組織成ElasticSearch中的索引,使應(yīng)用完成讀寫交互。最后, 索引是一個ElasticSearch中邏輯上的命名空間,是shards 集合的一個重新分組,當請求到達時, ElasticSearch 將它路由到合適的shard上,如 Figure 2-13 所示.
Figure 2-13. Elasticsearch index and shards
ElasticSearch中有兩種shard類型:基本 shards 和復(fù)制shards. 當啟動一ElasticSearch 節(jié)點, 開始只增加一個基本shard, 這就足夠了,當時當讀/檢索請求的吞吐量迅猛增加的時候會怎樣呢?這種情況下, 一個基本 shard 可能不夠用了,就需要另一個shard. 不能實時增加shard來期望ElasticSearch 來擴展; 這將在兩個新的基本shard中重新索引所有的數(shù)據(jù)。所以,在啟動一個 ElasticSearch項目的開始, 適當評估集群中有多少個基本shard 非常重要。在一個節(jié)點增加多個 shards 不能增加集群的容量,因為有著硬件的現(xiàn)在。為了增加集群容量,也需要增加更多的節(jié)點來承載基本 shards,見Figure 2-14.
Figure 2-14. ElasticSearch primary shard allocation
一個好事情時ElasticSearch在新節(jié)點上可以通過網(wǎng)絡(luò)自動拷貝shard,如 Figure 2-14.但是如何確保數(shù)據(jù)不丟失呢?這就是replica shards的角色。
Replica shards 開始源于故障切換;當primary shard 掛了, 一個副本被提升為primary來保證集群的連續(xù)性。Replica shards 在primary shards 做索引的時候擁有同樣的負載; 一旦一個文檔在 primary shard中建立了索引, 同樣也在replica shards中做了索引. 這就是為什么在集群中增加副本卻不會增加索引的性能,但是如果增加了額外的硬件,就會提升搜索的性能。在一個三節(jié)點集群中,有一個primary shards 和兩個副本 Figure 2-15 展示了如何重新分區(qū).
Figure 2-15. ElasticSearch primary and replica shards
另外, 通過在集群中幫助請求的負載均衡,從而得到更好的性能。最后要討論的是純 ElasticSearch 架構(gòu)的indices以及多節(jié)點. Indices 被重新分組到 ElasticSearch 的節(jié)點,Figure 2-16 展示了3種類型的節(jié)點。
Figure 2-16. ElasticSearch cluster topology
這是三種節(jié)點的描述:
Master nodes: 這些節(jié)點是輕量級的,負責(zé)集群管理。它們不承載任何數(shù)據(jù), server indices,或搜素請求. 它們專門來保證集群的穩(wěn)定性,負載較低。推薦使用三個master nodes通過冗余保證故障切換。
Data nodes: 這些節(jié)點持有數(shù)據(jù),索引和搜索請求。
Client nodes: 這保證部分處理步驟的負載均衡,且部分工作負載在數(shù)據(jù)節(jié)點執(zhí)行,例如搜索請求發(fā)散在不同節(jié)點上。
理解了ElasticSearch架構(gòu), 就可以使用API運行一些查詢了。
ElasticSearch 監(jiān)控
Elastic 提供了一個叫 Marvel 的插件,目標是監(jiān)控 ElasticSearch 集群. 這個插件是個商用產(chǎn)品,但你可以在開發(fā)模式免費使用它。
下載和安裝都非常簡單:https://www.elastic.co/downloads/marvel
Marvel 是依賴 Kibana的, Elastic的可視化控制臺,帶來大量的可視化技術(shù),使操作者準確地知道在集群上發(fā)生了什么。 Figure 2-17展示了 Marvel的控制面板.
Figure 2-17. ElasticSearch Marvel console
Marvel 提供了節(jié)點indices和shards的信息; CPU 利用率;JVM所使用的內(nèi)存;索引的速度,以及搜索的速度. Marvel 甚至可以進入到 Lucene的底層查看
flushes 和 merges的信息.例如集群中shard的分布列表 見 Figure 2-18.
Figure 2-18. Marvel’s shard allocation view
Marvel 可以提供大量有關(guān)集群的信息。Figure 2-19展示了節(jié)點統(tǒng)計的子集.
Figure 2-19. Marvel Node Statistics dashboard
dashboard 被組織成幾行; 實際上,在截屏中是看不到多于20行的內(nèi)容的.每行包含一個或行標題的可視化。 在 Figure 2-19中,沒看到發(fā)送到
indices的GET 請求; 這就是為什么線圖是平的. 在開發(fā)模式中,這些統(tǒng)計可以幫助判定服務(wù)器是否伸縮,例如,啟動一個單節(jié)點集群,查看特殊需求的行為。在生產(chǎn)環(huán)境,能夠真實地看到集群的信息,而不損失什么。
通過 ElasticSearch搜索
Marvel又一個叫 Sense的特性,是ElasticSearch的一個查詢編輯器. Sense 的強大是又一個自動補全查詢的能力,當不熟悉
ElasticSearch API時非常有用, 見Figure 2-20.
Figure 2-20. Marvel Sense completion feature
也可以將查詢導(dǎo)出到cURLs, 例如, 使用的腳本參見Figure 2-21.
Figure 2-21. Marvel Sense copy as cURL feature
在這種情況下,查詢被視為cURL 命令,見 Listing 2-3.
Listing 2-3. Example of cURL Command Generated by Sense
curl -XGET "http://192.168.59.103:9200/yahoo/_search" -d'
{
"query": {
"match_all": {}
}
}'
這一查詢基本上搜索了Yahoo索引下的全部文檔. 未來展示 search API的優(yōu)勢, 使用來自 Yahoo的數(shù)據(jù)集,它包含了若干年Yahoo股票的信息。一個 ElasticSearch’s search API中關(guān)鍵的特性是,這是一個聚合框架。可以用不同的方法聚合數(shù)據(jù); 更通用的方式是事業(yè)日期直方圖,相當于時間線。Figure 2-22 解釋了一個查詢的例子; 通過日期聚合股票數(shù)據(jù),間隔可以是月,也可以計算給定月份的股價最大值。
Figure 2-22. Marvel Sense Aggregation example
作為結(jié)果, 我們得到一個文檔的數(shù)組,每個條目包含了日期,每月的文檔數(shù)量,最高值,見Listing 2-4.
Listing 2-4. Aggregation Bucket
{
"key_as_string": "2015-01-01T00:00:00.000Z",
"key": 1420070400000,
"doc_count": 20,
"by_high_value": {
"value": 120
}
}
可以看到如 Figure 2-22的查詢, 有兩個層次的聚合: 一個是日期直方圖,第二個是最大值。實際上 , ElasticSearch 支持多層次聚合。
搜素API 非常豐富,不可能逐個瀏覽,詳情參見:
https://www.elastic.co/guide/en/elasticsearch/reference/1.4/search-search.html
現(xiàn)在熟悉了兩種 NoSQL技術(shù) , 看一下把它們集成到一個電子商務(wù)應(yīng)用的不同方法。
在基于SQL的架構(gòu)中 使用 NoSQL 緩存
盡管理解了NoSQL技術(shù)相對于 SQL 數(shù)據(jù)庫的優(yōu)勢,但不想打破依賴于SQL數(shù)據(jù)庫的現(xiàn)有架構(gòu)。下面的方法可以完善我們的架構(gòu),基于NoSQL技術(shù)增加訪問數(shù)據(jù)的靈活性。
文檔緩存
第一個要討論的是如何復(fù)制數(shù)據(jù)到我們NoSQL的后端。希望每次數(shù)據(jù)寫到SQL數(shù)據(jù)庫中的時候,一個文檔同時在我們的NoSQL創(chuàng)建或更新。文檔的創(chuàng)建、更新字段,或者豐富子文檔對應(yīng)于 RDBMS的表關(guān)系. 在訪問文檔的時候,只要API的GET 請求產(chǎn)生了,都先看NoSQL后端,如果有則返回此文檔。
如果文檔沒找到怎么辦?緩存沒有命中的事件將被觸發(fā),NoSQL manager 從 RDBMS中重建此文檔. 那在SQL層插入的transaction失敗了怎么辦? 框架應(yīng)該是交易型的,只有當SQL 的交易完成時才觸發(fā)文檔的重建。Figure 2-23 總結(jié)了這一機制.
Figure 2-23. Caching a document in NoSQL
Figure 2-23 描述的內(nèi)容:
第一框圖展示了一個賬戶如何在 RDBMS 中創(chuàng)建的,以及如何在NoSQL中創(chuàng)建一個完整賬戶的文檔表達
第二框圖展示了API如何從NoSQL存儲中獲得一個賬戶信息.
第三個框圖展示了一個緩存丟失的例子,當文檔不在NoSQL中的時候必須從RDBMS中重建
實際上,基于NoSQL為web應(yīng)用建立了一個緩存。這種方法依賴于NoSQL訪問整個文檔的靈活性而不增加SQL數(shù)據(jù)庫的負擔,也充分利用了NoSQL的分布式靈活性。 通過這種方法,隨著請求速度的大量增長可以擴展集群,減少SQL數(shù)據(jù)庫的壓力。
ElasticSearch的 Couchbase 插件
為了獲得這樣一個緩存機制,需要選擇NoSQL技術(shù)。第一個方法獨立使用
Couchbase, 但是 Couchbase的搜索特性不太好使。用map/reduce 函數(shù)索引數(shù)據(jù)較煩瑣,尤其是只做簡單聚合的時候。 Couch base 是個很棒的 NoSQL 數(shù)據(jù)庫, 但實現(xiàn)搜索確實痛苦。作為替代方法,可以使用Couchbase/ElasticSearch 集成插件, 基本上使用Cross Data Center Replication (XDCR) 傳輸所有數(shù)據(jù)到 ElasticSearch 集群(www.couchbase.com/jp/couchbase-server/connectors/elasticsearch).
就操作任務(wù)而言,要維護三種不同的技術(shù):RDBMS, Couchbase, 和 ElasticSearch.
最有效的ElasticSearch
保持使用 Couchbase 原因:
索引全部對象的能力, 例如將SQL中的賬戶信息簽到NoSQL
通過靈活的搜索API適應(yīng)從簡單到復(fù)雜聚合查詢的能力
從選擇 Couchbase 開始,作為最佳實踐,文檔存儲在數(shù)據(jù)庫中。當體驗架構(gòu)的時候,要知道什么是訪問和請求數(shù)據(jù)的最有效方法。在我們使用場景中, ElasticSearch 就是最有效的方法。