◆黃珊珊 丁小波 蔡茂貞
(中移互聯(lián)網(wǎng)有限公司云產(chǎn)品事業(yè)部 廣東 510600)
筆記搜索通過ES(Elastic Search)作為筆記的搜索和分析引擎,ES寫入歷史數(shù)據(jù)形成筆記的索引,kafka實(shí)現(xiàn)分布式消息訂閱同步筆記數(shù)據(jù),Mysql存放當(dāng)天所有筆記數(shù)據(jù)用于數(shù)據(jù)更新,Redis存放分詞和筆記ID,用戶搜索時(shí)先從ES查數(shù)據(jù),再和Redis比較,如果Redis有則以Redis為準(zhǔn)。
用戶把資料和文件放到互聯(lián)網(wǎng)上存儲(chǔ),提供存儲(chǔ)服務(wù)的就是網(wǎng)盤。網(wǎng)盤分為企業(yè)網(wǎng)盤和個(gè)人網(wǎng)盤兩種,從功能上來看,企業(yè)網(wǎng)盤相比以存儲(chǔ)備份為主的個(gè)人網(wǎng)盤,有了大幅的擴(kuò)充和提升,更加強(qiáng)調(diào)企業(yè)管理、協(xié)同的需求。企業(yè)網(wǎng)盤的基礎(chǔ)功能為文檔管理與協(xié)同辦公,包括存儲(chǔ)備份、預(yù)覽、搜索、在線協(xié)作、傳輸、分享等。網(wǎng)盤的盈利方式大致分為按流量付費(fèi)和按空間付費(fèi)。
iiMedia Research(艾媒咨詢)數(shù)據(jù)顯示,2020年中國智能手機(jī)用戶規(guī)模達(dá)9.26億人,隨著智能終端設(shè)備的普及,個(gè)人網(wǎng)盤需求不斷提升。個(gè)人網(wǎng)盤用戶的需求已不單純滿足于文件云端存儲(chǔ),而開始向信息共享、信息瀏覽、信息歸類等升級,促使云盤服務(wù)商不斷進(jìn)行產(chǎn)品功能的升級。
基于語音、圖像識(shí)別與分析等人工智能技術(shù)的應(yīng)用,個(gè)人網(wǎng)盤在內(nèi)容智能分類、內(nèi)容檢索和內(nèi)容創(chuàng)作上為用戶帶來更將智能、便利和高效的服務(wù),利用AI技術(shù)的個(gè)人云盤將可以采用更加智能化的方式幫助用戶提高數(shù)據(jù)管理的效率,進(jìn)一步優(yōu)化用戶使用體驗(yàn)。在網(wǎng)盤的內(nèi)容審查方面,AI在后臺(tái)審查中將充分發(fā)揮降本增效的優(yōu)勢,將保障平臺(tái)合規(guī)化發(fā)展,提高信息安全審核的效率,減少盜版侵權(quán)和淫穢色情信息在用戶之間的分享和傳播。
筆記搜索屬于網(wǎng)盤智能搜索中的一類,提供模糊匹配、拼音搜索、近義詞搜索、智能糾錯(cuò)等多種服務(wù)。
圖1 個(gè)人網(wǎng)盤需求數(shù)量圖
個(gè)人網(wǎng)盤終端用戶發(fā)布的筆記,通過平臺(tái)進(jìn)行存儲(chǔ)和數(shù)據(jù)維護(hù),并通過筆記外鏈分享平臺(tái)分享給其他終端用戶查看,在這個(gè)基礎(chǔ)上,增加筆記搜索功能,主要包括標(biāo)題、正文和附件名稱的搜索,筆記正文客戶端產(chǎn)品目前限制為單個(gè)筆記9萬字,在此基礎(chǔ)上實(shí)現(xiàn)筆記全文搜索,最大可能實(shí)現(xiàn)筆記數(shù)據(jù)精確匹配,系統(tǒng)同時(shí)支持拼音檢索。提升用戶使用彩云筆記功能體驗(yàn)。
技術(shù)選型:
Web容器:springboot+tomcat
Redis客戶端:jedis
ES客戶端:hight-levelclient
kafka客戶端:kafka-consumer
Mysql客戶端:jdbc-driver
4.1.1 kafka數(shù)據(jù)本地硬盤持久化機(jī)制
用于消費(fèi)kafka數(shù)據(jù),并持久化到本地磁盤,目的是用于問題的定位和數(shù)據(jù)回放。
使用一個(gè)文件,一個(gè)寫指針,一個(gè)讀指針,并使用2個(gè)文件記錄讀,寫位置。位置文件通過20位的長度記錄一個(gè)數(shù)字,更新時(shí)也是直接覆蓋這20位數(shù)據(jù)。
寫文件:
按每天的日期新建一個(gè)消費(fèi)文件[2021-11-11.txt],把讀取到的數(shù)據(jù)寫入該文件。
新建一個(gè)記錄寫的文件[2021-11-11_write.txt],把當(dāng)前的寫位置寫入該文件的前20位。
新建一個(gè)記錄寫的文件[2021-11-11_read.txt],把當(dāng)前的讀位置寫入該文件的前20位。
每次程序啟動(dòng)時(shí),需要讀取最早日期的讀寫位置文件,如果不存在則新建,默認(rèn)位置為0。如果存在,則開始讀取,如果讀取完畢,則+1天繼續(xù)尋找。
如果需要重跑某天的數(shù)據(jù),則只要?jiǎng)h除該天的讀位置文件即可。調(diào)用過程中可以獲取具體的消息位置,用于隨時(shí)調(diào)整開始o(jì)ffset。
4.1.2 中文和拼音分詞使用機(jī)制
ES安裝分詞插件IK分詞器。
ik_max_word:最細(xì)粒度的分詞,把一句話拆成數(shù)量最多的詞組。
ik_smark:最粗粒度的分詞,把一句話拆成數(shù)量最少的詞組。
建立索引時(shí)使用ik_max_word,查詢條件使用ik_smart。
通過自定義詞庫,把需要特定聯(lián)合的詞組放進(jìn)去作為最小分詞查詢條件。
ES安裝分詞插件拼音分詞器 。
ES寫入:把原有標(biāo)題、正文、附件名稱、+IK分詞列冗余、拼音分詞列冗余,共5個(gè)字段一起入庫。
ES讀?。焊鶕?jù)分詞+全文模糊搜索記錄。
4.1.3 Redis數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
每日更新的數(shù)據(jù):
4.1.4 ES數(shù)據(jù)割接配置
ES數(shù)據(jù)割接時(shí),需要獨(dú)立一個(gè)節(jié)點(diǎn)為協(xié)調(diào)節(jié)點(diǎn),該節(jié)點(diǎn)不存儲(chǔ)數(shù)據(jù),也不作為主節(jié)點(diǎn),只是作為一個(gè)空閑節(jié)點(diǎn),然后程序割接的時(shí)候只對該節(jié)點(diǎn)發(fā)送數(shù)據(jù),割接后,釋放該協(xié)調(diào)節(jié)點(diǎn)為數(shù)據(jù)節(jié)點(diǎn),增加原本的存儲(chǔ)空間。Es的日常使用的配置和割接時(shí)是一樣的,寫入延遲是120s[因?yàn)閑s數(shù)據(jù)一天定期更新,不需要實(shí)時(shí)寫入],異步寫入,每個(gè)文檔大小最大為50MB,寫入合并塊大小為1GB。
4.1.5 Mysql擴(kuò)容機(jī)制
現(xiàn)有方案:分表,今日新增數(shù)據(jù)通過切割成1000張表,每條數(shù)據(jù)通過手機(jī)號(hào)碼計(jì)算1000的hash,然后寫入到對應(yīng)的分表中??梢灾蚊咳招略?億條數(shù)據(jù)[2400tps,一天為2億]計(jì)算,每個(gè)表的數(shù)據(jù)為20w。
Mysql擴(kuò)容方案:
(1)增加HBase,把筆記正文標(biāo)題,正文,附件3個(gè)字段合并成json寫入HBase,其余字段寫入mysql的分表,可以提升Mysql的寫入tps5倍以上,可以支撐10億的日增量。
(2)Mysql分庫,把Mysql增加數(shù)據(jù)庫實(shí)例,平攤更大的日增量。
4.1.6 ES擴(kuò)容機(jī)制
ES現(xiàn)有方案:
存量數(shù)據(jù)為1億條doc,申請11臺(tái)機(jī)器,11個(gè)數(shù)據(jù)節(jié)點(diǎn),沒有協(xié)調(diào)節(jié)點(diǎn),每個(gè)機(jī)器64GB內(nèi)存,每個(gè)機(jī)器運(yùn)行一個(gè)ES實(shí)例,實(shí)例JVM內(nèi)存為31GB。
總共11個(gè)索引,每個(gè)索引3個(gè)分片,1副本[割接時(shí)去掉],寫入時(shí)按照號(hào)碼的0-10做hash定位到具體的索引名稱,然后把用戶的筆記按照大小合并成12個(gè)doc寫入該索引。如果用戶筆記數(shù)目過大,則在第12個(gè)文檔里面寫入一個(gè)標(biāo)志位,表示該用戶擴(kuò)展了96個(gè)文檔,然后就繼續(xù)合并成96個(gè)文檔寫入該索引,讀取時(shí),如果讀取到該標(biāo)志位,則需要進(jìn)行二次查詢得到該用戶的所有數(shù)據(jù)。如果用戶單個(gè)筆記的數(shù)據(jù)量超過50MB[ES單個(gè)文檔大小],則截取該用戶筆記的前50MB長度寫入,后面的丟棄。
分片分配理由:當(dāng)前有11個(gè)ES實(shí)例,11個(gè)索引,每個(gè)索引3分片1副本,即總共有33*2=66個(gè)塊分布在11臺(tái)機(jī)器上,每臺(tái)機(jī)器6個(gè)塊,一個(gè)號(hào)碼最多存儲(chǔ)在3臺(tái)機(jī)器上,最少1臺(tái)機(jī)器上。單號(hào)碼查詢的響應(yīng)機(jī)器數(shù)目少于總數(shù)的30%。
ES擴(kuò)容方案:擴(kuò)容索引,當(dāng)前寫入的索引范圍為0-10,使用號(hào)碼做hash-11得到,當(dāng)擴(kuò)容一次時(shí),增加10*11個(gè)索引,每個(gè)hash的索引范圍對應(yīng)為原h(huán)ash+原h(huán)ash*10-原h(huán)ash*10+9的范圍。寫入時(shí),按照文檔數(shù),hash或者順序?qū)懭脒@11個(gè)索引。擴(kuò)容2次時(shí),同樣增加110個(gè)索引,索引范圍為21個(gè)。以此類推。查詢時(shí),同樣經(jīng)過計(jì)算索引范圍,使用聯(lián)合查詢的api進(jìn)行查詢匹配。
舉例:當(dāng)號(hào)碼1390000000做hash-11時(shí),得到的數(shù)字是5,那么當(dāng)擴(kuò)展次數(shù)為0的時(shí)候,筆記數(shù)據(jù)寫入的索引名稱為5,當(dāng)擴(kuò)展次數(shù)為1的時(shí)候,寫入的索引名稱范圍為5,50-59,總共11個(gè),即這個(gè)號(hào)碼的所有筆記可以順序?qū)懭脒@11個(gè)索引,或者h(yuǎn)ash寫入這11個(gè)索引。
4.1.7 安全機(jī)制
增加kafka發(fā)送方和接收方的兩對rsa密鑰,用于發(fā)送時(shí)簽名加密,接收時(shí)解密驗(yàn)簽。
平臺(tái)在發(fā)布筆記數(shù)據(jù)時(shí),需要對發(fā)送數(shù)據(jù)加密,雙方約定好解密密鑰,推薦使用rsa非對稱加密,并需要通過驗(yàn)簽。
搜索應(yīng)用程序在消費(fèi)kafka數(shù)據(jù)時(shí),需要對接收收據(jù)解密,并驗(yàn)簽。
4.1.8 容錯(cuò)機(jī)制
增加kafka發(fā)送數(shù)據(jù)的md5校驗(yàn)值。
平臺(tái)發(fā)送筆記數(shù)據(jù)時(shí),增加一個(gè)字段,寫入通過md5加密的校驗(yàn)值。
搜索應(yīng)用程序在消費(fèi)kafka數(shù)據(jù)時(shí),需要對接收數(shù)據(jù)和md5做校驗(yàn)。
Mysql數(shù)據(jù)庫是通過雙機(jī)主備避免單點(diǎn)故障。
搜索應(yīng)用程序通過單機(jī)器雙節(jié)點(diǎn)部署程序,避免單點(diǎn)故障。
ES搜索節(jié)點(diǎn)集群本身可以保證單點(diǎn)故障。
搜索應(yīng)用程序?qū)懭氲谋镜匚募?,通過多個(gè)機(jī)器的冗余消費(fèi),當(dāng)單機(jī)數(shù)據(jù)有問題時(shí),可以通過其他節(jié)點(diǎn)繼續(xù)讀取寫入。即每個(gè)節(jié)點(diǎn)的寫入消費(fèi)數(shù)據(jù)是相同冗余的,但是實(shí)際讀取消費(fèi)數(shù)據(jù)是唯一的,如果某個(gè)節(jié)點(diǎn)發(fā)生問題,其他機(jī)器可以接力。
4.1.9 數(shù)據(jù)稽核機(jī)制
每日新增的數(shù)據(jù),搜索服務(wù)會(huì)把當(dāng)天接收到的數(shù)據(jù)寫入Mysql數(shù)據(jù)表,平臺(tái)需要導(dǎo)出每日發(fā)送kafka的數(shù)據(jù)文件[只導(dǎo)出noteid],通過FTP的方式放在指定的服務(wù)器上,搜索服務(wù)會(huì)通過FTP把該文件下載下來,然后通過Mysql的load data命令把該文件加載到對比表中,然后再通過程序進(jìn)行SQL的關(guān)聯(lián)得到差異表的數(shù)據(jù),并通過郵件預(yù)警的方式通知。
4.1.10 筆記搜索流程
筆記搜索通過Mysql+Redis+ES的異構(gòu)數(shù)據(jù)庫進(jìn)行筆記全文搜索。
(1)第一次接收用戶的查詢請求;
(2)將關(guān)鍵詞進(jìn)行java分詞,然后根據(jù)分詞從Redis獲取今日數(shù)據(jù)對應(yīng)的筆記數(shù)據(jù),返回分詞對應(yīng)的筆記ID;
(3)使用查詢關(guān)鍵詞去ES匹配今日以前的存量筆記,返回筆記數(shù)據(jù);
(4)步驟2中獲取到的筆記ID,通過筆記ID從Mysql中獲取筆記詳情;
(5)合并ES、Mysql查詢到的筆記數(shù)據(jù);
(6)搜索結(jié)果處理,如高亮標(biāo)簽、縮略圖等;
(7)將查詢結(jié)果寫入Mysql的分頁表中,并同時(shí)寫入分頁標(biāo)志;
(8)查詢分頁數(shù)據(jù)時(shí),先查詢對應(yīng)的分頁標(biāo)志,如果存在,則直接查詢mysql分頁表獲取分頁的筆記數(shù)據(jù),如果不存在則重復(fù)步驟1-7。
雖然筆記搜索系統(tǒng)的實(shí)現(xiàn)難度非常高,筆記大數(shù)據(jù)寫入和查詢過程困難重重,但通過各種實(shí)現(xiàn)機(jī)制的報(bào)障和可靠算法的支撐,綜合了各種技術(shù)方案的優(yōu)缺點(diǎn)(表1),最終實(shí)現(xiàn)了系統(tǒng)穩(wěn)定、安全、可靠、易擴(kuò)展。
表1 搜索方案對比
數(shù)據(jù)查詢時(shí)間為2s,4節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)1000線程,2000tps。
數(shù)據(jù)插入各組件性能:
kafka消費(fèi)速度:1GB/s
硬盤到Mysql:2400tps
Mysql到ES:3300tps
網(wǎng)盤使用筆記可以搜索技術(shù)降低搜索耗時(shí)和增加用戶活躍度,筆記1.1億條數(shù)據(jù),每天新增約200萬條數(shù)據(jù),使用筆記搜索技術(shù)前每天筆記搜索次數(shù)為8.9萬,平均搜索響應(yīng)時(shí)間為115ms,使用后每天筆記搜索次數(shù)為15.3萬,每月新增192萬月活,平均搜索響應(yīng)時(shí)間為86ms,減少25%的搜索耗時(shí)。
隨著互聯(lián)網(wǎng)技術(shù)的不斷發(fā)展以及用戶對搜索使用的不斷熟練,未來幾年中,筆記搜索技術(shù)將在以下幾個(gè)方面重點(diǎn)發(fā)展:
(1)搜索盡可能多的信息。盡管信息爆炸,盡管“99%的信息對99%的人沒有用處 ”,但從整體來看,用戶對信息的追求是無止境的,他們永遠(yuǎn)希望能占有全部的信息。
(2)搜索引擎專業(yè)化。面向某一行業(yè)、某一主題和某一地區(qū)的信息而建立的垂直搜索引擎是未來的發(fā)展方向,為有專業(yè)需要的人提供專業(yè)化的解決方案永遠(yuǎn)是正確的。
(3)搜索功能智能化。搜索引擎的智能化體現(xiàn)在兩方面,一是對搜索請求的理解,二是對筆記內(nèi)容的分析。其中通過對用戶的查詢計(jì)劃、意圖、興趣方向進(jìn)行推理、預(yù)測,并為用戶提供有效的答案,是這種系統(tǒng)的支柱技術(shù)。自然語言搜索能力作為智能化的一個(gè)體現(xiàn),是目前相對易于開發(fā)的技術(shù)。
(4)搜索服務(wù)個(gè)性化。搜索引擎?zhèn)€性化的核心是通過跟蹤分析用戶的搜索行為,充分地利用這些信息來提高用戶的搜索效率。通過搜索行為分析技術(shù)提高搜索效率的途徑主要有兩種:“群體行為分析”和“個(gè)性化搜索”。
(5)支持多媒體搜索。隨著寬帶技術(shù)的發(fā)展,筆記中的多媒體會(huì)呈現(xiàn)爆發(fā)式增長。開發(fā)出可查詢圖像、聲音、圖片和視頻的多媒體搜索引擎是一個(gè)新的方向。
網(wǎng)絡(luò)安全技術(shù)與應(yīng)用2022年8期