本文摘自:http://blog.umcloud.com/metasearch/
從一本食譜開始說起
多年前,一名職場(chǎng)失意的程序員帶著新婚妻子去倫敦生活,迫于生活壓力,妻子決定從事廚師這一份工作來維持家庭開支。廚師最缺的就是一本好用的菜譜,但由于菜目數(shù)量龐大,查閱起來不方便,因此這名程序員就決定為妻子寫一個(gè)食物搜索引擎。而這個(gè)食物搜索引擎,正是日后大名鼎鼎的Lucene的前身,而這名程序員就是Shay Banon,Lucene的奠基者。由于Lucene使用復(fù)雜,他的妻子使用起來非常困難,Shay隨后就對(duì)Lucene的代碼進(jìn)行抽象分裝,使得其他程序員可以在應(yīng)用中使用Lucene來添加全文搜索功能,Shay將這個(gè)項(xiàng)目取名為Compass,從此進(jìn)入了開源領(lǐng)域。
憑借Compass優(yōu)秀的功能,Shay隨后順利找到了一份工作,這份工作處于高性能和內(nèi)存網(wǎng)格的分布式環(huán)境中,對(duì)搜索引擎的要求更高。Shay決定重寫Compass庫,使其成為一個(gè)獨(dú)立的服務(wù) – ElasticSearch。這個(gè)項(xiàng)目的意義重大自然不用說,無論是開源還是專有領(lǐng)域,Lucene都被認(rèn)為是迄今為止性能較好、功能較為全面的搜索引擎庫,而ElasticSearch將復(fù)雜的Lucene封裝起來,開放簡(jiǎn)單的Restful API,讓用戶能十分方便地使用。

Figure 1.1 – ElasticSearch logo
目前ElasticSearch已經(jīng)成為了Github上比較受歡迎的項(xiàng)目之一,代碼貢獻(xiàn)量也超過百人,并且隨之產(chǎn)生的產(chǎn)品還有Kibana、Logstash等,而這一切,卻只是源于一本食譜。
棋逢對(duì)手
在去年的11月份,HDS(Hitachi Data System)公司發(fā)布了它的新產(chǎn)品HCI(Hitachi Content Intelligence),這款內(nèi)容智能方案可以立足于多種結(jié)構(gòu)化與非結(jié)構(gòu)化的數(shù)據(jù)孤島進(jìn)行搜索與內(nèi)容讀取,然后對(duì)其加以分析。作為HDS對(duì)象存儲(chǔ)產(chǎn)品組合(簡(jiǎn)稱HCP)中的一部分,HCI幫助這套整體方案實(shí)現(xiàn)文件同步與共享、云存儲(chǔ)網(wǎng)關(guān)以及新的搜索與分析功能。HCI能夠運(yùn)行在物理或者虛擬服務(wù)器之上,亦可被托管于公有或者私有云當(dāng)中。

Figure 2.1 –HCI數(shù)據(jù)連接示意圖****
HCI所提供的數(shù)據(jù)連接器能夠支持Hitachi Content Platform、Hitachi Data Ingestor、HCP Anywhere、S3托管存儲(chǔ)庫以及文件系統(tǒng)(CIFS/NFS)。HCI擁有完備的說明文檔,包括一套包含示例的軟件開發(fā)者工具包,合作伙伴與客戶可利用其創(chuàng)建未直接提供的、指向各類數(shù)據(jù)存儲(chǔ)庫的連接。HCI可作為一組容器進(jìn)行實(shí)例化,并作為一項(xiàng)自助式服務(wù)實(shí)體被交付給用戶,同時(shí)提供對(duì)詳盡查詢與自然語言查詢的支持能力。HCI的開發(fā)團(tuán)隊(duì)表示,他們使用了Solr來作為HCI的內(nèi)容搜索引擎。咦,Solr是什么?
如今我們正處于一個(gè)信息大爆炸的年代,數(shù)據(jù)的急速增長(zhǎng)考量著信息技術(shù)產(chǎn)業(yè)各個(gè)維度、各個(gè)角落,幾乎每個(gè)領(lǐng)域都需要更快更好的產(chǎn)品來滿足用戶的需求。同樣,在搜索領(lǐng)域,如何快速地搜索數(shù)據(jù)便成為了一個(gè)重大的后端挑戰(zhàn),在上一章中我們已經(jīng)介紹了性能優(yōu)異的ElasticSearch,然而同樣在Lucene開源平臺(tái)上,還有另一個(gè)優(yōu)秀的開源搜索引擎:Solr。

Figure 2.2 – Google Trends :ElasticSearch vs Solr
如果我們查詢Google Trends,會(huì)發(fā)現(xiàn)ElasticSearch的熱度是遠(yuǎn)遠(yuǎn)高于Solr,但是即便如此,作為一款成熟的產(chǎn)品,Solr也擁有強(qiáng)大而廣泛的用戶群體。 它提供分布式索引,復(fù)制,負(fù)載平衡查詢和自動(dòng)故障轉(zhuǎn)移和修復(fù)等功能。 如果部署正確,然后進(jìn)行良好的管理,Slor完全可以成為一個(gè)高可靠,可擴(kuò)展,容錯(cuò)高的搜索引擎。 Netflix,eBay,Instagram和 Amazon(CloudSearch)等幾家互聯(lián)網(wǎng)巨頭都使用Solr,當(dāng)然也包括了我們前文介紹的HDS。
數(shù)據(jù)源對(duì)比
Solr支持多種數(shù)據(jù)源、多種格式的索引,比如XML、CSV、JSON等純文本格式,還有HTML、PSD、微軟Office系列軟件的格式等。 Elasticsearch在這方面表現(xiàn)可以說不分伯仲,同樣支持多種數(shù)據(jù)類型,如ActiveMQ,AWS SQS,DynamoDB(Amazon NoSQL),F(xiàn)ileSystem,Git,JDBC,JMS,Kafka,LDAP,MongoDB等,當(dāng)然還有豐富的第三方插件。
文檔對(duì)比
Solr在這里分?jǐn)?shù)很高。 它的文檔組織十分良好,具有API用例的明確示例和上下文說明,我們可以方便的找到一些關(guān)于例如查詢和更新索引的語法內(nèi)容,而不需要深挖源代碼。 Elasticsearch在這方面就乏善可陳一些了,雖然文檔是有組織的,但它缺少很好的例子和明確的配置說明,一些例子是用YAML編寫的,有些是JSON,你經(jīng)常能發(fā)現(xiàn)代碼邏輯與文檔的內(nèi)容之間存在一些差異。
社區(qū)
Solr擁有一個(gè)成熟的開發(fā)和貢獻(xiàn)者社區(qū),任何人都可以為Solr寫代碼,只要你的代碼和功能夠好。ElasticSearch在技術(shù)上是開源的,所有貢獻(xiàn)者都可以訪問源代碼,用戶可以修改源代碼,但是用戶的源代碼是否能被接納還是取決于Elastic的員工。所以就這一點(diǎn)來說,我為Solr轉(zhuǎn)身。
搜索性能對(duì)比
這兩個(gè)搜索引擎都使用各種分析器和標(biāo)記器,將文本分解成terms或tokens,然后進(jìn)行索引。 Elasticsearch允許指定查詢分析器列表;相比之下,Solr不支持此功能。Solr更傾向于文本搜索,而Elasticsearch通常用于分析查詢,過濾和聚合。 Elasticsearch的開發(fā)團(tuán)隊(duì)一直在努力通過各種方法(通過減少內(nèi)存占用和CPU使用等)來提高ElasticSearch的查詢效率。并且在實(shí)時(shí)環(huán)境中,如果用戶在建立索引同時(shí)查詢,Solr的查詢效率會(huì)比較差。

Figure 2.3 –建立索引并查詢時(shí),ElasticSearch和Solr搜索性能對(duì)比
當(dāng)比較兩者時(shí),很顯然,如果我們的應(yīng)用情景不局限于文本搜索,就搜索性能來說,Elasticsearch將會(huì)是更好的選擇。
擴(kuò)展性、分布式對(duì)比
shards作為L(zhǎng)ucene索引的基本分區(qū)單元,Solr和ElasticSearch都使用它們。 我們可以通過在集群中的不同設(shè)備上運(yùn)行分片來分發(fā)索引。相比較而言,Solr允許添加shards(使用隱式路由時(shí))或拆分(使用復(fù)合ID時(shí)),并且允許用戶增加副本,但是我們不能刪除shards。在ElasticSearch中,默認(rèn)情況下每個(gè)索引都有五個(gè)shards。 我們不能更改primary shards的數(shù)量,但它允許我們?cè)黾痈北镜臄?shù)量。ElasticSearch的自動(dòng)分片重平衡功能對(duì)于擴(kuò)展集群時(shí)很有用。,如果我們添加新機(jī)器,它將自動(dòng)平衡不同設(shè)備中可用的分片。
總結(jié)
綜上所述,雖然ElasticSeach的文檔不是很完善,但是憑借其優(yōu)秀搜索表現(xiàn),以及更符合RESTful的設(shè)計(jì),我還是比較推崇ElasticSearch來作為對(duì)象存儲(chǔ)的元數(shù)據(jù)搜索引擎。
存儲(chǔ)界的深海巨獸
或許和Linux、Openstack這些開源界的航母比起來,這個(gè)項(xiàng)目顯得不那么的如雷貫耳,但是如果你遇到一個(gè)存儲(chǔ)行業(yè)的從業(yè)者,和他談起Ceph,他一定不會(huì)陌生。
Ceph 最初是一項(xiàng)關(guān)于存儲(chǔ)系統(tǒng)的PhD 研究項(xiàng)目,由 Sage Weil 在University of California, Santa Cruz(UCSC)實(shí)施,其初衷是為了開發(fā)一個(gè)分布式文件系統(tǒng),但隨著項(xiàng)目開發(fā)者越來越多,Ceph已經(jīng)提供了完整的統(tǒng)一存儲(chǔ)方案,涵蓋了塊存儲(chǔ)、對(duì)象存儲(chǔ)和文件系統(tǒng)存儲(chǔ)。從2010 年 3 月底,我們可以在主線 Linux 內(nèi)核(從 2.6.34 版開始)中找到 Ceph 的身影。
作為一款分布式存儲(chǔ)系統(tǒng),Ceph集結(jié)多個(gè)優(yōu)良的特點(diǎn):
- 高擴(kuò)展性:使用普通x86服務(wù)器,支持10~1000臺(tái)服務(wù)器,支持TB到PB級(jí)的擴(kuò)展。
- 高可靠性:沒有單點(diǎn)故障,多數(shù)據(jù)副本,自動(dòng)管理,自動(dòng)修復(fù)。
- 高性能:數(shù)據(jù)分布均衡,并行化度高。對(duì)于objects storage和block storage,不需要元數(shù)據(jù)服務(wù)器。

Figure 3.1 – Ceph結(jié)構(gòu)圖
Ceph底層提供了分布式的RADOS存儲(chǔ),用與支撐上層的librados和RGW(對(duì)象存儲(chǔ))、RBD(塊存儲(chǔ))、CephFS(文件系統(tǒng)存儲(chǔ))等服務(wù)。Ceph實(shí)現(xiàn)了非常底層的對(duì)象存儲(chǔ),是純粹的SDS,并且支持XFS文件系統(tǒng),能輕易得Scale,沒有單點(diǎn)故障。Ceph 使用自動(dòng)恢復(fù)、多副本技術(shù),即使有多臺(tái)存儲(chǔ)節(jié)點(diǎn)發(fā)生故障,也不影響數(shù) 據(jù)的可靠性和可用性。 全分布式架構(gòu)放入底層支持多硬盤同時(shí)并行工作,容量和性能可以線性擴(kuò)展。憑借其優(yōu)異的性能,目前已經(jīng)有越來越多的公司使用Ceph作為分布式存儲(chǔ)解決方案,而這其中,UMCloud已經(jīng)實(shí)現(xiàn)部署30PB級(jí)別的Ceph集群,是目前世界上規(guī)模比較大的Ceph集群。
對(duì)象存儲(chǔ)-為互聯(lián)網(wǎng)而生
隨著互聯(lián)網(wǎng)、Web2.0技術(shù)的快速更替,用戶可以分享海量的照片、視頻、音樂。全世界的Web應(yīng)用每天會(huì)創(chuàng)建出成千上億的小文件;Youtube、Facebook這些熱門網(wǎng)站每天都新增數(shù)十億條內(nèi)容,人們每天發(fā)送數(shù)千億封電子郵件。據(jù)IDC統(tǒng)計(jì)未來在10年間數(shù)據(jù)將增長(zhǎng)44倍,到2020年全球數(shù)據(jù)將增加到35ZB,其中80%是非結(jié)構(gòu)化數(shù)據(jù),且大部分是非活躍數(shù)據(jù)。
面對(duì)如此龐大的數(shù)據(jù)上傳量,塊存儲(chǔ)(SAN)和文件存儲(chǔ)(NAS)顯得有些局促。通常塊存儲(chǔ)的一個(gè)LUN容量?jī)H數(shù)TB,而一個(gè)文件系統(tǒng)支持的文件數(shù)量通常只在百萬級(jí)別。人們需要一種全新的架構(gòu)的存儲(chǔ)系統(tǒng)來滿足超大的數(shù)據(jù)量,這種存儲(chǔ)系統(tǒng)需要具備極高的可擴(kuò)展性,能夠滿足人們對(duì)存儲(chǔ)容量TB到EB規(guī)模的擴(kuò)展的需求。在這個(gè)大時(shí)代背景下,對(duì)象存儲(chǔ)應(yīng)運(yùn)而生。
對(duì)象存儲(chǔ)是一種基于對(duì)象的數(shù)據(jù)存儲(chǔ)架構(gòu),具備智能、自我管理能力,采用扁平化結(jié)構(gòu)管理所有數(shù)據(jù),用戶可以通過web服務(wù)協(xié)議實(shí)現(xiàn)對(duì)象的讀寫和存儲(chǔ)資源的訪問。文件系統(tǒng)存儲(chǔ)中數(shù)據(jù)被看成一個(gè)文件層級(jí)樹,在塊存儲(chǔ)中數(shù)據(jù)被區(qū)分成塊和條帶,而在對(duì)象存儲(chǔ)中,數(shù)據(jù)則以對(duì)象的方式管理。一個(gè)對(duì)象包含數(shù)據(jù)本身和其屬性(元數(shù)據(jù)),以及一個(gè)全局唯一的標(biāo)識(shí)符。由于元數(shù)據(jù)被單獨(dú)區(qū)分了出來,用戶可以為一個(gè)對(duì)象自定義元數(shù)據(jù),從而實(shí)現(xiàn)更好的數(shù)據(jù)索引。
2006年,云計(jì)算巨頭Amazon發(fā)布S3,其使用的RESTful和SOAP訪問接口成為了對(duì)象存儲(chǔ)的事實(shí)標(biāo)準(zhǔn)。S3支持存儲(chǔ)最大為5TB的單個(gè)任意對(duì)象,并且每個(gè)對(duì)象可以分配高達(dá)2KB的元數(shù)據(jù)。在S3中,對(duì)象被組織存放在存儲(chǔ)桶(Bucket)中,用戶在秘鑰認(rèn)證后,就可以通過使用RESTful樣式的HTTP接口來訪問存儲(chǔ)桶、對(duì)象及相關(guān)的數(shù)元數(shù)據(jù)等。

Figure 4.1 -Amazon S3 簡(jiǎn)化結(jié)構(gòu)圖
S3雖然不開源,并且收取每月0.15美金/GB的服務(wù)費(fèi)用,但是憑借其提供包括Web托管,映像托管和備份系統(tǒng)等完整的存儲(chǔ)方案,以及超強(qiáng)的穩(wěn)定性(S3保證99.9%的每月正常運(yùn)行時(shí)間服務(wù)水平協(xié)議,即每月不超過43分鐘的停機(jī)時(shí)間),S3還是成為了全球?qū)ο蟠鎯?chǔ)客戶青睞的方案,據(jù)報(bào)道,截至2013年4月,Amazon S3存儲(chǔ)了超過2萬億個(gè)對(duì)象。
等等,難道我們非得使用AWS S3并且每個(gè)月交高昂的服務(wù)費(fèi)來使用對(duì)象存儲(chǔ)嗎?答案是不需要,正如圖三中所列出的,目前開源社區(qū)已經(jīng)提供了成熟的對(duì)象存儲(chǔ)解決方案了,并且提供了兼容S3的接口,所以我們可以搭建本地對(duì)象存儲(chǔ)服務(wù),讓S3對(duì)接我們自己的存儲(chǔ)集群,那么我們要用哪種存儲(chǔ)集群呢?自然是Ceph。

Figure 4.2 – Ceph搭配S3提供對(duì)象存儲(chǔ)
在上一章節(jié)我們已經(jīng)介紹過,Ceph的組件RGW(Rados Gateway)封裝了Rados接口而提供Gateway服務(wù),并且RGW實(shí)現(xiàn)了S3兼容的接口,因此用戶可以使用S3的命令行工具或是S3 SDK來使用RGW。
所以我們要干嘛
盡管Ceph目前已經(jīng)很好地支持了對(duì)象存儲(chǔ),用戶可以通過S3來操作存儲(chǔ)桶、對(duì)象以及設(shè)置對(duì)象元數(shù)據(jù),但是Ceph本身并沒有元數(shù)據(jù)搜索的功能,不能索引元數(shù)據(jù)來訪問對(duì)象。因此在接下來的內(nèi)容中,本文會(huì)介紹如何使用ElasticSearch來實(shí)現(xiàn)Ceph的元數(shù)據(jù)搜索功能。
方案一
這個(gè)方案的架構(gòu)比較直觀,前端應(yīng)用將對(duì)象上傳給Ceph RGW中,并把這個(gè)對(duì)象的自定義元數(shù)據(jù)發(fā)送到ElasticSearch集群中。當(dāng)用戶需要獲取某個(gè)對(duì)象時(shí),先向ElasticSearch發(fā)送搜索請(qǐng)求來獲取對(duì)象地址,該請(qǐng)求可以是對(duì)象名或是對(duì)象id號(hào),亦或是用戶自定義的元數(shù)據(jù)。等到ElasticSearch返回這個(gè)對(duì)象的地址后,前端應(yīng)用通過這個(gè)地址來直接向Ceph RGW獲取對(duì)象本身。


Figure 5.1.2 – 方案一架構(gòu)圖 對(duì)象獲取
方案實(shí)現(xiàn)
部署Ceph集群
Ceph集群部署方法在這邊不再詳細(xì)贅述,大家可以自行查找部署方法,個(gè)人推薦使用Ceph-Ansible來部署,比較簡(jiǎn)單并且節(jié)省時(shí)間。
開啟RGW服務(wù)
我們可以使用Ceph-Ansible來部署RGW,但是在這里還是想介紹一下手動(dòng)配置開啟RGW的方法。
1.每個(gè)rgw實(shí)例都需要一個(gè)授權(quán)用戶及key,下面的例子中創(chuàng)建了一個(gè)名為client.radosgw.gateway的用戶,并將密鑰文件存儲(chǔ)在/etc/ceph目錄下:
`ceph auth get-or-create client.radosgw.gateway osd` `'allow rwx'` `mon` `'allow rwx'` `-o` `/etc/ceph/ceph``.client.radosgw.keyring`
2.將秘鑰文件賦予RGW實(shí)例:
`ceph auth add client.radosgw.gateway --``in``-``file``=``/etc/ceph/ceph``.client.radosgw.keyring`
3.在/etc/ceph/ceph.conf這個(gè)Ceph集群配置文件中加入RGW實(shí)例的配置內(nèi)容
`[client.radosgw.gateway]`
`fsid = xxxxxxxxxxxxxxxxx`
`mon_host = xxxxxxxx:xxxx`
`log` `file` `=` `/var/log/ceph/client``.radosgw.gateway.log`
`keyring =` `/etc/ceph/ceph``.client.radosgw.keyring`
`rgw_frontends =civetweb port=8001`
Ceph可以支持多種種RGW前端配置方法(Apache, Civetweb, Nginx等),這里我們使用默認(rèn)的前端Civetweb,并讓其監(jiān)聽8001端口,keyring參數(shù)對(duì)應(yīng)上文中生成的秘鑰文件地址。在實(shí)際操作中,我還遇到了許多RGW的跨域訪問問題,由于本文側(cè)重介紹元數(shù)據(jù)搜索方法,因此RGW跨域問題的解決方法會(huì)在以后的博文中詳細(xì)解答。
4.啟動(dòng)RGW實(shí)例
`radosgw -c` `/etc/ceph/ceph``.conf -n client.radosgw.gateway`
-c參數(shù)指向Ceph集群配置文件, -n參數(shù)指向RGW實(shí)例名稱
5.啟動(dòng)RGW實(shí)例后,我們可以通過向RGW發(fā)送GET請(qǐng)求來判斷RGW服務(wù)是否正常開啟

配置S3用戶訪問RGW
待RGW實(shí)例啟動(dòng)成功后,我們就需要給S3的訪問做好準(zhǔn)備。我們需要在本地Ceph集群中給S3訪問創(chuàng)建賬號(hào),我們創(chuàng)建一個(gè)accessKey和secretKey均為admin的賬號(hào):
`radosgw-admin user create --uid=admin --secret-key=admin --access-key=admin --display-name=``"admin"`
部署ElasticSearch集群
我們可以在Elastic官網(wǎng)(https://www.elastic.co/downloads/elasticsearch)里下載到新版本的ElasticSearch,解壓縮后直接運(yùn)行即可(需要非root賬戶):
`.``/bin/elasticsearch` `-d`
``
-d參數(shù)讓Elasticsearch運(yùn)行在后臺(tái)。由于這邊只是POC,因此我們只開啟了一個(gè)ElasticSearch節(jié)點(diǎn),并且只開放本地端口,因此不需要修改config下的配置文件。

Elasticsearch的默認(rèn)端口為9200,同樣的做法,我們通過檢測(cè)端口號(hào)確定ElasticSearch正常運(yùn)行。我們也可以發(fā)送一個(gè)HTTP請(qǐng)求來看看ElasticSearch運(yùn)行情況:
curl '[http://localhost:9200/?pretty](http://localhost:9200/?pretty)'
``
ElasticSearch收到請(qǐng)求后會(huì)返回一組JSON格式的數(shù)據(jù):

Demo演示
為了讓整個(gè)流程可視化,我寫了一個(gè)簡(jiǎn)單前端web應(yīng)用,可以讓用戶來自定義一些元數(shù)據(jù)類型。用戶上傳對(duì)象時(shí)需要輸入自定義元數(shù)據(jù)的值。用戶隨后可以搜索相應(yīng)元數(shù)據(jù)來獲取對(duì)象。ElasticSearch和S3都有相應(yīng)的JS SDK,可以很方便地使用他們:S3只需要提供endpoint(指向RGW),accessKey和secretKey就可以來訪問RGW,這三樣?xùn)|西在之前我們都已經(jīng)準(zhǔn)備好;ElasticSearch在程序中只需要指定ElasticSearch的端口即可。

Figure 5.1.3 – Demo演示 – 對(duì)象搜索主頁
我們?cè)谶@邊幾個(gè)自定義元數(shù)據(jù):’Bukcet’用來表明存儲(chǔ)桶名稱,’endpoint’用來標(biāo)記RGW端口, ’Category’用以區(qū)分不同的對(duì)象類別。

Figure 5.1.4 – Demo演示 – 對(duì)象上傳
前端在上傳對(duì)象時(shí),我們?cè)趧偛判绿砑拥脑獢?shù)據(jù)‘Category’寫入’car’,然后前端將對(duì)象本身發(fā)送至Ceph RGW端的bucket2中,將元數(shù)據(jù)發(fā)送到ElasticSearch。我們可以在后臺(tái)檢查是否元數(shù)據(jù)是否已經(jīng)被上傳到ElasticSearch,這里我們對(duì)整個(gè)ElasticSearch進(jìn)行car字樣全文搜索:
`curl -XGET` `'[http://localhost:9200/_search](http://localhost:9200/_search)'`` -d` `'{"query":{"match":{"_all":"car"}}}'`

在后臺(tái)返回結(jié)果中我們可以看到這個(gè)對(duì)象的元數(shù)據(jù)已經(jīng)被上傳至ElasticSearch,并且可以看到這個(gè)對(duì)象名、owner(admin)、新增的元數(shù)據(jù)字段’category’以及對(duì)應(yīng)的值為’car’。Elasticsearch根據(jù)結(jié)果相關(guān)性評(píng)分來對(duì)結(jié)果集進(jìn)行排序,所謂的「結(jié)果相關(guān)性評(píng)分」就是文檔與查詢條件的匹配程度(_score參數(shù))。

Figure 5.1.5 – Demo演示 – 對(duì)象搜索
在搜索框中輸入car,前端隨即向ElasticSearch發(fā)送搜索請(qǐng)求,其實(shí)等同于上面我們?cè)诤笈_(tái)驗(yàn)證時(shí)發(fā)送的請(qǐng)求,前端會(huì)分析ElasticSearch返回的JSON數(shù)據(jù)并且提取對(duì)象地址,然后向RGW發(fā)送請(qǐng)求,RGW返回對(duì)象。
方案一總結(jié)
以上便是方案一的實(shí)現(xiàn)過程,不難看出,這個(gè)方案的思路比較直接,實(shí)現(xiàn)也不難,但是RGW與ElasticSearch之間的數(shù)據(jù)一致性完全依賴于前端應(yīng)用。S3除了SDK以外還有s3cmd這個(gè)命令行工具,RGW自身也可以通過HTTP請(qǐng)求來上傳對(duì)象,試想一下,用戶完全有可能直接在后臺(tái)上傳對(duì)象,而不是通過前端應(yīng)用,這樣就造成了ElasticSearch無法同步對(duì)應(yīng)的元數(shù)據(jù)。
方案二
Ceph在Jewel版本之后加入對(duì)ElasticSearch的支持,我們可以通過定義新的zone類型來實(shí)現(xiàn)RGW元數(shù)據(jù)自動(dòng)同步到ElasticSearch中,這樣一來便保證了RGW和ElasticSearch數(shù)據(jù)的一致性,讓前后端耦合大大降低。

Figure 5.2.1 – 方案二架構(gòu)圖 對(duì)象上傳

Figure 5.2.2 – 方案二架構(gòu)圖 對(duì)象獲取
從架構(gòu)圖可以看出,方案一和方案二的唯一區(qū)別在與對(duì)象上傳:前端上傳對(duì)象時(shí)不再需要上傳元數(shù)據(jù)到ElasticSearch,Ceph RGW中自帶的sync plugin可以自動(dòng)將元數(shù)據(jù)同步到ElasticSearch中去。
Ceph元數(shù)據(jù)同步原理
Ceph的元數(shù)據(jù)同步依賴于RGW Admin API,其更新的依據(jù)對(duì)應(yīng)一組Zonegroup和Zone,等等,什么是Zonegroup和Zone?Zonegroup一般來代表邏輯上的地理區(qū)域(省會(huì),國家等),一個(gè)Zonegroup中可以包含一個(gè)或多個(gè)Zone,并且需要指定一個(gè)Zone作為Master來處理來自前端的元數(shù)據(jù)寫入請(qǐng)求,也就是說,我們只能往Master Zone里寫入或是更新元數(shù)據(jù)。

Figure 5.2.3 – Ceph對(duì)象存儲(chǔ)數(shù)據(jù)同步示意圖
更新Master Zone上的元數(shù)據(jù)更新日志會(huì)被記錄在mdlog(metadata log)里,而Master Zone也是通過對(duì)比mdlog來把更新后的元數(shù)據(jù)推送到Slave Zone上。Slave zone上更新的元數(shù)據(jù)會(huì)被forward到Master Zone里,Master Zone確認(rèn)更新后會(huì)主動(dòng)把更新推送到所有Zone上。而同步的過程是通過RGW Admin API來獲取mdlog,然后更新對(duì)應(yīng)的marker。
方案實(shí)現(xiàn)
為了實(shí)現(xiàn)RGW的元數(shù)據(jù)同步到ElasticSearch,我們配置一個(gè)zonegroup(us),在其中添加2個(gè)zone:us-1(master), us-2(slave)。并且分別在每個(gè)zone上啟一個(gè)RGW實(shí)例,RGW.us-1用來接受來自前端的讀寫請(qǐng)求,RGW.us-2用來把元數(shù)據(jù)同步至ElasticSearch。

Figure 5.2.4 – 方案二具體架構(gòu)圖
部署Ceph集群
同方案一
Ceph集群配置
1.為了實(shí)現(xiàn)Zone之間的同步,我們首先需要為集群創(chuàng)建一個(gè)realm:
`radosgw-admin -c .``/ceph``.conf realm create --rgw-realm=earth --default`
realm是Ceph集群的一個(gè)獨(dú)立命名空間,每個(gè)realm可以包括多個(gè)Zonegroup從而來實(shí)現(xiàn)Zonegroup之間的同步,每個(gè) realm 都有關(guān)聯(lián)的當(dāng)前的period 以及一組按照時(shí)間順序排列的 period 列表,還有zonegroup的當(dāng)前配置。
2.在earth這個(gè)命名空間下創(chuàng)建一個(gè)zonegroup: us
`radosgw-admin -c .``/ceph``.conf zonegroup create --rgw-zonegroup=us --endpoints=http:``//localhost``:8001 --master --default --rgw-realm=earth`
3.在us這個(gè)zonegroup下面創(chuàng)建一個(gè)master zone: us-1:
`radosgw-admin -c .``/ceph``.conf zone create --rgw-zonegroup=us --rgw-zone=us-1 --endpoints=http:``//localhost``:8001 --master --default --access-key=admin --secret=admin`
注意master zone的endpoint需要對(duì)應(yīng)zonegroup的endpoint
4.創(chuàng)建一個(gè)s3用戶:
`radosgw-admin -c .``/ceph``.conf user create --uid=admin --display-name=``"admin"` `--access-key=admin --secret=admin --system`
5.提交集群配置:
`radosgw-admin -c .``/ceph``.conf period update --commit`
一個(gè)period用來標(biāo)定當(dāng)前realm的狀態(tài)(zonegroup以及zone的配置),其擁有唯一的id和epoch。編輯一個(gè)zonegroup或是zone后的period更新處于stagging狀態(tài)并不生效,如果要生效需要運(yùn)行這行命令。
6.在us這個(gè)zonegroup下面創(chuàng)建第二個(gè)zone(非master):us-2
`radosgw-admin -c .``/ceph``.conf zone create --rgw-zonegroup=us --rgw-zone=us-2 --endpoints=http:``//localhost``:8002 --access-key=admin --secret=admin --tier-``type``=elasticsearch`
這邊的tier-type字段用來告訴zone,我們需要用哪個(gè)module進(jìn)行跨zone的數(shù)據(jù)同步,這里我們當(dāng)然填elasticsearch。
7.讓us-2獲取period更新:
`radosgw-admin period pull --rgw-zone=us-2`
8.修改us-2的配置,讓其指向ElasticSearch:
`radosgw-admin -c .``/ceph``.conf zone modify --rgw-zonegroup=us --rgw-zone=us-2 --access-key=admin --secret=admin --tier-config=endpoint=http:``//localhost``:9200`
我們?cè)趖ier-config這個(gè)參數(shù)中添加endpoint這個(gè)key,并且讓它指向ElasticSearch監(jiān)聽的端口。
9.再次提交集群配置:
`radosgw-admin -c .``/ceph``.conf period update --commit --rgw-zone=us-2`
啟動(dòng)RGW實(shí)例
RGW配置以及對(duì)應(yīng)的秘鑰生成方法與方案一中相同,只是需要監(jiān)聽不同的端口:
`[client.radosgw.us-1]`
`fsid = xxxxxxxxxxxxxxxxx`
`mon_host = xxxxxxxx:xxxx`
`keyring =` `/etc/ceph/ceph``.client.radosgw.keyring`
`log` `file` `=` `/etc/ceph/ceph``.client.radosgw.us-1.log`
`rgw frontends = civetweb port=8001`
`rgw zone = us-1`
`[client.radosgw.us-2]`
`fsid = xxxxxxxxxxxxxxxxx`
`mon_host = xxxxxxxx:xxxx`
`keyring =` `/etc/ceph/ceph``.client.radosgw.keyring`
`log` `file` `=` `/etc/ceph/ceph``.client.radosgw.us-2.log`
`rgw frontends = civetweb port=8002`
`rgw zone = us-2`
開啟這兩個(gè)RGW實(shí)例后,RGW會(huì)自動(dòng)開始同步元數(shù)據(jù),我們可以嘗試通過前端上傳對(duì)象,然后在ElasticSearch端檢測(cè)元數(shù)據(jù)是否同步成功。