[DBD] 開發筆記 — (1)
2019/11/03
最近在弄一個有趣的東西,需求是這樣的:
- Multiple process
- 有讀寫需求
- 最多有一億個 record,record 內容大概是 128 bytes
希望 read/write performance 可以好一點。(尤其是 random write/read)
首先一開始 survey 兩個 DB, leveldb 和 sqlite3。leveldb 除了 read 方面性能比 sqlite3 差一點外,其他都是大勝。所以 DB 就選了 leveldb。
leveldb 的數據 random get 最差,1 億個 record 的 random get 會是 5~10ms。
想了一些方法提速:
- 減小 .ldb 大小 (write_buffer_size, max_file_size)
- sharding
除了這些之外 leveldb 有個特性,就是不允許同時多個 process 同時 open 同一個 leveldb (rocksDB 可以但是 single w open/multiple r open)
所以不得已就走到 DBD 這條路上。
自幹 DBD ? 還是套 framework ? 稍微估計一下自幹 DBD 會有幾個問題:
- schedule 問題。(依據目前 schedule 我可能會寫不完)
- maintain 問題。(日後後人 maintain 這一坨 code 好像不太好)
於是走到了 rpc 這條路上。
survey 一下 google 的 grpc 和 facebook 的 thrift 都符合我的需求。
目前項目偏好 grpc 於是就跟著前人使用 grpc。
但是測了一下 grpc 的 helloworld 範例,過 domain socket 的 一個 rpc call 的 rtt 至少需要 200 us。這樣的公設比太高,我一次存取 DB 也才 250 us。
(sharding 10 leveldb 會從 1 億變成 1千萬,random get 會變成 250 us。 因此random get 過 rpc 會是 200 us + 250 us ,也就是因為多過 rpc latency 會便一倍,從 250 us 變成至少 450 us。)
目前有點猶豫要不要繼續使用 grpc,有看到別人寫 thrift 的 performance 好 grpc 很多。另外 thrift 更加彈性,可以抽換 transport layer(私心想要抽換成 shared memory,謎之音 file open /dev/shm 啊 XD)。
總而言之,目前就先這樣吧 grpc(domain socket) + leveldb(sharding 10)。
如果有任何的 performance tunning 需求在看要不要把 grpc 換掉成 thrift。
還有相較於 thrift,grpc 無法指定內部 thread pool 的大小 (Orz),從 code 是依據 CPU core 的數目來直接決定 thread pool 大小。Thrift 似乎可以自己指定 (TThreadPoolServer)。
另外 grpc 有 streaming rpc call ,thrift 沒有。(這個 project 沒用到)