mysql、sphinx及許多資料庫和搜尋引擎中的查詢是單執行緒的。比如說,在一台32個cpu核心、16個磁碟的r910伺服器上執行乙個查詢,它最多隻會用到乙個核心和乙個磁碟。沒錯,只會使用乙個。
如果查詢是cpu密集型作業,那麼會使用大約3%的整機cpu能力(以上述32核機器為例)。如果是磁碟密集型,則大約會使用6%的整機io能力(也是與上例同樣的配置,16個磁碟組成raid10或raid0)。
我再換個說法吧。如果你在一台單核單磁碟的機器上執行了某個查詢,花了10秒,那麼把同樣的查詢放到一台32核16磁碟的機器上去跑,同樣需要10秒,不會有絲毫改善。
你早就知道這一點了,對吧?那麼,我的問題是——有沒有辦法可以改善呢?
如果是sphinx,太棒了,答案是有!而且不需要花上太多的工夫。你甚至不需要修改應用和資料庫,只需要稍微改下sphinx的配置。
首先,我來說明一下我們的目標。
sphinx本身就支援分布式搜尋,在很久以前就已經朝著水平擴充套件的目標來設計。如果索引在一台機器上放不下,可以讓多台機器分別對不同的部分進行索引,設定乙個聚合節點,負責從應用接收請求,然後把請求再同時發給所有的資料節點,最後將它們返回的結果合併起來,返回給應用。在應用看起來,就好像只有一台伺服器在為它服務。
好,下面你猜怎麼著?哈,我們可以把這個功能應用到單台機器上,讓我們的查詢快上n多倍。而且,現在sphinx已經支援這種做法了,所以我們根本不用再假裝查詢哪些遠端節點。
還有另外乙個好處,配置分布式搜尋以後,索引是可以並行建的!
還是有一點需要注意,雖然這種做法可以加速絕大多數的查詢,但還是有一些例外的情況。因為,並行的查詢結果仍然需要合併起來,而這個合併過程是單執行緒的。而且,合併包括一些cpu密集的操作,如分級、排序,甚至用group by進行count,如果資料量很大,合併過程就會變成瓶頸。
要確認這一點也很簡單,只要檢視sphinx的查詢日誌,看看每個查詢匹配的記錄數有多少,我們就心裡有數了。
假設在伺服器上乙個索引配置如下 (很多細節都省略了):
01
source src1
02
06
07
index idx1
08
12
13
searchd
14
現在我們使用有3個cpu核心和磁碟的機器來做這個索引--就是這個idx1.下面是我們更改的配置檔案 :
01
source src1
02
06
07
source src1p0 : src1
08
11
12
source src1p1 : src1
13
16
17
source src1p2 : src1
18
21
22
index idx1_template
23
27
28
index idx1p0 : idx1_template
29
32
33
index idx1p1 : idx1_template
34
37
38
index idx1p2 : idx1_template
39
42
43
index idx1
44
50
51
searchd
52
做完這些後,你需要重建索引. 但是現在idx1p0到idx1p2的索引indexer命令可以同步進行.
另外,用不同的操作來分離資料不是最好的辦法, 你可以在mysql中用乙個輔助表來區分它們的範圍, 配合 sql_query_range使用或是別的什麼, 具體根據你的資料來決定.
PHP搜尋優化 sphinx 實戰
環境 win7 64 wamp 解壓sphinx安裝包後,簡歷如下結構。注意,conf目錄是我的配置檔案目錄 在conf目錄下,簡歷newdefend.conf檔案,配置內容如下 配置資料來源 source domain src 配置增量資料來源 source delta domain src do...
PHP搜尋優化 sphinx 實戰
環境 win7 64 wamp 解壓sphinx安裝包後,簡歷如下結構。注意,conf目錄是我的配置檔案目錄 在conf目錄下,簡歷newdefend.conf檔案,配置內容如下 配置資料來源 source domain src 配置增量資料來源 source delta domain src do...
PHP搜尋優化 sphinx 搭建測試
安裝。環境 win7 64位 2 解壓到d sphinx。新建資料夾data 和 log,在本地test庫中,匯入example.sql檔案。結構如下 3 配置 複製sphinx.conf.in檔案到bin目錄下。重新命名為sphinx.conf。配置內容如下。每一行代表什麼意思,目前我也說不清楚,...