品牌名稱
攜程旅行網
所在行業
互聯網
企業規模
51-200人

信息圖譜攜程酒店的應用

634次閱讀

對于用戶的每一次查詢,都能根據其意圖做到相應的場景和產品的匹配”,是攜程酒店技術團隊的目標,但實現這個目標他們遇到了三大問題…本文著重講述他們是如何構建場景與信息關系,用 Nebula 處理關聯關系,從而快速返回場景化定制推薦信息給酒店用戶的實踐過程。

背景

用一句話來概述攜程愚公項目的需求便是“對于用戶的每一次查詢,都能根據其意圖做到相應的場景和產品的匹配”。

信息圖譜在攜程酒店的應用

目前,在酒店排序方面,攜程酒店已經做到了針對不同的用戶群體和使用場景給出定制化服務:在不同的場景下,酒店列表頁面會有不同的排序,獲得了很高的用戶價值提升。而攜程酒店通過在前端展示場景化內容,也降低用戶決策的費力度。

信息圖譜在攜程酒店的應用

假如當前用戶場景是滑雪度假,作為服務提供方我們自然期望前端的各個展示位都能與滑雪相關聯,如上圖酒店列表頁中酒店的短標簽位展示了一個滑雪套餐,酒店的榜單位展示的是當前酒店在當地的滑雪榜排名,以及酒店的展示圖片為雪景下的酒店。

信息圖譜在攜程酒店的應用

酒店詳情頁中,酒店相冊所展示內容也是雪景。相冊排序第一的分類為【滑雪精選】,而酒店的其他短標簽位榜單同列表頁的邏輯類似,展示和滑雪相關的內容。在地理信息位則展示與最近的滑雪場的距離。

信息圖譜在攜程酒店的應用

信息圖譜在攜程酒店的應用

上面兩張圖分別是酒店和房型的詳情信息,在酒店設施、房型氛圍圖內容呈現上,也根據滑雪度假場景做出了相應的調整。

以上 4 張圖,簡單地描述了攜程酒店對于前端各個展示位通過與場景相關聯所能達到的一個展示的效果。

而要實現上述功能,首先要把各種場景與內容信息之間建立關聯,輸入場景的時候就能直接快速地檢索到相關信息進行展示。為此需要解決以下問題:

  1. 缺乏場景和信息的 mapping 關系

  2. 信息的豐富性不夠,無法支撐場景化

  3. 運營和系統不夠高效

信息圖譜在攜程酒店的應用

具體來說,場景與信息關聯關系缺失的原因是,在愚公項目之前,攜程酒店前端展示內容相互獨立,沒有統一的整合體系。像上面提到的特色標簽帶娃、愛住標簽,設施標簽中親子樂園標簽,盡管從語義上能很直接地將它們同親子場景關聯,但它們一個是特色,一個是設施,除了使用同一個的展示位之外,標簽間并沒有其他的共同點。

另一個比較典型的例子就是點評,上圖右側 App 截圖是武漢東湖賓館的三條點評,第一條講到親子出行,第二條講到賞櫻內容,第三條講到旅游建議,而這三類內容目前僅作為一個酒店點評展示并沒有其他更多的作用。而在愚公項目中,如果我們定義了三個場景,一個叫親子,一個叫賞櫻,一個叫旅游,關聯點評與場景標簽,那么我們可以做的事情就更多了。比如一家酒店,其中有 30% 點評提到了親子,可能就可以判斷酒店有親子特色。再比如,提到櫻花的點評中,抽取出簡短、優美的語句同賞櫻場景關聯,當前端傳過來櫻花場景時,這個短句子作為展示補充就可以展示在前端位置…諸如類似用途,我們可以天馬行空、不停的想象,但實現的關鍵點是建立場景與信息之間的關聯。

信息圖譜在攜程酒店的應用

第二個問題是信息豐富度不夠,無法支撐場景化需求。舉個簡單例子,在列表頁篩選了滑雪后,沒有滑雪相關的圖片,也沒有相關標簽地理的位置信息;在詳情頁沒有滑雪相關的相冊信息,也沒有滑雪的氛圍圖,雖然酒店的設施有滑雪設施,但它沒有根據滑雪這一場景做出更高優先級的展示,第二設施滑雪設施也沒有相關的圖片展示,這樣就導致酒店推薦生動性不足。

信息圖譜在攜程酒店的應用

第三個問題是系統和運營不夠高效。具體來說:

  • 新場景 & 新數據開發成本很大。每個場景上線,需要根據聯動位置逐個開發
    • 每個位置接入新信息,需要跟版本發布
  • 數據時效性:無統一標準,時效性不足
    • 例如特色標簽,多個 job 串行:T+x 生效
  • 數據排序:無統一收口方
    • 列表頁短標簽:靜態信息、前端均有邏輯+運營后臺
    • 排查鏈路長,日常維護效率低
  • 數據標準:有多套標準存在
    • 哪些是親子酒店?

展開來說,攜程酒店前端展示位來源于多個服務,比如圖中標出的這 十多個展示位,其中就包含點評、榜單、標簽等一系列服務。如果這些服務的聯動邏輯,沒有統一收口方,那么每新增一個場景,相應的展示位都需要進行相應的開發,這樣開發成本就會比較大。第二點的數據實時性,目前更新 job 存在部分串行,部分數據運營修改之后可能在 t+x 之后才能生效,實時性不高。第三點是數據排序展示邏輯沒有統一的收口方,前后端都有維護相應邏輯的地方,造成冗余信息數據、排查鏈路變長、維護效率低。最后一點是缺少統一數據標準。要判斷酒店是否符合親子特色,怎么做?如果一個酒店有三個特色標簽提到親子,那么它是否是一家親子酒店呢?又或者酒店點評中有 20% 內容提到了親子,那么它是否是一家親子酒店呢?諸如此類的標準,我們需要個準確的定義,場景化的規則才能得以實施。

總結來說,要達到前端各個展示位內容的場景化,需要解決三個問題,一個是場景與信息之間缺少關聯;二是目前的信息豐富度沒有辦法支撐場景化;三是系統的運營效率在原有的架構下不夠高效。為了解決以上的問題,愚公項目就應運而生了。

愚公項目:用戶預訂全流程信息場景化

下圖為愚公項目的總體框架。

項目框架

信息圖譜在攜程酒店的應用

項目涉及到多個系統的提升:

  • 統一的意圖識別
  • 展示位置邏輯下沉
  • 關系匹配
  • 信息挖掘
  • 數據源豐富

愚公項目主要分為上圖 5 部分內容,從上往下第一部分是意圖識別,主要通過用戶的歷史偏好和實時數據來識別用戶的具體意圖,比如用戶他歷史點評中多次出現了“帶娃”、實時的入住篩選項人數中也有小孩篩選項,那么我們判斷他當前意圖有很大概率是親子旅游。

第二部分是信息展示邏輯下沉,之前提到前端有十多個展示位,當中的展示邏輯分別有不同的信息服務維護,在這個模塊我們將這些展示位的邏輯統一收口,信息之間便能做到聯動。此外,還能達到去重、去沖突等作用,還可以整體地對排序召回等邏輯進行規劃。

第三部分是關系匹配,建立場景與數據之間的匹配關系,這里的數據涉及存量的基礎信息數據,通過挖掘得到的增量數據。前期,主要通過人工運維的方式將它們與場景建立一個關聯,后續則會使用 NLP 手段來自動建立聯系。而數據與數據之間、數據與場景之間的這些關系,則會使用 Nebula Graph 作為存儲和檢索的媒介。

第四部分是信息挖掘,即從各類的數據源中抽取出與場景相關聯的信息,又或者是酒店的亮點信息。之前提過的點評例子,在點評中找到與場景相關聯的句子,從中抽取出通順、優美的短句,把它們作為場景化關聯的數據源,在前端進行展示,從而豐富數據源。在信息挖掘模塊,總體的流程會涉及 NLP 相關的數據標注、模型訓練、badcase 反饋、標注再訓練。

最后是數據源,首先要從盡可能多的數據來源中獲取信息,加入圖譜中。當然要盡可能保證數據的準確性,直接從源頭而非第三方來獲取數據。為了保證準確性,后續開發中可能會加入反查機制,比如說某個酒店有游泳池的設施展示信息,通過挖掘數據發現這個酒店當前的游泳池設施早已關閉,那么我們就可以將數據同步給運營人員使得數據更加的準確。

上面 5 個部分,如果將展示位置邏輯的下沉和關系匹配的建立比作一個項目的地基,那么其他的模塊則是在項目上建起的高樓,沒有地基哪來的高樓呢?

下面,講解展示位置邏輯的下沉和關系匹配是如何搭建。

前端信息展示邏輯下沉 & 關系匹配

模塊的重點是收口前端多個展示位邏輯的數據召回邏輯,建立展示位與場景之間的關聯關系。

具體來說,當一個場景進來,系統需要知道哪些展示位要與它聯動,相應的展示位的數據召回邏輯也會隨之變化。舉個例子,親子場景,親子游、親子樂園這樣的短標簽就可以很好地表達親子的含義,這時短標簽位就適合直接與親子場景建立關聯。而美食場景,某個酒店在美食榜中名列前茅的話,相對應美食特色標簽會更有說服力,美食場景就更適合同美食榜單進行關聯。建立關聯關系后,每個展示位是否需要根據場景變化,就有了統一的標準,進而數據召回邏輯也就得到了統一。

信息圖譜在攜程酒店的應用

信息圖譜在攜程酒店的應用

上表和圖標注了 10+ 個前端展示位和它們的一個聯動的等級,聯動等級越高,則代表它展示會更需要貼合場景化,也更能找到更多的與場景相關聯的信息。

信息圖譜在攜程酒店的應用

上面是場景與展示位之間如何建立關系,接下來講講場景與數據之間又如何建立關系。上圖比較直觀,首先要挖掘場景,找到凸顯酒店特色或吸引用戶的點,接著以場景為基礎,找到與場景相聯動的一個展示位,就像之前提到的不同的展示位可以突出不同的特點,場景與合適的展示位關聯可以達到更好的展示效果。最后,通過展示位拓展到相應的數據,而對應的數據可能是已存在或者是為特定場景新增的數據。

信息圖譜在攜程酒店的應用

舉例說明下關系的配置過程,先看一下這張表,現在要定一個新的滑雪場景,首先得判斷前端哪些展示位可以與這個場景建立關聯,找到了酒店的列表頁中快篩短標簽、酒店詳情頁中酒店的頭圖點評等這些展示位,都可以與這個場景建立聯動。然后,只需要通過這些展示位找到相應的數據源和數據類型,配置關系即可。

以短標簽為例,短標簽包含主題標簽、設施標簽等,這些數據源中可能已經存在與滑雪相關的內容,我們可以直接在配置后臺關聯場景關系。如果不存在相關內容,也可以由運營人員進行添加,又或者通過數據挖掘產生新的數據源,再進行關聯。整個關聯在后臺十分直觀地進行展示,配置完成后,數據會實時地寫入到 Nebula Graph 中,前端就可以直接通過滑雪場景篩選到相關的展示。

支撐信息場景化的技術架構

先從 Nebula 的架構和集群部署講起,

信息圖譜在攜程酒店的應用

這張圖大家一定不陌生,Nebula 服務包含 graph 服務、meta 服務和 storage 這三個服務。其中,graph 服務用于處理客戶端的請求,meta 服務用于存儲分片、schema、用戶賬號等等元數據,storage 則用于存儲圖中的點邊、索引數據。

在 Nebula 集群中數據一致性是依賴于 raft 協議,其中 meta 服務和 storage 服務都是基于 raft 協議的集群。而 storage 服務相較于 meta 服務結構更為復雜。具體來說,storage 服務中每一個分片的所有副本共同構成了一個 raft 集群,也就是說 storage 并不是一個 raft 集群,而是有多少個分片,它就有多少個 raft 集群。在 raft 集群中由集群中的 leader 來處理請求,而 follower 用來投票選舉、同步數據、同步日志,并為 leader 提供一個候補。leader 會定時發送心跳,如果有一段時間 follower 沒有接到 leader 發來的心跳,那么他們就會自動開始選舉并產生新 leader,來自 graph 的請求無論是讀還是寫,基本上由 leader 來響應。

由于 raft 協議特點,leader 的投票需要超過半數以上 follower 投票才能選出,一般集群的部署策略是 2n+1 臺機器,這樣可以容忍 n 臺機器產生的問題。

機器部署

信息圖譜在攜程酒店的應用

攜程酒店的部署方式是三機房分散比例部署,5n 臺 Storage Service,將它們分散為 1n:2n:2n,這樣任意一個機房出問題,另外兩個機房都可以繼續使用。但這樣部署也存在一定的問題,即便是三個機房但總體而言其實只是一個集群,讀取時必然存在跨機房訪問讀取帶來的時延問題。此外,這種單機房部署的模式無法支持類似于藍綠之類的發布方式,也無法基于就近訪問來分配流量。

信息圖譜在攜程酒店的應用

這塊,未來攜程酒店的期望是每個機房都能部署獨立集群,做到按集群進行流量控制和支持就近訪問。當一邊集群故障可直接通過域名流量切換到另一邊的單邊集群,不需要耗費太多的切換成本,而寫數據的時候也可以支持藍綠模式的寫入部署。這個模式也讓服務出海變得更為切實可行,比如在海外直接部署一個獨立集群,可大大減少國內海外讀取的時延問題。 這也引出另一個問題,數據同步方面攜程酒店是從國內寫海外,在這種情況下,同步的實時性和穩定性都不能得到很好的保障。攜程酒店也在與攜程系統研發部團隊討論服務端之間直接數據同步的解決方案,如果能實現的話,可以更好地減輕數據同步產生的時延影響。 總之,raft 讓 Nebula 方便地應對由機器本身不可用產生的問題,上面說的新的集群的部署方式,則是在 raft 基礎上讓整個集群可用性更高,對于一個攜程酒店這樣的線上應用容錯也更加符合實際的需求。 講完集群的部署問題,接下來講講項目的架構。

技術架構

信息圖譜在攜程酒店的應用

先比較下項目架構的前后變化,上圖可以看到原來的架構中,客戶端請求的每一種數據來源都有其獨立的場景化配置,部分數據源由于沒有明確的語義完全沒有辦法支持場景化的配置,這就會導致三個主要的問題:

  • 開發繁瑣
  • 實現難度高
  • 信息孤島

第一點,由于信息展示的邏輯離散、存在多個獨立服務,無法形成統一的場景化標準和數據召回邏輯,每個場景化模塊需要單獨的配置文件和實現邏輯。第二點,像類似酒店圖片、酒店問答等類型內容,無法與場景直接建立關聯,只能單純通過人工運營的方式建立關聯,需要耗費很大的成本。第三點,各個信息源的維護沒有統一的標準,信息之間相互獨立,容易造成不同信息源之間可能有信息重復或沖突的情況,比如說酒店主題和酒店設施中包含語義十分相似的標簽,如果這兩個標簽同時展示在前端的話,就會造成信息冗余的問題。

那么如何解決這些問題呢?要搭建一套可以存儲各類信息與信息之間的關系,信息與場景之間的關系,以及將信息召回的邏輯進行統一收口的系統,我們稱之為信息中臺系統。

信息圖譜在攜程酒店的應用

上圖與之前架構的區別,在于把每種數據獨立的場景化配置替換成知識圖譜模塊跟語義標注模塊:知識圖譜模塊用于存儲信息與信息之間、信息場景之間的關系,這里我們會用到 Nebula 。通過 Nebula 建立合適 schema 跟映射關系,大部分數據能在兩度以內完成查找。語義標注模塊則對語義不明確的信息進行挖掘、標注,再與場景建立聯系。像酒店描述信息、酒店問答信息都可從中挖掘有用的數據,補充進知識圖譜。

上圖略抽象,接下來具體地講講中臺系統中每一個模塊的構成和功能。

信息圖譜在攜程酒店的應用

信息中臺的整體架構從右往左可以分成 4 個模塊,分別是信息中臺 API 模塊、信息圖譜模塊、知識標注模塊和數據模塊。

其中,信息中臺 API 模塊是信息中臺對客戶端的服務,這個模塊起到的作用包含場景獲取、數據查詢、數據包裝,整合數據展示邏輯等等。信息中臺 API 讓相冊、標簽、設備這些服務由之前的各自包含獨立的展示邏輯轉化為從統一的來源獲取展示邏輯。

知識圖譜模塊主要整合了數據的召回邏輯,使用 Nebula 作為信息之間的一個存儲引擎,對于基礎數據,比如設施標簽數據,將它們與酒店場景抽象成點,將它們之間的關系抽象成邊。而標注產生的數據則會抽象成點,與它們與酒店場景之間的關聯關系抽象成邊。當輸入場景和酒店 ID 時,通過 Nebula 查詢語句快速地檢索到該酒店下符合場景的所有測試點的索引信息。另外,通過讀取實時消息更新 Nebula 數據,實現實時更新,而不是 t+x 生效,實時性也得到了很大的增強。

信息標注模塊大幅度地增加數據豐富度,對大量 UGC、酒店描述內容,在其中找到與場景相關聯的信息是比較耗費資源的工作。這個時候,使用 NLP 相關技術便能提高效率。上圖中間部分主要畫出了數據在整個信息標注模塊中的流轉過程。首先預處理點評、圖文秀此類信息,得到子句、短句放入標注模塊進行標注。標注的時候,會使用語義標簽,這些語義標簽來源于熱搜詞或者人工定義等等渠道。在使用語義標簽的時候,標簽會直接與場景建立關系,一般情況下這種關系是一對一的,但也會存在一對多的情況。標注好的數據會進行模型訓練,同靜態規則一起進入任務調度模塊對數據批量地打標,最后產生的部分數據進行抽樣人工 check 之后就可以使用。這個信息標注模塊整合了數據產生的流程,大幅度提升了數據產生的效率。

最后,數據模塊負責的是數據整合和傳導,模塊數據來源包含有信息標注模塊產生的各類信息,也包含其他從外部同步來的數據。這些數據最終通過數據同步框架寫入 Nebula Graph 數據庫中。

信息圖譜在攜程酒店的應用

再來講解數據在數據庫模塊中的流轉過程。特色數據、設施數據、酒店數據等等類型分為全量和增量數據,全量數據包含 DB、消息隊列、消息接口、Hive 表等等,其中 Hive 表直接通過 Hive job 直接同步 Nebula,而 DB、消息隊列、消息接口則通過 nebula-java 客戶端同步。攜程酒店結合 Nebula Java 客戶端實現了一套可配置化的同步框架,并搭建了信息同步的服務。當數據來源是接口、消息隊列時,通過實現相應的接口組裝數據,并配置消息字段與 Nebula 字段的映射關系實現數據同步。當數據來源是 DB 時,直接用從 DB 中取數 SQL 語句,并配置 DB 字段與 Nebula 字段的映射關系實現數據同步。增量數據主要來源于消息隊列,增量 job 與全量 job 使用相同映射關系,對于增量消息而言只需實現組裝數據的接口即可實現同步。

除了數據同步之外,攜程酒店還有數據運營的平臺,包含下面 4 個功能:

  1. schema:收口 Nebula schema 操作,Nebula 本身有圖形化界面,攜程酒店將 schema 操作收口到后臺,可便于配置權限、記錄操作日志。

  2. 監控:在數據導入過程中,攜程酒店在 ClickHouse 看板中記錄數據、來源、操作類型、主題信息,便于直觀地查看數據統計信息。此外當有錯誤發生時,結合報錯信息中 Nebula query log 加上 CK(ClickHouse)上的數據,可快速定位到具體點、邊、報錯的類型、數據來源、消息 ID 等等信息。

  3. 依賴配置:在數據組裝時,前面提到有數據源和 Nebula 字段的映射關系配置,每次 job 啟動會實時讀取映射配置,攜程酒店技術團隊將配置放到配置后臺,從而實現實時配置實時生效。

  4. 重試機制:在數據傳輸錯誤發生時,加入重試機制。但消息隊列這類數據本身有重傳的機制,只需在數據異常時給出相應標識。而接口、DB 這類數據暫時沒有重試機制,后續會加入重試機制。

schema 定義和壓測

信息圖譜在攜程酒店的應用

再來講一下 schema 定義和壓測結果。

信息中臺圖譜數據模型分為 4 個大塊,分別是標簽信息、基礎信息、UGC 信息和 GEO 信息。標簽信息中包含設施標簽、特色標簽、長標簽、UGC 標簽等這些點;基礎信息中包含了房型信息、設施信息、政策信息等這些點;UGC 信息中包含挖掘出的子句點、用戶點等信息;GEO 信息包含了 POI 、省份、城市點等等這些點。酒店作為最中心的點被這 4 塊區域所包含,同時與上面提到的每個點都有相關聯的邊。

此外,最上層抽象了語義標簽點,所有與場景建立關聯的點都會有語義標簽直接建立相應的邊關系。這樣,當輸入一個酒店 ID、場景 ID,能很快地篩選出當中所有點的信息。這樣的 schema 是比較符合業務邏輯的,但在實際的上線過程中還是出現了些問題,其中比較典型的是熱點數據問題。

舉個例子來說,A 類型數據量可能是百萬級,B 類型數據量是千級,每一個 A 與 B 之間存在關聯,那么關聯的邊量級可能在十萬級或者百萬級,查詢時 B 可能會變成超級節點影響部分性能。

對此,想過幾個解決方案。一是增加分片數,用來解決熱點數據集中在某一兩臺機器中的問題,但這樣只是分散熱點,并沒有徹底地解決熱點問題。二是增加邏輯點,將某個熱點分散成多個屬性相同、但 VID 不同的點,這些點同中心點連接時,通過 Hash 或者其他方法把邊打散,但這樣不僅增加了數據導入的邏輯復雜度,在某些情況下還會影響數據與數據之間邊本來邏輯的準確性。也想過 follower 讀這個方案,由于 raft 協議的限制,只有 leader 能處理請求,在一致性要求不高的情況下,是否可以支持 follower 處理讀請求,再結合增加分片數,使整個集群中的各個機器的負荷能得到大幅度的均衡——這個問題需要 Nebula 研發團隊提供技術支持。

最終,解決熱點問題是在攜程系統研發部團隊的支持下,通過配置參數解決了個別機器由于熱點數據產生的負載過高的問題——方案是分別開啟前綴匹配布隆過濾器、加大 blockcache。

信息圖譜在攜程酒店的應用

上表為上線前做的性能測試圖,集群配置是 6 臺 graph、5 臺 meta、10 臺 storage。在 250+ 萬點、2 億多條邊的情況下,一度查找在 1 萬左右 QPS,在 20 ms左右;同時寫入 10+ 萬數據時,在 40 ms 左右;兩度查找在 7,000 左右 QPS 時,在 32 ms 左右,同時寫入增量數據 10+ 萬時,在 50 ms 左右…總體來說,性能上還是比較符合業務需求和預期。 此外 Nebula 采用天然的分布式架構、活躍的中文社區都是促成攜程酒店最終選擇其作為信息圖譜搭建平臺基礎設施的原因之一。

以上為攜程酒店信息知識圖譜實踐分享。