大容量类Redis存储--Pika介绍
嘉賓介紹
大家好,首先自我介紹一下,我是360 web平臺-基礎(chǔ)架構(gòu)組的宋昭,負責大容量類redis存儲pika的和分布式存儲Bada的開發(fā)工作,這是我的github和博客地址,平時歡迎指正交流^^
我的github:https://github.com/KernelMaker
我的博客:http://kernelmaker.github.io
下面是pika的github,歡迎關(guān)注
https://github.com/Qihoo360/pika
Pika介紹
pika是360 DBA和基礎(chǔ)架構(gòu)組聯(lián)合開發(fā)的類redis存儲系統(tǒng), 使用Redis協(xié)議,兼容redis絕大多數(shù)命令(String,Hash,List,ZSet,Set),用戶不需要修改任何代碼, 就可以將服務遷移至pika.
pika主要是使用持久化存儲來解決redis在內(nèi)存占用超過50G,80G時遇到的如啟動恢復時間長,主從同步代價大,硬件成本貴等問題,并且在對外用法上盡可能做到與redis一致,用戶基本上對后端是redis或pika無感知
既然pika要做到兼容redis并解決redis在大容量時的各種問題,那么首先要面對的問題便是如何從redis遷移到pika,畢竟現(xiàn)在redis的使用非常廣泛,如果從redis遷移到pika很麻煩,那應該也不會有多少人用了
從redis遷移到pika需要經(jīng)過幾個步驟?
開發(fā)需要做的:
基本不用做任何事情
dba需要做的:
1.dba遷移redis數(shù)據(jù)到pika
2.dba將redis的數(shù)據(jù)實時同步到pika,確保redis與pika的數(shù)據(jù)始終一致
3.dba切換lvs后端ip,由pika替換redis
注:pika提供redis_to_pika工具,通過aof來將db和實時增量數(shù)據(jù)同步到pika
遷移過程中需要停業(yè)務/業(yè)務會受到影響嗎:
不會
注
由于pika的數(shù)據(jù)存在硬盤上,故單線程的性能肯定不如redis, 但pika使用多線程來盡可能的彌補數(shù)據(jù)讀寫性能較之redis內(nèi)存讀寫的差異, 線程數(shù)比較多的情況下, 某些數(shù)據(jù)結(jié)構(gòu)的性能會優(yōu)于redis
pika肯定不會是一個完全優(yōu)于redis的方案, 和redis相比也有弊端,只是在某些場景下面更適合. 所以目前公司內(nèi)部redis, pika 是共同存在的方案, DBA會根據(jù)業(yè)務的場景挑選合適的方案
本次分享分成6個部分
背景
為什么做pika(大容量redis遇到的問題)
pika架構(gòu)
pika的創(chuàng)新及優(yōu)化
pika的優(yōu)勢及不足
總結(jié)
背景
redis提供了豐富的多數(shù)據(jù)結(jié)構(gòu)的接口, 在redis之前, 比如memcache,都認為后端只需要存儲kv的結(jié)構(gòu)就可以, 不需要感知這個value里面的內(nèi)容, 用戶需要使用的話通過json_encode,json_decode等形式進行數(shù)據(jù)的讀取就行. 但是其實redis做了一個微創(chuàng)新, 提供了多數(shù)據(jù)結(jié)果的支持, 讓服務端寫代碼起來更加的方便了
因此redis在公司的使用率也是越來越廣泛, 用戶不知不覺把越來越多的數(shù)據(jù)存儲在redis中, 隨著用戶的使用, DBA發(fā)現(xiàn)有些redis實例的大小也是越來越大, 發(fā)現(xiàn)在redis實例內(nèi)存使用比較大的情況下, 遇到的問題也會越來越多, 因此和我們一起實現(xiàn)了大容量redis的解決方案
最近半年公司每天redis 的訪問情況
Imgur
redis 架構(gòu)方案
Imgur
為什么做pika(大容量redis遇到的問題)
恢復時間長
我們線上的redis一般同時開啟rdb和aof. 我們知道aof的作用是實時的記錄用戶的寫入操作, rdb是redis某一時刻數(shù)據(jù)的完整快照. 那么恢復的時候一般是通過rdb+aof的方式進行恢復, 根據(jù)我們線上的情況50G redis恢復時間需要差不多40~70分鐘(取決于服務器性能)
一主多從, 主從切換代價大
redis在主庫掛掉以后, 從庫升級為新的主庫. 那么切換主庫以后, 所有的從庫都需要跟新主做一次全同步, 代價非常大
緩沖區(qū)寫滿問題
為了實現(xiàn)部分同步,redis使用了repl_backlog來緩存部分同步命令,repl_backlog默認1M。 當主從之間網(wǎng)絡(luò)有故障, 同步出現(xiàn)延遲了大于1M以后, slave丟失了master的同步點,就會觸發(fā)全同步的過程. 如果多個從庫同時觸發(fā)全同步的過程, 在全同步的過程中,redis會將同步點之后的增量請求給每一個slave緩存一份,在寫入量大的情況下很容易就將主庫給拖死,當然你也可以把repl_backlog調(diào)大來緩解,比如2G,不過對全內(nèi)存的redis而言,這2G的內(nèi)存代價也不小
內(nèi)存太貴
我們一般線上使用的redis機器是64G, 96G. 我們只會使用80%的空間.
如果一個redis的實例是50G, 那么基本一臺機器只能運行一個redis實例. 因此特別的浪費資源
總結(jié): 可以看到在redis比較小的情況下, 這些問題都不是問題, 但是當redis容量上去以后. 很多操作需要的時間也就越來越長了
pika 整體架構(gòu)
Imgur
主要組成:
1. 網(wǎng)絡(luò)模塊 pink
2. 線程模型
3. 存儲引擎 nemo
4. 日志模塊 binlog
5. 主從同步模塊
pink 網(wǎng)絡(luò)模塊
* 基礎(chǔ)架構(gòu)團隊開發(fā)網(wǎng)絡(luò)編程框架, 支持pb, redis等等協(xié)議. 提供了對thread的封裝, 用戶定義不同thread的行為, 使用更加清晰
* 支持單線程模型, 多線程worker模型
* github 地址: https://github.com/baotiao/pink
線程模型
Imgur
pika使用的是多線程模型,使用多個工作線程來進行讀寫操作,線程分為11種:
PikaServer:主線程
DispatchThread:監(jiān)聽端口1個端口,接收用戶連接請求
ClientWorker:存在多個(用戶配置),每個線程里有若干個用戶客戶端的連接,負責接收處理用戶命令并返回結(jié)果,每個線程執(zhí)行寫命令后,追加到binlog中
Trysync:嘗試與master建立首次連接,并在以后出現(xiàn)故障后發(fā)起重連
ReplicaSender:存在多個(動態(tài)創(chuàng)建銷毀,本master節(jié)點掛多少個slave節(jié)點就有多少個),每個線程根據(jù)slave節(jié)點發(fā)來的同步偏移量,從binlog指定的偏移開始實時同步命令給slave節(jié)點
ReplicaReceiver:存在1個(動態(tài)創(chuàng)建銷毀,一個slave節(jié)點同時只能有一個master),將用戶指定或當前的偏移量發(fā)送給master節(jié)點并開始接收master實時發(fā)來的同步命令,在本地使用和master完全一致的偏移量來追加binlog,然后分發(fā)給多個BinlogBGWorker中的一個來執(zhí)行
BinlogBGWorker:存在多個(用戶配置),ReplicaReceiver將命令按key取hash分配給其中的一個BinlogBGWorker,它負責真正執(zhí)行命令
SlavePing:slave用來向master發(fā)送心跳進行存活檢測
HeartBeat:master用來接收所有slave發(fā)送來的心跳并回復進行存活檢測
bgsave:后臺dump線程
scan:后臺掃描keyspace線程
purge:后臺刪除binlog線程
存儲引擎 nemo
pika的存儲引擎是基于Rocksdb實現(xiàn)的. 封裝了String,Hash, List, ZSet, Set等數(shù)據(jù)結(jié)構(gòu)
我們知道redis是需要支持多數(shù)據(jù)結(jié)構(gòu)的, 而rocksdb只是一個kv的接口, 那么我們?nèi)绾螌崿F(xiàn)的呢?
比如對于Hash數(shù)據(jù)結(jié)構(gòu):
對于每一個Hash存儲,它包括hash鍵(key),hash鍵下的域名(field)和存儲的值 (value).
nemo的存儲方式是將key和field組合成為一個新的key,將這個新生成的key與所要存儲的value組成最終落盤的kv鍵值對。同時,對于每一個hash鍵,nemo還為它添加了一個存儲元信息的落盤kv,它保存的是對應hash鍵下的所有域值對的個數(shù)。
每個hash鍵、field、value到落盤kv的映射轉(zhuǎn)換
Imgur
每個hash鍵的元信息的落盤kv的存儲格式
Imgur
比如對于List 數(shù)據(jù)結(jié)構(gòu):
顧名思義,每個List結(jié)構(gòu)的底層存儲也是采用鏈表結(jié)構(gòu)來完成的。對于每個List鍵,它的每個元素都落盤為一個kv鍵值對,作為一個鏈表的一個節(jié)點,稱為元素節(jié)點。和hash一樣,每個List鍵也擁有自己的元信息。
每個元素節(jié)點對應的落盤kv存儲格式
Imgur
每個元信息的落盤kv的存儲格式
Imgur
其他的數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的方式也類似, 通過將數(shù)據(jù)結(jié)構(gòu)拆分為一個個獨立的KV, 存儲到rocksdb 里面去. 從而實現(xiàn)多數(shù)據(jù)結(jié)構(gòu)的結(jié)構(gòu)
日志模塊 binlog
pika的主從同步是使用Binlog來完成的.
binlog 本質(zhì)是順序?qū)懳募? 通過Index + offset 進行同步點檢查.
解決了同步緩沖區(qū)太小的問題
支持全同步 + 增量同步
master執(zhí)行完一條寫命令就將命令追加到Binlog中,ReplicaSender將這條命令從Binlog中讀出來發(fā)送給slave,slave的ReplicaReceiver收到該命令,執(zhí)行,并追加到自己的Binlog中.
當發(fā)生網(wǎng)絡(luò)閃斷或slave掛掉重啟時, slave僅需要將自己當前的Binlog Index + offset 發(fā)送給master,master找到后從該偏移量開始同步后續(xù)命令
為了防止讀文件中寫錯一個字節(jié)則導致整個文件不可用,所以pika采用了類似leveldb log的格式來進行存儲,具體如下:
Imgur
主從同步模塊
Imgur
上圖是一個主從同步的一個過程(即根據(jù)主節(jié)點數(shù)據(jù)庫的操作日志,將主節(jié)點數(shù)據(jù)庫的改動同步到從節(jié)點的數(shù)據(jù)庫上),從圖中可以看出,每一個從節(jié)點在主節(jié)點下都有一個唯一對應的BinlogSenderThread
主要模塊:
WorkerThread:接受和處理用戶的命令;
BinlogSenderThread:負責順序地向?qū)膹墓?jié)點發(fā)送在需要同步的命令;
BinlogReceiverModule: 負責接受主節(jié)點發(fā)送過來的同步命令
Binglog:用于順序的記錄需要同步的命令
主要的工作過程:
1.當WorkerThread接收到客戶端的命令,按照執(zhí)行順序,添加到Binlog里;
2.BinglogSenderThread判斷它所負責的從節(jié)點在主節(jié)點的Binlog里是否有需要同步的命令,若有則發(fā)送給從節(jié)點;
3.BinglogReceiverModule模塊則做以下三件事情:
a. 接收主節(jié)點的BinlogSenderThread發(fā)送過來的同步命令;
b. 把接收到的命令應用到本地的數(shù)據(jù)上;
c. 把接收到的命令添加到本地Binlog里
至此,一條命令從主節(jié)點到從節(jié)點的同步過程完成
BinLogReceiverModule的工作過程:
Imgur
上圖是BinLogReceiverModule的組成,從圖中可以看出BinlogReceiverModule由一個BinlogReceiverThread和多個BinlogBGWorker組成。
BinlogReceiverThread:負責接受由主節(jié)點傳送過來的命令,并分發(fā)給各個BinlogBGWorker,若當前的節(jié)點是只讀狀態(tài)(不能接受客戶端的同步命令),則在這個階段寫B(tài)inlog
BinlogBGWorker:負責執(zhí)行同步命令;若該節(jié)點不是只讀狀態(tài)(還能接受客戶端的同步命令),則在這個階段寫B(tài)inlog(在命令執(zhí)行之前寫)
BinlogReceiverThread接收到一個同步命令后,它會給這個命令賦予一個唯一的序列號(這個序列號是遞增的),并把它分發(fā)給一個BinlogBGWorker;而各個BinlogBGWorker則會根據(jù)各個命令的所對應的序列號的順序來執(zhí)行各個命令,這樣也就保證了命令執(zhí)行的順序和主節(jié)點執(zhí)行的順序一致了
之所以這么設(shè)計主要原因是:
配備多個BinlogBGWorker是可以提高主從同步的效率,減少主從同步的滯后延遲;
讓BinlogBGWorker在執(zhí)行執(zhí)行之前寫B(tài)inlog可以提高命令執(zhí)行的并行度;
在當前節(jié)點是非只讀狀態(tài),讓BinglogReceiverThread來寫B(tài)inlog,是為了讓Binglog里保存的命令順序和命令的執(zhí)行順序保持一致;
綜上所述,正是因為這樣的架構(gòu)及實現(xiàn),pika可以較好的解決上面說到redis在大數(shù)據(jù)量下的不足:
恢復時間長
pika的存儲引擎是nemo, nemo使用的是rocksdb, rocksdb啟動不需要加載全部數(shù)據(jù), 只需要加載recover log文件就可以啟動, 因此恢復時間非常快
一主多從, 主從切換代價大
在主從切換的時候, 新主確定以后, 從庫會用當前的偏移量嘗試與新主做一次部分同步, 如果部分同步不成功才做全同步. 這樣盡可能的減少全同步次數(shù)
緩沖區(qū)寫滿問題
pika不是用內(nèi)存buffer進行同步數(shù)據(jù)的緩存, 而是記錄在本地的binlog上, binlog的大小可配,遠遠大于內(nèi)存可以使用的上限,因此不會出現(xiàn)把緩沖區(qū)寫滿的問題,減少無用的全同步次數(shù)
內(nèi)存昂貴問題
pika的存儲引擎nemo使用的是rocksdb, rocksdb同時使用內(nèi)存和磁盤減少對內(nèi)存的依賴. 同時我們盡可能使用SSD盤來存放數(shù)據(jù), 盡可能跟上redis的性能.
pika的創(chuàng)新及優(yōu)化
多數(shù)據(jù)結(jié)構(gòu)key的快速刪除
以Hash為例,redis一個Hash key可能包含百萬或者千萬的field,對于Hash key的刪除,redis首先從db dict中刪除掉這個key,然后立刻返回,該key對應的hash空間采用惰性的方式來慢慢回收,而我們知道,pika的是將Hash結(jié)構(gòu)轉(zhuǎn)換成一個個KV來存儲的,刪除一個Hash Key就等于要刪除其對應的千萬field,此時用戶的一個del操作等價于引擎千萬次的del操作,當初做的時候我們有如下考量:
Solution 1:阻塞刪除,這也是目前其他類似Pika項目的主要解決方案,直到把Hash key對應的所有field key全部刪除才返回給用戶
優(yōu)點:易實現(xiàn)
缺點:阻塞處理,影響服務
Solution 2:刪除meta key之后立刻返回,其他的field key后臺起線程慢慢刪除
優(yōu)點:速度快
缺點:使用場景受限,如果用戶刪除某個Hash key之后又立刻插入這個key,則此時還未刪除的field key會被無當做新key的一部分,出錯
上述兩種方案皆不可行,我們最終在rocksdb上做了改動,使它支持多數(shù)據(jù)結(jié)構(gòu)版本的概念
最終解決方案:
Hash Key的元信息增加版本,表示當前key的有效版本;
操作:
Put:查詢元信息,獲得key的最新版本,后綴到val;
Get:查詢元信息,獲得key的最新版本,過濾低版本的數(shù)據(jù);
Del:key的元信息版本號+1即可;
Iterator: 迭代時,查詢key的版本,過濾舊版本數(shù)據(jù);
Compact:數(shù)據(jù)的實際刪除是在Compact過程中,根據(jù)版本信息過濾;
通過對rocksdb的修改,pika實現(xiàn)了對多數(shù)據(jù)結(jié)構(gòu)key的秒刪功能,并且將真正的刪除操作交給了compact來減少顯示調(diào)用引擎del造成的多次操作(插入del record及compact)
快照式備份
不同于Redis,Pika的數(shù)據(jù)主要存儲在磁盤中,這就使得其在做數(shù)據(jù)備份時有天然的優(yōu)勢,可以直接通過文件拷貝實現(xiàn)
流程:
打快照:阻寫,并在這個過程中或的快照內(nèi)容
異步線程拷貝文件:通過修改Rocksdb提供的BackupEngine拷貝快照中文件,這個過程中會阻止文件的刪除
Imgur
這樣的備份速度基本等同于cp的速度,降低了備份的代價
后續(xù)優(yōu)化:不過目前pika正在嘗試使用硬鏈建立checkpoint來實現(xiàn)數(shù)據(jù)的更快備份(秒級),并且減少備份數(shù)據(jù)的空間占用(從之前的2倍優(yōu)化到不到2倍),更好的支持超大容量存儲
過期支持
redis的過期是通過將需要過期的key在多存一份,記錄它的過期時間,然后每次讀取時進行比較來完成的,這樣的實現(xiàn)簡單,但基于內(nèi)存的讀寫都很快不會有性能問題,目前其他類似pika的開源項目也采用這樣的方式,將過期key在db多存一份,不過不同于redis,這些項目的db也是落盤,采用這樣簡單粗暴的方式無形中又多了一次磁盤讀,影響效率,那么pika是如何解決的呢?
pika通過給修改rocksdb Set、Get接口并且新增compact filter,給每個value增加ttl后綴,并且在Get的時候來進行過濾,將真正的過期刪除交給compact(基于ttl來Drop),在磁盤大容量的前提下,使用額外空間來減少磁盤讀取次數(shù),提高效率
空間回收
rocksdb 默認的compact 策略是在寫放大, 讀放大, 空間放大的權(quán)衡. 那么DBA同學當然希望盡可能減少空間的使用, 因此DBA希望能夠隨時觸發(fā)compact, 而又盡可能的不影響線上的使用, 而rocksdb 默認的手動compact 策略是最高優(yōu)先級的, 會阻塞線上的正常流程的合并, 因此我們修改了rocksdb compact的部分邏輯,低優(yōu)先級手動compact優(yōu)先級,使得自動compact可以打斷手動compact,來避免level 0文件數(shù)量過多而造成的rocksdb主動停寫. pika支持DBA隨時compact
方便的運維
pika較之其他類似開源項目,還有一個優(yōu)勢就是它可以方便的運維,例如
1. pika的binlog可以配置按個數(shù)或者按天來刪除,提供工具來支持不用再啟實例來進行指定節(jié)點binlog的實時備份,支持binlog恢復數(shù)據(jù)到指定某一秒(正在做)
2. 支持info命令來查看后臺任務的執(zhí)行狀態(tài)(bgsave,purgelogs,keyscan)
3. 支持monitor
4. 支持通過redis aof和monitor來遷移數(shù)據(jù)
5. 支持config set來動態(tài)修改配置項
6. 支持多用戶(admin及普通用戶)及命令黑名單,可以禁止掉不想讓普通用戶使用的命令
7. 支持不活躍客戶端的自動刪除,支持慢日志,client kill all,readonly開關(guān)
8. 支持快照式備份及手動compact
9. 等等...
pika在追求盡可能高的性能及穩(wěn)定性的同時,還注重使用者的使用體驗,一個產(chǎn)品即使擁有再給力的性能如果不可運維我想也不會有人想用,所以pika會不斷發(fā)現(xiàn)并解決使用上的問題,使得它更好用
pika的優(yōu)勢及不足
pika相對于redis,最大的不同就是pika是持久化存儲,數(shù)據(jù)存在磁盤上,而redis是內(nèi)存存儲,由此不同也給pika帶來了相對于redis的優(yōu)勢和劣勢
優(yōu)勢:
容量大:Pika沒有Redis的內(nèi)存限制, 最大使用空間等于磁盤空間的大小
加載db速度快:Pika 在寫入的時候, 數(shù)據(jù)是落盤的, 所以即使節(jié)點掛了, 不需要rdb或者aof,pika 重啟不用重新加載數(shù)據(jù)到內(nèi)存而是直接使用已經(jīng)持久化在磁盤上的數(shù)據(jù), 不需要任何數(shù)據(jù)回放操作(除去少量rocksdb自身的recover),這大大降低了重啟成本。
備份速度快:Pika備份的速度大致等同于cp的速度(拷貝數(shù)據(jù)文件后還有一個快照的恢復過程,會花費一些時間),目前已經(jīng)開發(fā)完更快更省空間的秒級備份,即將投入使用,這樣在對于百G大庫的備份是快捷的,更快的備份速度更好的解決了主從的全同步問題
劣勢:
由于Pika是基于內(nèi)存和文件來存放數(shù)據(jù), 所以性能肯定比Redis低一些, 但是我們一般使用SSD盤來存放數(shù)據(jù), 盡可能跟上Redis的性能。
總結(jié)
如果用戶的業(yè)務場景數(shù)據(jù)比較大,Redis會出現(xiàn)上面說到的那些問題,如果這些問題對用戶來說不可容忍,那么可以考慮使用pika。
我們對pika整體進行了性能測試,結(jié)果如下:
服務端配置:
處理器:24核 Intel(R) Xeon(R) CPU E5-2630 v2 @ 2.60GHz
內(nèi)存:165157944 kB
操作系統(tǒng):CentOS release 6.2 (Final)
網(wǎng)卡:Intel Corporation I350 Gigabit Network Connection
客戶端配置:
同服務端
測試結(jié)果:
pika配置18個worker,用40個客戶端;
1. 寫性能:
方法:客戶端依次執(zhí)行set、hset、lpush、zadd、sadd接口寫入數(shù)據(jù),每個數(shù)據(jù)結(jié)構(gòu)10000個key;
結(jié)果:qps 110000
2. 讀性能:
方法:客戶端一次執(zhí)行g(shù)et、hget、lindex、zscore、smembers,每個數(shù)據(jù)結(jié)構(gòu)5000000個key;
結(jié)果:qps 170000
單數(shù)據(jù)結(jié)構(gòu)性能用戶可以依據(jù)自己的需求來測試,數(shù)據(jù)結(jié)構(gòu)間的性能比較大致是:
String > Hash = Set > ZSet > List
在實際使用中,大多數(shù)場景下pika的性能大約是Redis的50%~80%,在某些特定場景下,例如range 500,pika的性能只有redis的20%,針對這些場景我們?nèi)匀辉诟倪M
在360內(nèi)部使用情況:
粗略的統(tǒng)計如下:
實例數(shù)160個
當前每天承載的總請求量超過100億
當前承載的數(shù)據(jù)總量約3TB
wiki
github 地址:
https://github.com/Qihoo360/pika
github wiki:
https://github.com/Qihoo360/pika/wiki/pika介紹
Q&A
Q1:元信息是跟key一起存儲的嗎?
A1:是的
Q2:快照的生成依賴于什么?會阻塞讀寫嗎?
A2:快照是后臺生成的,阻塞的地方只是在最開始取當前db狀態(tài)和同步點信息的時候,非常短
Q3:為什么能做到基本上不阻塞?
A3:因為pika的數(shù)據(jù)本來就是存在磁盤上的,備份就等同于文件拷貝.只要在拷貝前計算一下該拷貝那些文件,然后就可以后臺搞了
Q4:看hashset的實現(xiàn),只記錄那些信息,是怎么處理hgetall的
A4:比如hash有5個field,那么在pika存儲,除了元信息之外,真正數(shù)據(jù)是這么存的:key+field1 -> value1,key+field2-> value2等等,在hgetall的時候,只需要通過rocksdb的iterator,seek到key,然后迭代便可取出所有的field了
Q5:當存儲超過SSD空間后,怎么擴容呢?
A5: pika受制于底下引擎的限制,不支持擴容,如果連ssd都不夠用了,就只能靠掛lvm來解決了
Q6:那新的數(shù)據(jù)如何融合到db里
A6:只需要給新的實例啟動前,配置文件db路徑為備份的目錄,然后啟動新實例即可
Q7:依賴于rocksdb_backup機制?
A7:是的,目前是基于rocksdb_backup做的,不過我們最新的秒備份已經(jīng)差不多做完了,可以直接通過硬鏈接省去文件的拷貝,以達到更快的備份速度及更少的空間占用
Q8:dispatch 和 clientWorker 這種生產(chǎn)者消費者模型對性能的影響。
A8:clientworker之間是互不影響的,dispatch在把某個連接分配給其中一個worker時僅與worker有極小概率的沖突(dispatch已分發(fā)完一輪連接,又回到這個worker,并且該worker此時也在操作自己的任務隊列),這樣的模型是比較通用的做法(與MC類似),性能瓶頸不會出現(xiàn)在這里
Q9:對hash類型的讀取、修改、增加、刪除任意部分field的過程及性能。
A9:性能比string接口稍有下降,因為多了一個元信息的讀寫,過程的話無非就是先讀元信息,在讀寫真正的數(shù)據(jù)等等,說起來比較多,感興趣的話可以下來交流^^
Q10:binlog有對操作做可重入處理嗎
A10:binlog里記錄的就是用戶發(fā)來的redis命令,所以不是冪等的
Q11:存放元數(shù)據(jù)的那個key如何不成為瓶頸
A11: 這樣的設(shè)計元信息的key的確會成為瓶頸,不過對于比較熱的元數(shù)據(jù)key,頻繁更新會讓他駐留在rocksdb的memtable中,這樣可以彌補一下讀寫性能
Q12:請問講師使用的是redis cluster嗎?為何只有一個master并且50g那么大?在截圖那個qps下,會遇到什么瓶頸?
A12: 目前在公司redis cluster的應用不是很廣泛,所以大的業(yè)務很容易將redis內(nèi)存撐到50G,截圖的qps,根據(jù)上面的介紹,性能梯度是String>Hash=Set>ZSet>List,之所以可以到達10w+的qps,也是因為String,Hash,Set這樣的接口操作和redis相比差不多,在worker數(shù)多的情況下,String甚至還高于redis,所以整體上看qps還不錯,不過對于List這樣的數(shù)據(jù)結(jié)構(gòu),實現(xiàn)中就是基于kv來做的list,所以性能低于前面的數(shù)據(jù)結(jié)構(gòu)
Q13:在多線程情況下,對事務的處理是怎么實現(xiàn)的
A13:pika上層會對寫操作加行鎖,來確保對同一個key的寫db和寫binlog不被打斷
Q14:hashset每次hset都要讀取count值嗎
A14:是的,因為版本號的原因,每一次都需要讀取元信息
Q15:binlog可以理解為redis的aof文件么?存儲的都是命令日志記錄?
A15:是的,和aof差不多,存儲的都是用戶命令,不過除了做aof的功能,在主從同步中它也承擔了redis中repl_backlog的功能
總結(jié)
以上是生活随笔為你收集整理的大容量类Redis存储--Pika介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CISCO ACL配置全解
- 下一篇: IP网络设计系列之-局域网设计