自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何構(gòu)建一個(gè)低成本,高可用,少運(yùn)維的ES平臺(tái)?

開(kāi)發(fā) 架構(gòu) 系統(tǒng)運(yùn)維
這里介紹的搜索中臺(tái)只是最基礎(chǔ)的中臺(tái)能力,我們還在進(jìn)一步探索些復(fù)雜場(chǎng)景下如何抽象來(lái)降低業(yè)務(wù)成本,也就是垂直化的搜索產(chǎn)品。

  基于 Elasticsearch 的通用搜索是螞蟻內(nèi)部最大的搜索產(chǎn)品,目前擁有上萬(wàn)億文檔,服務(wù)了上百個(gè)業(yè)務(wù)方。而通用搜索的發(fā)展主要分為兩個(gè)階段:平臺(tái)化和中臺(tái)化。

[[249346]]

本文作者將從以下幾個(gè)方面介紹在這兩個(gè)階段的發(fā)展中為業(yè)務(wù)解決了哪些痛點(diǎn)以及是如何去解決這些痛點(diǎn)的:

  • 源動(dòng)力

  • ES 平臺(tái)

  • 回看業(yè)務(wù)

  • 搜索中臺(tái)

 

源動(dòng)力:架構(gòu)復(fù)雜、運(yùn)維艱難

 

 

和大多數(shù)大型企業(yè)一樣,螞蟻內(nèi)部也有一套自研的搜索系統(tǒng),我們稱(chēng)之為主搜。

 

但是由于這種系統(tǒng)可定制性高,所以一般業(yè)務(wù)接入比較復(fù)雜,周期比較長(zhǎng)。而對(duì)于大量新興的中小業(yè)務(wù)而言,迭代速度尤為關(guān)鍵,因此難以用主搜去滿(mǎn)足。

 

主搜不能滿(mǎn)足,業(yè)務(wù)又實(shí)際要用,怎么辦呢?那就只能自建了。在前幾年螞蟻內(nèi)部有很多小的搜索系統(tǒng),有 ES,也有 Solr,甚至還有自己用 Lucene 的。

 

 

業(yè)務(wù)痛點(diǎn)

 

 

業(yè)務(wù)由于自身迭代速度很快,去運(yùn)維這些搜索系統(tǒng)成本很大。就像 ES,雖然搭建一套很是簡(jiǎn)單,但是用在真實(shí)生產(chǎn)環(huán)境中還是需要很多專(zhuān)業(yè)知識(shí)的。

 

作為業(yè)務(wù)部門(mén)很難去投入人力去運(yùn)維維護(hù)。并且由于螞蟻?zhàn)陨淼臉I(yè)務(wù)特性,很多業(yè)務(wù)都是需要高可用保證的。

 

而我們都知道 ES 本身的高可用目前只能跨機(jī)房部署了,先不談跨機(jī)房部署時(shí)的分配策略,光是就近訪問(wèn)一點(diǎn),業(yè)務(wù)都很難去完成。

 

因?yàn)檫@些原因,導(dǎo)致這類(lèi)場(chǎng)景基本都沒(méi)有高可用,業(yè)務(wù)層寧愿寫(xiě)兩套代碼,準(zhǔn)備一套兜底方案。他們覺(jué)得容災(zāi)時(shí)直接降級(jí)也比高可用簡(jiǎn)單。

 

 

架構(gòu)痛點(diǎn)

 

從整體架構(gòu)層面看,各個(gè)業(yè)務(wù)自行搭建搜索引擎造成了煙囪林立,各種重復(fù)建設(shè)。

 

并且這種中小業(yè)務(wù)一般數(shù)據(jù)量都比較小,往往一個(gè)業(yè)務(wù)一套三節(jié)點(diǎn)集群只有幾萬(wàn)條數(shù)據(jù),造成整體資源利用率很低。

 

而且由于搜索引擎選用的版本,部署的方式都不一致,也難以保證質(zhì)量。在架構(gòu)層面只能當(dāng)做不存在搜索能力。

 

 

低成本,高可用,少運(yùn)維的 Elasticsearch 平臺(tái)應(yīng)運(yùn)而生

 

 

基于以上痛點(diǎn),我們產(chǎn)生了構(gòu)建一套標(biāo)準(zhǔn)搜索平臺(tái)的想法,將業(yè)務(wù)從運(yùn)維中解放出來(lái),也從架構(gòu)層面統(tǒng)一基礎(chǔ)設(shè)施,提供一種簡(jiǎn)單可信的搜索服務(wù)。

 

架構(gòu)圖如下:

如何做低成本,高可用,少運(yùn)維呢?我們先來(lái)一起看一下整體架構(gòu),如上圖。

 

首先說(shuō)明一下我們這兩個(gè)框框代表兩個(gè)機(jī)房,我們整體就是一種多機(jī)房的架構(gòu),用來(lái)保證高可用:

  • 最上層是用戶(hù)接入層,有 API,Kibana,Console 三種方式,用戶(hù)和使用 ES 原生的 API 一樣可以直接使用我們的產(chǎn)品。

  • 中間為路由層(Router),負(fù)責(zé)將用戶(hù)請(qǐng)求真實(shí)發(fā)送到對(duì)應(yīng)集群中,負(fù)責(zé)一些干預(yù)處理邏輯。

  • 下面每個(gè)機(jī)房中都有隊(duì)列(Queue),負(fù)責(zé)削峰填谷和容災(zāi)多寫(xiě)。

  • 每個(gè)機(jī)房中有多個(gè) ES 集群,用戶(hù)的數(shù)據(jù)最終落在一個(gè)真實(shí)的集群中,或者一組對(duì)等的高可用集群中。

  • 右邊紅色的是 Meta,負(fù)責(zé)所有組件的一站式自動(dòng)化運(yùn)維和元數(shù)據(jù)管理。

  • 最下面是 Kubernetes,我們所有的組件均是以容器跑在 K8S 上的,這解放了我們很多物理機(jī)運(yùn)維操作,使得滾動(dòng)重啟這些變得非常方便。

 

低成本:多租戶(hù)

看完了整體,下面就逐點(diǎn)介紹下我們是怎么做的,第一個(gè)目標(biāo)是低成本。在架構(gòu)層面,成本優(yōu)化是個(gè)每年必談的話題。

 

那么降低成本是什么意思?實(shí)際上就是提高資源利用率。提高資源利用率方法有很多,比如提高壓縮比,降低查詢(xún)開(kāi)銷(xiāo)。但是在平臺(tái)上最簡(jiǎn)單有效的方式則是多租戶(hù)。

 

今天我就主要介紹下我們的多租戶(hù)方案:多租戶(hù)的關(guān)鍵就是租戶(hù)隔離,租戶(hù)隔離分為邏輯隔離和物理隔離。

 

邏輯隔離

首先介紹下我們的邏輯隔離方案,邏輯隔離就是讓業(yè)務(wù)還是和之前自己搭 ES 一樣的用法,也就是透明訪問(wèn)。

 

但是實(shí)際上訪問(wèn)的只是真實(shí)集群中屬于自己的一部分?jǐn)?shù)據(jù),而看不到其他人的數(shù)據(jù),也就是保證水平權(quán)限。

 

而 ES 有一點(diǎn)很適合用來(lái)做邏輯隔離,ES 的訪問(wèn)實(shí)際上都是按照 Index 的。因此我們邏輯隔離的問(wèn)題就轉(zhuǎn)化為如何讓用戶(hù)只能看到自己的表了。

 

我們是通過(guò) Console 保存用戶(hù)和表的映射關(guān)系,然后在訪問(wèn)時(shí)通過(guò) Router,也就是前面介紹的路由層進(jìn)行干預(yù),使得用戶(hù)只能訪問(wèn)自己的 Index。

 

具體而言,我們路由層采用 OpenResty+Lua 實(shí)現(xiàn),將請(qǐng)求過(guò)程分為了右圖的四步:Dispatch,F(xiàn)ilter,Router,Reprocess。

 

在 Dispatch 階段我們將請(qǐng)求結(jié)構(gòu)化,抽出其用戶(hù),App,Index,Action 數(shù)據(jù)。

 

然后進(jìn)入 Filter 階段,進(jìn)行寫(xiě)過(guò)濾和改寫(xiě)。

 

Filter 又分為三步:

  • Access 進(jìn)行限流和驗(yàn)權(quán)這類(lèi)的準(zhǔn)入性攔截。

  • Action 對(duì)具體的操作進(jìn)行攔截處理,比如說(shuō) DDL,也就是建表,刪表,修改結(jié)構(gòu)這些操作,我們將其轉(zhuǎn)發(fā)到 Console 進(jìn)行處理。

    一方面方便記錄其 Index 和 App 的對(duì)應(yīng)信息;另一方面由于建刪表這種還是很影響集群性能的,我們通過(guò)轉(zhuǎn)發(fā)給 Console 可以對(duì)用戶(hù)進(jìn)行進(jìn)一步限制,防止惡意行為對(duì)系統(tǒng)的影響。

  • Params 則是請(qǐng)求改寫(xiě),在這一步我們會(huì)根據(jù)具體的 Index 和 Action 進(jìn)行相應(yīng)的改寫(xiě)。

    比如去掉用戶(hù)沒(méi)有權(quán)限的 Index;比如對(duì)于 Kibana 索引將其改為用戶(hù)自己的唯一 Kibana 索引以實(shí)現(xiàn) Kibana 的多租戶(hù);比如對(duì) ES 不同版本的簡(jiǎn)單兼容。

    在這一步我們可以做很多,不過(guò)需要注意的有兩點(diǎn):一是盡量不要解析 Body,解 Body 是一種非常影響性能的行為,除了特殊的改寫(xiě)外應(yīng)該盡力避免,比如 Index 就應(yīng)該讓用戶(hù)寫(xiě)在 URL 上,并利用 ES 本身的參數(shù)關(guān)閉 Body 中指定 Index 的功能,這樣改寫(xiě)速度可以快很多。

    二是對(duì)于 _all 和 getMapping 這種對(duì)所有 Index 進(jìn)行訪問(wèn)的,如果我們替換為用戶(hù)所有的索引會(huì)造成 URL 過(guò)長(zhǎng),我們采用的是創(chuàng)建一個(gè)和應(yīng)用名同名的別名,然后將其改寫(xiě)成這個(gè)別名。

 

進(jìn)行完 Filter 就到了真實(shí)的 Router 層,這一層就是根據(jù) Filter 的結(jié)果做真實(shí)的路由請(qǐng)求,可能是轉(zhuǎn)發(fā)到真實(shí)集群也可能是轉(zhuǎn)發(fā)到我們其他的微服務(wù)中。

 

最后是 Reprocess ,這是拿到業(yè)務(wù)響應(yīng)后的最終處理,我們?cè)谶@邊會(huì)對(duì)一些結(jié)果進(jìn)行改寫(xiě),并且異步記錄日志。

 

上面這四步就是我們路由層的大致邏輯,通過(guò) App 和 Index 的權(quán)限關(guān)系控制水平權(quán)限,通過(guò) Index 改寫(xiě)路由進(jìn)行共享集群。

 

物理隔離

做完了邏輯隔離,我們可以保證業(yè)務(wù)的水平權(quán)限了,那么是否就可以了呢?

 

顯然不是的,實(shí)際中不同業(yè)務(wù)訪問(wèn)差異還是很大的,只做邏輯隔離往往會(huì)造成業(yè)務(wù)間相互影響。

 

這時(shí)候就需要物理隔離了。不過(guò)物理隔離我們目前也沒(méi)有找到非常好的方案,這邊給大家分享下我們的一些嘗試。

 

首當(dāng)其沖,我們采用的方法是服務(wù)分層,也就是將不同用途,不同重要性的業(yè)務(wù)分開(kāi),對(duì)于關(guān)鍵性的主鏈路業(yè)務(wù)甚至可以獨(dú)占集群。

 

對(duì)于其他的,我們主要分為兩類(lèi):寫(xiě)多查少的日志型和查多寫(xiě)少的檢索型業(yè)務(wù),按照其不同的要求和流量預(yù)估將其分配在我們預(yù)設(shè)的集群中。

 

不過(guò)需要注意的是申報(bào)的和實(shí)際的總會(huì)有差異的,所以我們還有定期巡檢機(jī)制,會(huì)將已上線業(yè)務(wù)按照其真實(shí)流量進(jìn)行集群遷移。

 

做完了服務(wù)分層,我們基本可以解決了低重要性業(yè)務(wù)影響高重要性業(yè)務(wù)的場(chǎng)景,但是在同級(jí)業(yè)務(wù)中依舊會(huì)有些業(yè)務(wù)因?yàn)楸热缯f(shuō)做營(yíng)銷(xiāo)活動(dòng)這種造成突發(fā)流量。

 

對(duì)于這種問(wèn)題怎么辦?一般而言就是全局限流,但是由于我們的訪問(wèn)都是長(zhǎng)連接,所以限流并不好做。

 

如右圖所示,用戶(hù)通過(guò)一個(gè) LVS 訪問(wèn)了我們多個(gè) Router,然后我們又通過(guò)了 LVS 訪問(wèn)了多個(gè) ES 節(jié)點(diǎn),我們要做限流,也就是要保證所有 Router 上的令牌總數(shù)。

 

一般而言全局限流有兩種方案:

  • 一是以限流維度將所有請(qǐng)求打在同一實(shí)例上,也就是將同一表的所有訪問(wèn)打在一臺(tái)機(jī)器上。

    但是在 ES 訪問(wèn)量這么高的場(chǎng)景下,這種并不合適,并且由于我們前面已經(jīng)有了一層 LVS 做負(fù)載均衡,再做一層路由會(huì)顯得過(guò)于復(fù)雜。

  • 第二種方案就是均分令牌,但是由于長(zhǎng)連接的問(wèn)題,會(huì)造成有些節(jié)點(diǎn)早已被限流,但是其他節(jié)點(diǎn)卻沒(méi)有什么流量。

 

那么怎么辦呢?

既然是令牌使用不均衡,那么我們就讓其分配也不均衡就好了唄。所以我們采用了一種基于反饋的全局限流方案,什么叫基于反饋呢?

 

就是我們用巡檢去定時(shí)采集用量,用的多就多給一些,用的少就少給你一點(diǎn)。

 

那么多給一些少給一點(diǎn)到底是什么樣的標(biāo)準(zhǔn)呢?這時(shí)我們就需要決策單元來(lái)處理了,目前我們采取的方案是簡(jiǎn)單的按比例分配。

 

這邊需要注意的一點(diǎn)是當(dāng)有新機(jī)器接入時(shí),不是一開(kāi)始就達(dá)到終態(tài)的,而是漸進(jìn)的過(guò)程。

 

所以需要對(duì)這個(gè)收斂期設(shè)置一些策略,目前因?yàn)槲覀儥C(jī)器性能比較好,不怕突發(fā)毛刺,所以我們?cè)O(shè)置的是全部放行,到穩(wěn)定后再進(jìn)行限流。

 

這里說(shuō)到長(zhǎng)連接就順便提一個(gè) Nginx 的小參數(shù):keepalive_timeout。用過(guò) Nginx 的同學(xué)應(yīng)該都見(jiàn)過(guò),表示長(zhǎng)連接超時(shí)時(shí)間,默認(rèn)有 75s。

 

但是這個(gè)參數(shù)實(shí)際上還有一個(gè)可選配置,表示寫(xiě)在響應(yīng)頭里的超時(shí)時(shí)間,如果這個(gè)參數(shù)沒(méi)寫(xiě)的話就會(huì)出現(xiàn)在服務(wù)端釋放的瞬間客戶(hù)端正好復(fù)用了這個(gè)連接,造成 Connection Reset 或者 NoHttpResponse 的問(wèn)題。

 

出現(xiàn)頻率不高,但是真實(shí)影響用戶(hù)體驗(yàn),因?yàn)殡S機(jī)低頻出現(xiàn),我們之前一直以為是客戶(hù)端問(wèn)題,后來(lái)才發(fā)現(xiàn)原來(lái)是這個(gè)釋放順序的問(wèn)題。

 

至此服務(wù)分層,全局限流都已經(jīng)完成了,是不是可以睡個(gè)好覺(jué)了呢? 很遺憾,還是不行,因?yàn)?ES 語(yǔ)法非常靈活,并且有許多大代價(jià)的操作。

 

比如上千億條數(shù)據(jù)做聚合,或者是用通配符做個(gè)中綴查詢(xún),寫(xiě)一個(gè)復(fù)雜的 Script 都有可能造成拖垮我們整個(gè)集群,那么對(duì)于這種情況怎么辦呢? 

 

我們目前也是處于探索階段,比較有用的一種方式是事后補(bǔ)救,也就是我們通過(guò)巡檢去發(fā)現(xiàn)一些耗時(shí)大的 Task,然后對(duì)其應(yīng)用的后繼操作進(jìn)行懲罰,比如降級(jí),甚至熔斷。

 

這樣就可以避免持續(xù)性的影響整個(gè)集群。但是一瞬間的 RT 上升還是不可避免的,因此我們也在嘗試事前攔截,不過(guò)這個(gè)比較復(fù)雜,感興趣的同學(xué)可以一起線下交流一下。

 

高可用:對(duì)等多集群

 

講完了低成本,那么就來(lái)到了我們第二個(gè)目標(biāo),高可用。正如我之前提到那樣,ES 本身其實(shí)提供了跨機(jī)房部署的方案,通過(guò)打標(biāo)就可以進(jìn)行跨機(jī)房部署,然后通過(guò) Preference 可以保證業(yè)務(wù)就近查詢(xún)。

 

我這里就不再詳細(xì)說(shuō)了,但是這種方案需要兩地三中心, 而我們很多對(duì)外輸出的場(chǎng)景出于成本考慮,并沒(méi)有三中心,只有兩地兩中心,因此雙機(jī)房如何保證高可用就是我們遇到的一個(gè)挑戰(zhàn)。

 

下面我主要就給大家分享下我們基于對(duì)等多機(jī)房的高可用方案,提供了兩種類(lèi)型,共三種方案分別適用于不同的業(yè)務(wù)場(chǎng)景。

 

我們有單寫(xiě)多讀和多寫(xiě)多讀兩種類(lèi)型:單寫(xiě)多讀我們采用的是跨集群復(fù)制的方案,通過(guò)修改 ES,我們?cè)黾恿死?Translog 將主集群數(shù)據(jù)推送給備庫(kù)的能力。

 

就和 6.5 的 ccr 類(lèi)似,但是我們采用的是推模式,而不是拉模式,因?yàn)槲覀冎白鲞^(guò)測(cè)試,對(duì)于海量數(shù)據(jù)寫(xiě)入,推比拉的性能好了不少。

 

容災(zāi)時(shí)進(jìn)行主備互換,然后恢復(fù)后再補(bǔ)上在途數(shù)據(jù)。由上層來(lái)保證單寫(xiě),多讀和容災(zāi)切換邏輯。

 

這種方案通過(guò) ES 本身的 Translog 同步,部署結(jié)構(gòu)簡(jiǎn)單,數(shù)據(jù)也很準(zhǔn)確,類(lèi)似于數(shù)據(jù)庫(kù)的備庫(kù),比較適合對(duì)寫(xiě)入 RT 沒(méi)有過(guò)高要求的高可用場(chǎng)景。

多寫(xiě)多讀,我們提供了兩種方案:

  • 第一種方案比較取巧,就是因?yàn)楹芏嚓P(guān)鍵鏈路的業(yè)務(wù)場(chǎng)景都是從 DB 同步到搜索中的,因此我們打通了數(shù)據(jù)通道,可以自動(dòng)化的從 DB 寫(xiě)入到搜索,用戶(hù)無(wú)需關(guān)心。

    那么對(duì)于這類(lèi)用戶(hù)的高可用,我們采用的就是利用 DB 的高可用,搭建兩條數(shù)據(jù)管道,分別寫(xiě)入不同的集群。這樣就可以實(shí)現(xiàn)高可用了,并且還可以絕對(duì)保證最終一致性。

  • 第二種方案則是在對(duì)寫(xiě)入 RT 有強(qiáng)要求,有沒(méi)有數(shù)據(jù)源的情況下,我們會(huì)采用中間層的多寫(xiě)來(lái)實(shí)現(xiàn)高可用。

    我們利用消息隊(duì)列作為中間層,來(lái)實(shí)現(xiàn)雙寫(xiě)。就是用戶(hù)寫(xiě)的時(shí)候,寫(xiě)成功后保證隊(duì)列也寫(xiě)成功了才返回成功,如果一個(gè)不成功就整體失敗。

    然后由隊(duì)列去保證推送到另一個(gè)對(duì)等集群中。用外部版本號(hào)去保證一致性。但是由于是中間層,對(duì)于 Delete by Query 的一致性保證就有些無(wú)能為力了。所以也僅適合特定的業(yè)務(wù)場(chǎng)景。

 

最后,在高可用上我還想說(shuō)的一點(diǎn)是對(duì)于平臺(tái)產(chǎn)品而言,技術(shù)方案有哪些,怎么實(shí)現(xiàn)的業(yè)務(wù)其實(shí)并不關(guān)心,業(yè)務(wù)關(guān)心的僅僅是他們能不能就近訪問(wèn)降低 RT,和容災(zāi)時(shí)自動(dòng)切換保證可用。

 

因此我們?cè)谄脚_(tái)上屏蔽了這些復(fù)雜的高可用類(lèi)型和這些適用的場(chǎng)景,完全交由我們的后端去判斷,讓用戶(hù)可以輕松自助接入。

 

并且在交互上也將讀寫(xiě)控制,容災(zāi)操作移到了我們自己系統(tǒng)內(nèi),對(duì)用戶(hù)無(wú)感知。

 

只有用戶(hù)可以這樣透明擁有高可用能力了,我們的平臺(tái)才真正成為了高可用的搜索平臺(tái)。

 

少運(yùn)維

 

最后一個(gè)目標(biāo),少運(yùn)維,就簡(jiǎn)單介紹一下我們?cè)谡w運(yùn)維系統(tǒng)搭建過(guò)程中沉淀出的四個(gè)原則:

  • 自包含:ES 做的就很不錯(cuò)了,一個(gè) Jar 就可以啟動(dòng),而我們的整套系統(tǒng)也都應(yīng)該和單個(gè) ES 一樣,一條很簡(jiǎn)單的命令就能啟動(dòng),沒(méi)有什么外部依賴(lài),這樣就很好去輸出。

  • 組件化:是指我們每個(gè)模塊都應(yīng)該可以插拔,來(lái)適應(yīng)不同的業(yè)務(wù)場(chǎng)景,比如有的不需要多租戶(hù),有的不需要削峰填谷。

  • 一站到底:是指我們的所有組件,Router,Queue,ES,還有很多微服務(wù)的管控都應(yīng)該在一個(gè)系統(tǒng)中去管控,萬(wàn)萬(wàn)不能一個(gè)組件一套自己的管控。

  • 自動(dòng)化就不說(shuō)了,大家都懂。

  • 右邊就是我們的一個(gè)大盤(pán)頁(yè)面,展現(xiàn)了 Router,ES 和 Queue 的訪問(wèn)情況。當(dāng)然,這是 Mock 的數(shù)據(jù)。

 

回看業(yè)務(wù):無(wú)需運(yùn)維,卻依舊不爽

 

 

至此我們已經(jīng)擁有了一套低成本,高可用,少運(yùn)維的 Elasticsearch 平臺(tái)了,也解決了之前談到的業(yè)務(wù)痛點(diǎn),那么用戶(hù)用的是否就爽了呢?

 

我們花了大半個(gè)月的時(shí)間,對(duì)我們的業(yè)務(wù)進(jìn)行了走訪調(diào)研,發(fā)現(xiàn)業(yè)務(wù)雖然已經(jīng)從運(yùn)維中解放了出來(lái),但是身上還是有不少搜索的枷鎖。

 

我們主要分為兩類(lèi)用戶(hù),數(shù)據(jù)分析和全文檢索的:

  • 數(shù)據(jù)分析主要覺(jué)得配置太復(fù)雜,它只是想導(dǎo)入一個(gè)日志數(shù)據(jù),要學(xué)一堆的字段配置,而且很久才會(huì)用到一次,每次學(xué)完就忘,用到再重學(xué),很耽誤事情。

    其次,無(wú)關(guān)邏輯重,因?yàn)閿?shù)據(jù)分析類(lèi)的一般都是保留多天的數(shù)據(jù),過(guò)期的數(shù)據(jù)就可以刪除了,為了實(shí)現(xiàn)這一個(gè)功能,數(shù)據(jù)分析的同學(xué)要寫(xiě)很多代碼,還要控制不同的別名,很是麻煩。

  • 而全文檢索類(lèi)的同學(xué)主要痛點(diǎn)有三個(gè),一是分詞配置復(fù)雜;二是難以修改字段,Reindex 太復(fù)雜,還要自己先創(chuàng)建別名,再控制無(wú)縫切換;第三點(diǎn)是 Debug 艱難。

    雖然現(xiàn)在有 Explain,但是用過(guò)的同學(xué)應(yīng)該都懂,想要整體梳理出具體的算分原因還是需要自己在腦中開(kāi)辟很大的一塊緩存的。對(duì)于不熟悉 ES 的同學(xué)就太痛苦了。

 

整理一下,這些痛點(diǎn)歸類(lèi)起來(lái)就兩個(gè)痛點(diǎn):學(xué)習(xí)成本高和接口過(guò)于原子。

 

搜索中臺(tái):抽象邏輯,解放業(yè)務(wù)

 

 

學(xué)習(xí)成本高和接口過(guò)于原子,雖然是業(yè)務(wù)的痛點(diǎn),但是對(duì) ES 本身而言卻反而是優(yōu)點(diǎn),為什么學(xué)習(xí)成本高呢?因?yàn)楣δ茇S富。而為什么接口原子呢?為了讓上層可以靈活使用。

 

這些對(duì)于專(zhuān)家用戶(hù)而言,非常不錯(cuò),但是對(duì)于業(yè)務(wù)而言,的確很是麻煩。因此我們開(kāi)始了我們第二個(gè)階段,搜索中臺(tái)。

 

什么叫中臺(tái)呢,就是把一些通用的業(yè)務(wù)邏輯下移,來(lái)減少業(yè)務(wù)的邏輯,讓業(yè)務(wù)專(zhuān)注于業(yè)務(wù)本身。

 

而為什么業(yè)務(wù)不能做這些呢?當(dāng)然也能做。但是俗話說(shuō)『天下武功,唯快不破』,前臺(tái)越輕,越能適應(yīng)這變化極快的業(yè)務(wù)訴求。

 

因此我們的搜索中臺(tái)的主要目標(biāo)就是兩點(diǎn):

  • 一是降低業(yè)務(wù)學(xué)習(xí)成本,加快上手速度。我們這次介紹的主要是如何降低對(duì)于配置類(lèi)這種低頻操作的學(xué)習(xí)成本。

  • 二是抽象復(fù)雜邏輯來(lái)加速業(yè)務(wù)迭代,我們這次主要會(huì)介紹抽象了哪兩種業(yè)務(wù)邏輯。

 

降低學(xué)習(xí)成本

 

降低學(xué)習(xí)成本,這個(gè)怎么做呢?眾所周知,黑屏變白屏,也就是白屏化。但是很多的白屏化就是把命令放在了 Web 上,回車(chē)變按鈕。這樣真的可以降低用戶(hù)學(xué)習(xí)成本么? 我想毋庸置疑,這樣是不行的。

 

我們?cè)诳梢暬蠂L試了許多方案,也走了許多彎路,最后發(fā)現(xiàn)要想真正降低用戶(hù)學(xué)習(xí)成本,需要把握三個(gè)要點(diǎn):

 

①用戶(hù)分層,區(qū)分出小白用戶(hù)和專(zhuān)家用戶(hù),不要讓專(zhuān)家用戶(hù)的意見(jiàn)影響整體產(chǎn)品的極簡(jiǎn)設(shè)計(jì),對(duì)于小白用戶(hù)一定是越少越好,選擇越少,路徑越短,反饋越及時(shí),效果越好。

 

正如所謂的沉默的大多數(shù),很多小白用戶(hù)并不會(huì)去主動(dòng)發(fā)聲,只會(huì)隨著復(fù)雜的配置而放棄使用。

 

下圖就是我們對(duì)于專(zhuān)家用戶(hù)和小白用戶(hù)在配置表結(jié)構(gòu)時(shí)不同的頁(yè)面,對(duì)于專(zhuān)家用戶(hù),基本就是 ES 所有的功能可視化,加快使用速度。對(duì)于小白用戶(hù)而言,則是完全屏蔽這些功能點(diǎn),讓其可以直接使用。

 

 

②引導(dǎo)式配置,引導(dǎo)式配置其實(shí)也就是加上限制,通過(guò)對(duì)用戶(hù)的上一步輸入決定下一步的可選。

 

要避免一個(gè)頁(yè)面打開(kāi)一堆配置項(xiàng),這樣用戶(hù)就會(huì)無(wú)從下手,更不要談學(xué)習(xí)成本了。

 

通過(guò)引導(dǎo)式配置來(lái)減少用戶(hù)的選擇,降低用戶(hù)的記憶成本。限制不一定就意味著約束用戶(hù),合適的限制更可以降低用戶(hù)的理解成本。

 

比如右圖就是我們的一個(gè)分詞器配置,很簡(jiǎn)單的引導(dǎo),用戶(hù)選擇了中文字典后才可以選擇相應(yīng)的詞典。

 

③深層次結(jié)構(gòu)打平,什么叫深層次結(jié)構(gòu)打平,就是指像現(xiàn)在的分詞器,相似度這些都是在 Index 級(jí)別下的,我們將其抽象出來(lái),變?yōu)槿值摹?/span>

 

用戶(hù)可以自行創(chuàng)建全局的分詞器,相似度,并且還可以共享給其他人,就像一個(gè)資源一樣。然后在 Index 中則是引用這個(gè)分詞器。

 

雖然這邊做的僅僅是將分詞器從 Index 級(jí)別變?yōu)榱巳郑菂s真正的減少了很多業(yè)務(wù)操作,因?yàn)樵谝粋€(gè)業(yè)務(wù)場(chǎng)景中,往往存在多張表,而多張表往往會(huì)使用同一套分詞器。

 

通過(guò)這種全局性的分詞器用戶(hù)僅需修改一處即可作用于所有位置。

 

抽象復(fù)雜邏輯

 

好的,說(shuō)完了白屏化的一些經(jīng)驗(yàn),這邊給大家分享我們對(duì)于復(fù)雜邏輯的抽象封裝的兩種新型表結(jié)構(gòu)。

 

這兩種分別是數(shù)據(jù)分析類(lèi)場(chǎng)景,我們抽象出了日志型表,另一種是全文檢索類(lèi)場(chǎng)景,我們抽象出了別名型表。

 

日志型表的作用顧名思義就是存日志,也就是之前說(shuō)的對(duì)于數(shù)據(jù)分析類(lèi)業(yè)務(wù),往往只保留幾天。

 

比如我們現(xiàn)在有個(gè)業(yè)務(wù)場(chǎng)景,有張 ES 的日志表,只想保留 3 天,于是我們就給它按天創(chuàng)建索引。

 

然后寫(xiě)入索引掛載到今天,查詢(xún)索引掛載所有的,用 Router 去自動(dòng)改寫(xiě)別名,用戶(hù)還是傳入 ES,但是執(zhí)行寫(xiě)入操作時(shí)實(shí)際就是在 es_write 執(zhí)行,查詢(xún)就是在 es_read 執(zhí)行。

 

當(dāng)然實(shí)際中我們并不是按天建的索引,我們會(huì)利用 Rollover 創(chuàng)建很多的索引來(lái)保證海量寫(xiě)入下的速度。但是整體邏輯還是和這個(gè)是一樣的。

 

而對(duì)于全文檢索類(lèi)場(chǎng)景,主要的痛點(diǎn)就是表結(jié)構(gòu)的變更和分詞器,字典類(lèi)的變更,需要重建索引。

 

所以我們抽象了一個(gè)叫別名表的表結(jié)構(gòu),用戶(hù)創(chuàng)建一張表 ES,實(shí)際創(chuàng)建的是一個(gè) ES 的別名,我們會(huì)把它和我們真實(shí)的 Index 一一對(duì)應(yīng)上。這樣利用這個(gè)別名,我們就可以自動(dòng)幫用戶(hù)完成索引重建的操作。

 

而索引重建,我們有兩種方式,一是用戶(hù)配置了數(shù)據(jù)源的,我們會(huì)直接從數(shù)據(jù)源進(jìn)行重建,重建完成后直接切換。

 

另外對(duì)于沒(méi)有數(shù)據(jù)源,直接 API 寫(xiě)入的,目前我們是利用了 ES 的 Reindex  再配合我們消息隊(duì)列的消息回放實(shí)現(xiàn)的。

 

具體而言,我們就是首先提交 Reindex,同時(shí)數(shù)據(jù)開(kāi)始進(jìn) Queue 轉(zhuǎn)發(fā),然后待 Reindex 完成后,Queue 再?gòu)?Reindex 開(kāi)始時(shí)進(jìn)行回放,追平時(shí)切別名即可。

 

總結(jié)

 

 

總結(jié)一下這次分享的內(nèi)容,我們首先構(gòu)建了一個(gè)低成本,高可用,少運(yùn)維的 ES 平臺(tái)將業(yè)務(wù)從運(yùn)維中解脫出來(lái),然后又進(jìn)一步構(gòu)建了搜索中臺(tái),通過(guò)降低業(yè)務(wù)學(xué)習(xí)成本,下沉通用業(yè)務(wù)邏輯來(lái)加速業(yè)務(wù)迭代,賦能業(yè)務(wù)。 

 

當(dāng)然,這里介紹的搜索中臺(tái)只是最基礎(chǔ)的中臺(tái)能力,我們還在進(jìn)一步探索些復(fù)雜場(chǎng)景下如何抽象來(lái)降低業(yè)務(wù)成本,也就是垂直化的搜索產(chǎn)品。

 

作者:善仁

編輯:陶家龍、孫淑娟

出處:轉(zhuǎn)載自金融級(jí)分布式架構(gòu)(ID:Antfin_SOFA)微信公眾號(hào),本文根據(jù)他在 2018 Elastic 中國(guó)開(kāi)發(fā)者大會(huì)的分享整理。

完整PPT:http://www.sofastack.tech/posts/2018-11-12-01

[[249348]]

善仁,螞蟻金服通用搜索產(chǎn)品負(fù)責(zé)人,通用搜索目前擁有上萬(wàn)億文檔,服務(wù)了上百個(gè)業(yè)務(wù)方,是螞蟻內(nèi)部最大的搜索產(chǎn)品。其所在的螞蟻中間件搜索團(tuán)隊(duì)專(zhuān)注于構(gòu)建簡(jiǎn)單可信的搜索產(chǎn)品,是阿里經(jīng)濟(jì)體中最大的搜索服務(wù)提供商。目前專(zhuān)注于抽象各種復(fù)雜場(chǎng)景下的搜索解決方案,力求讓搜索人人可用,人人會(huì)用。

 

 

 

責(zé)任編輯:張燕妮 來(lái)源: 51CTO技術(shù)棧
相關(guān)推薦

2015-01-22 15:14:02

IT運(yùn)維高效

2016-11-17 12:49:36

云運(yùn)維銀行卡建設(shè)

2013-01-23 09:40:11

云計(jì)算云平臺(tái)信息化

2013-01-22 15:35:19

UCSRAC數(shù)據(jù)中心

2017-02-06 11:43:57

ZooKeeper集群

2017-02-19 19:57:05

ZooKeeper集群

2012-07-05 09:53:49

虛擬化

2018-06-23 07:53:31

大數(shù)據(jù)分析框架數(shù)據(jù)

2012-07-04 11:21:07

OpenStack

2012-11-14 15:25:58

2014-08-14 16:38:22

HeartbeatApache集群

2022-05-11 13:55:18

高可用性分布式彈性

2023-12-07 12:38:09

架構(gòu)低成本開(kāi)發(fā)

2018-07-02 08:25:14

2015-12-04 11:36:04

SaaS架構(gòu)設(shè)計(jì)可持續(xù)

2016-09-21 12:54:10

CAAS系統(tǒng)鏡像

2017-05-27 14:47:08

2015-09-28 17:22:44

浪潮

2010-11-15 18:37:41

高可用的廣域網(wǎng)絡(luò)

2020-08-06 08:17:52

FaaS平臺(tái)Serverless
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)