儲存系統實現-構建自己的儲存系統(一)

iteye_21202發表於2013-05-16

一直在斷斷續續的看Lucene原始碼,怎麼也理不清其中千絲萬縷的聯絡,遂想自己邊寫邊理解。在寫的過程中更加理解索引的意義,以及在開發過程中如何利用索引加快檢索,如何利用跳躍表來實現快速查詢。如何利用快取來實現減少磁碟IO的開銷。

這裡先從整個流程說起,這裡簡單的模擬了一下資料儲存和查詢的過程。在寫這個的過程中基本可以深刻理解索引的真實意義。

儲存資料

1.在資料檔案中寫入資料,得到該資料的起始位置和結束位置,也就是兩個偏移量。目前我儲存這三個值每個物件也就20個位元組,即使5萬的索引資料也就1M,這樣的資料在記憶體中直接操作都沒有問題。

2.在索引檔案中生成一個主鍵,然後把資料檔案中得到的兩個偏移量儲存到索引檔案中。

查詢資料(按主鍵ID查詢)

1.在索引檔案中根據主鍵ID查詢相應的偏移量。這裡如果是從頭開始遍歷效能還是比較差的。我在檔案中如果儲存了100萬的資料,如果獲取最後一條資料需要的時間是7~10秒,這樣的效能是不可接受的。因為整個儲存是順序儲存(按ID自增),所以可能會想到二分查詢。我這裡使用了跳躍表的查詢方式。如果按照一般的步長的話讀第100萬條資料需要走100萬步,那麼如果用跳躍表的方式可以大大簡少讀取和資料的對比次數。優化後單執行緒的效能在100毫秒以內。效能還是相當不錯。後續會專門開闢一篇文章來講我的實現方式。

2.根據這個偏移量去資料檔案去查詢相應的資料。

問題

1.我這裡是直接儲存資料的偏移量來直接定位資料,這樣會有一個非常嚴重的問題,就是在資料更新的時候會破壞整個資料的偏移量,所以看似這種用儲存偏移量可以極快的加快檢索速度,但是如果有插入和更新操作中效能損失是致命的,這意味著需要更新整個儲存的偏移量。目前還在探索中,還沒有想到一個比較好的解決辦法來解決!

2.快取的使用,因為不管是讀還是寫檔案的過程中都是需要加鎖的。所以在併發的過程中會導致鎖等待,這樣效能會有比較大的損失。我這裡使用了記憶體快取快取一些熱點資料,命中率比較高的情況下效能還是有比較大的提升,由於整個記憶體比較有限,所以希望最大限度的快取索引,以達到減少IO開銷的目的。如果是隨機訪問的話效能會比較差,所以如何提高隨機訪問的效能也是我後續需要思考的問題。

總結

通過寫這個儲存,可以學習一些比較底層的知識。後續不斷完善中。

相關文章