天天看點

深入淺出jcr之十二 key-value存儲系統

      在寫文章方面,惰性心理無時無刻不折磨着我,文章的标題已經列在那裡很長時間,可是我就是不願意打開,不願意把心中所想描繪出來。類似的情況可能也折磨着很多的其他同學。雖然jackrabbit是一個小衆的架構,看的人和想看的人非常的少,但是其中确實包含了很多值得我們學習和研究的技術和實作,當然也有很多不足,需要我們去改進。是以我強迫自己繼續寫下去。

上一篇文章講到高亮和及時搜尋的問題,在文章的最後我也提出了一些問題,就是如果将高亮去掉,那麼勢必會帶來一個問題,那就是小文本檔案的存儲問題,一般有大型網絡經驗的人都知道,小文本存儲在磁盤上,讀取性能是非常低的,原因就是目前的磁盤的構造決定的。

目前市面的磁盤由磁頭和磁片組成,資料都通過磁頭寫到磁片上,而寫在磁片上又是根據磁道來劃分,如果我們的小檔案是單獨存儲的,那麼一個磁頭會将它們寫在不同的磁道上,下次在讀取的時候,磁頭就需要不停的尋道,找到它想讀取到的檔案。尋道有兩個過程,第一個是找到正确的磁道,而第二個過程是找到磁道上正确的起始位置。尤其是第一過程,尋道過程在大并發的情況下,磁頭需要不停的進行尋道的工作,這個尋道是非常的消耗時間的。

是以小檔案存儲講究的合并,即将小檔案合并成大檔案。

同樣,在jackrabbit中,由于二進制文檔資料被提取之後,是放到索引檔案的,是以帶來的一個問題是索引檔案的大小成倍增加,在索引同步的時候,代價明顯增大,這一點ahuaxuan在前文中也有較為相信的描述。而現在,我們就是要解決這個問題,提取之後的文本資料究竟應該放在什麼地方。

是單獨放在目錄裡面嗎?對目錄進行分級,一般多個大檔案,比如視訊檔案之類的都會采取這種做法。對于一個平均長度是100kb-200kb的文本資料來說,如果也采取目錄分級的方法來存放的話,那勢必會存在非常多的這種檔案,一旦又涉及到叢集,那麼對于jackrabbit來說,這一定是一場噩夢。

最好的方法是能夠将這些小檔案存儲到一個大檔案中,而且可以通過nodeid直接取到這樣的小文本。這個時候我們就自然而然的想到使用key-value資料存儲系統。比如市面上有tc,bdb,等等,但是他們都是local的,還是做不了資料的共享,無法使用到叢集的場景下,一個clustornode的資料無法和其他clustornode共享。

這個時候我們又自然而然的想到memcachedb, tt+tc, mina+bdb.通過在local的key-value存儲系統上套一個socket服務,一個local的key-value存儲系統變成了一個remote的key-value系統,任何人都可以調用它們的服務。即使是在叢集的環境下,也沒有問題了。

大的方向确定之後,就是做各種性能測試。第一個排除的是memcachedb,之前有人跟我講它的性能不是很好,我還不相信,經過自己的一輪測試下來,發現,在100kb文本的情況下,50000次save操作,耗時超過了我吃飯的時間。調整參數之後再測,稍微快一點,但是還是太慢了,有空整理一下我的測試結果。

為了確定bdb沒有這麼差的性能,我開始測試java版本的bdb在100k文本下的性能,經過多次測試,在我這塊7000轉的磁盤上,每秒鐘的寫入速度可以達到23m/s,讀取速度38m/s,每秒鐘讀取100kb文本可以到350requests/second,這證明bdb是沒有問題的。

那麼memcachedb不夠快應該是其本身的問題(當然也不排除我的參數配置不準确,即使不準确,也不應該差這麼多)。

于是,我自定義了一個簡單二進制協定,用mina+bdb,實作java版本的memcachedb,同樣的測試,結果為寫入14m/s,讀取17m/s,每秒平均請求數為150 requests/s.

顯然,這裡有很大的優化的餘地。至少網絡io上不應該成為瓶頸。而且可以大膽的預測,在真正的存儲系統中,磁盤将會是主要性能瓶頸。支援多磁盤的key-value存儲系統可以有效的提高系統的整體讀寫性能。

同樣我也測試過tc+tt,50000次100kb的save,耗時1300秒,在大文本的情況下性能也不咋滴。而且它還不支援多磁盤。更正,上面的結果是受網絡環境的限制。我的測試網絡帶寬一會4m,一會20m,暈倒,等會把測試代碼放到tc+tt server上測試

同時也希望使用過memcachedb存儲大文本的同學出來說說它的性能到底如何。