360開源的類Redis存儲系統Pika的最佳實踐

360DBA及基礎架構團隊根據360內部的Pika使用經驗及社區用戶的問題反饋,整理了以下這些Pika的最佳實踐分享給大家。

Pika最佳實踐之一

在羣裏提問主動帶上版本號能大幅度加快問題解決速度。(Pika社區QQ羣:294254078)

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功能,如果你遇到了下面的情況,那麼你的實例可能存在無效數據風險:

  1. 異常的數據體積(大於估算值10%以上),可以通過執行compact命令,在compact執行完畢後觀察數據體積是否恢復正常。
  2. 請求耗時突然異常增大,可以通過執行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等管理類、風險性命令來避免誤操作造成的故障。

本文首發於公衆號“Hulk一線技術雜談”:https://mp.weixin.qq.com/s/bRfUpWmXxrzXx4fgJytDfw

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章