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