Booking.com如何在毫秒內搜索數百萬個地點

譯自:How Booking.com Searches Through Millions of Locations in Milliseconds

Booking.com是一家與酒店、旅館、度假租賃等相關的在線旅行社。每個月都有數億用戶通過訪問該網站來尋找合適的度假住宿。Booking的一個主要特性是可以以地圖的方式提供查找服務,其地圖市場提供了上千萬套房產,用戶可以通過地圖查找到:

  • 提供租賃房產的位置
  • 附近感興趣的地方(博物館、沙灘、歷史建築等)
  • 租賃房產與感興趣的地方的距離
image

爲實現此需求,需要能夠快速加載地圖,其後端需要搜索世界各地數百萬個不同的點。

Igor Dotsenko 寫了一篇博客來探究他們是如何實現該目標的。

在地圖上查找

當用戶打開地圖查找房產時,會出現一個有邊界的框,此時需要在邊框內展示感興趣的點,這樣Booking才能在該框中快速查找最感興趣的點。

image

Quadtrees(四叉樹)

底層數據結構採用的是Quadtree。Quadtrees是一種樹,特別適用於2D空間數據,如地圖、圖像、視頻遊戲等。通過Quadtrees可以實現高效地插入/刪除點操作、快速範圍查找、最近鄰搜索等。

Quadtrees和其他樹結構一樣存在父子節點。對於一個Quadtrees,其內部節點總是包含4個子節點(內部節點即非葉子的節點,葉子節點沒有子節點)。父節點表示一個特定的2D區域空間,每個子節點表示該區域的象限。

image

當處理地圖數據時,父節點表示地圖上的某些區域,其4個子節點分別表示父區域的西北、東北、西南和東南四個象限。

對於Booking,每個節點表示地圖上的特定有界框,用戶可以通過在地圖上放大或平移來修改可見的有界框。節點的每個子節點將西北、東北、西南和東南邊界框保持在父節點的邊界框內。

每個節點還包含少量標記(代表感興趣的地點),每個標記會分配一個重要值,重要值大的標記被分配給樹中更高的節點(即根節點中的標記是最重要的)。

image

下面看下Booking是如何查找、構建和更新Quadtree的。

查找Quadtree

當用戶選擇一個特定的有界框時,Booking會從Quadtree 中爲該有界框查找最重要的標記,因此使用了廣度優先查找(從上往下按照重要度查找到一定數目的標記)。

首先從根節點開始查找與選擇的有界框交叉的標記,如果需要更多的標記,則會繼續查找與有界框交叉的子節點,並將其添加到隊列中。使用先進先出的順序處理隊列中的節點(查找和有界框交叉的標記)。一旦查找到足夠(等於請求數目)的標記,則結束查找並將結果發送給用戶(展示在地圖上)。

構建Quadtree

本段內容來自該博客

Quadtree保存在內存中,且會時不時地通過重建來添加新的標記(或修改標記的重要程度)。

一開始只有一個表示整個世界的根節點,且爲空。爲了使用標記構建樹,需要通過遍歷所有標記來將其插入到樹中。假設每個節點最多可以包含10個標記,每次插入時:

  1. 將當前標記放到當前節點的標記集中
  2. 如果當前標記的數目<=10,則插入結束,遍歷下一個標記
  3. 如果當前標記的數目>10,則需要從該節點中找到重要值最低的標記,並將其放到子節點中(越靠近根節點的節點,其標記的重要值越高)
    • 如果該節點沒有子節點,則需要創建子節點(將節點的有界框分爲4個子有界框,即4個子節點)
    • 從子節點中查找與有界框重要值最低的標記相交的節點
    • 將此標記遞歸放入子節點(即重複第一個步驟)

結果

Booking通過創建更多的Quadtree,並讓每個Quadtree負責特定的地理區域來實現水平伸縮。對於存儲了300,000個標記的Quadtree,其p99檢索速度小於5.5毫秒。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章