Pika最佳實踐
Pika是360 熱門的c++開源專案,基於rocksdb開發的大容量類Redis儲存,力求在完全相容Redis協議、繼承Redis便捷運維設計的前提下透過持久化儲存方式解決Redis在大容量場景下主從同步代價高、恢復時間慢、單執行緒相對脆弱、記憶體成本高等問題。
我們根據360內部的Pika使用經驗及社群使用者的問題反饋,整理了本文並在這裡分享給大家
Pika 最佳實踐之一
在群裡提問主動帶上版本號能大幅度加快問題解決速度
Pika 最佳實踐之二
Pika已在2019年1月24日更新至3.0.7,但仍然有大量使用者停留在兩年前的2.2.X或一年前的2.3.X,我們建議使用3.0的最新版,如果不願意使用3.X那麼請使用2.3.6,否則你會發現你遇到的很多問題都在我們的bug修復列表中
Pika 最佳實踐之三
Pika的執行緒數量建議和cpu匯流排程數一致,如果是單機多例項的部署,每個Pika例項的執行緒數量可以酌情降低,但不建議低於cpu匯流排程數的1/2
Pika 最佳實踐之四
Pika的效能和IO效能息息相關,我們不建議在機械盤上部署耗時敏感專案的Pika,另外為了避免一些稀奇古怪的問題,主從伺服器的硬體效能應當儘量一致
Pika 最佳實踐之五
在使用Pika多資料結構(hash,list,zset,zset)的時候,儘量確保每個key中的field不要太多,如果業務型別為耗時敏感型那麼建議每個key的field數量不要超過1萬個,特大key可以考慮拆分為多個小key,這樣可以避免超大key很多潛在的效能風險,而儲存型業務(耗時不敏感)則沒有這個要求
Pika 最佳實踐之六
root-connection-num引數非常有用,意為“允許透過127.0.0.1登入Pika的連線數”,它與最大連線數配置項maxclients獨立,maxclients的用盡並不會影響root-connection-num,因此在發生異常maxclients被用盡的場景中,管理員仍然可以登入Pika所在伺服器並透過127.0.0.1來登入Pika處理問題,避免了maxclients耗盡無法登入處理的尷尬局面
Pika 最佳實踐之七
client kill命令被加強了,如果你想一次性殺掉當前Pika的所有連線,只需要執行client kill all,不用擔心,用於同步的連線不會受到影響
Pika 最佳實踐之八
適當地調整timeout引數,透過該引數Pika會主動斷開不活動時間超過timeout值的連線,避免連線數耗盡問題的發生,由於連線也需要申請記憶體,因此合理的配置timeout引數也能夠在一定程度上降低Pika的記憶體佔用
Pika 最佳實踐之九
Pika的記憶體佔用主要集中在sst檔案的cache和連線申請記憶體,而通常連線申請記憶體會比sst的cache要大很多,Pika目前已支援連線申請記憶體的動態調整、回收,因此連線佔用的總記憶體大小是可以粗略估算的,如果你的Pika記憶體佔用遠超預估或大於10g,那麼可能為你當前使用的版本存在記憶體洩漏問題,嘗試依次執行命令client kill all和tcmalloc free來對連線記憶體進行強制回收,如果效果不好請升級到最新版本
Pika 最佳實踐之十
非常不建議單機執行Pika,最簡叢集狀態應為一主一從,而主從叢集的容災模式有很多種,可以考慮使用lvs、vip漂移、配置管理中介軟體等
Pika 最佳實踐之十一
建議使用主從叢集而不是雙主模式,在實際使用中雙主模式對使用規範的要求、網路環境要求相對更高,使用不規範、網路環境不好會造成雙主模式出現問題,在出現問題後,雙主模式的資料修復比主從叢集資料修復複雜度要大
Pika 最佳實踐之十二
如果你的Pika單機執行(非主從、主主叢集),並部署在可靠的儲存上,那麼可以考慮透過關閉binlog(將write-binlog引數設定為no)來提高寫入效能,不過我們並不推薦單機執行,至少應當有一個從庫用於容災
Pika 最佳實踐之十三
Pika的資料目錄中有大量的sst檔案,這些檔案隨著Pika資料量的增加而增加,因此你需要為Pika配置一個更大的open_file_limit避免不夠用,如果你不希望Pika佔用太多的檔案描述符,可以透過適當增大單個sst的體積來降低sst的總數量,對應引數為target-file-size-base
Pika 最佳實踐之十四
不要修改log目錄中的write2file檔案和manifest,它們是同步相關的重要檔案,write2file為binlog角色,而manifest則用來確保例項重啟後的binlog續寫及例項為從庫時幫助同步中斷重連後續傳
Pika 最佳實踐之十五
Pika的全量同步是透過rsync來進行的,因此我們提供了rsync的傳輸限速引數db-sync-speed,該引數的單位是mb,我們建議在千兆環境中該引數設定不應高於75,而在萬兆環境中不應高於500,這樣可以避免Pika在全量同步的時候將所在伺服器網路卡用盡而影響到部署在伺服器上的其它服務
Pika 最佳實踐之十六
在Pika中執行key *並不會造成Pika阻塞(Pika是多執行緒的),但在存在巨量key的場景下可能會造成臨時佔用巨量記憶體(這些記憶體用於該連線存放key *的執行結果,會在key *執行完畢後釋放),因此使用keys *一定要小心謹慎
Pika 最佳實踐之十七
如果發現Pika有資料但info keyspace的顯示均為0,這是因為Pika並沒有像Redis對key的數量做實時統計並展示,Pika中key的統計需要人工觸發,執行info keyspace 1,注意執行info keyspace是不會觸發統計的,沒有帶上最後的引數1將會僅僅展示上一次的統計結果,key的統計是需要時間的,執行狀態可以透過info stats中的is_scaning_keyspace進行檢視,該項值為yes表明統計正在進行,為no時表明沒有正在進行的統計/上一次統計已結束,在統計執行完畢前info keyspace不會更新,info keyspace的資料是存放在記憶體裡的,重啟將清零
Pika 最佳實踐之十八
不要在Pika執行全量compact的時候觸發key統計(info keyspace 1)或執行keys *,否則會造成資料體積暫時膨脹直到key統計、keys *執行結束
Pika 最佳實踐之十九
對存在大量過期、多資料結構內元素操作的例項配置compact-cron可以非常好地避免無效但還未被徹底清理的資料對效能造成的影響,或升級到3.0後開啟新的key級auto_compact功能,如果你遇到了下面的情況,那麼你的例項可能存在無效資料風險:
異常的資料體積(大於估算值10%以上),可以透過執行compact命令,在compact執行完畢後觀察資料體積是否恢復正常
請求耗時突然異常增大,可以透過執行compact命令,在compact執行完畢後觀察請求耗時是否恢復正常
Pika 最佳實踐之二十
在Pika3.0中我們提供了過期key的統計(可透過info keyspace 1來觸發統計,透過info keyspace檢視統計結果),統計結果中的invaild_keys的值為“已刪除/過期但還未被物理刪除的key的數量”,Pika會在後臺逐步地對已刪除/過期的key進行物理清理,由於這是一個後臺行為,因此在存在大規模過期key的場景下這些key可能無法被及時清理,因此建議關注該值,若發現無效key數量過多可透過compact命令進行全面清理,這樣能夠將未物理清理的無效資料控制在一個較好的程度從而確保Pika的效能穩定,如果Pika中儲存的資料是過濾性過期的,例如每個key的過期時間為7天,那麼建議透過配置compact-cron引數來實現每天的定時全自動全量compact,compact會佔用一定的IO資源,因此如果磁碟IO壓力過大,建議將其配置為業務低峰期執行,例如深夜
Pika 最佳實踐之二十一
write2file的角色相當於binlog,應當根據實際寫入情況調整write2file到合適的保留週期/數量,建議write2file保留週期/數量不低於48小時,足夠的write2file能夠讓很多情況變得輕鬆,例如:大資料叢集的從庫擴容、從庫伺服器關機維修、從庫遷移等等,不會因為主庫write2file過期而被迫全量重傳
Pika 最佳實踐之二十二
在主庫寫入量過大(普通ssd,大致寫入qps大於5萬)的情況下從庫可能會發生同步延遲問題,可以調整從庫的sync-thread-num引數來提高從庫同步效能,該引數控制著從庫的同步執行緒,每個執行緒透過hash來負責對應的key的同步,因此主庫寫入操作的不同的key的數量越多該引數的效果就會越好,而如果巨量的寫入僅集中在幾個key中,那麼該引數可能無法達到預期效果
Pika 最佳實踐之二十三
Pika的備份生成為快照式,透過硬連結存放在dump目錄中以日期為字尾,備份每天只能生成一份,多次生成備份時新的備份會覆蓋之前的。在生成備份快照的時候,為了確保資料的一致性Pika會暫時阻塞寫入,阻塞時間與實際資料量相關,根據測試500g的Pika生成備份快照也僅需50ms,在寫入阻塞的過程中連線不會中斷請求不會異常,但client會感覺到“在那一瞬間請求耗時增加了一些”。由於Pika的快照是db目錄中sst檔案的硬連線,因此最初這個目錄是不會佔用磁碟空間的,而在Pika db目錄中的sst檔案發生了合併、刪除後,硬連結會因為其特性而體現真實體積從而開始佔用磁碟空間,所以請根據實際的磁碟空間調整備份保留天數,避免備份太多而造成磁碟空間用盡
Pika 最佳實踐之二十四
如果寫入量巨大且磁碟效能不足以滿足rocksdb memtable的及時刷盤需求,那麼rocksdb很可能會進入防寫模式(寫入將被全部阻塞),對於該問題我們建議更換效能更好的儲存來支撐,或者降低寫入頻率(例如將集中寫資料的2小時拉長到4小時),也可適當加大write-buffer-size的值來提高memtable的總容量從而降低整個memtable被寫滿的可能,但實際根據測試發現修改該引數並不能徹底解決該問題,因為“寫的memtable遲早要刷下去的!之前刷不動,現在也刷不動!”
Pika 最佳實踐之二十五
Pika對資料進行了壓縮,預設壓縮演算法為snappy,並允許改為zlib,因此每一次資料的存入、讀出都需要經過壓縮、解壓,這對cpu有一定的消耗,非常建議像使用Redis一樣使用Pika:在Pika中關閉壓縮,而在client中完成資料的壓縮、解壓,這樣不僅能夠降低資料體積,還能有效降低Pika的cpu壓力,如果你的儲存空間不是問題但並不想調整client,可以關閉壓縮來降低cpu壓力,代價是磁碟佔用的增加,注意關閉、開啟壓縮需要重啟例項但無需重做資料
Pika 最佳實踐之二十六
讀寫分離很重要,Pika在常見的主從叢集中由於寫入是單點的(主庫),因此寫入效能是有極限的,而讀取可以透過多個從庫來共同支撐,因此Pika叢集的讀取效能是隨著從庫數量的增加而增加的,所以對於讀取量很大的場景,建議在業務層程式碼加入讀寫分離策略同時在Pika層增加從庫數量透過多個從庫來提供讀服務,這樣能夠大幅度提高叢集穩定性並有效降低讀耗時
Pika 最佳實踐之二十七
全量compact的原理是逐步對rocksdb的每一層做資料合併、清理工作,在這個過程中會新增、刪除大量的sst檔案,因此在執行全量compact的時候可以發現資料體積先增大後減小並最終減小到一個穩定值(無效、重複資料合併、清理完畢僅剩有效資料),建議在執行compact前確保磁碟空餘空間不低於30%避免新增sst檔案時將磁碟空間耗盡,另外pika支援對指定資料結構進行compact,例如一個例項中已知hash結構的無效資料很少但hash結構資料量很大,set結構資料量很大且無效資料很多,在這個例子中hash結構的compact是沒有必要的,你可以透過compact set實現僅僅對set結構的compact
Pika 最佳實踐之二十八
備份是以硬連結db目錄中的sst的方式產生的,因此在存在備份檔案的情況下,一旦執行全量compact由於Pika db目錄中的所有sst都會被compact“清洗”一遍(逐步將所有老的sst刪除替換成新的sst),這將造成備份硬連結檔案的體積變為真實體積,極端情況下備份檔案會額外佔用一倍的空間,因此如果你的磁碟空餘空間不大,那麼在執行全量compact之前最好刪除備份
Pika 最佳實踐之二十九
Pika和Redis一樣支援慢日誌功能並可透過slowlog命令檢視,但我們知道slowlog的儲存是有上限的,這個上限取決於你的配置,如果配置過大會造成slowlog佔用太多記憶體,而Pika允許將慢日誌記錄到pika.ERROR日誌中用於追溯、分析,該功能需要將slowlog-write-errorlog設定為yes
Pika 最佳實踐之三十
Pika沒有提供Redis的命令改名(rename-command)功能,因為部分命令的改名會造成一些工具、中介軟體的工作異常(例如將config改名後哨兵會無法工作),因此Pika額外增加了userpass、userblacklist來解決這一問題。userpass對應requirepass,使用userpass登入的使用者會受到userblacklist的限制,它們無法執行配置在userblacklist中的命令,而requirepass則不受影響,可以簡單的將透過requirepass登入Pika的使用者理解為“超級使用者”,將透過userpass登入Pika的使用者理解為“普通使用者”,我們非常建議Pika運維將userpass提供給業務用於程式碼訪問並在userblacklist增加例如slaveof,config,shutdown,bgsave,dumpoff,client,keys等管理類、風險性命令來避免誤操作造成的故障
我們會隨著Pika版本的不斷更新及使用者的反饋定期更新Pika最佳實踐
HULK一線技術雜談
由360雲平臺團隊打造的技術分享公眾號,內容涉及雲端計算、資料庫、大資料、監控、泛前端、自動化測試等眾多技術領域,透過夯實的技術積累和豐富的一線實戰經驗,為你帶來最有料的技術分享
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31555491/viewspace-2636495/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- AutoMapper 最佳實踐APP
- 《.NET最佳實踐》
- Django 最佳實踐Django
- metaq最佳實踐
- springDataJpa 最佳實踐Spring
- KeyPath 最佳實踐
- JavaScript 最佳實踐JavaScript
- SnapKit 最佳實踐APK
- JDBC 最佳實踐JDBC
- Kafka最佳實踐Kafka
- Iptables 最佳實踐 !
- Serilog 最佳實踐
- Flutter 最佳實踐Flutter
- Java最佳實踐Java
- MongoDB 最佳實踐MongoDB
- Gradle最佳實踐Gradle
- 【譯】VueJS 最佳實踐VueJS
- App瘦身最佳實踐APP
- Android MVP 最佳實踐AndroidMVP
- OpenResty 最佳實踐 (1)REST
- Android SharedPreferences最佳實踐Android
- mysqldump的最佳實踐MySql
- [筆記]最佳實踐筆記
- OpenResty 最佳實踐 (2)REST
- RESTful API 最佳實踐RESTAPI
- HTTPS安全最佳實踐HTTP
- Go HttpServer 最佳實踐GoHTTPServer
- Android Emoji 最佳實踐Android
- Rocketmq原理&最佳實踐MQ
- restful api最佳實踐RESTAPI
- Dockerfile 安全最佳實踐Docker
- MongoDB最佳安全實踐MongoDB
- RocketMQ的最佳實踐MQ
- Java null最佳實踐JavaNull
- 冪等最佳實踐
- Kubernetes Deployment 最佳實踐
- flutter + getx 最佳實踐Flutter
- Code Review最佳實踐View