狼廠項目實踐:通用檢索框架準實時流的設計與實現

背景

檢索對實時性的要求很高,不只是對索引創建、結果召回、策略干擾等核心部分,也包括數據錄入的部分。檢索的數據流主要包括全量數據與增量數據,其中全量數據是在運行前就已經生成好的,在檢索進程運行開始時就直接解析加載了,後面不會再產生,因此不會對錄入有高實時性的需求;而增量數據理論上在整個檢索進程運行過程當中隨時均可能新增,新增了就須要錄入。因此,提升增量數據錄入的實時性,對提高整個檢索的性能有重要做用。node

設計思路與折衷

目前搜索引擎實現增量更新的方案主要有這幾種:(1)提供寫接口,(2)使用文件,(3)使用消息隊列。bash

方案1即檢索框架自己提供寫數據的接口,數據發佈方直接調用,寫入數據。這種方式應該是單次寫入速度最快的,但會使兩方代碼過於耦合,不易擴展和維護。且檢索框架須要提供數據接收讀取的完整機制,也要消耗不少資源。對於發佈方來講,發佈操做也必須依賴接收方的進度。若是數據更新頻率很低,數據量很小,能夠考慮使用這種方式。
狼廠項目實踐:通用檢索框架準實時流的設計與實現
方案2主要是經過文件形式,即每次有新數據到來時,都先寫入一個文件中,而後按期將文件配送到檢索進程本地。檢索服務運行時,會監控本地文件夾的inode變化,一旦有文件產生或修改,就執行回調函數,讀取該文件,進行增量加載。這種方式必定程度上實現了數據發佈方和接收方的解耦,但代價是要增長對文件的操做,而且實際應用中須要依賴數據配送,這是個很耗時的過程。文件自己的產生,拷貝,讀寫,效率也不算高,尤爲在文件內容堆積得很大的時候。因此這種方案,實時性很難保證。
狼廠項目實踐:通用檢索框架準實時流的設計與實現
方案3是經過消息隊列。數據發佈方將數據推到消息隊列中,接收方本身讀取。這種方式很好地實現了雙方業務的解耦,且無需維護對文件的一系列操做,也無需數據配送,實時性大大提高。對於發佈方來講,不用再記錄數據到底要發給哪幾個檢索實例,只需發佈一份數據到消息隊列中便可,檢索實例的增長、減小也都不須要在發佈方進行修改,更加靈活。對於接收方,不用再按期處理堆積得不少的數據,資源使用也更平衡。同時也能夠方便地實現流量控制等。不過穩定性須要依賴於消息隊列自己。
狼廠項目實踐:通用檢索框架準實時流的設計與實現
目前糯米的檢索使用的是方案2,框架成熟,運行穩定,容錯容災也都很完整。但針對糯米自己的業務特色,仍有能夠改進的空間。糯米主要是提供生活服務類的檢索,特色就是數據更新頻繁,數據量大。而文件形式的更新,第一是實時性較差,第二是靈活性不高。而這些均可以經過消息隊列的特色進行優化。框架

消息隊列大都分爲隊列模式和訂閱模式,根據業務需求,多個檢索實例都須要相同的一份數據,因此選擇訂閱模式。異步

針對業務特色,最終選擇方案3,使用消息隊列的訂閱模式,來實現數據的實時加載。函數

具體實現

糯米現有檢索框架通常都是在一個單獨的線程中監控文件變化,經過回調實現增量數據加載。主線程只需在其時傳入須要的配置以及對數據進行處理的回調函數便可,耦合度很低。因此消息隊列的添加理論上只需對這個線程所作的工做進行相應修改便可。oop

糯米現有檢索框架中,增量數據加載的工做流程大體以下:性能

狼廠項目實踐:通用檢索框架準實時流的設計與實現
首先讀取配置文件信息,包括增量文件的命名規則以及讀到的行數等,這是爲了後面打開文件及移動讀指針作準備。這些配置放在本地一個單獨的文件中。以後註冊監控的回調函數,在文件夾inode發生變化時,會觸發raise喚醒wait中的處理線程,從指定行開始逐個字節讀文件,每讀完一條數據就進行一次處理,讀完整個文件後,就wait直到下個文件產生。優化

可見,整個流程都是圍繞着文件展開的。改成使用消息隊列讀取數據後,這些和文件相關的操做就都不須要了,改成接入相應消息隊列的訂閱相關接口。下面描述一種使用消息隊列(Kafka)的訂閱模式進行數據加載的大體流程:
狼廠項目實踐:通用檢索框架準實時流的設計與實現
首先添加一個消息隊列的訂閱類,定義實現異步訂閱的基本方法。搜索引擎

init中,主要實現對各個參數的配置,以及訂閱起始點的讀取。這個起始點是由數據發佈方給出的,因此要在發起訂閱前就設定好。目前的作法和上面同樣,單獨在本地建一個配置文件,裏面存放了起始點的相關數據,init中直接讀取便可。spa

StartSubscribe主要包含兩個方法:獲取要訂閱的消息隊列的子通道的數量,而後對每一個子通道發起訂閱請求。

以後進入SubscribeMainloop,在while循環中接收、處理數據。接收事件經過epoll_wait,只要有可讀或報錯事件觸發,epoll_wait就會返回,不然會阻塞直到超時或有新事件到來。

epoll_wait返回後,若是包含可讀事件,就調用回調函數進行處理便可。若是包含報錯事件,會根據報錯嘗試從新發起訂閱請求。

這樣一條增量數據的加載就完成了,while循環會一直重複這個流程,直到加載完消息隊列裏最新的一條數據。以後就會阻塞在epoll_wait上,直到有新的數據發佈進來。

總結

本文簡單介紹了一種使用消息隊列的訂閱模式實現通用檢索框架增量數據加載的新方案,及其設計與實現。糯米現有檢索框架文件形式的更新,因爲數據配送系統自己的複雜性,須要至少半小時才能更新一次數據。而使用消息隊列更新一條數據的用時在0.5秒之內,更新1000條數據也可在2秒之內完成,實現了準實時流,值得全面推廣在檢索框架的增量數據錄入部分使用。複製代碼

爲何某些人會一直比你優秀,是由於他自己就很優秀還一直在持續努力變得更優秀,而你是否是還在知足於現狀心裏在竊喜,

轉載:http://blog.51cto.com/13732225/2175348

相關文章
相關標籤/搜索