用 Golang 寫一個搜尋引擎 (0x00)--- 從零開始

吳YH堅發表於2017-01-16

很早就想寫一系列的這樣的文章了,之前在一個電商公司做搜尋,對搜尋引擎有一些認識,來到一個新的創業公司以後非常高興還有機會繼續做這方面的事情,雖然領域已經變了,而且不是做搜尋了,但是技術還是那些技術,並且有機會接觸到了Go語言,對於一個將近10年C/C++的程式設計師來說,Go的一些特質讓我覺得非常舒服,可參見我之前的這篇文章。

從公司專案衍生出了一個自己的搜尋引擎專案,然後有了這篇文章。

先聊聊目標吧,我希望實現一個這樣的搜尋引擎

  • 使用Go語言實現,方便部署,最好就用一個二進位制檔案搞定一些,不需要安裝任何依賴。
  • 類似一個電商的搜尋引擎,支援多欄位的檢索,不僅僅是文字的全文索引,還需要包括過濾功能(比如價格區間過濾),彙總功能(比如結果集中品牌數量彙總),基本的統計功能。
  • 索引器和搜尋器在一起,主要是為了簡潔,不用啟多個例項。
  • 支援建立多個索引,並且多個索引如果有主鍵關聯,可以進行多索引的聯查(速度就只能呵呵了)。
  • 對於1000萬的文件,單個詞的平均查詢時間小於10ms。
  • 對於一臺8核8G記憶體的機器,QPS達到2000。
  • 儘可能的少用機器記憶體,在2G的機器上也能進行1000萬以上的文件搜尋。
  • 有較強的擴充套件性,可以自己擴充套件策略。
  • 可以進行分散式的叢集部署,增加可搜尋的文件數量,提高系統的查詢吞吐量。
  • 支援中文分詞,但分詞不是我們的重點。
  • 支援相關性排序,但相關性排序也不是我們的重點。
  • 重要的一點,由於是對搜尋引擎的一個全面實現,儘量不用開源的程式碼,所有演算法和資料結構都自己實現,當然,也可以方便的進行開源替代。

當然,一個搜尋引擎涉及的部分實在是太多了,下面幾個部分不是我們的重點,也不會進行深入的實現

  • 沒有爬蟲部分,搜尋引擎的爬蟲又是一個另外的話題了,也可以寫一個很複雜的系統出來,所以我們這裡不涉及爬蟲的部分
  • 不涉及演算法的部分,所謂演算法部分就是排序演算法,各種相關度計算,這也是一個另外的話題了,等這一系列文章結束以後再來說說排序的演算法,目前僅僅有的是按照TF*IDF進行基本的相關性的基本排序
  • 不涉及分詞部分,分詞部分也是一個單獨的話題,直接實現了一個非常非常非常(重要事情說三遍)簡單的中文分詞器(一個函式),可以用就行了。

目前程式碼部分已經完成了一大半了,但是還沒有進行優化,並且最後一個分散式引擎還沒有完成。但是程式碼的核心部分,也就是搜尋引擎本身的技術部分已經完成了,也已經在github上託管了,所以這一系列文章出現不更新的情況也不太可能,畢竟程式碼已經基本完成了。

好了,下面我們開始吧,整個系列文章將分成以下幾個部分來進行描述

  • 一個單機的搜尋引擎的架構,包括搜尋引擎的模組組成,各個模組的功能已經他們之間的關係,這個部分會對搜尋引擎整體有個瞭解,方便後面的文章的詳細描述,這一部分可能會比較短,後面到第三部分會再詳細說。
  • 搜尋引擎的底層技術部分,這部分比較多的內容,會分開一個一個的講,包括倒排索引技術,正排索引技術,分詞演算法,MMAP技術,這些是構成一個搜尋引擎必要的底層技術,會在這一部分做介紹
  • 一步一步的實現一個單機的搜尋引擎,按照模組從最底層的倒排和正排索引實現一直到最上層的引擎部分的實現,這一部分如果涉及到了相應的資料結構和演算法也會單獨寫,比如雜湊表演算法,B+TREE演算法,BitMap演算法,有些我這個引擎中沒有實現的演算法也會一起講講,比如跳錶,字首樹,布隆過濾器等等。
  • 分散式部分【TODO:需要等我程式碼寫完了才行】,包括如何進行分散式,各個機器之間如果進行同步,索引如果進行分片

程式碼已經在git上開源了,我會本週再整理一下就公佈出來,目前就一堆程式碼實在沒辦法看。

好了,算是開了一個頭了,文章的更新頻率會在一週3到5篇左右吧,歡迎大家掃描一下下面的微信公眾號訂閱,首先會在這裡發出來:)

用 Golang 寫一個搜尋引擎 (0x00)--- 從零開始

相關文章