1号店11.11:分布式搜索引擎的架构实践
http://www.uml.org.cn/zjjs/201512011.asp
“11.11”是一年一度的電商盛宴,為了準(zhǔn)備這個(gè)一年內(nèi)最大規(guī)模的促銷,1號(hào)店各條戰(zhàn)線都在緊張有序地忙碌著。1號(hào)店搜索團(tuán)隊(duì)經(jīng)過(guò)幾年的大促歷練,不斷推動(dòng)架構(gòu)演進(jìn),積累了越來(lái)越多的經(jīng)驗(yàn)。
11.11的主要特點(diǎn)是流量大和突發(fā)性高,這就帶來(lái)了兩個(gè)核心的需求:
可擴(kuò)展 如何抗住這樣的流量,針對(duì)這個(gè)需求,1號(hào)店搜索團(tuán)隊(duì)構(gòu)建了分布式搜索引擎,支持橫向擴(kuò)展;并且針對(duì)業(yè)務(wù)特點(diǎn)做了Routing優(yōu)化,讓搜索的效率更高。
快速響應(yīng) 流量越大,單位時(shí)間內(nèi)的流量?jī)r(jià)值就越大,出現(xiàn)問(wèn)題的損失也就越大,如何做到快速響應(yīng)變得非常關(guān)鍵。針對(duì)這個(gè)需求,搜索系統(tǒng)支持自動(dòng)部署和快速擴(kuò)容以應(yīng)對(duì)突發(fā)流量,索引數(shù)據(jù)從導(dǎo)入、處理到上線服務(wù)會(huì)經(jīng)過(guò)層層驗(yàn)證,同時(shí)還有監(jiān)控體系及時(shí)發(fā)現(xiàn)線上的問(wèn)題。
下面我們針對(duì)這些設(shè)計(jì)要點(diǎn)分別展開(kāi)。
分布式搜索引擎1號(hào)店分布式搜索引擎是Lucene/Solr核心的,結(jié)合SOA框架Hedwig構(gòu)建了一層分布式框架,支持搜索請(qǐng)求的分發(fā)和合并,并且構(gòu)建了搜索管理后臺(tái),支持多索引管理、集群管理、全量索引切換和實(shí)時(shí)索引更新。
選擇自己構(gòu)建分布式方案,而不是采用開(kāi)源的SolrCloud或ElasticSearch,主要是基于以下幾點(diǎn)考慮:
(1) ElasticSearch/SolrCloud都適合于把搜索引擎作為一個(gè)黑盒系統(tǒng)來(lái)使用,而1號(hào)店搜索業(yè)務(wù)的展現(xiàn)形式多樣性很高,搜索條件有的會(huì)很復(fù)雜,有的需要通過(guò)自定義插件來(lái)實(shí)現(xiàn),性能調(diào)優(yōu)時(shí)也需要對(duì)引擎內(nèi)部的執(zhí)行細(xì)節(jié)進(jìn)行監(jiān)控。
(2) 將ElasticSearch/SolrCloud與公司內(nèi)部的發(fā)布系統(tǒng)、監(jiān)控系統(tǒng)和SOA體系結(jié)合起來(lái),也是一項(xiàng)比較耗時(shí)的工作。
(3) 相對(duì)于整體使用,我們更傾向于把Lucene/Solr開(kāi)源家族中的各個(gè)組件按需引入,一方面降低引入復(fù)雜工程的可維護(hù)性風(fēng)險(xiǎn),另一方面逐漸深入理解這些組件,可以在必要時(shí)替換為定制化的組件。
分布式搜索是為了解決數(shù)據(jù)增長(zhǎng)過(guò)程中索引變大和操作時(shí)間變長(zhǎng)的問(wèn)題,它將原來(lái)的單個(gè)索引文件劃分成n個(gè)切片(shards),讓每個(gè)shard都足夠小,從而保證索引可以在多臺(tái)服務(wù)器上部署,而且搜索操作可以在較短時(shí)間內(nèi)返回。
如上圖所示,分布式搜索中有兩個(gè)主要組件:Shard Searcher和Broker,其中Shard Searcher與單機(jī)搜索引擎類似,基于Lucene/Solr完成基本的搜索任務(wù)。Broker負(fù)責(zé)把針對(duì)整個(gè)索引的搜索請(qǐng)求轉(zhuǎn)化為針對(duì)單個(gè)Shard的搜索請(qǐng)求,它把Shard搜索請(qǐng)求分發(fā)給各個(gè)ShardSearcher,并且把各個(gè)Shard的結(jié)果進(jìn)行合并,生成最終的結(jié)果。
分布式搜索中,一次搜索所需的資源與它要訪問(wèn)的Shard數(shù)和每個(gè)Shard要返回的結(jié)果數(shù)有非常強(qiáng)的關(guān)聯(lián)關(guān)系,在Shard數(shù)特別多或結(jié)果數(shù)特別多時(shí)可能會(huì)碰到一些的內(nèi)存、CPU資源使用的問(wèn)題。針對(duì)結(jié)果數(shù)特別多的情況,可以按照業(yè)務(wù)場(chǎng)景優(yōu)化,比如如果對(duì)排序無(wú)要求,就可以每次指定一個(gè)Shard進(jìn)行搜索,搜完這個(gè)Shard再換下一個(gè),這樣就限制了每次搜索的Shard數(shù),另一方面也可以考慮使用DeepPaging等技術(shù),減少每次Shard搜索的成本。我們下一小節(jié)也會(huì)介紹1號(hào)店主站搜索是如何減少每次搜索Shard數(shù)的。
另外,上圖中的Broker和Shard Searcher僅僅是概念上的劃分,實(shí)際部署時(shí)有幾種選擇:
A) 每個(gè)節(jié)點(diǎn)上都有Broker和部分Shard的Shard Searcher。
B) Broker單獨(dú)部署成一個(gè)集群,與Shard Searcher隔離。
C) Broker作為客戶端的一部分,和搜索應(yīng)用一起部署。
我們開(kāi)始使用的是A方式,后來(lái)主站搜索轉(zhuǎn)為C方式,主要是考慮到可以節(jié)省一次網(wǎng)絡(luò)調(diào)用(以及請(qǐng)求和結(jié)果的序列化開(kāi)銷),另外Broker在客戶端也可以更多地使用應(yīng)用邏輯相關(guān)的數(shù)據(jù)進(jìn)行更高效的Routing。
高效Routing通過(guò)前面的講述,我們不難看出,使用分布式搜索引擎,面臨的核心問(wèn)題就是如何選擇高效的Sharding策略和Routing方案。為了設(shè)計(jì)Routing方案,我們需要深入理解業(yè)務(wù)場(chǎng)景。
1號(hào)店有很多的類目,每個(gè)類目的業(yè)務(wù)模式也不盡相同。以圖書(shū)和快消品為例,圖書(shū)是一種典型的長(zhǎng)尾商品,它需要索引大量的SKU(Stock Keeping Unit,可以理解為一個(gè)獨(dú)立的商品),但每個(gè)SKU的訪問(wèn)量和銷量都不高;快消品是另外一個(gè)極端,總體SKU數(shù)量不高,但是訪問(wèn)量和效率都很高。這就造成了一個(gè)不平衡的局面,圖書(shū)的SKU數(shù)目占比達(dá)到了50%以上,流量卻小于10%,我們就首先排除了按Shard數(shù)目取模(id mod N)這種平衡劃分的策略。
1號(hào)店搜索有兩個(gè)主要入口,一個(gè)是搜索框的搜詞,另外是類目導(dǎo)航。在這兩個(gè)入口中,類目的點(diǎn)擊肯定是訪問(wèn)到一個(gè)特定的一級(jí)類目下,搜詞時(shí)用戶其實(shí)也只會(huì)關(guān)注相關(guān)的幾個(gè)類目。基于這種訪問(wèn)模式,我們就采用了按照類目來(lái)切分Shard的策略?;静僮鳛?#xff1a;
(1) 按照一級(jí)類目切分Shard。
(2) 如果該Shard過(guò)大,則按照二級(jí)類目繼續(xù)切分。
(3) 經(jīng)過(guò)前兩步之后,如果切分后的Shard過(guò)小,則按照相關(guān)性進(jìn)行Shard合并。
經(jīng)過(guò)這樣一番嘗試,Sharding策略就確定下來(lái),切分之后的Shard索引大小一般為200~500MB,Shard上單次搜索可以控制在10ms以下。
接下來(lái)說(shuō)到Routing,我們還是分搜詞和類目導(dǎo)航兩種場(chǎng)景,對(duì)于類目導(dǎo)航,原理上非常簡(jiǎn)單,按照類目ID來(lái)查找Sharding策略,就可以確定需要訪問(wèn)的Shard,雖然現(xiàn)實(shí)中還需要考慮擴(kuò)展類目等特殊場(chǎng)景,但是也不難做出一個(gè)簡(jiǎn)單的Routing策略。再加上類目數(shù)是有限的,Routing規(guī)則在Broker本地內(nèi)存就可以緩存起來(lái)。
搜詞場(chǎng)景就復(fù)雜很多,僅憑詞本身很難判斷它屬于哪個(gè)Shard。我們首先按照詞的熱度分為兩類,采取不同的Routing策略。對(duì)于熱詞,搜詞流量同樣符合80-20規(guī)則,20%的熱詞占比80%的搜索流量,對(duì)于熱詞,我們可以在建完索引之后,就跑一遍熱詞搜索,記錄那些Shard有結(jié)果,離線構(gòu)建出熱詞Routing表。切換索引時(shí),Routing表也一起加載進(jìn)去。對(duì)于非熱詞,則采用首次搜索去訪問(wèn)所有Shard,根據(jù)結(jié)果記錄Routing表,這個(gè)詞在下次搜索時(shí),就有了緩存可用。
基本的Routing策略上線之后,通過(guò)監(jiān)控每個(gè)Shard的訪問(wèn)量,我們又發(fā)現(xiàn)了新的問(wèn)題,圖書(shū)類目的訪問(wèn)量比它應(yīng)有的流量要高出不少。仔細(xì)分析之后發(fā)現(xiàn),由于圖書(shū)類目的特殊性,很多詞都可以在圖書(shū)中找到結(jié)果,然而這些結(jié)果一般都不是用戶想要的,實(shí)際上也不會(huì)排到前幾頁(yè),并沒(méi)有展示的機(jī)會(huì)。于是我們又增加了一種360-Routing策略,跟進(jìn)搜索前五頁(yè)的結(jié)果(每頁(yè)72個(gè)商品,共360個(gè)商品)計(jì)算Routing,下次搜索時(shí)優(yōu)先是用這份Routing規(guī)則。由于前五頁(yè)的流量占比在80%以上,這就進(jìn)一步減少了單次搜索需要訪問(wèn)的Shard數(shù)。
使用了以上這些Routing規(guī)則,1號(hào)店主站搜索每次搜索平均只需要訪問(wèn)1/3的索引數(shù)據(jù),這就節(jié)約了2/3的資源,提高了搜索效率。
自動(dòng)部署與快速擴(kuò)容文章一開(kāi)始我們提到11.11要求搜索系統(tǒng)支持快速擴(kuò)容,為了講清楚這個(gè)功能,我們首先要從索引部署講起。
按照類目進(jìn)行Sharding和Routing的方式,在帶來(lái)高效的同時(shí),也帶來(lái)了管理上的成本。按照類目切分,必然會(huì)導(dǎo)致各個(gè)Shard的大小不平均,而對(duì)應(yīng)的Routing方案,必然會(huì)帶來(lái)各個(gè)Shard的訪問(wèn)量不平均。這兩個(gè)維度不平均就要求更加復(fù)雜的索引部署方案,主要的原則為:
(1) 首先根據(jù)流量比例和高可用的需求,確定每個(gè)Shard的副本數(shù)。
(2) 然后按照單個(gè)節(jié)點(diǎn)不能放置同一Shard的多個(gè)副本,節(jié)點(diǎn)上的承擔(dān)的流量總和與節(jié)點(diǎn)的服務(wù)能力成正比。
(3) 每個(gè)節(jié)點(diǎn)上的索引總大小盡量也保持差異最小。
按照流量比例,副本數(shù)計(jì)算如下:
部署之后的效果如下圖所示。
Shard數(shù)增多之后,人工計(jì)算部署方案就顯得較為復(fù)雜,于是我們就把部署方案生成做成了自動(dòng)化,一個(gè)基本的Packing算法就可以完成這個(gè)工作。除了初始部署之外,自動(dòng)部署工具還可以支持節(jié)點(diǎn)增加、減少和更換。
在11.11的場(chǎng)景下,這個(gè)自動(dòng)化部署工具也可以支持快速擴(kuò)容,基本過(guò)程為:
(1) Index Server(部署工具界面)計(jì)算出擴(kuò)容之后的部署方案,寫(xiě)入到ZooKeeper。這里的算法與初始部署有些不同,它需要保證現(xiàn)有服務(wù)器的Shard盡量不變。
(2) 每個(gè)Shard Searcher服務(wù)器都會(huì)監(jiān)聽(tīng)ZooKeeper上的部署方案,方案改變之后,Shard Searcher會(huì)獲取新的方案與本地方案對(duì)比,進(jìn)行增減操作。
(3) Shard Searcher從HDFS上獲取索引數(shù)據(jù),與最近的實(shí)時(shí)更新數(shù)據(jù)合并之后,啟動(dòng)索引提供服務(wù)。
有了自動(dòng)擴(kuò)容工具,11.11容量規(guī)劃確定之后,新的服務(wù)器就可以很快部署上線,也減少了人工操作可能引入的失誤等問(wèn)題。大促期間如果需要緊急擴(kuò)容,也可以在幾分鐘內(nèi)提高整個(gè)系統(tǒng)的服務(wù)能力。
實(shí)時(shí)監(jiān)控體系
11.11大促期間每一分鐘都影響很大,我們需要實(shí)時(shí)了解線上數(shù)據(jù)和服務(wù)情況,確保系統(tǒng)處于一致和可用的狀態(tài),為此,我們構(gòu)建了搜索的監(jiān)控體系。
在索引數(shù)據(jù)方面,從源頭開(kāi)始對(duì)索引數(shù)據(jù)準(zhǔn)備的各個(gè)環(huán)節(jié)進(jìn)行驗(yàn)證,包括數(shù)據(jù)的條數(shù)、處理過(guò)程中的異常、最后生成的索引在常見(jiàn)搜索中的執(zhí)行結(jié)果差異等,層層預(yù)防,防止有問(wèn)題的索引數(shù)據(jù)被用到線上。
在搜索服務(wù)方面,監(jiān)控系統(tǒng)會(huì)定時(shí)執(zhí)行常見(jiàn)的搜索,對(duì)比排序結(jié)果,結(jié)果差異較大時(shí)及時(shí)告警。同時(shí)大促期間會(huì)有一些商品很快賣完,這些商品繼續(xù)顯示在搜索結(jié)果中也沒(méi)有價(jià)值,搜索監(jiān)控也會(huì)及時(shí)發(fā)現(xiàn)這些商品,觸發(fā)索引更新,把商品排到后面。
結(jié)語(yǔ)每年11.11對(duì)系統(tǒng)都是一次大閱兵,通過(guò)構(gòu)建分布式搜索引擎,我們實(shí)現(xiàn)了基礎(chǔ)架構(gòu)的可擴(kuò)展性,結(jié)合業(yè)務(wù)場(chǎng)景設(shè)計(jì)的Routing規(guī)則,保證了 搜索的高效執(zhí)行,自動(dòng)化工具支持大促必需的自動(dòng)擴(kuò)容,配合成體系的驗(yàn)證和監(jiān)控,我們有信心應(yīng)對(duì)更高流量的沖擊,保障大促平穩(wěn)度過(guò)。
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/articles/8257433.html
總結(jié)
以上是生活随笔為你收集整理的1号店11.11:分布式搜索引擎的架构实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 千万级日订单下,饿了么异地多活数据实施D
- 下一篇: tcpcopy部署