讀了部分LevelDb的code,有以下幾點感觸:
1. 對資源控制的很小心:Level Db中將記憶體,檔案個數均視作資源,任何一次寫入都需要判斷當前是否有足夠的資源,比如記憶體是否超過了限定值,檔案個數是否已經太多以致持續高速寫入將會導致讀操作的IO頻繁影響效能等;任何一個指標達到了閾值則開始流控,比如每次寫入delay 1ms等。
2. 檔案compaction的啟動標準給出了一個量化指標:
// We arrange to automatically compact this file after // a certain number of seeks. Let's assume: // (1) One seek costs 10ms // (2) Writing or reading 1MB costs 10ms (100MB/s) // (3) A compaction of 1MB does 25MB of IO: // 1MB read from this level // 10-12MB read from next level (boundaries may be misaligned) // 10-12MB written to next level // This implies that 25 seeks cost the same as the compaction // of 1MB of data. I.e., one seek costs approximately the // same as the compaction of 40KB of data. We are a little // conservative and allow approximately one seek for every 16KB // of data before triggering a compaction.
作者認為一次seek大概的cost大概可以相當於compaction 16kb的資料,所以如果一個檔案大小是X的話,則seek X/16次的時候其cost已經跟將該檔案compaction一樣了,這時候就可以啟動對該檔案的compaction了。
3. 每次訪問的時候對memfile ref count ++,這個節省了記憶體拷貝的開銷,但是如果read qps很高的話,可能導致記憶體中的memtable始終無法被釋放,從而可能導致記憶體佔用過多,最後block寫,這點不是很有道理。
4. Iterator裡面多路merge使用的是簡單的數組尋找,沒有使用優先順序隊列等,也許作者覺得這個DB就不是為大規模資料訪問準備的?
5. 其merge的方法也挺有意思的,將檔案分為多個level,除開level0外,其餘level中的檔案之間沒有overlap(http://leveldb.googlecode.com/svn/trunk/doc/impl.html),我覺得這樣增加了複雜性,至於效能能好多少就不得而知了。
6. blockindex的key可能未必真正存在,比如兩個block的end key分別是i am raymond 和i see youha, 則block index中的key可以儲存成i b,因為i b > i am raymond 並且i b < i see youha, 這樣降低了blockindex的儲存空間。
7. 只要有可能總是使用變長編碼和壓縮,這個應該是google的強項了
8. block cache裡面同時儲存了檔案資訊,當檔案被移除的時候,該檔案的block也被移除,這個作用個人覺得對效能影響不大,不過如果記憶體很有限,檔案個數以勻速增長和刪除,可能是有意義的。
整體感覺,Level DB適合小規模儲存,可以當成BerkeleyDB來使用,對於移動開發平台應該挺有優勢的,對於構建大規模資料平台可能不合適。
另外感覺LEVELDB的某些實現過於精細,可能google卻是碰到了那些我們很少碰到的問題吧。