1. 程式人生 > >億級資料的高併發通用搜索引擎架構設計

億級資料的高併發通用搜索引擎架構設計

[文章作者:張宴 本文版本:v1.0 最後修改:2008.12.09 轉載請註明原文連結:http://blog.s135.com/post/385/]

  曾經在七月,寫過一篇文章──《基於Sphinx+MySQL的千萬級資料全文檢索(搜尋引擎)架構設計》,前公司的分類資訊搜尋基於此架構,效果明顯,甚至將很大一部分帶Where條件的MySQL SQL查詢,都改用了Sphinx+MySQL搜尋。但是,這套架構仍存在侷限:一是MySQL本身的併發能力有限,在200~300個併發連線下,查詢和更新就比較慢了;二是由於MySQL表的主鍵與Sphinx索引的ID一一對應,從而無法跨多表建立整站查詢,而且新增加類別還得修改配置檔案,比較麻煩;三是因為和MySQL整合,無法發揮出Sphinx的優勢。

  最近,我設計出了下列這套最新的搜尋引擎架構,目前已經寫出“搜尋查詢介面”和“索引更新介面”的beta版。經測試,在一臺“奔騰四 3.6GHz 雙核CPU、2GB記憶體”的普通PC機,7000萬條索引記錄的條件下,“搜尋查詢介面”平均查詢速度為0.0XX秒(查詢速度已經達到百度、谷歌、搜狗、中國雅虎等搜尋引擎的水平,詳見文章末尾的“附2”),並且能夠支撐高達5000的併發連線;而“索引更新介面”進行資料分析、入佇列、返回資訊給使用者的全過程,高達1500 Requests/Sec。

  “佇列控制器”這一部分是核心,它要控制佇列讀取,更新MySQL主表與增量表,更新搜尋引擎資料儲存層Tokyo Tyrant,準實時(1分鐘內)完成更新Sphinx增量索引,定期合併Sphinx索引。我預計在這周寫出beta版。

點選在新視窗中瀏覽此圖片

  圖示說明:
  1、搜尋查詢介面:
  ①、Web應用伺服器通過HTTP POST/GET方式,將搜尋關鍵字等條件,傳遞給搜尋引擎伺服器的search.php介面;
  ②③、search.php通過Sphinx的API(我根據最新的Sphinx 0.9.9-rc1 API,改寫了一個C語言的PHP擴充套件sphinx.so),查詢Sphinx索引服務,取得滿足查詢條件的搜尋引擎唯一ID(15位搜尋唯一ID:前5位類別ID+後10位原資料表主鍵ID)列表;
  ④⑤、search.php將這些ID號作為key,通過Memcache協議一次性從Tokyo Tyrant中mget取回ID號對應的文字資料。
  ⑥⑦、search.php將搜尋結果集,按查詢條件,進行摘要和關鍵字高亮顯示處理,以JSON格式或XML格式返回給Web應用伺服器。

  2、索引更新介面:

  ⑴、Web應用伺服器通過HTTP POST/GET方式,將要增加、刪除、更新的內容告知搜尋伺服器的update.php介面;
  ⑵、update.php將接收到的資訊處理後,寫入TT高速佇列(我基於Tokyo Tyrant做的一個佇列系統);
  注:這兩步的速度可達到1500次請求/秒以上,可應對6000萬PV的搜尋索引更新呼叫。

  3、搜尋索引與資料儲存控制:
  ㈠、“佇列控制器”守護程序從TT高速佇列中迴圈讀取資訊(每次50條,直到末尾);
  ㈡、“佇列控制器”將讀取出的資訊寫入搜尋引擎資料儲存層Tokyo Tyrant;
  ㈢、“佇列控制器”將讀取出的資訊非同步寫入MySQL主表(這張主表按500萬條記錄進行分割槽,僅作為資料永久性備份用);
  ㈣、“佇列控制器”將讀取出的資訊寫入MySQL增量表;
  ㈤、“佇列控制器”在1分鐘內,觸發Sphinx更新增量索引,Sphinx的indexer會將MySQL增量表作為資料來源,建立增量索引。Sphinx的增量索引和作為資料來源的MySQL增量表成對應關係;
  ㈥、“佇列控制器”每間隔3小時,短暫停止從TT高速佇列中讀取資訊,並觸發Sphinx將增量索引合併入主索引(這個過程非常快),同時清空MySQL增量表(保證了MySQL增量表的記錄數始終只有幾千條至幾十萬條,大大加快Sphinx增量索引更新速度),然後恢復從TT高速佇列中取出資料,寫入MySQL增量表。

  本架構使用的開源軟體:

  1、Sphinx 0.9.9-rc1
  2、Tokyo Tyrant 1.1.9
  3、MySQL 5.1.30
  4、Nginx 0.7.22
  5、PHP 5.2.6

  本架構自主研發的程式:
  1、搜尋查詢介面(search.php)
  2、索引更新介面(update.php)
  3、佇列控制器
  4、Sphinx 0.9.9-rc1 API的PHP擴充套件(sphinx.so)
  5、基於Tokyo Tyrant的高速佇列系統


  附1:MySQL FullText、Lucene搜尋、Sphinx搜尋的第三方對比結果:
  1、查詢速度:
  MySQL FullText最慢,Lucene、Sphinx查詢速度不相上下,Sphinx稍佔優勢。
  點選在新視窗中瀏覽此圖片

  2、建索引速度:
  Sphinx建索引速度是最快的,比Lucene快9倍以上。因此,Sphinx非常適合做準實時搜尋引擎。

  3、詳細對比資料見以下PDF文件:  



  附2:國內各大中文搜尋引擎搜尋速度分析:
  以“APMServ張宴”為關鍵字,比較在各大中文搜尋引擎的搜尋速度:
  1、百度:
  ①、第一次搜尋
  點選在新視窗中瀏覽此圖片

  ②、第二次搜尋
  點選在新視窗中瀏覽此圖片

  分析:百度對第一次搜尋的搜尋結果做了Cache,所以第二次查詢非常快。


  2、谷歌:
  ①、第一次搜尋
  點選在新視窗中瀏覽此圖片

  ②、第二次搜尋
  點選在新視窗中瀏覽此圖片

  分析:谷歌也對第一次搜尋的搜尋結果做了Cache,但兩次查詢跟百度同比,都要慢一些。


  3、搜狗:
  ①、第一次搜尋
  點選在新視窗中瀏覽此圖片

  ②、第二次搜尋
  點選在新視窗中瀏覽此圖片

  ③、第三次搜尋
  點選在新視窗中瀏覽此圖片

  分析:搜狗疑似對第一次搜尋的搜尋結果做了短暫的Cache,第二次搜尋速度非常快,第三次搜尋的速度比第二次搜尋的速度慢。搜狗第一次搜尋的速度跟百度差不多。


  4、中國雅虎:
  ①、第一次搜尋
  點選在新視窗中瀏覽此圖片

  ②、第二次搜尋
  點選在新視窗中瀏覽此圖片

  分析:搜尋結果沒有做Cache。中國雅虎的搜尋速度跟百度第一次搜尋的速度差不多。


  5、網易有道:
  ①、第一次搜尋
  點選在新視窗中瀏覽此圖片

  ②、第二次搜尋
  點選在新視窗中瀏覽此圖片

  分析:有道對第一次搜尋的搜尋結果做了Cache。但是,跟谷歌一樣,兩次搜尋同比都要較百度、搜狗、中國雅虎慢一些。