A1: 目前只支持Linux環(huán)境,包括Centos,Ubuntu; 不支持Windowns, Mac
A2: 參考編譯安裝wiki
A3: 一些舊版本的pika對Ubuntu環(huán)境兼容不好,某些情況下會(huì)出現(xiàn);可以先修改代碼,用std::isnan和std::isinf替代isnan,isinf, 并包含頭文件cmath。 我們會(huì)在新版兼容這個(gè)。
#include <cmath>
A1: pika有一些比較耗時(shí)的任務(wù),如刪binlog,掃描key,備份,同步數(shù)據(jù)文件等等,為了不影響正常的用戶請求,這些任務(wù)都是放到后臺(tái)執(zhí)行的,并且將能并行的都放到不同線程里來最大程度上提升后臺(tái)任務(wù)的執(zhí)行速度;你說的變成框架是pink嗎?pink是支持定時(shí)器的,每一個(gè)workerthread只要用戶定義了cronhandle和頻率,就會(huì)定時(shí)執(zhí)行要執(zhí)行的內(nèi)容,不過這時(shí)候worker是被獨(dú)占的,響應(yīng)不了用戶請求,所以占時(shí)的任務(wù)最好還是單獨(dú)開線程去做,redis的bio也是這個(gè)原因
A2: 這主要有兩個(gè)原因,第一為了提高同步速度,sender只發(fā)不收,receiver只收不發(fā),心跳是又單獨(dú)的線程去做,如果心跳又sender來做,那么為了一秒僅有一次的心跳還要去復(fù)雜化sender和receiver的邏輯;第二其實(shí)前期嘗試過合并在一起來進(jìn)行連接級(jí)別的存活檢測,當(dāng)寫入壓力過大的時(shí)候會(huì)心跳包的收發(fā)會(huì)延后,導(dǎo)致存活檢測被影響,slave誤判master超時(shí)而進(jìn)行不必要的重連
A3: 的確是一個(gè)header,不過不是為了標(biāo)記它是hash,因?yàn)閚emo底下已經(jīng)將string,hash,list,zset,set這五個(gè)數(shù)據(jù)結(jié)構(gòu)分成的5個(gè)庫,互不影響,之所以有header是因?yàn)橐粋€(gè)hash有一個(gè)meta key和一堆field key,meta key對應(yīng)的value記錄的是這個(gè)hash的基礎(chǔ)信息,如hash的size等等,這個(gè)header也是區(qū)分meta key和field key用的
A4: list的實(shí)現(xiàn)是完全基于kv實(shí)現(xiàn)的list,通過seq來實(shí)現(xiàn)list類似prev和next指針,cur_seq是在meta信息里的,也就是當(dāng)前已經(jīng)用到那個(gè)seq了,新來的節(jié)點(diǎn)從這個(gè)seq開始遞增接著用
A5: 存的是redis的命令
A6: 是的,pika前期為了更快的實(shí)現(xiàn)全同步的功能,此處是直接調(diào)用rsync命令來完成數(shù)據(jù)文件的收發(fā),也是由它來進(jìn)行文件的續(xù)傳校驗(yàn)等
A7: rocksdb提夠?qū)Ξ?dāng)前db快照備份的功能,我們基于此,在dump時(shí)先對pika阻住用戶的寫,然后記錄當(dāng)前的binlog偏移量并且調(diào)用rocksdb的接口來拿到當(dāng)前db的元信息,這個(gè)時(shí)候就可以放開用戶寫,然后基于這個(gè)元信息來進(jìn)行快照數(shù)據(jù)的后臺(tái)拷貝,阻寫的時(shí)間很短
A8: master是先寫db再寫binlog,之前slave只用一個(gè)worker來同步會(huì)在master寫入壓力很大的情況下由于slave一個(gè)worker寫入太慢而造成同步差距過大,后來我們調(diào)整結(jié)構(gòu),讓slave通過多個(gè)worker來寫提高寫入速度,不過這時(shí)候有一個(gè)問題,為了保證主從binlog順序一致,寫binlog的操作還是只能又一個(gè)線程來做,也就是receiver,所以slave這邊是先寫binlog在寫db,所以slave存在寫完binlog掛掉導(dǎo)致丟失數(shù)據(jù)的問題,不過redis在master寫完db后掛掉同樣會(huì)丟失數(shù)據(jù),所以redis采用全同步的辦法來解決這一問題,pika同樣,默認(rèn)使用部分同步來繼續(xù),如果業(yè)務(wù)對數(shù)據(jù)十分敏感,此處可以強(qiáng)制slave重啟后進(jìn)行全同步即可
A9: 之前主從同步的差異是由主的多個(gè)worker寫入而從只有一個(gè)worker寫入帶來的,現(xiàn)在的做法提高了從寫db的速度,不過協(xié)議解析還是有一個(gè)線程來做,還是有瓶頸,不過這樣的優(yōu)化主從同步的性能提高了3~5倍左右,如果key很少的話,優(yōu)化不明顯,因?yàn)閟lave這面是通過key的hash值來sharding到其中一個(gè)worker上的
A10: pika多數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)主要是“meta key + 普通key”來實(shí)現(xiàn)的,所以對于多數(shù)據(jù)結(jié)構(gòu)的讀寫,肯定都是對rocksdb進(jìn)行2次及以上的讀寫次數(shù),你說的版本信息我們是存在meta_key中的,和其他meta信息一起被讀出來,其實(shí)并沒有因?yàn)榘姹咎?hào)而額外增加讀寫次數(shù)
A11: 因?yàn)?Redis 所有的操作都是對于內(nèi)存的操作,因此理論上 Redis 的每次操作很短的。
A12: 目前沒有對數(shù)據(jù)進(jìn)行分片,你可以理解成和單機(jī) Redis 類似,支持 master-slave 的架構(gòu),因此單個(gè) pika 實(shí)例存儲(chǔ)的大小的限制是磁盤大小的限制。
A13: pika 支持所有的 Redis 客戶端,因?yàn)?pika 設(shè)計(jì)之初就考慮到了用戶的遷移成本,因此各種語言的客戶端都支持。pipelining 是客戶端來做的,因此我們是支持 pipelining 的。
A14: 我們開始做 pika 的時(shí)候,Redis cluster shard 還不完善,而且 Redis cluster 定位的場景和 pika 還是有區(qū)別。目前我們內(nèi)部還沒大范圍使用 Redis cluster。
A15: 我們暴露給用戶的 ip 是我們 LVS 的 ip。在 Redis 前面 LVS 是為了方便主從切換,這樣可以做到用戶完全不感知。這里 LVS 下面掛的多個(gè) Redis 實(shí)例,都是 master-slave 結(jié)構(gòu)的。
A16: 我們公司內(nèi)部有業(yè)務(wù)部門用 ssdb,目前除了游戲大部分的 ssdb 已經(jīng)遷移到 pika上來。我覺得 pika 的優(yōu)勢在于我們代碼實(shí)現(xiàn)的比較細(xì),性能會(huì)比較好。
A17: 存儲(chǔ)引擎上我們在 LevelDB,RocksDB 上面做過對比。LevelDB,RocksDB 在數(shù)據(jù)量比較小的時(shí)候性能差異不大,但是在數(shù)據(jù)量比較大的情況下,比如 200G 的時(shí)候,RocksDB 的性能會(huì)比 LevelDB 要來得好。但是 RocksDB 也有他的缺點(diǎn),就是代碼沒有 LevelDB 來的那么優(yōu)雅,我一直覺得一個(gè)好的 c++ 程序員看 LevelDB 代碼和 effective c++ 就好了。
A18: 是的。所以目前內(nèi)部的 pika 的架構(gòu)是支持一主多從、多機(jī)房自洽的方案。目前線上最多一個(gè)主 14 個(gè)從這樣的結(jié)構(gòu)。DBA 可以很容易的slaveof 給一個(gè)主掛上slave,然后進(jìn)行數(shù)據(jù)的全同步過程。
A19: 這里大家可以看到,這個(gè)測試結(jié)果是 pika work thread 開了 18 個(gè)。
在多數(shù)據(jù)結(jié)構(gòu)的接口里面 kv 的結(jié)構(gòu)的性能是最好的,而多數(shù)據(jù)結(jié)構(gòu)的接口比如 hash、zset 等等就算開了 18 個(gè)線程,性能依然不如 Redis 要來得好。因?yàn)?hash、zset 等數(shù)據(jù)結(jié)構(gòu)需要有搶占多數(shù)據(jù)結(jié)構(gòu)元數(shù)據(jù)鎖的開銷,因此性能很容易下來。但是 kv 接口基本沒有鎖的開銷。唯一的鎖開銷就是 RocksDB 為了實(shí)現(xiàn)線程安全增加的鎖,因此這個(gè)結(jié)果也是可以理解了。
A20: 其實(shí)我們在 bada 里面增加了多數(shù)據(jù)結(jié)構(gòu)的接口,并且兼容了 Redis 的協(xié)議,但是后來用戶的使用中,發(fā)現(xiàn)其實(shí)使用多數(shù)據(jù)結(jié)構(gòu)接口的用戶數(shù)據(jù)量其實(shí)不是特別大。單機(jī) 1T 的盤基本都能夠承受下來。但是還是因?yàn)?Hash 分布式切片不均衡,導(dǎo)致我們的維護(hù)成本增加,因此我們?nèi)?shí)現(xiàn)了 m-s 架構(gòu)方案。
目前 bada 的方案也是和 pika 并存的方案,我們會(huì)根據(jù)用戶具體的使用場景推薦使用的存儲(chǔ)方案。我一直覺得肯定不是一套存儲(chǔ)方案解決公司內(nèi)部的所有需求,一定是某一個(gè)方案更適用于某一種存儲(chǔ)方案。
A21: Pika 目前并沒有使用類似 Redis 的 sentinel,pika 前面是掛 LVS 來負(fù)責(zé)主從切換。目前也沒有使用 Codis 這樣的 proxy 方案。
A22: 一主 14 從的場景是用戶的寫入都是晚上定期的灌數(shù)據(jù),讀取的話從各個(gè)從庫進(jìn)行讀取。因此這個(gè)數(shù)據(jù)一致性是用戶可以接受的場景。
更多建議: