高性能kv存儲之Redis、Redis Cluster、Pika:如何應對4000億的日訪問量?
一、背景介紹
隨著360公司業務發展,業務使用kv存儲的需求越來越大。為了應對kv存儲需求爆發式的增長和多使用場景的需求,360web平臺部致力於打造一個全方位,適用於多場景需求的kv解決方案。目前,我們線上大規模使用的kv存儲有Redis,Redis cluster以及Pika。
為什麽說是爆發式的需求增長呢?早在2015年9月份,公司Redis的日訪問量還處於800億,到了2016年第三季度日訪問量已經突破2500億,2017年第一季度日訪問量已經接近4000億。短短的一年半時間,日訪問量增長了5倍。下面給大家分別簡單介紹一下Redis,Redis Cluster以及Pika的特點和使用場景。
二、kv存儲之Redis
1、Redis介紹
Redis做為大家熟知的開源內存數據庫,在很多項目中被廣泛的使用。它支持String、Hash、List、Set、Zset、Geo、Hyperloglogs等多數據結構。同時也支持主從復制、Lua腳本、事務、數據持久化、高可用和集群化等等
2、Redis特性
1)高性能:Redis雖然是單線程的,但是它同樣擁有著超高的性能。我們線上的普通PC Server上,經過測試,每秒請求數OPS能夠達到10w左右。
2)多樣化數據結構:Redis支持String、Hash、List、Set、Zset、Geo等多數據結構。
3)持久化:RDB持久化:快照式持久化方式,將內存中的全量數據dump到磁盤。它的優勢是加載速度比AOF快,劣勢是快照式的全量備份,沒有增量數據,造成數據丟失。
AOF持久化:AOF記錄Redis執行的所有寫操作命令。恢復數據的過程相當於回放這些寫操作。使用AOF的持久化方式,優勢是有靈活的刷盤策略,保證數據的安全性。劣勢是AOF文件體積比RDB大,占用磁盤多,數據加載到內存的數據慢。
4)多重數據刪除策略:
①惰性刪除:當讀/寫一個已經過期的key時,會觸發惰性刪除策略,刪除掉這個過期key。
②定期刪除:由於惰性刪除策略無法保證冷數據被及時刪掉,所以Redis會定期主動淘汰一批已過期的key。
③主動刪除:當前已用內存超過maxmemory限定時,觸發主動清理策略,該策略由啟動參數的配置決定,可配置參數及說明如下:
- volatile-lru:從已設置過期時間的樣本中根據LRU算法刪除數據 (redis3.0之前的默認策略)
- volatile-ttl:從已設置過期時間的樣本中挑選過期時間最小的數據刪除
- volatile-random:從已設置過期時間的樣本中隨機選擇數據刪除
- allkeys-lru:從樣本中根據LRU算法刪除數據
- allkeys-random:從樣本中任意選擇刪除數據
- noenviction:禁止從內存中刪除數據 (從redis3.0 開始默認策略)
maxmemory-samples 刪除數據的抽樣樣本數,redis3.0之前默認樣本數為3,redis3.0開始默認樣本數為5,該參數設置過小會導致主動刪除策略不準確,過大會消耗多余的cpu。
5)高可用:Redis自身帶有哨兵的組件,可以監控Redis主從的運行狀態和自動的故障切換,實現Redis的高可用。
3、Redis使用場景
一般場景:OPS < 10W,數據量較小
進階場景:單點寫入可以支撐,但讀取量巨大,可以采用讀寫分離,1主多從的方案;
寫入讀取量都很大,單點寫入無法支撐,可以采用Hash分片方式。
但是,無論數讀寫分離的方式還是Hash分片的方式,在的Redis的架構中沒有引入中間件或者更加智能的驅動的情況下,都需要從代碼上去保證,這一定程度上增加了開發人員的代碼復雜度。同時隨著業務的增長,擴展性也較差。那麽如何更加理想的去解決這個問題,使用Redis Cluster會是一個更加簡潔有效的方案。
三、kv存儲之Redis Cluster
1、Redis Cluster介紹
Redis Cluster 是一個分布式、無中心節點的、高可用、可線性擴展的內存數據庫,Redis Cluster的功能是普通單機 Redis 的功能的一個子集。Redis Cluster為了保證一致性而犧牲了一部分容錯性: 系統會在保證對網絡斷線和節點失效具有有限抵抗力的前提下, 盡可能地保持數據的一致性。
2、Redis Cluster重要概念:
①hash slots——哈希槽
Redis 集群沒有使用一致性hash,而是引入了哈希槽(hash slot)的概念。Redis 集群一共有16384個hash slot,集群使用CRC16校驗後對16384取模來計算鍵key屬於哪個槽。
②cluster node——集群節點
集群中的每個主節點負責處理16384個hash slot中的一部分。每個node的hash slot數量可以靈活手工調整。
③cluster map——集群信息表
集群中的每個節點都記錄整個集群的Cluster map信息,集群信息包括每個節點的唯一id號,ip地址,port端口號,role 在集群中的角色,主節點負責的hash slot的範圍,節點狀態等。節點之間通過Gossip協議進行通信,傳播集群信息,並發現新節點向其他節點發送ping包,檢查目標節點是否正常運行。
3、Redis Cluster架構
4、Redis Cluster數據路由
①client執行命令,計算key對應的hash slots
②根據本地緩存的cluster map信息,連接負責該hash slots的數據節點獲取數據
如果slot不在當前連接的節點,返回moved錯誤,重定向客戶端到新的目的服務器上獲取數據,並更新client本地緩存的cluster map
如果slot在當前節點且key存在,則執行操作結果給客戶端
如果slot遷出中,返回ask錯誤,重定向客戶端到遷移的目的服務器上獲取數據
5、使用場景
大容量、高並發、可線性擴展
剛才僅僅是對Redis Cluster做了簡單的介紹,關於集群的創建、數據的遷移、集群的擴容和縮容、hash slots重分布、集群的reblance等日常操作,使用Redis Cluster中遇到的問題以及在改進smart driver道路上解決的問題等等,如果有同學感興趣的話,歡迎私下共同交流學習。
四、kv存儲之Pika
1、Pika是什麽
Pika 是DBA需求,基礎架構組開發的大容量、高性能、持久化、支持多數據結構的類Redis存儲系統,目前已經開源,最新版本為Pika 2.2版本。它所使用的nemo引擎本質上是對Rocksdb的改造和封裝,使其支持多數據結構的存儲,並在nemo引擎之上封裝redis接口,使其完全支持Redis協議。Pika兼容string、hash、list、zset、set等多數據結構,使用磁盤而非內存存儲數據解決了Redis由於存儲數據量巨大而導致內存不夠用的容量瓶頸。
2、Pika PK Redis
Pika PK Redis之優勢:
①大容量存儲:Pika數據容量受制於磁盤,最大使用空間等於磁盤空間的大小,而Redis數據容量受限於主機內存
②秒級啟動:Pika 在寫入的時候, 數據是落盤的,Pika 重啟不用加載所有數據到內存,不需要進行回放數據操作。而Redis啟動需要將所有數據從磁盤加載到內存,隨著容量增加,啟動時間遞增到分鐘級甚至更長時間。
③秒級備份:Pika的備份方式,是將所有數據文件做快照。Redis無論是用RDB還是AOF的方式來實現數據備份的目的,都需要將全量的數據寫入到磁盤,備份速度慢。
④秒刪數據:Pika的數據刪除是標記刪除,Pika Key的元信息上有版本信息,表示當前key的有效版本,已刪除的數據在Compact合並數據的過程中刪除。而單線程的Redis在大量刪除數據時候會影響線上業務,刪除大對象會阻塞住Redis的主線程,刪除速度慢。
⑤同步續傳:Pika寫入數據會有write2file日誌文件,只要該文件未刪除,無需全量同步數據,均可斷點續傳數據。而Redis一旦主從同步緩沖區被循環重寫,容易導致全量數據重傳。
⑥高壓縮比:Pika存儲的數據默認會被壓縮,相對於Redis,Pika有5~10倍的壓縮比。所以Redis的數據存儲到Pika,數據體積會小很多。
⑦高性價比:相對於Redis使用昂貴的內存成本,Pika使用磁盤存儲數據,性價比極高
Pika PK Redis之劣勢:
①讀寫性能較弱:Pika是持久化的,基於磁盤的kv存儲。而Redis是內存數據庫。雖然pika是多線程的,但是在大多場景下,性能還是略遜色於Redis
②多數據結構性能損耗:Pika底層使用Rocksdb存儲引擎,它並不支持多數據結構,Pika在Rocksdb的上層進行了改造和封裝,實現了對多數據結構的支持。同時在性能上,會有一些損耗。
③兼容大部分Reids接口:Pika兼容了90% Redis接口,使其易用性得到大大提升。但是目前還沒有做到完全兼容。
3、Pika整體架構
4、Pika使用場景
①業務量並沒有那麽大,使用Redis內存成本太高
②數據量很大,使用Redis單個服務器內存無法承載
③經常出現時間復雜度很高的請求讓Redis間歇性阻塞
④讀寫分離且不希望故障切主後影到從庫,能夠快速切換
5、Pika使用現狀
①內部:目前Pika已經在360內部的各個業務線廣泛使用,共計覆蓋43個主業務線和76個子業務線,近千億的日訪問量和數十T的數據規模,節約了大量昂貴的服務器內存,降低了使用成本。
②社區:在業內,據不完全統計,很多著名互聯網公司也使用了Pika,例如新浪微博、美團、58同城、迅雷、萬達電商、環信…………
6、Redis如何遷移到Pika
那麽,在適用於 Pika的業務場景下,我們如何將Redis數據遷移到Pika呢?
Pika自帶的工具集,其中aof_to_pika這個工具可以幫助我們完成很平滑的這個任務。由於該工具依賴於AOF來發送數據,所以原Redis必須要開啟AOF,並關閉AOF重寫的策略。aof_to_pika通過reader線程讀取aof文件中的內容,根據設定的單次發送長度拼裝成數據塊,將要發送的數據庫加入隊列。同時sender線程不斷的從隊列中讀取數據發送到目的Pika完成數據的重放。
除了Redis的遷移工具之外。考慮有同學可能也使用到了ssdb,那麽Pika也很貼心的提供了從ssdb遷移數據到Pika的工具ssdb_to_pika。
五、多場景的業務需求
最後,針對於業務多變的kv存儲需求,常常有兩個重點是我們最為關註的,一個是數據量,另一個是訪問量。圍繞著數據量和訪問量的大小,往往決定了我們是使用Redis、Redis Cluseter or Pika。
六、QA
Q1:Pika支持集群嗎?
A1:Pika目前主持主從結構,也支持codis。自身目前還不支持分布式的集群化,我們還在做多數據結構集群化的調研。
Q2:Pika 與Redis什麽關系?替代嗎還是補充?看著像是補充。 Pika 如果是替代Redis,那使用磁盤如何保證高性能。
A2: Pika與Redis是使用場景上互相補充的關系。目前線上的Pika機器都使用的ssd,一般場景下ops在5w以內場景都能輕松應對。
Q3:Redis持久化方式如何選取?還是不做持久化?
A3:持久化多數場景下選擇AOF方式,做不做持久化取決於業務對數據安全性的要求,畢竟純緩存的數據一旦服務器宕機或者數據庫崩潰,數據都會全部丟失。
Q4 : 張老師你好,Pika掛固態硬盤讀寫性能是否可以pk Redis?360 業務有這樣應用嗎?
A4:目前360內部使用Pika的應用,全部使用的都是SSD硬盤。
Q5 : Pika 裏邊 zset 是落地的麽,zset是怎麽實現的呢? 對scan 類的命令支持怎樣?Pika 性能如何?
A5: 是落地的,大致原理是將一條key-score-members轉換成3條rocksdb的kv來存儲。scan是都支持的,和Redis一樣。Pika的性能我們認為還不錯,能夠滿足多數場景,但是建議大家要部署在SSD上,和內存比SSD還是便宜太多的,另外非常歡迎大家用測試比較Pika與相似項目的性能!
Q6 : 老師,像類似於fastdfs也是存儲在硬盤的,請問Pika與他們在使用場景上有什麽不同呢?
A6: 就我個人知識了解,fastdfs是一個分布式文件系統,存儲小文件、圖片等,與Pika面向的場景不一樣,Pika是為了解決Redis單機內存不足而設計的一個在線數據庫,當然,只要單機磁盤容量夠,也是可以存儲二進制文件到pika的。
Q7: Pika和Aerospike相比有哪些優勢呢?Aerospike開源版本內存加持久化後,執行刪除操作,重啟後刪除的數據會重新從磁盤加載,Pika有沒有這個弊病?
A7: Pika的設計初衷其實就是為滿足業務在Redis存儲中,因為內存不足而造成業務損失,所以,我們的Pika的命令基本與Redis保持一致,並且client也是復用Redis的,這樣,業務從Redis切換到Pika,無任何復雜度,這一點,我個人看Aerospike是比不了的。另外,Pika是不會加載刪除數據。
Q8:redis 中熱鍵大鍵如何處理?發現大部分故障都源於此
A8: 熱點數據需要進行業務邏輯上的拆分或者多級緩存分擔壓力。我們線上也因為大鍵造成了一些困擾,例如:網卡帶寬被打死、del大鍵造成Redis堵塞等,從Redis本身,確實沒有太好的辦法來解決,只能從業務層面分析出現大鍵的原因,做出響應的對策,例如:對大鍵進行壓縮存儲、或者存儲大鍵到有多線程處理的pika中等等。
高性能kv存儲之Redis、Redis Cluster、Pika:如何應對4000億的日訪問量?