數(shù)據(jù)存儲方案
輿情監(jiān)控平臺的核心價值,就是能夠提供快速精準(zhǔn)的信息檢索,并且輿情系統(tǒng)的使用場景具有以下特點:
實時數(shù)據(jù)價值更高
輿情數(shù)據(jù)傳播趨勢特征明顯,人們關(guān)注的信息大部分集中在7天之內(nèi),且信息采集呈現(xiàn)的及時性,往往是分鐘級的。
信息檢索維度靈活
客戶信息篩選的維度是多樣的,如根據(jù)微博粉絲量、性別、文章段落等。
檢索業(yè)務(wù)處理集中
輿情平臺的檢索壓力有明顯的特征曲線,工作時間負載壓力大,早晚高峰報告查詢集中。
1.選型發(fā)展
信息檢索是輿情系統(tǒng)的核心需求,基于 Lucene 的全文檢索引擎是實時數(shù)據(jù)檢索的組件首選,早期我們使用 Solr,但是 Solr 依賴外部組件協(xié)調(diào)(ZooKeeper),運維成本很高。2015年,我們引入ElasticSearch(ES)作為平臺的底層數(shù)據(jù)庫,提升了輿情數(shù)據(jù)存儲集群的運維效率,也提高了平臺存儲的穩(wěn)定性。隨著業(yè)務(wù)發(fā)展,數(shù)據(jù)量越來越大,即使是已經(jīng)按照業(yè)務(wù)拆分的集群隔離也已經(jīng)不能滿足業(yè)務(wù)查詢的性能要求,2017年底,我們做了大幅底層集群優(yōu)化和硬件升級,從業(yè)務(wù)集群隔離拓展到多集群、多索引的混合集群模式。伴隨產(chǎn)品維度和數(shù)據(jù)量的增長,2018年我們將 HBase 作為非索引大字段的底層存儲,引入基于 Ceph 底層的 OSS 對象數(shù)據(jù)存儲引擎,支撐圖片、音視頻的存儲;架構(gòu)升級后,支持伴隨業(yè)務(wù)的靈活可擴展的緩存多集群方案。
2.存儲架構(gòu)
數(shù)據(jù)寫入
通過數(shù)據(jù)流計算完成的標(biāo)準(zhǔn)數(shù)據(jù),通過 Data Pipeline 同步寫入 全量數(shù)據(jù)倉庫和ES準(zhǔn)實時索引集群,ES 集群存儲文本索引字段,構(gòu)建倒排索引,文檔關(guān)聯(lián)的原始 HTML 和 資源(如圖片、視頻),分別存儲到 HBase和 OSS 對象存儲平臺,構(gòu)建ES 文檔關(guān)聯(lián)。
業(yè)務(wù)拆分
按照業(yè)務(wù)劃分,對實時數(shù)據(jù)敏感的客戶,熱數(shù)據(jù)通過 ES 準(zhǔn)實時索引構(gòu)建檢索結(jié)果,能夠做到數(shù)據(jù)采集到UI呈現(xiàn)低于 30 秒的業(yè)務(wù)體驗,對于預(yù)警時效敏感的客戶,系統(tǒng)將信息準(zhǔn)實時推送給客戶,但這部分客戶犧牲了一部分的定制化干預(yù)功能,如情感標(biāo)簽的定向優(yōu)化。
對大部分客戶,我們根據(jù)業(yè)務(wù)規(guī)則分組,將客戶的專題規(guī)則,經(jīng)由計算中心,同步計算到可擴展的 ES 業(yè)務(wù)緩存,這樣做到客戶專題級別的存儲隔離,大幅提高信息檢索的性能,同時,在同步計算節(jié)點,我們嵌入了可插拔的規(guī)則引擎計算插件,可以二次干預(yù)標(biāo)簽或者附加值計算,給定點客戶提供了更優(yōu)的數(shù)據(jù)分析體驗,通過不斷集群調(diào)優(yōu)和算法改造,實時計算上萬客戶的全部專題,UI 數(shù)據(jù)呈現(xiàn)目前已經(jīng)能做到延遲小于3分鐘。
離線備份
輿情客戶數(shù)據(jù)具有鮮明的時間屬性,歷史數(shù)據(jù)關(guān)注度和分析價值不高,因此我們對數(shù)據(jù)除了 T+1 的同步備份外,線上實時 ES 集群只保留最近2年的數(shù)據(jù),保證的集群的性能不隨數(shù)據(jù)增量衰減,同時,離線備份的數(shù)據(jù),同時用于定期的數(shù)據(jù)統(tǒng)計任務(wù),服務(wù)于輿情分析師,作為長周期報告的數(shù)據(jù)分析來源。
存儲架構(gòu)的升級和變遷,很大程度上是伴隨著系統(tǒng)的負載壓力和不斷增長的數(shù)據(jù)和客戶增量,不斷迭代演進的,通過空間換時間,我們目前已經(jīng)構(gòu)建了一個超過200個 ES 節(jié)點的多集群架構(gòu),支撐每天幾十TB級的數(shù)據(jù)增量,以及上萬客戶的復(fù)雜輿情檢索和計算。
檢索優(yōu)化方案
盡管我們使用 ES作為全文檢索的核心引擎,無論數(shù)據(jù)索引和簡單查詢,都能做到很好的性能支撐,但是輿情檢索有一定的特殊性和復(fù)雜性。
檢索精度要求
輿情服務(wù)的客戶,對于數(shù)據(jù)檢索具有高召回的要求,通過關(guān)鍵詞檢索,任何匹配關(guān)鍵詞、或匹配關(guān)鍵詞組合的數(shù)據(jù),都應(yīng)該被及時檢索并呈現(xiàn),但中文語法復(fù)雜,對于歧義、包含等語義情況,常常存在分詞造成的誤差,導(dǎo)致檢索召回率降低,造成客戶投訴。
檢索性能要求
輿情信息檢索過程中,相似文章需要默認折疊,以分頁形式展示到前端,而數(shù)據(jù)實時入庫,我們要求折疊數(shù)據(jù)的計算是實時的,雖然 ES 聚合(aggregation)性能隨著社區(qū)發(fā)展不斷優(yōu)化,但其仍不能很好的處理億級數(shù)據(jù)的分頁聚合需求,尤其面對超過上千復(fù)雜關(guān)鍵詞邏輯時,性能會變得更差。
數(shù)據(jù)相關(guān)性要求
輿情檢索是要發(fā)現(xiàn)價值信息,而 ES 自身的評分機制,并不能完整反映互聯(lián)網(wǎng)公開數(shù)據(jù)的權(quán)重,比如權(quán)重大的網(wǎng)站發(fā)布的文章、傳播量大的文章,或者負面傾向大的文章,往往需要排在數(shù)據(jù)呈現(xiàn)的前面,即數(shù)據(jù)的相關(guān)性,我們需要做二次的定制。
業(yè)務(wù)靈活性要求
為了讓信息檢索更靈活,我們設(shè)計了一套復(fù)雜的檢索語法,如:或、與、非、距離、字段定制、嵌套檢索等,同時一個檢索,還需要加入特定的規(guī)則干預(yù),如數(shù)據(jù)定向、黑白名單、屏蔽過濾等,各種附加的操作都對 ES 的檢索帶來巨大的復(fù)雜性。
針對上述種種問題,我們列舉部分檢索優(yōu)化點供參考:
集群調(diào)優(yōu)
1.內(nèi)存參數(shù)優(yōu)化
內(nèi)存對于 ES 來說異常重要,單個數(shù)據(jù)節(jié)點,JVM 內(nèi)存設(shè)置為 31GB(不超過32GB),觸發(fā)內(nèi)存指針壓縮技術(shù),配置 G1垃圾回收器;同時,Lucene 被設(shè)計為可以利用操作系統(tǒng)底層機制來緩存內(nèi)存數(shù)據(jù)結(jié)構(gòu),我們至少預(yù)留操作系統(tǒng)內(nèi)存的一半作為 Lucene 的非堆內(nèi)存,如果物理機內(nèi)存小于 64G,給到 ES 節(jié)點的內(nèi)存應(yīng)該不超過內(nèi)存的 50%;另外,內(nèi)存交換到磁盤對服務(wù)器性能來說是致命的打擊,一般會降低一個數(shù)量級,應(yīng)該配置禁止內(nèi)存交換。
2.動態(tài)分片設(shè)置
一個ES ?index 的分片,底層對應(yīng)一個 Lucene 的索引文件,會消耗系統(tǒng)的文件句柄、CPU和內(nèi)存資源,每個檢索請求也會路由分類到每個分片,我們需要綜合考慮查詢請求的負載和分片的大小,合理設(shè)置分片的數(shù)量,因此在我們的 ES 集群管理中,每天的索引分片數(shù)是動態(tài)計算的(根據(jù)近期數(shù)據(jù)增量,預(yù)估當(dāng)天數(shù)據(jù)量,調(diào)整創(chuàng)建索引的分片數(shù)量)。
3.定時段(segment)合并
ES 數(shù)據(jù)寫入過程中,會產(chǎn)生大量的段文件,ES 每個分片的資源開銷,取決于 segment 的數(shù)量,而通過段合并,將較小的分段合并為較大的分段,能減少開銷并提高查詢性能,但段合并是一項十分耗費性能的操作,我們應(yīng)該關(guān)閉索引的自動段合并,在業(yè)務(wù)低峰時段做定時索引段合并。
硬件優(yōu)化
盡量選配 SSD 硬盤,考慮到成本原因,可以結(jié)合業(yè)務(wù)場景,對業(yè)務(wù)檢索有較高的性能要求的,建議使用 SSD 磁盤,檢索不敏感的集群則使用普通磁盤。
同時,當(dāng) ES 集群上有大量的索引時,通過單節(jié)點配置多個掛載磁盤,能夠讓數(shù)據(jù)高效寫入不同的磁盤,在硬件性能較差時,能顯著提升數(shù)據(jù)寫入的效率。
分詞優(yōu)化
我們知道ES 底層是基于分詞的倒排索引,常見的開源中文分詞器很多,如 ik 分詞器、ansj 分詞器、結(jié)巴分詞器、hanlp 分詞器等,但是針對精度要求非常高的輿情數(shù)據(jù)檢索場景,上述分詞器均存在不同程度的誤差。
的是單個詞匯單元,輸出一個字母n-gram 詞匯單元序列,而 Shingles 是將一個序列的詞匯單元,輸出一個單詞級別的 n-gram 詞組單元序列。