天天看點

釋出一個參考ssdb,用go實作的類似redis的高性能nosql:ledisdb

是一個參考ssdb,采用go實作,底層基于leveldb,類似redis的高性能nosql資料庫,提供了kv,list,hash以及zset資料結構的支援。

我們現在的應用極大的依賴redis,但随着我們使用者量越來越大,redis的記憶體越來越不夠用,并且replication可能還會導緻逾時問題。雖然後續我們可以通過添加多台機器來解決,但是在現有機器配置下面,我們仍希望單台機器承載更多的使用者。另外,因為業務的特性,我們其實并不需要将所有的資料放到記憶體,隻需要存放目前活躍使用者。

經過我們的調研,發現ssdb已經很好的幫我們解決了這個問題,它提供了跟redis一緻的接口(當然有些地方還是稍微不同),但是底層采用leveldb進行存儲。根據其官網的描述,性能已經接近甚至超越了redis。

本着的精神,我決定用go實作一個類似的db,取名為ledisdb,也就是level-redis-db,為啥不用現成的ssdb,我覺得有如下幾個原因:

go語言開發的快速,這點毋庸置疑,雖然性能上面鐵定離c++的代碼有差距,但是我能夠快速的進行原型搭建并實驗。實際上,我在很短的時間裡面就開發出了ledisdb,讓我後續繼續開發有了信心。

leveldb的研究,我一直很想将leveldb應用到我們的項目中,作為本機熱點資料的首選資料存儲方式,通過ledisdb,讓我對leveldb的使用有了很多經驗。

redis的熟悉,雖然我用了很久的redis,但是很多redis的指令仍然需要去查手冊,通過實作ledisdb,我更加熟悉了redis的指令,同時,因為要了解這個指令redis如何實作,對redis内部又重新來了一次剖析。

在準備開發ledisdb的時候,我就在思索一個問題,我需不需要開發另一個redis?其實這是一個很明确的問題,我不需要另一個redis。ledisdb雖然參考了redis,但為了實作簡單,有時候我做了很多減法或者變更,譬如對于zset這種資料結構,我就隻支援int64類型的score,而redis的score是double類型的,具體原因後續講解zset的時候詳細說明。

是以,我們可以認為,ledisdb是一個基于redis通信協定,提供了多種進階資料結構的nosql資料庫,它并不是另一個redis。

因為ledisdb是用go寫的,是以首先需要安裝go以及配置goroot,gopath。

具體的安裝說明,可以檢視代碼目錄下面的readme。

使用ledisdb很簡單,隻需要運作:

ledisdb的配置檔案采用json格式,為啥選用json,我在裡面有過說明。

我們可以使用任何redis用戶端連接配接ledisdb,譬如redis-cli,如下:

因為leveldb是c++寫的,是以在go裡面需要使用,cgo是一種很好的方式。這裡,我直接使用了這個庫,并在上面進行了封裝,詳見。雖然有一個go-leveldb,無奈仍不能用。

cgo的性能開銷還是有的,這點在我做benchmark的時候就明顯感覺出來,不過後續優化的空間很大,譬如将多個leveldb的調用邏輯該用c重寫,這樣隻需要一次cgo就可以了。不過這個後續在考慮。

leveldb的一些參數在建構編譯的時候是需要調整的,這點我沒啥經驗,隻能google和參考ssdb。譬如下面這幾個:

相關參數的調優,隻能等我後續深入研究leveldb了在好好考慮。

任何一個服務端服務沒有性能測試報告那就是耍流氓,我現在隻是簡單的用了redis_benchmark進行測試,測試環境為一台快兩年的老爺mac air機器。

測試語句:

redis-benchmark預設沒有hash以及zset的測試,後續我在自己加入。

leveldb配置:

可以看到,ledisdb的性能趕redis以及ssdb還是有差距的,但也不至于不可用,有些差别并不大。至于為啥lrange比ssdb高,我比較困惑。

後續的測試報告,我會不斷在benchmark檔案裡面更新。

還是一個非常新的項目,比起ssdb已經在生産環境中用了很久,還有很多路要走,還有一些重要的功能需要實作,譬如replication等。

歡迎有興趣的童鞋一起參與進來,在漫漫程式開發路上有一些好基友可是很幸運的。