1. 程式人生 > >MySQL 億級資料需求的優化思路(二),100億資料,1萬字段屬性的秒級檢索

MySQL 億級資料需求的優化思路(二),100億資料,1萬字段屬性的秒級檢索

最近在研究億級資料的時候,無意中看到了一個關於寫58同城的文章

https://blog.csdn.net/admin1973/article/details/55251499?from=timeline

其實上面講的version+ext的方式以及壓縮json的思路,對於我來講都可以看得懂,想得通,其實最感興趣的還是他們那個E-Search架構,然後開始進行實驗和研究其演算法。

上圖是從那篇文章裡扒出來的圖,是由他們58幾個牛人寫的,並維護的。

按照我的理解一步一步的進行邏輯剖析,有誤的話希望大嬸們及時評論改正。 

分析思路開始:

tid uid
time cateid ext
1 1 123 招聘 {"job":"driver","salary":8000,"location":"bj"}
2 1 345 房產 {"rent":1000,"location":"dl","acreage":120}
3 1 567 二手 {"type":"iphone","money",200}

這個是文章裡提到的資料表結構,ext存這比較多可擴充套件的屬性。然後E-Search就是要對這些屬性進行快速的查詢搜尋。

裡面提到了Searcher1 Searcher2,就是一個個用於建立索引用的表。

比如房產:

 

房產現在裡面有三個欄位,每一個欄位對應一張表或多張表,因為欄位資料到一定數量的時候,可能單臺伺服器的儲存空間不夠了,所以需要分庫分表。分表可以按照Hash演算法,然後切割成單臺伺服器可以容下的數量範圍,在超過一定冗餘範圍,就要增加一臺冗餘伺服器,繼續分庫分表。上面的例子,按照每張表儲存100萬資料的方式儲存。

裡面提到merger服務,合併層,並且強調了,增加機器就可以擴容,同時也說明了服務啟動時可以載入索引資料到記憶體,請求訪問時從記憶體中load資料,訪問速度很快。

那這個merger要做些什麼呢?應該怎麼做呢?

好了,現在分析業務需求,咱們模擬一個場景和一個查詢需求,分析一下整體是怎麼工作的。

在看了58同城網站時候,發現了幾個特點。

一、有分頁,但是沒有一共多少條的分析和統計

二、檢索條件是可以隨意的設定,有很多的條件可以進行新增

然後我們沿著我們的表設計開始進行模擬一個搜尋過程。

那麼,我們假設幾個查詢條件

價格:1700~2500

地址:大連 (dl)

面積:190平米以內

按照價格從低到高進行排序

分頁每頁10條

按照以上的查詢條件,我們分別在這六張表上進行搜尋。

租金:Table1 2000條,Table2 500條,一共2500條

地址:Table3 999993條,Table4 8條,一共 1000001條

面積:Table5 5000條

下一步,當然就要把這些條件查詢的結果進行合併,就是所謂的merger要做的事。

首先,要知道排序要用價格從低到高進行排序,我們知道查詢結果就是按照索引進行排序好的排序檔案,大小就是12345這樣從低到高進行索引的。那就從Table1開始迴圈,因為是and關係,只要資料既符合地址的條件,又符合面積的條件,就算合格一條,只要累積滿足了10條,就可以返回了。這個時候,其他的條件載入在記憶體裡,但怎麼比較比較快呢?

這時候,就涉及到Hash演算法了,比如Java有個HashMap,我們可以把其他資料全部載入到HashMap裡,然後Table1每迴圈一次要用containsKey方法,與其他的表進行確認一下是否存在,由於Hash演算法速度很快,就可以很快的湊出來前10條。

這個時候,第一頁的結果就完成了。

那麼,就要問了,第二頁,第三頁,第四頁怎麼辦?

在我們迴圈Table1的時候,會有一個迴圈的遊標位置,index,比如湊了10條,遊標游到了25才湊齊返回,那我們就把這個25一同返回,作為下一頁的起點。

由於系統不需要統計一共查詢多少結果,所以我們依次往下迭代就可以了。

前臺得到了25這個遊標,那麼,下一頁直接從Table1結果25在往後開始迴圈尋找條件符合的資料,湊成10條,並且返回index ,依次往後進行。

 

其他問題總結:

一、索引表冗餘問題

就像那個文章所說的,系統不要求一致性,所以每次有新的資料插入,在插入Ext表之後,分別給到searcher的索引表裡,進行更新索引,當某個欄位索引表空間不夠了,增加冗餘伺服器,進行切分資料以保證重建索引速度及存放空間能力。

二、merger服務冗餘問題

由於merger服務與索引表在同一伺服器上,當表控制元件需要增加的時候,merger服務也隨著增加,同時要保證這臺伺服器的記憶體能夠可以實現單表最大資料儲存計算能力。

三、EXT資料的冗餘問題

直接就按照UID的增加,如果單臺伺服器不夠,直接增加

四、100億資料匯入問題

有個100億的資料問題,要求從Oracle資料庫匯入到MySql下。要求原系統不能停,還要求最後的資料是一致的。這個思路就是,把MySql進行分庫分表規劃好後,進行導資料,並且業務系統在不停的情況下產生的新的操作,同時更新Oracle和MySql,最後就可以實現兩個庫的一致性。