背景
阿裡雲開放搜尋OpenSearch是一款阿裡巴巴自主研發的大規模分布式搜尋引擎平台,該平台承載了淘寶、天貓、1688、神馬搜尋、口碑、菜鳥等搜尋業務,通過OpenSearch雲服務的方式,将阿裡巴巴成熟的搜尋技術共享給廣大開發者。随着近些年客戶數量的增加,使用者資料越來越多樣化,對于搜尋結果可定制化的需求也越來越高,線上幹預服務就是針對該需求而設計的。
https://www.atatech.org/articles/119624#1 幹預服務架構
以功能較全的違禁詞幹預為例,介紹搜尋幹預服務的整體架構:
http://git.cn-hangzhou.oss-cdn.aliyun-inc.com/uploads/opensearch_online/wiki/d37e236b75491ca08eedf78874c336e5/image.png- 幹預資料系統前端,将幹預資料推送到資料庫中,同時觸發幹預資料推送服務。
- 幹預資料推送程序把資料寫入swift,線上服務從swift中拉取幹預資料,Online生效。
- 幹預資料推送服務程序查詢資料的線上生效情況,同時将生效情況錄入資料庫中。
PS. 除了推送幹預資料,管理前端還包括删除、修改、查詢幹預資料的功能。另外,線上生效API,幹預曆史操作記錄的檢視也是從此接入。
目前主流的幹預服務架構,包括以下兩條資料流
- 通過SyncService寫入ODPS的全量流
- 通過api推送的實時流
上述方案的核心在于解決線上資料生效檢查的問題,本文後續将介紹OpenSearch的解決方案。
現有幹預服務架構存在的問題
上述幹預服務架構不适合直接複用在OpenSearch現有的架構上,主要原因有以下幾點:
- 不支援多租戶幹預資料管理,使用方自己存儲幹預資料
- 不支援按條件dump幹預資料到odps表中,使用方自己從自己的維護的資料庫中dump資料
- 針對違禁詞幹預,支援查詢線上業務是否生效,其他幹預類型不支援
- 不支援使用者自定義的資料格式的校驗
- 不支援保序
- 幹預服務是一個獨立服務,一個程序,單點運作,存在風險
- 沒有部署在hippo上,不便于運維
https://www.atatech.org/articles/119624#2 整體架構
http://git.cn-hangzhou.oss-cdn.aliyun-inc.com/uploads/opensearch_online/wiki/313c7cfc762f6402e178fa88e9a7f015/%E5%B9%B2%E9%A2%84%E7%B3%BB%E7%BB%9F.png 如上圖所示,幹預系統的整體架構主要包括三個子產品:綠色标注的reception woker,主要面向前端推送、删除和查詢幹預資料。藍色标注的ops woker,負責提供幹預系統的運維服務,包括注冊/删除幹預類型,查詢資料生效狀态等等。紫色标注的sync worker,負責同步DB中的資料到線上服務,該woker是面向内部的服務,無法通過外部API通路。值得一提的是,考慮到某些業務有dump全量到ODPS的需求,幹預系統在設計的時候預留了dump資料的API,可以通過接口操作ops worker實作dump,其中ODPS的access_key, secret均可以通過config檔案配置。
https://www.atatech.org/articles/119624#3 OpsWorker
- 通過ops worker可以添加新的幹預類型,包括定義幹預資料的schema、對每個字段的檢驗規則、資料的發送目标(如: swift zk位址,swift topic)
- ops worker提供按條件dump資料的odps中的api
- ops worker會定期更新每個類型的類型的哨兵doc的時間戳,并檢查對應的表資料是否生效;
服務重新開機恢複:
ops worker保證重新開機自動從斷點恢複服務,以dump data為例,資料庫中儲存pending_task_table和history_task_table兩張表,分别記錄正在dump的任務和曆史任務。使用者送出dump請求時,ops worker利用dict type、dict id和ODPS資訊生成signature,查找pending_task_table,如已經存在相同任務則傳回其task_id。如果不存在,線程隻需将相關資訊寫入資料庫,ops worker另啟一個線程掃描pending_task_table,執行dump任務,dump完成删除pending_task_table相關任務,同時修改history_task_table中任務狀态。如果服務運作過程中當機,重新開機之後依舊會啟動線程從pending_task_table中讀取待dump的任務,保證服務的正确運作。
https://www.atatech.org/articles/119624#4 ReceptionWorker
- 通過ops worker注冊幹預類型後,就可以發送幹預資料。
- reception worker支援增、删、改、查。
- reception worker接受到幹預資料後,根據注冊好的校驗規則,對資料進行驗證。校驗規則如:資料的字段類型、内容格式、總的幹預資料條數、發送到swift中的格式等。
- 驗證通過後将資料儲存到db中,成功後api傳回推送成功
除此之外,reception worker還具備保序功能:
- 使用者請求中帶上timestamp,如沒有,reception worker按收到請求的時間作為請求的timestamp
- 資料庫中存放資料記錄表中有個字段用來儲存該timestamp;
- worker在寫資料時,比較請求的timestamp和資料庫中該記錄對應的timestamp大小,如:
- 請求中的timestamp較大,則更新資料庫中的記錄中的data,task_id, timestamp
- 請求中的timestamp較小,則不更新
https://www.atatech.org/articles/119624#5 SyncWorker
http://git.cn-hangzhou.oss-cdn.aliyun-inc.com/uploads/opensearch_online/wiki/f6940c55aafb1feebfcca063b5e98263/sync_worker.png- 訂閱drc消息,将資料庫更新的記錄同步到swift中
- 不同類型的幹預資料可以在同一張db表中
- 對每種類型的幹預資料啟動一個線程,從drc訂閱增量資料,過濾出需要的幹預類型的資料,轉換成相應的格式後發到swift中
https://www.atatech.org/articles/119624#6 線上生效驗證
http://git.cn-hangzhou.oss-cdn.aliyun-inc.com/uploads/opensearch_online/wiki/7859a1b68b940cbd280ed0d05ff4c834/%E5%B9%B2%E9%A2%84%E6%9C%8D%E5%8A%A1%E6%95%B0%E6%8D%AE%E6%B5%81%E8%BD%AC%E5%9B%BE.png注:idx表示dict_idx, data表示幹預資料,u_tx表示使用者給資料打上的用于保序的時間戳,s_tx表示reception_worker收到資料給打的時間戳。
如圖,我們采用時間戳的方式來驗證資料生效,幹預資料推送進入資料庫時記錄其時間,sync worker同步DB中的資料到Online Service。同時,資料庫中保留哨兵(sentinel)時間戳,ops worker定期去更新資料庫中的哨兵時間戳,DRC同步更新的資料到Online Service,ops worker定期檢查未生效的資料,如果其時間戳小于Online中時間戳,表明資料已經生效。
以上圖為例進一步說明:
- reception worker接收到幹預資料推送請求,如圖中:
- 請求1,包含了詞典id1的資料,請求中有資料的timestamp;
- 請求2,包含了詞典id2的資料,請求中有資料的timestamp;
- 請求3,包含了詞典id2的資料,請求中無timestamp,此時reception worker會以接收到請求的時間點作為請求的timestamp
- reception worker會根據請求中的timestamp對資料做保序處理;
- reception worker會将請求中的資料做處理(包括資料驗證、條數控制等),生成task_id, 将幹預資料寫入data table中,同時将task_id和寫data table完成的時間戳(s_t:system_timestamp)寫到task table中,如圖中:
- 請求1,對應的task1,完成的時間為s_t1,status為未生效;
- 請求2,對應的task2,完成的時間為s_t2,status為未生效;
- 請求3,對應的task3,完成的時間為s_t3,status為未生效;
- 其中s_t1 < s_t2 < s_t3
- 寫db完成後,reception worker傳回響應,響應中包含了本次請求對應的task_id
- 在這個過程中,ops worker周期性的重新整理哨兵doc: sentinel記錄中的timestamp,如圖中:
- 在reception worker完成請求2寫資料庫的時候,sentinel的timestamp被更新為s_t2;
- 在reception worker完成請求3寫資料庫的時候,sentinel的timestamp被更新為s_t3;
- sync worker通過drc訂閱了data table的資料變化,并将變化的資料依次寫入到swift中,寫入swift中的資料序列如圖中:
- id1,id2, sentinel, id3, sentinel
- 線上服務通過訂閱swift擷取對應的消息,每個表隻訂閱自己關心的資料,每個表都會訂閱sentinel的資料,如圖中:
- cluster1中的table1,訂閱到的消息序列為id1, sentinel, sentinel
- cluster1中的table2,訂閱到的消息序列為id2, sentinel, sentinel
- cluster1中的table3,訂閱到的消息序列為sentinel, id3, sentinel
- cluster1中的table4,訂閱到的消息序列為sentinel, sentinel
- 線上服務依次處理訂閱過來的消息
- ops worker在周期性的擷取task table中未生效的task,并通過dict_type和dict_id查詢線上服務,擷取其中加載的sentinel doc的最新時間戳,通過該值和表中task對應的timestamp做比較,如:
- 查詢傳回的值較小,則說明資料未生效;則繼續檢查;
- 查詢傳回的值較大,則說明資料已生效,将task table中對應記錄中的status設定為已生效;
- 圖中的task1,僅當sentinel doc的timestamp大于等于s_t2時,則已生效
- 圖中的task2,僅當sentinel doc的timestamp大于等于s_t2時,則已生效
- 圖中的task3,僅當sentinel doc的timestamp大于等于s_t3時,則已生效
https://www.atatech.org/articles/119624#7 産品設計
查詢分析詞典幹預邏輯主要可以拆分為三個流程,
- 建立幹預詞典流程
- 管理幹預詞典流程
- 綁定/解綁到規則/模型流程
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuU2YyADNlNGOwIzNyAjYiJTNmNWNkNDZ2MWOjdDZiFWMvwVbvNmLj5Wat4Wd5lGbh5iY1BXLn1WauU3bop3ZuFGat42YucWbp1iMhRXYvw1LcpDc0RHaiojIsJye.png)
下面以停用詞詞典為例,介紹OpenSearch幹預服務産品設計方案
查詢分析幹預詞典建立和呈現
使用者從主導航欄點選幹預功能,選擇查詢分析子菜單,進入到查詢分析幹預功能首頁。在首頁,使用者可以實作幹預詞典的建立、幹預詞典的清單呈現和簡單的操作管理。
建立查詢分析幹預詞典
使用者在查詢分析幹預首頁點選建立按鈕,彈出建立詞典彈框。
- 詞典名稱,可自定義名稱,用來清單展示。
- 詞典類型,可選同義詞、停用詞、拼寫檢查。
- 點選确定後,幹預詞典建立完成。
- 建立好的幹預詞典顯示在字典清單。
- 建立完成的幹預詞典後續不支援詞典名稱和詞典類型的修改。
幹預詞典清單
- 包含幹預詞典的名稱、詞典類型、使用該詞典的查詢分析規則名稱、詞典的更新時間以及操作欄。
-
在操作欄可以對詞典進行編輯和删除。
a. 點選編輯後進入對應詞典的編輯頁面,使用者可在詞典編輯頁面上傳幹預内容。
b. 點選删除後彈出删除提示彈框,确認删除後,該幹預詞典内的幹預資料失效,幹預詞典也不再在清單内展現。
- 重新整理清單: 使用者配置使用幹預詞典的查詢規則後如果清單内未顯示最近的配置,點選重新整理嘗試重新擷取配置結果。
停用詞幹預詞典幹預資料上傳
核心邏輯描述,
幹預對象:系統原生停用詞詞典
幹預方式:手動輸入、檔案批量上傳
幹預行為類型:添加、屏蔽
手動輸入方式上傳幹預資料
a. 添加操作:添加的内容隻是具體的停用詞。添加生效後,幹預詞條在查詢中會按照停用詞處理。
b. 屏蔽操作:填寫格式同上。生效後,該幹預詞條在查詢中不會按照停用詞處理。
c. 每行隻支援填寫一個停用詞,點選“新增”,使用者可以繼續增加新幹預詞條
批量導入方式上傳幹預資料
使用者可上傳檔案添加幹預資料,檔案内容的格式待定。
詞典幹預内容清單。呈現内容包括幹預行為類型,幹預詞條,幹預生效時間,生效狀态和操作欄。
- 生效狀态隻有兩種,已生效和正在生效。
- 操作欄支援使用者進行幹預内容的删除操作,删除後該條幹預失效,清單内也不再展現。