Riak 简介,第 1 部分: 与语言无关的 HTTP API
轉(zhuǎn)載:http://www.ibm.com/developerworks/cn/opensource/os-riak1/index.html
簡(jiǎn)介
典型的現(xiàn)代關(guān)系數(shù)據(jù)庫在某些類型的應(yīng)用程序中表現(xiàn)平平,難以滿足如今的互聯(lián)網(wǎng)應(yīng)用程序的性能和可擴(kuò)展性要求。因此,需要采用不同的方法。在過去幾年中,一種新的數(shù)據(jù)存儲(chǔ)類型變得非常流行,通常稱為 NoSQL,因?yàn)樗梢灾苯咏鉀Q關(guān)系數(shù)據(jù)庫的一些缺陷。Riak 就是這類數(shù)據(jù)存儲(chǔ)類型中的一種。
Riak 并不是惟一的一種 NoSQL 數(shù)據(jù)存儲(chǔ)。另外兩種較流行的數(shù)據(jù)存儲(chǔ)是 MongoDB 和 Cassandra。盡管在許多方面十分相似,但是它們之間也存在明顯的不同。例如,Riak 是一種分布式系統(tǒng),而 MongoDB 是一種單獨(dú)的系統(tǒng)數(shù)據(jù)庫,也就是說,Riak 沒有主節(jié)點(diǎn)的概念,因此在處理故障方面有更好的彈性。盡管 Cassandra 同樣是基于 Amazon 的 Dynamo 描述,但是它在組織數(shù)據(jù)方面摒棄了向量時(shí)鐘和相容散列等特性。Riak 的數(shù)據(jù)模型更加靈活。在 Riak 中,在第一次訪問 bucket 時(shí)會(huì)動(dòng)態(tài)創(chuàng)建這些 bucket;Cassandra 的數(shù)據(jù)模型是在 XML 文件中定義的,因此在修改它們過后需要重啟整個(gè)群集。
Riak 的另一個(gè)優(yōu)勢(shì)是它是用 Erlang 編寫的。而 MongoDB 和 Cassandra 是用通用語言(分別為 C++和 Java)編寫,因此 Erlang 從一開始就支持分布式、容錯(cuò)應(yīng)用程序,所以更加適用于開發(fā) NoSQL 數(shù)據(jù)存儲(chǔ)等應(yīng)用程序,這些應(yīng)用程序與使用 Erlang 編寫的應(yīng)用程序有一些共同的特征。
Map/Reduce 作業(yè)只能使用 Erlang 或 JavaScript 編寫。對(duì)于本文呢,我們選擇使用 JavaScript 編寫 map 和 reduce 函數(shù),但是也可以用 Erlang 編寫它們。雖然 Erlang 代碼的執(zhí)行速度可能稍快一些,然而我們選擇 JavaScript 代碼的理由是它的受眾更廣。參閱 參考資料 中的鏈接,詳細(xì)了解 Erlang。
回頁首
開始
如果您希望嘗試本文中的一些示例,則需要在您的系統(tǒng)中安裝 Riak(參閱 參考資料)和 Erlang。
您還需要構(gòu)建一個(gè)包含三個(gè)節(jié)點(diǎn)的群集并在您的本地機(jī)器上運(yùn)行它。Riak 中保存的所有數(shù)據(jù)都被復(fù)制到群集的大量節(jié)點(diǎn)中。數(shù)據(jù)所在的 bucket 的一個(gè)屬性 (n_val) 決定了將要復(fù)制的節(jié)點(diǎn)的數(shù)量。該屬性的默認(rèn)值為 3,因此,要完成本示例,我們需要?jiǎng)?chuàng)建一個(gè)至少包含三個(gè)節(jié)點(diǎn)的群集(之后您可以創(chuàng)建任意數(shù)量的節(jié)點(diǎn))。
下載了源代碼后,您需要進(jìn)行構(gòu)建。基本步驟如下:
這將構(gòu)建 Riak (./rel/riak)。要在本地運(yùn)行多個(gè)節(jié)點(diǎn),則需要生成 ./rel/riak 的副本,對(duì)每個(gè)額外的節(jié)點(diǎn)使用一個(gè)副本。將 ./rel/riak 復(fù)制到 ./rel/riak2、./rel/riak3 等地方,然后對(duì)每個(gè)副本執(zhí)行下面的修改:
- 在 riakN/etc/app.config 中,修改下面的值:http{} 部分中指定的端口,handoff_port 和 pb_port,將它們修改為惟一值
- 打開 riakN/etc/vm.args 并修改名稱,同樣是修改為惟一值,例如 -name riak2@127.0.0.1
現(xiàn)在依次啟動(dòng)每個(gè)節(jié)點(diǎn),如 清單 1 所示。
清單 1. 清單 1. 啟動(dòng)每個(gè)節(jié)點(diǎn)
| $ cd rel $ ./riak/bin/riak start $ ./riak2/bin/riak start $ ./riak3/bin/riak start |
最后,將節(jié)點(diǎn)連接起來形成群集,如 清單 2 所示。
清單 2. 清單 2. 形成群集
| $ ./riak2/bin/riak-admin join riak@127.0.0.1 $ ./riak3/bin/riak-admin join riak@127.0.0.1 |
您現(xiàn)在應(yīng)該創(chuàng)建了一個(gè)在本地運(yùn)行的 3 節(jié)點(diǎn)群集。要進(jìn)行測(cè)試,運(yùn)行如下命令: $ ./riak/bin/riak-admin status | grep ring_members。
您應(yīng)當(dāng)看到,每個(gè)節(jié)點(diǎn)都是剛剛創(chuàng)建的群集的一部分,例如 ring_members : ['riak2@127.0.0.1','riak3@127.0.0.1','riak@127.0.0.1']。
回頁首
Riak API
目前有三種方式可以訪問 Riak:HTTP API(RESTful 界面)、Protocol Buffers 和一個(gè)原生 Erlang 界面。提供多個(gè)界面使您能夠選擇如何集成應(yīng)用程序。如果您使用 Erlang 編寫應(yīng)用程序,那么應(yīng)當(dāng)使用原生的 Erlang 界面,這樣就可以將二者緊密地集成在一起。其他一些因素也會(huì)影響界面的選擇,比如性能。例如,使用 Protocol Buffers 界面的客戶端的性能要比使用 HTTP API 的客戶端性能更高一些;從性能方面講,數(shù)據(jù)通信量變小,解析所有這些 HTTP 標(biāo)頭的開銷相對(duì)更高。然而,使用 HTTP API 的優(yōu)點(diǎn)是,如今的大部分開發(fā)人員(特別是 Web 開發(fā)人員)非常熟悉 RESTful 界面,再加上大多數(shù)編程語言都有內(nèi)置的原語,支持通過 HTTP 請(qǐng)求資源,例如,打開一個(gè) URL,因此不需要額外的軟件。在本文中,我們將重點(diǎn)介紹 HTTP API。
所有示例都將使用 curl 通過 HTTP 界面與 Riak 交互。這樣做是為了更好地理解底層的 API。許多語言都提供了大量客戶端庫,在開發(fā)使用 Riak 作為數(shù)據(jù)存儲(chǔ)的應(yīng)用程序時(shí),應(yīng)當(dāng)考慮使用這些客戶端庫。客戶端庫提供了與 Riak 連接的 API,可以輕松地與應(yīng)用程序集成;您不必親自編寫代碼來處理在使用 curl 時(shí)出現(xiàn)的響應(yīng)。
API 支持常見的 HTTP 方法:GET、PUT、POST、DELETE,它們將分別用于檢索、更新、創(chuàng)建和刪除對(duì)象。我們稍后將依次介紹每一種方法。
存儲(chǔ)對(duì)象
您可以將 Riak 看成是創(chuàng)建鍵(字符串)與值(對(duì)象)的分布式映射。Riak 將值保存在 bucket 中。在保存對(duì)象之前,不需要顯式地創(chuàng)建 bucket;如果將對(duì)象保存到一個(gè)不存在的 bucket 中,則會(huì)自動(dòng)創(chuàng)建該 bucket。
Bucket 在 Riak 中是一個(gè)虛擬概念,主要是為了對(duì)相關(guān)對(duì)象分組而存在。bucket 還具有其他一些屬性,這些屬性的值定義了 Riak 對(duì)存儲(chǔ)在其中的對(duì)象的處理。下面是 bucket 屬性的一些示例:
- n_val:對(duì)象在群集內(nèi)進(jìn)行復(fù)制的次數(shù)
- allow_mult:是否允許并發(fā)更新
您可以通過對(duì) bucket 發(fā)出 GET 請(qǐng)求查看 bucket 的屬性(及其當(dāng)前值)。
要存儲(chǔ)對(duì)象,我們將對(duì) 清單 3 所示的其中一個(gè) URL 執(zhí)行 HTTP POST。
清單 3. 清單 3. 存儲(chǔ)對(duì)象
| POST -> /riak/<bucket> (1) POST -> /riak/<bucket>/<key> (2) |
鍵可以由 Riak (1)自動(dòng)分配,或由用戶 (2) 定義。
當(dāng)使用用戶定義的鍵存儲(chǔ)對(duì)象時(shí),也可以向 (2) 執(zhí)行一個(gè) HTTP PUT 操作來創(chuàng)建對(duì)象。
Riak 的最新版本還支持以下 URL 格式:/buckets/<bucket>/keys/<key>,但是在本文中,我們將使用更舊的格式來維持與早期 Riak 版本的向后兼容性。
如果沒有指定鍵,Riak 會(huì)自動(dòng)為對(duì)象分配一個(gè)鍵。例如,我們將在 bucket “foo” 中存儲(chǔ)一個(gè)明文對(duì)象,并且不會(huì)顯式指定鍵(參見 清單 4)。
清單 4. 清單 4. 在不顯式指定鍵的情況下存儲(chǔ)一個(gè)明文對(duì)象
| $ curl -i -H "Content-Type: plain/text" -d "Some text" \ http://localhost:8098/riak/foo/HTTP/1.1 201 Created Vary: Accept-Encoding Location: /riak/foo/3vbskqUuCdtLZjX5hx2JHKD2FTK Content-Type: plain/text Content-Length: ... |
通過檢查 Location 標(biāo)頭,您可以看到 Riak 分配給對(duì)象的鍵。這樣做不容易記憶,因此另一種選擇是讓用戶提供鍵。讓我們創(chuàng)建一個(gè)藝術(shù)家 bucket,并添加一個(gè)叫做 Bruce 的藝術(shù)家(參見 清單 5)。
清單 5. 清單 5. 創(chuàng)建一個(gè)藝術(shù)家 bucket 并添加一個(gè)藝術(shù)家
| $ curl -i -d '{"name":"Bruce"}' -H "Content-Type: application/json" \ http://localhost:8098/riak/artists/BruceHTTP/1.1 204 No Content Vary: Accept-Encoding Content-Type: application/json Content-Length: ... |
如果使用我們指定的鍵成功存儲(chǔ)了對(duì)象,我們將從服務(wù)器得到一個(gè) 204 No Content 響應(yīng)。
在本例中,我們將對(duì)象的值保存為 JSON,但是它既可以是明文格式,也可以是其他格式。在存儲(chǔ)對(duì)象時(shí),需要注意正確設(shè)置 Content-Type 標(biāo)頭。例如,如果希望存儲(chǔ)一個(gè) JPEG 圖像,那么您必須將內(nèi)容類型設(shè)置為 image/jpeg。
檢索對(duì)象
要檢索已存儲(chǔ)的對(duì)象,使用您希望檢索的對(duì)象的鍵對(duì) bucket 運(yùn)行 GET 方法。如果對(duì)象存在,則會(huì)在響應(yīng)的正文中返回對(duì)象,否則服務(wù)器會(huì)返回 404 Object Not Found 響應(yīng)(參見 清單 6)。
清單 6. 清單 6. 在 bucket 上執(zhí)行一個(gè) GET 方法
| $ curl http://localhost:8098/riak/artists/BruceHTTP/1.1 200 OK ... { "name" : "Bruce" } |
更新對(duì)象
在更新對(duì)象時(shí),和存儲(chǔ)對(duì)象一樣,需要用到 Content-Type 標(biāo)頭。例如,讓我們來添加 Bruce 的別名,如 清單 7 所示。
清單 7. 清單 7. 添加 Bruce 的別名
| $ curl -i -X PUT -d '{"name":"Bruce", "nickname":"The Boss"}' \ -H "Content-Type: application/json" http://localhost:8098/riak/artists/Bruce |
如前所述,Riak 自動(dòng)創(chuàng)建了 bucket。這些 bucket 擁有一些屬性,其中一個(gè)屬性為 allow_mult,用于確定是否允許執(zhí)行并發(fā)寫操作。默認(rèn)情況下,該屬性被設(shè)置為 false;但是,如果允許進(jìn)行并發(fā)更新,則需要向每個(gè)更新發(fā)送 X-Riak-Vclock 標(biāo)頭。應(yīng)該將該標(biāo)頭的值設(shè)置為與客戶端最后一次讀取對(duì)象時(shí)看到的值相同。
Riak 使用向量時(shí)鐘 (vector clock) 判斷修改對(duì)象的原因。向量時(shí)鐘的工作原理超出了本文的討論范圍,但是,在允許執(zhí)行并發(fā)寫操作時(shí),可能會(huì)出現(xiàn)沖突,這時(shí)需要使用應(yīng)用程序來解決這些沖突(參閱 參考資料)。
刪除對(duì)象
刪除對(duì)象的操作使用了一個(gè)與前面的命令類似的模式,我們只需要對(duì)希望刪除的對(duì)象所對(duì)應(yīng)的 URL 執(zhí)行一個(gè) HTTP DELETE 方法: $ curl -i -X DELETE http://localhost:8098/riak/artists/Bruce。
如果成功刪除對(duì)象,我們會(huì)從服務(wù)器獲得一個(gè) 204 No Content 響應(yīng);如果試圖刪除的對(duì)象不存在,那么服務(wù)器會(huì)返回一個(gè) 404 Object Not Found 響應(yīng)。
回頁首
鏈接
目前為止,我們已經(jīng)了解了如何通過將對(duì)象與特定鍵相關(guān)聯(lián)來存儲(chǔ)對(duì)象,稍后可以使用此特定鍵來檢索對(duì)象。如果能夠?qū)⑦@個(gè)簡(jiǎn)單的模型進(jìn)行擴(kuò)展以表示對(duì)象如何(以及是否)與其他對(duì)象相關(guān),那么這會(huì)非常有用。我們當(dāng)然可以實(shí)現(xiàn)這一點(diǎn),并且 Riak 是使用鏈接實(shí)現(xiàn)的。
那么,什么是鏈接?鏈接允許用戶創(chuàng)建對(duì)象之間的關(guān)系。如果熟悉 UML 類圖的話,您可以將鏈接看作是對(duì)象之間的某種關(guān)聯(lián),并用一個(gè)書簽說明這種關(guān)系;在關(guān)系數(shù)據(jù)庫中,該關(guān)系被表示為一個(gè)外鍵。
通過 “Link” 標(biāo)頭,以將鏈接 “依附” 到對(duì)象上。下面演示了鏈接標(biāo)頭看起來是什么樣子。例如,關(guān)系的目標(biāo)(即我們準(zhǔn)備進(jìn)行鏈接的對(duì)象)是尖括號(hào)中的內(nèi)容。關(guān)系內(nèi)容(本例中為 “performer”)是通過 riaktag 屬性來表示的:Link: </riak/artists/Bruce>; riaktag="performer"。
現(xiàn)在讓我們添加一些專輯,并將它們與專輯的表演者藝術(shù)家 Bruce 關(guān)聯(lián)起來(參見 清單 8)。
清單 8. 清單 8. 添加一些專輯
| $ curl -H "Content-Type: text/plain" \ -H 'Link: </riak/artists/Bruce> riaktag="performer"' \ -d "The River" http://localhost:8098/riak/albums/TheRiver$ curl -H "Content-Type: text/plain" \ -H 'Link: </riak/artists/Bruce> riaktag="performer"' \ -d "Born To Run" http://localhost:8098/riak/albums/BornToRun |
現(xiàn)在我們已經(jīng)設(shè)置了一些關(guān)系,接下來要通過 link walking 查詢它們,link walking 是一個(gè)用于查詢對(duì)象關(guān)系的進(jìn)程。例如,要查找表演 River 專輯的藝術(shù)家,您應(yīng)當(dāng)這樣做:$ curl -i http://localhost:8098/riak/albums/TheRiver/artists,performer,1。
末尾的位是鏈接說明。鏈接查詢的外觀就是這個(gè)樣子。第一個(gè)部分(artists)指定我們應(yīng)當(dāng)執(zhí)行查詢的 bucket。第二個(gè)部分(performer)指定了我們希望用于限制結(jié)果的標(biāo)簽,最后的 1 部分表示我們希望包含這個(gè)查詢階段的結(jié)果。
還可以發(fā)出過渡性查詢。假設(shè)我們?cè)趯]嫼退囆g(shù)家之間建立了關(guān)系,如 圖 1 所示。
圖 1. 圖 1. 專輯和藝術(shù)家之間的關(guān)系
通過執(zhí)行下面的命令,可以發(fā)出 “哪些藝術(shù)家與表演 The River 專輯的藝術(shù)家合作過” 之類的查詢:$ curl -i http://localhost:8098/riak/albums/TheRiver/artists,_,0/artists,collaborator,1。鏈接說明中的下劃線的作用類似于通配符,表示我們不關(guān)心具體的關(guān)系是什么。
回頁首
運(yùn)行 Map/Reduce 查詢
Map/Reduce 是一個(gè)由 Google 推廣的框架,用于在大型數(shù)據(jù)集上同時(shí)運(yùn)行分布式計(jì)算。Riak 還提供 Map/Reduce 支持,它允許對(duì)群集中的數(shù)據(jù)運(yùn)行功能更強(qiáng)大的查詢。
Map/Reduce 函數(shù)包括一個(gè) map 階段和一個(gè) reduce 階段。map 階段應(yīng)用于某些數(shù)據(jù)并生成 0 個(gè)或多個(gè)結(jié)果;這在編程中類似于通過列表中的每一項(xiàng)映射函數(shù)。map 階段是并行發(fā)生的。reduce 階段將獲取 map 階段的所有結(jié)果,并將它們組合起來。
例如,計(jì)算某個(gè)單詞在大量文檔中出現(xiàn)的次數(shù)。每個(gè) map 階段都將計(jì)算每個(gè)單詞在特定文檔中出現(xiàn)的次數(shù)。這些中間計(jì)數(shù)在計(jì)算完后將發(fā)送到 reduce 函數(shù),然后計(jì)算總數(shù)并得出在所有文檔中的次數(shù)。參見 參考資料,獲得有關(guān) Google 的 Map/Reduce 文章的鏈接。
回頁首
示例:分布式 grep
對(duì)于本文,我們將開發(fā)一個(gè) Map/Reduce 函數(shù),該函數(shù)將對(duì) Riak 中存儲(chǔ)的一組文檔執(zhí)行一次分布式 grep。和 grep 一樣,最終的輸出是一些匹配所提供模式的行。此外,每個(gè)結(jié)果還將表示文檔中出現(xiàn)匹配時(shí)所在位置的行號(hào)。
要執(zhí)行一個(gè) Map/Reduce 查詢,我們將對(duì) /mapred 資源執(zhí)行 POST 操作。請(qǐng)求的內(nèi)容是查詢的 JSON 表示;和前面的例子一樣,必須提供 Content-Type 標(biāo)頭,并且始終將其設(shè)置為 application/json。清單 9 顯示了我們?yōu)閳?zhí)行分布式 grep 而做的查詢。后面將依次討論查詢的每一個(gè)部分。
清單 9. 清單 9. 示例 Map/Reduce 查詢
| {"inputs": [["documents","s1"],["documents","s2"]],"query": [{ "map": { "language": "javascript", "name": "GrepUtils.map", "keep": true, "arg": "[s|S]herlock" } },{ "reduce": { "language": "javascript", "name": "GrepUtils.reduce" } }] } |
每個(gè)查詢都包含若干輸入,例如,我們希望對(duì)之執(zhí)行計(jì)算的文檔,在 map 和 reduce 階段運(yùn)行的函數(shù)的名稱。也可以直接在查詢中包含 map 和 reduce 函數(shù)的源代碼,只需要使用源屬性替代名稱即可,但是我在本例中沒有這樣做;然而,要使用指定的函數(shù),則需要對(duì) Riak 的默認(rèn)配置進(jìn)行一些修改。將清單 9 中的代碼保存到某個(gè)目錄中。對(duì)于群集中的每個(gè)節(jié)點(diǎn),找到文件 etc/app.config,打開它并將屬性 property js_source_dir 設(shè)置為您用于保存代碼的目錄。您需要重啟群集中的所有節(jié)點(diǎn)使變更生效。
清單 10 中的代碼包含將在 map 和 reduce 階段執(zhí)行的函數(shù)。map 函數(shù)將查看文檔的每一行,確定是否與提供的模式(arg 參數(shù))匹配。本例中的 reduce 函數(shù)并不會(huì)執(zhí)行太多操作;它類似于一個(gè)恒等函數(shù),僅僅用于返回輸入。
清單 10. 清單 10. GrepUtils.js
| var GrepUtils = { map: function (v, k, arg) {var i, len, lines, r = [], re = new RegExp(arg);lines = v.values[0].data.split(/\r?\n/); for (i = 0, len = lines.length; i < len; i += 1) {var match = re.exec(lines[i]);if (match) {r.push((i+1) + “. “ + lines[i]);}}return r;}, reduce: function (v) {return [v];} }; |
在運(yùn)行查詢之前,我們需要一些數(shù)據(jù)。我從 Project Gutenberg Web 站點(diǎn)下載了 Sherlock Holmes 電子圖書(參見 參考資料)。第一個(gè)文本存儲(chǔ)在鍵 “s1” 下的 “documents” bucket 中;第二個(gè)文本位于同一個(gè) bucket 中,鍵為 “s2”。
清單 11 展示了如何將這類文檔上傳到 Riak。
清單 11. 清單 11. 將文檔上傳到 Riak
| $ curl -i -X POST http://localhost:8098/riak/documents/s1 \ -H “Content-Type: text/plain” --data-binary @s1.txt |
上傳文檔后,我們現(xiàn)在可以對(duì)文檔執(zhí)行搜索。在本例中,我們想輸出匹配常規(guī)表達(dá)式 "[s|S]herlock"(參見 清單 12)的所有行。
清單 12. 清單 12. 搜索文檔
| $ curl -X POST -H "Content-Type: application/json" \ http://localhost:8098/mapred --data @-<<\EOF {"inputs": [["documents","s1"],["documents","s2"]],"query": [{ "map": { "language":"javascript", "name":"GrepUtils.map", "keep":true, "arg": "[s|S]herlock" } },{ "reduce": { "language": "javascript", "name": "GrepUtils.reduce" } }] } EOF |
查詢中的 arg 屬性包含我們希望在文檔中對(duì)其執(zhí)行 grep 查詢的模式;該值被作為 arg 參數(shù)傳遞給 map 函數(shù)。
清單 13 中顯示了對(duì)樣例數(shù)據(jù)運(yùn)行 Map/Reduce 作業(yè)所產(chǎn)生的輸出。
清單 13. 清單 13. 運(yùn)行 Map/Reduce 作業(yè)的樣例輸出
| [["1. Project Gutenberg's The Adventures of Sherlock Holmes, by Arthur Conan Doyle","9. Title: The Adventures of Sherlock Holmes","62. To Sherlock Holmes she is always THE woman. I have seldom heard","819. as I had pictured it from Sherlock Holmes' succinct description,","1017. \"Good-night, Mister Sherlock Holmes.\"","1034. \"You have really got it!\" he cried, grasping Sherlock Holmes by" …]] |
回頁首
流化 Map/Reduce
在關(guān)于 Map/Reduce 的最后部分中,我們將簡(jiǎn)單地了解 Riak 的 Map/Reduce 流化 (streaming) 特性。該特性對(duì)于包含 map 階段并需要花一些時(shí)間完成這些階段的作業(yè)非常有用,因?yàn)閷?duì)結(jié)果進(jìn)行流化允許您在生成每個(gè) map 階段的結(jié)果后立即訪問它們,并且在執(zhí)行 reduce 階段之前訪問它們。
我們可以對(duì)分布式 grep 查詢應(yīng)用這個(gè)特性。本例中的 reduce 步驟并沒有多少實(shí)際操作。事實(shí)上,我們完全可以去掉 reduce 階段,只需要將每個(gè) map 階段的結(jié)果直接發(fā)送到客戶端即可。為了實(shí)現(xiàn)此目標(biāo),需要對(duì)查詢進(jìn)行修改,刪除 reduce 步驟,將 ?chunked=true 添加到 URL 末尾,表示我們希望對(duì)結(jié)果進(jìn)行流化(參見 清單 14)。
清單 14. 清單 14. 修改查詢以流化結(jié)果
| $ curl -X POST -H "Content-Type: application/json" \ http://localhost:8098/mapred?chunked=true --data @-<<\EOF { "inputs": [["documents","s1"],["documents","s2"]],"query": [{ "map": {"language": "javascript", "name": "GrepUtils.map","keep": true, "arg": "[s|S]herlock" } }] } EOF |
在完成 map 階段后,會(huì)將每個(gè) map 階段的結(jié)果(在本例中為匹配查詢字符串的行)返回給客戶端。該方法可用于需要在查詢的中間結(jié)果可用時(shí)就對(duì)它們進(jìn)行處理的應(yīng)用程序。
回頁首
結(jié)束語
Riak 是基于 Amazon 的 Dynamo 文件中記載的規(guī)則的一種開源的、高度可擴(kuò)展的鍵值存儲(chǔ)庫。Riak 非常易于部署和擴(kuò)展。可以無縫地向群集添加額外的節(jié)點(diǎn)。link walking 之類的特性以及對(duì) Map/Reduce 的支持允許實(shí)現(xiàn)更加復(fù)雜的查詢。除了 HTTP API 外,Riak 還提供了一個(gè)原生 Erlang API 以及對(duì) Protocol Buffer 的支持。在本系列的第 2 部分中,我們將探討各種不同語言中的大量客戶端庫,并展示如何將 Riak 用作一種高度可擴(kuò)展的緩存。
參考資料
學(xué)習(xí)
- 參見 Basic Cluster Setup and Building a Development Environment,獲得有關(guān)設(shè)置一個(gè) 3 節(jié)點(diǎn)群集的詳細(xì)信息。
- 閱讀 Google 的 MapReduce: Simplified Data Processing on Large Clusters。
- Erlang 編程簡(jiǎn)介,第 1 部分(Martin Brown,developerWorks,2011 年 5 月):對(duì) Erlang 的函數(shù)性編程風(fēng)格與其他編程模式進(jìn)行了比較,如命令式、過程式和面向?qū)ο蟮木幊獭?
- 強(qiáng)烈建議閱讀 Amazon 的 Dynamo 文檔,以了解 Riak 的基礎(chǔ)知識(shí)。
- 閱讀文章 How To Analyze Apache Logs,了解如何使用 Riak 處理您的服務(wù)器日志。
- 了解 向量時(shí)鐘,以及為什么它們要比您想象的更加容易理解。
- 在 Riak wiki 上找到有關(guān) 向量時(shí)鐘 的出色介紹,以及更多有關(guān) link walking 的信息。
- 如果您需要一些文本資源進(jìn)行測(cè)試的話,Project Gutenberg 站點(diǎn) 是一個(gè)不錯(cuò)的選擇。
- developerWorks 中國(guó)網(wǎng)站 Web 開發(fā)專區(qū) 提供了涵蓋各種基于 Web 的解決方案的文章。
- 要收聽面向軟件開發(fā)人員的有趣訪談和討論,請(qǐng)參閱 developerWorks podcasts。
- IBM Rational Twitter:立即加入并關(guān)注 developerWorks tweets。
- 觀看 演示如何用 WebSphere Studio 快速開發(fā)Web Services,其中包括面向初學(xué)者的產(chǎn)品安裝和設(shè)置演示,以及為經(jīng)驗(yàn)豐富的開發(fā)人員提供的高級(jí)功能。
- 隨時(shí)關(guān)注 developerWorks 技術(shù)活動(dòng)和網(wǎng)絡(luò)廣播。
- 訪問 developerWorks Open source 專區(qū)獲得豐富的 how-to 信息、工具和項(xiàng)目更新以及最受歡迎的文章和教程,幫助您用開放源碼技術(shù)進(jìn)行開發(fā),并將它們與 IBM 產(chǎn)品結(jié)合使用。
獲得產(chǎn)品和技術(shù)
- 從 basho.com 下載 Riak。
- 下載 Erlang 編程語言。
- 使用專門面向開發(fā)人員的軟件創(chuàng)新您的下一個(gè)開源開發(fā)項(xiàng)目;訪問 IBM 產(chǎn)品評(píng)估試用版軟件,可以通過下載或從 DVD 獲得它。?
總結(jié)
以上是生活随笔為你收集整理的Riak 简介,第 1 部分: 与语言无关的 HTTP API的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis缓存对象相关
- 下一篇: html5如何实现无序排列,无序列表让l