leveldb ssdb 效能 使用場景評估

2022-02-12 18:38:19 字數 3391 閱讀 3609

最近有個業務場景儲存壓力很大,寫遠遠大於讀,讀也集中在最近寫入,想想這不很適合採用leveldb儲存麼。leveldb的話好像用ssdb比較多,花了兩天時間就ssdb簡單做下測試,以下總結。

ssdb 是對leveldb儲存引擎的redis相容協議封裝,並且實現了主從同步,原始碼不多易讀。對於支援的操作,除了get/set kv儲存,由於 leveldb 是有序的,還可實現很多操作;通過scan遍歷的命令,利用有序性 list、hset也通過key+fileld/seq - val 方式儲存,ttl 會單獨儲存乙個hset 儲存過期時間,由乙個單獨執行緒定時輪詢刪除。

leveldb 參考:  

機器:兩台r720xd e5-2620 2.1g (6核12執行緒)*2/記憶體128gb/300gb機械硬碟

資料: key: key 10位順序數字 value: 50位元組

併發: 預設情況100連線併發

客戶端:  使用erlang erdis模組get/set

配置:leveldb:

cache_size: 500

block_size: 1

write_buffer_size: 64

compression: no

max_open_files: 1000

- 檔案大小:1.3gb

- 寫速度:7w/s  cpu 250%  mem:30m

- 隨機讀: 5.5w/s  cpu  100%  mem:1gb

- 併發讀寫1:10: 讀 5k/s 寫:5w/s,cpu 250%

- 檔案大小:9.6gb

- 寫速度:7w/s  cpu: 250%  mem:70m

- 隨機讀:  1.6w/s cpu:100% mem:70m

-併發讀寫:1: 10: 4k/s 讀  5w/s 寫 cpu: 250%

總結:讀太隨機的lru cache 無法有效快取任何資料,請求都要經過檔案系統讀取,效能下降;但寫保效能持不變

- 檔案大小:66gb

- 寫速度:7w/s  cpu:250% mem:80m

- 隨機讀:  1.6w/s cpu:180% mem:80m

-併發讀寫:1: 10: 4k/s 讀:5w/s 寫:280%

總結:和1.5億級別效果保持一致

leveldb預設快取meta data、和8m的block;本次測試使用了500m block_cache,從測試效果看,因為隨機讀,cache只在2k資料級別上起到作用,且帶來很高效能提公升。

1.5億、10億時,完全依賴kernel 對檔案系統的page cache,機器有128gb記憶體,leveldb 沒有使用direct io,檔案都快取,實際執行中不會有磁碟io。

那麼使用指令碼清理:     

while true;  do echo 1 > /proc/sys/vm/drop_caches;echo clean cache ok; sleep 1; done

- 隨機讀 約160/s  cpu: 5%  mem: 120m  iostat 95%util

- 1併發隨機讀,100併發寫:90/s 讀, 1500/s 寫,隨機讀取影響寫入速度

總結:隨機io在機械硬碟上是完全無解了,只能靠cache扛,相比page cache,block_cache 更有效,應該更加需求增加bock_cache。

相比增加記憶體,使用ssd硬碟成本更低。

讀取系統呼叫:

open("./var/data/006090.ldb", o_rdonly) = 27

stat("./var/data/006090.ldb", ) = 0

mmap(null, 34349641, prot_read, map_shared, 27, 0) = 0x7f0334f76000

madvise(0x7f040457e000, 737280, madv_dontneed) = 0

munmap(0x7f03dc2ab000, 34349599)        = 0

close(27)                               = 0

ssdb 是多執行緒的,但上面測試效果看有明顯多核利用率很低問題,從原始碼看可以知道:

- 1個主線程,負責網路io

- 10個讀執行緒,負責像scan複雜操作讀

- 1個寫執行緒,負責寫操作磁碟io

- 1個leveldb 的compact執行緒

也就是:乙個主線程負責網路,乙個寫執行緒負責leveldb操作;而讀 get 只主線程在工作。

- 10個執行緒處理讀:2.5/s  cpu 450%

60%消耗在sys,高併發讀檔案對核心瓶頸

- 減小至3個執行緒處理讀:3.2w/s 280%(相比10執行緒,更少的cpu消耗,更高的效能)

- 使用lrucahce 在1kw區間隨機讀  7w/s ,200%cpu

leveldb 更新前先寫日誌方式,但預設方式日誌mmap是不會做msync,也就是完全依賴作業系統刷磁碟,這樣存在機器掉電等意外故障時可能會丟失部分最新訊息。支援leveldb:writeoptions.sync可選引數,但ssdb預設false,改為需要修改**。

修改true後,奇怪效能無變化?**上看並不是每個寫都會msync,而是4kbuffer後刷一次。

那麼leveldb 在故障時可能丟時少量數量就是沒辦法的了,如需要強可靠需要注意。

測測msync速度怎麼樣呢?

簡單單執行緒c程式,每寫100位元組做一次msync,效果:

伺服器2w/s, 我的mac pro ssd 3w/s (此時ssd也沒太大優勢)

msync 每次都做的話,肯定是有較大的效能影響的,但是可以做group msync;group  msync 會增加延時,就看可接受都少了,如0.1ms,那就就可以以1w/s 脈衝式、批量sync磁碟,保證所有請求都寫入磁碟再返回。

leveldb 的寫入、修改、刪除都是支援優化的batch操作,使用multi_set命令。

1. 寫效能

測試中,寫入速度一直維持7w/s, 可滿足到多需求, leveldb 寫入可以到40w/s, 這裡受限於ssdb 執行緒模型無法利用更多的核心。需要的話通過pipline、網絡卡中斷平衡、提高網路、leveldb寫執行緒數 來提高寫入效能。

2. 讀效能

一般業務都存在資料熱點,可調整cache_size, block_size 提高快取命中率,block_size 為快取塊大小1k~4m視具體業務value而定。

如果業務熱點度不高,那只能上ssd硬碟了。

注意使用了page cache,不小心清空會讓效能急劇下降,還是盡量配置足夠大的cache_size。還有就是啟動有個預熱過程。

3. compaction

本次使用的順序key寫入,因為業務上key 都是順序的,然後一段時間從後往前順序刪除。compaction影響會很小,如果業務大量隨機key寫入、修改、刪除會增加compaction量,需要注意另外做壓力測試。

效能使用指令

vmstat 1 總的cpu利用率 mpstat p all 1 每個cpu核的利用率 top pidstat 每個程序的cpu利用率 資訊 proc stat proc pid stat 檢視網路流量 sar n dev 1 100 網絡卡流量 sar n edev 1 100 網絡卡丟包 資料 ...

提高sql查詢效能 使用instr函式替換like

在查詢時經常使用like作為關鍵字進行模糊查詢,在生產環境中由於資料量較大,使用like查詢時比較慢,嘗試了一些方法,最終發現使用oracle的instr函式可以顯著提高查詢的效率.關於資料量 selectcount 1 fromt partner role 612565 selectcount 1...

pdfcrop不能使用

最近,用到了pdfcrop,用來去除pdf中空白的邊。但是使用pdfcrop margins 0 pdf 後,給出了錯誤 error pdfcrop cannot call ghostscript 但是我已經安裝了ctex,裡面已經包含ghostscript,所以就不知道什麼錯誤。在網上針對這個問題...