環信即時通訊云使用案例
背景介紹
pika在環信的即時通訊云平臺系統中使用,用來存儲消息內容和日志,目前在部分集群中數據量已經達到數TB,QPS在數十萬級別。這些數據最早存儲在mysql里面,但mysql性能有限,而且擴容不方便。我們評估了下codis,能解決我們在mysql里面面臨的性能及擴容問題,在一段時間用codis存儲這些數據。但隨著數據量級增長,TB級別的數據存儲在內存里面,成本過于昂貴。后來了解到pika數據存儲在磁盤里面,而且兼容redis協議及命令,可以掛載在codis proxy后面做server,這樣既保留codis proxy的高性能,又能解決TB級數據量的存儲成本問題。但pika還不支持codis的slot遷移,當壓力上漲時,擴容是個問題。通過研究codis及pika的實現,在pika上開發實現了codis的slot遷移。目前已在生產環境中使用,運行良好,考慮到該功能能幫助更多的人解決一些實際的問題,我們經過再三測試驗證后向官方提交了PR
線上數據
支持slot遷移版本的pika已經在環信的生產環境中使用,獲得了一些線上環境的數據:
當pika容量在500G時,全量同步一次的時間大概在7個小時左右(千M網卡)
運行slotsreload命令每秒鐘處理key的數據在萬級,所以上面針對過期數據使用支持slot遷移的方式是可行的,已經過線上環境驗證。
在進行slot遷移時,每秒鐘遷移的key數量在200~300之間,當數據量大時,遷移需要花費很長時間,但遷移期間不影響線上業務正常使用。
codis多連接版本可以提升性能2~3倍,完全釋放pika的性能
pika codis slot 功能介紹
部署方法
codis部署方式沒有改動,只是在添加codis-server(redis)的地方部署上支持codis slot遷移的pika,該版本pika部署和之前的pika部署方式一樣,只是配置文件中需要添加一樣,以打開支持遷移的開關:
# slotmigrate [yes | no]
slotmigrate : yes
使用方法
部署成功后即可進行使用,和官方的codis沒有任何不同,一個大的可以擴容的redis。當codis-server(pika)壓力過大需要擴容的使用,按照官方的遷移方法進行slot遷移即可。
帶來好處
codis-server集群可以在不停機的情況下進行水平擴容
dbsize命令可以實時獲取當前數據庫(pika)中key的數量
注意事項
slot遷移開關
出于和pika之前官方版本更好的兼容,以及用戶升級到支持遷移的pika版本操作更方便的考慮。在設計實現pika支持codis slot遷移時,設計并實現了slot遷移開關,該開關可以通過配置文件進行開關或者關閉(即上面配置文件改動的地方,yes是打開,no是關閉),也可以通過redis-cli的config set slotmigrate進行在線的打開或者關閉:
$ redis-cli -h 127.0.0.1 -p 9221 config set slotmigrate yes
$ redis-cli -h 127.0.0.1 -p 9221 config set slotmigrate no
當關閉開關時,pika不支持slot遷移,和之前版本的pika沒有區別(dbsize也不能實時獲取);當打開開關時,支持slot遷移(dbsize能實時獲取),但需要有以下幾點注意:
pika打開slot遷移開關后,磁盤容量會有10%~30%的增加,性能會有10%~15%的下降
如果是一個全新的數據庫,里面沒有數據,在配置文件中打開了遷移開關,即可進行使用和隨時進行slot遷移;如果數據庫里面已經有數據,通過暫時關機更改配置文件打開開關或者通過命令行打開開關(已立即可以進行正常使用),在進行slot遷移前要先在命令行運行slotsreload命令,
127.0.0.1:9221> slotsreload
該命令是一個在后臺運行的命令,類似bgsave模式,可以通過info命令查看slotsreload是否運行結束,在運行結束后才可以進行遷移。
如果數據庫使用的場景中,有大量過期數據,大量使用expire等設置key過期的命令,建議不要在配置文件中打開開關(那些過期的數據,在slot里面沒有進行過期刪除,會導致數據累積,后面會考慮改進這點),可以考慮在需要遷移前在命令行打開開關,然后運行slotsreload命令,在slotsreload命令運行結束后,進行遷移,遷移完成后在命令行運行slotsdel命令進行收尾工作(釋放磁盤占用),命令后面跟需要清理掉slot,如下方式
$ 127.0.0.1:9221> slotsdel 1013 990
額外開銷
如上面所說,pika支持slot遷移會使用更多一些的磁盤,性能上會有一些下降。如果對磁盤使用或者性能有很高的要求,則可以按照上面3針對過期數據的使用方式進行使用。
同名不同類型的key
pika支持同名的key有kv,hash,list,set, zset等5種類型,但如果要使用pika支持slot遷移,不要使用同名但不同類型的key,如不要:set test1 100后再lpush test1 a b c,產生同名不同類型的key。在支持slot遷移的pika中使用同名但不同類型的key,遷移的時候會丟失那些同名的key。
codis多連接
codis 2.0及之前版本proxy和后端server是使用的單連接,當后端server是redis時,這個性能還是很不錯的,但當后面是pika、ssdb等磁盤數據庫時,單連接嚴重限制了后端server的性能,需要讓codis支持多連接,針對多連接這個問題的討論見:https://github.com/CodisLabs/codis/pull/1007
該討論提供了兩種解決方法:
如果是codis 2.0版本可以使用https://github.com/left2right/codis ,編譯后在proxy的配置文件中作如下增加;
# Proxy connections number model with backend server: server/slot, server means only one connection between proxy and backend server,
# slot means every slot has one connection between proxy and backend server, default is server
backend_connection_model=server
如果是codis 3.1版本,可以使用官方版本,并打開多連接,該版本多連接的實現見:https://github.com/CodisLabs/codis/commit/7f72696051ca0992ac3df44c3a95a41727e960f7
總結
pika支持codis slot遷移版本帶來了一些好處,如動態水平擴容,dbsize實時獲取,也帶來了一些開銷,如磁盤和性能。但它提供了一個開關,一個供你在這之間可以進行權衡的開關;它同時為pika的水平擴展提供了一個選擇,一個當你的數據量快速增長帶來問題時無痛解決問題的選擇。
關于Pika
Pika是360 DBA和基礎架構組聯合開發的類redis存儲系統, 使用Redis協議,兼容redis絕大多數命令(String,Hash,List,ZSet,Set),用戶不需要修改任何代碼, 就可以將服務遷移至pika。pika主要是使用持久化存儲來解決redis在內存占用超過50G,80G時遇到的如啟動恢復時間長,主從同步代價大,硬件成本貴等問題,并且在對外用法上盡可能做到與redis一致,用戶基本上對后端是redis或pika無感知。