百度智慧雲Redis容量版設計與實踐
本文根據劉東輝老師在【第十三屆中國資料庫技術大會(DTCC2022)】線上演講內容整理而成。
Redis作為“扛流量”和“加速”的利器,在百度集團內部有著極其廣泛的應用。但由於資料全部儲存在記憶體,Redis成本高昂,為此我們研發了相容Redis協議、大容量、低成本的Redis容量版產品,在簡單KV場景下效能為Redis 70%,單GB成本相比Redis降低80%+。
本次分享會闡述百度智慧雲Redis容量版(PegaDB)的設計與實踐。內容包括:PegaDB簡介及應用場景;PegaDB核心技術及實踐經驗;百度智慧雲Redis核心團隊與開源社群的合作;PegaDB後續規劃。
百度智慧雲Redis容量版概述
百度智慧雲Redis容量版又叫PegaDB,它是一個完全相容Redis協議、大容量、低成本、高效能的分散式KV資料庫。PegaDB具備以下特點:
1,全面相容Redis,支援業務平滑遷移;
2,支援水平擴充套件,單叢集PB級儲存;
3,基於SSD構建,單GB成本相比Redis降低80%+;
4,支援毫秒級線上資料處理;
5,支援異地多活架構,提供多地域容災能力;
6,支援可調一致性、冷熱分離、JSON資料模型等企業級特性;
PegaDB典型應用場景包括: 大資料量場景,Redis儲存成本高;開源KV資料庫,在效能、功能和可用性方面無法完全滿足需求;典型冷熱分離場景,傳統Cache + DB架構,業務開發複雜度高。目前PegaDB已廣泛應用於百度鳳巢、Feed、手百、地圖、度秘等多個核心業務。
百度智慧雲Redis容量版設計與實踐
PegaDB設計與實踐丨背景
首先介紹一下研發PegaDB的背景。最早設計PegaDB主要是為了解決百度集團在使用Redis過程中遇到的成本和容量問題。要知道,Redis是記憶體儲存,開啟持久化時需要額外預留記憶體,儲存成本較高;同時,Redis單個叢集的容量是有限的,公有云產品最大支援4TB,無法支撐大資料量儲存;不僅如此,百度集團還有其它KV資料庫,在相容性、通用性、易用性也存在一定的問題。
明確了業務痛點,PegaDB的定位也就清晰了。大容量、低成本、相容Redis、通用KV儲存, 同時還要具備高效能、高可用、可擴充套件等分散式儲存系統必備的特性。
PegaDB設計與實踐丨業界方案
相容Redis協議的KV資料庫,大致有如下三類方案:
第一類方案以Pika、Kvrocks為代表,採用基於磁碟的設計,資料全部儲存在磁碟,在單機KV儲存引擎RocksDB之上實現Redis的資料型別。但這類方案目前都沒有成熟的叢集方案去解決擴充套件性問題, 同時還存在效能、不支援多活架構等問題。
第二類方案以Meitu Titan、Tedis為代表的,也是採用基於磁碟的設計,資料全部儲存在磁碟,但是在分散式KV儲存引擎TiKV之上實現Redis的資料型別。但這類方案通常對Redis相容性不太好,同時也存在效能、不支援多活架構等問題。
第三類方案以Redis On Flash為代表,資料儲存在記憶體和磁碟,在記憶體中儲存熱點資料,在磁碟中儲存冷資料, 可以調整記憶體和磁碟的配比。這類方案基於Redis二次開發, 再組合單機KV儲存引擎RocksDB去擴充套件儲存容量,但這類方案比較適合資料冷熱區分明顯的場景, 存在通用性問題, 同時也存在大Value場景效能不好等問題。
PegaDB設計與實踐丨設計選型
PegaDB在選型時面臨的主要問題有: 是二次開發還是從0開始? 如果二次開發, 基於哪個開源專案進行開發(Pika、Kvrocks、Ardb ……)?
出於研發人力、專案上線時間等因素考慮, 選擇了基於開源專案進行二次開發。考慮到程式碼簡潔性、方便二次開發、設計思路及發展規劃契合度等因素, 最終選擇了基於Kvrocks進行二次開發,並深度參與開源社群建設。
PegaDB設計與實踐丨Kvrocks介紹
Kvrocks是美圖公司開發的一款分散式KV資料庫,並於2019年正式開源。使用RocksDB作為底層儲存引擎併相容Redis協議,旨在解決Redis記憶體成本高以及容量有限的問題。
接下來分享一下Kvrocks的基本設計思路。
Kvrocks是基於RocksDB儲存引擎來封裝Redis的資料型別,Hash等複雜資料型別會被拆分為多條KV資料;同時為了提升效能,Kvrocks採用了多Worker執行緒的處理模型;多副本間資料複製,Kvrocks同Redis一樣採用了主從複製的方式, 不過增量複製是基於引擎WAL的“物理複製”;此外,Kvrocks還藉助RocksDB Compaction Filter特性實現了資料過期,並透過增加Version資訊實現了大Key秒刪。
PegaDB設計與實踐丨Kvrocks不足
針對百度的業務場景, Kvrocks存在一定的不足。擴充套件性方面,Kvrocks不支援水平擴充套件,無法支撐業務幾十TB甚至百TB級規模資料儲存;效能方面,Kvrocks在大Value、冷熱區分明顯等場景下存在效能問題, 無法滿足業務高QPS和毫秒級響應延遲的需求;可用性方面,由於Kvrocks和Redis一樣, 選擇了非同步複製模型,無法滿足較高一致性需求; Kvrocks不支援多活架構, 無法滿足業務地域級容災需求;功能方面,Kvrocks不支援Redis4.0以上版本命令、事務、Lua、多DB特性, 無法滿足使用高版本Redis業務平滑遷移的需求。
為此,結合生產環境中實際遇到的問題,PegaDB在Kvrocks基礎上做了很多改進:
PegaDB設計與實踐丨叢集方案
對於擴充套件性需求, 首先需要支援叢集。在資料分佈策略選擇上,PegaDB選擇了同Redis-Cluster一樣的思路,預分配固定數量的Slot。在叢集架構方面選擇了中心化的架構,由MetaServer統一管理叢集元資訊。
同時,PegaDB的叢集架構不強依賴代理層,支援MetaServer向PegaDB下發拓撲,完全相容Redis-Cluster SDK。
由於實際生產環境業務的資料規模和訪問量是不斷變化的,PegaDB叢集還需要具備彈性伸縮的能力。
PegaDB設計與實踐丨擴縮容設計
對於資料庫這種有狀態的服務,叢集的擴縮容,主要有兩個問題要解決:資料遷移和拓撲變更。
PegaDB叢集的資料分佈到固定數量的Slot,每個PegaDB負責一定數量的Slot,資料遷移就是將源節點中的一部分Slot搬遷到目標節點。PegaDB資料遷移採用了類似選擇性複製的思路,遷移流程分為全量資料遷移、增量資料遷移兩個階段。
全量資料遷移藉助RocksDB Snapshot 快照將需要遷移的 Slot 所包含的 Key 迭代出來,同時在 Key 編碼中增加了 SlotID,這樣同一個Slot的Key會儲存在一起,顯著提升了迭代效率。PegaDB 增量資料遷移直接使用了引擎層的 WAL 日誌,這種方式不需要經過Redis協議解析和命令處理,相比傳送原生Redis命令的方式更加高效。
此外,為了遷移時不影響正常請求,使用了獨立的遷移執行緒,並且透過支援Slot併發遷移,利用RocksDB Delete Range特性清理源端資料來提升效率。為了保證資料一致性,拓撲變更期間會有短時間禁寫,通常是毫秒級。
PegaDB設計與實踐丨主從複製最佳化
介紹PegaDB對主從複製的最佳化前,先簡單回顧下Kvrocks的主從複製實現。Kvrocks和Redis主從複製思路類似,都包括全量複製和增量複製。Kvrocks在全量複製方面基於RocksDB Checkpoint資料快照,增量複製基於引擎層WAL的“物理複製”,並且基於WAL seq_id實現了斷點續傳。
但是Kvrocks複製模型有兩個典型的問題:第一,無同源增量複製保證主從切換會帶來資料不一致;第二,非同步複製模型,主從切換可能會導致資料丟失。
PegaDB是如何針對上述兩個問題進行最佳化的呢? PegaDB引入了複製ID的概念,當例項成為主庫時會生成新的Replication ID(複製歷史的標識),每條寫入RocksDB的操作都包含一個單調遞增的Sequence ID和Replication ID,只有從庫Replication ID與主庫相同並且Sequence ID小於主庫時才可以進行重同步。由於Sequence ID和Replication ID是存在於WAL中的,因此不僅支援Failover後部分重同步,而且支援重啟後部分重同步。
針對第二個問題,PegaDB採用了半同步複製的方案,其具有更強的一致性,支援配置同步的從庫個數,並且支援超時機制。此外,PegaDB的代理層還支援配置請求粒度讀取一致性。
PegaDB設計與實踐丨效能最佳化
為了更好的滿足業務需求,PegaDB在效能方面也做了很多最佳化。本次分享主要介紹PegaDB在儲存引擎、快取、資料編碼方面所做的最佳化。
儲存引擎方面,LSM引擎存在明顯的寫放大問題,尤其在寫入量比較高的大Value場景下,經常會觸發磁碟頻寬瓶頸,導致效能顯著下降。對於這個問題,業界有WiscKey和PebbleDB兩種典型的方案, WiscKey採用了Key Value分離的思路,PebblesDB採用了弱化全域性有序約束的思路。由於PebbleDB沒有成熟的開源實現,最終我們選擇了WiscKey的思路。對於WiscKey的方案,當時有Badger、TitanDB這兩個相對成熟開源實現, TianDB基於RocksDB擴充套件了Key Value分離的功能,天然相容RocksDB豐富的特性,而且方便後續升級到高版本RocksDB。而Badger是使用GO語言重新開發的儲存引擎,Badger支援的特性相對較少,PegaDB使用了大量RocksDB的特性,選擇Badger適配成本較高。再者TianDB也不會有Badger GO語言GC時帶來的STW問題,因此最終選擇了TianDB, 並擴充套件實現了CheckPoint特性(已提交社群#207)。隨著RocksDB社群全新版本的Key-Value分離實現BlobDB(2021年釋出)越來越成熟, PegaDB也從TianDB逐步遷移到了BlobDB。
除了Key-Value分離,PegaDB針對儲存引擎還做了很多調優工作,主要有耗時抖動最佳化、讀取最佳化、寫入最佳化。
耗時抖動最佳化:利用Rate Limiter對Compaction進行限速,支援部分Compaction,升級高版本RocksDB(Compaction有顯著最佳化#9423),使用Partition index/filter;
讀取最佳化:Memtable開啟全域性Filter,Data Block開啟Hash索引,L0和L1不壓縮,自定義Prefix Extractor,支援配置多CF共享和獨享Block Cache。
寫入最佳化:Key-Value分離,開啟GC預讀,開啟enable_pipelined_write,開啟sync_file_range。
接下來介紹一下在快取方面所做的最佳化。
針對冷熱資料區分明顯場景通常採用傳統Cache(Redis)+DB(MySQL)架構,但是這種架構需要業務自己來維護Cache的DB的資料一致性,業務開發複雜度較高。
為此PegaDB支援了熱Key快取,單節點可支援百萬級熱Key訪問, 大大簡化了冷熱區分明顯場景的業務架構。
RocksDB支援Block Cache和Row Cache, 為什麼PegaDB還要再增加處理層的快取?
PegaDB的熱Key快取,相比Block Cache, 粒度更細,快取利用率高;相比Row Cache,沒有Compaction導致的快速失效的問題,快取命令中更高。
在編碼最佳化方面,Kvrocks分散編碼的方式在批次、範圍操作時會涉及多次磁碟IO效能差。PegaDB自定了字首迭代器,顯著提升了迭代效率;同時,PegaDB擴充套件了緊湊型編碼,批次、範圍操作時,一次磁碟操作可以讀到全部的資料,大大提升了效能。
PegaDB設計與實踐丨異地多活架構
百度很多業務場景對可用性有著很高的要求,需要支援地域級別容災。這就要求PegaDB支援多地域部署,同時為了降低業務訪問延遲,PegaDB多個地域的叢集還需要支援就近訪問。
為此,PegaDB設計了異地多活的架構, PegaDB並沒有採用傳統基於DTS的方案來進行多個地域間資料的同步,這主要是出於同步效能的考慮。
如下圖所示,PegaDB設計了SyncAgent同步元件來同步資料,SyncAgent和PegaDB同機部署,並且出於HA考慮SyncAgent在PegaDB主從例項上都會部署,但是隻有主庫上的SyncAgent會工作;為了避免迴圈複製,在WAL日誌中增加了ShardID資訊,ShardID全域性唯一,SyncAgent透過ShardID區分是否是本地域寫入的資料,SyncAgent只會同步本地寫入的資料,因此也就解決了迴圈複製的問題。為了支援斷點續傳, PegaDB增加了OpID資訊,OpID單調遞增,並且會及時更新到配置中心,同步中斷後基於配置中心中儲存的OpID資訊進行斷點續傳。對於異地多活架構,還需要解決多地域寫衝突的問題, PegaDB採用簡單的LWW方案(Last Write Win)。
PegaDB設計與實踐丨Json資料模型
PegaDB雖然相容Redis豐富的資料型別,但是業務實際使用過程中仍遇到了一些問題。比如業務要儲存JSON格式的資料,只能轉換成STRING/HASH資料型別來儲存,這就帶來了一些問題:1、需要業務對資料進行序列化/反序列操作,增加了開發複雜度;2、讀取、更新部分欄位,存在讀寫放大問題;3、併發更新欄位時存在資料一致性問題。
針對上述問題,PegaDB借鑑RedisJSON Module的思路,原生支援了JSON資料模型,這樣做的好處是業務無需再做模型轉換,使用STRING/HASH儲存JSON格式資料的問題自然也就沒有了。
PegaDB的JSON資料模型完全相容RedisJSON Module的協議,同時支援JSONPath語法查詢和更新文件中的元素,支援原子操作所有JSON Value型別,並且採用了緊湊型編碼儲存,天然支援熱Key快取,對於冷熱區分明顯的場景特別友好。
PegaDB設計與實踐丨ZSET&HASH命令增強
除了JSON等新增的資料型別,PegaDB結合業務需求對現有資料型別也做了很多擴充套件,比如:ZSET型別支援聚合、結果過濾操作,HASH型別支援Range操作。
開源社群協作
PegaDB從設計之初,就堅定了深度參與社群,與社群共建的思路。截止到目前PegaDB已經持續向Kvrocks社群回饋了主從複製最佳化、事務、儲存引擎最佳化、叢集等多個重要PR。並且與社群一起推進了Kvrocks成為Apache孵化專案,目前百度Redis團隊擁有2名Kvrocks PPMC成員(共4名),4個Commiter。後續會繼續和社群一起努力讓Kvrocks專案發展的越來越好。
未來規劃
未來PegaDB會繼續在以下幾個方面繼續提升,1、藉助雲基礎設施進一步提升彈效能力,釋出Serverless產品;2、借鑑Redis Module生態,支援更豐富的資料模型;3、支援聯結器,更方便整合大資料生態,簡化業務開發;4、透過核心io_uring特性、執行緒模型最佳化等方案持續最佳化效能
廣告時間:百度智慧雲Redis容量版(PegaDB)已經在百度智慧雲正式釋出,也歡迎大家使用!
|嘉賓介紹|
劉東輝
百度 資深研發工程師
劉東輝,百度智慧雲Redis核心團隊技術負責人,開源專案Kvrocks Core Team成員。近十年一直專注於分散式快取、儲存方向,先後主導過微博、百度NOSQL資料庫研發工作,並在DTCC、SACC等技術大會上做過多次技術分享,具有非常豐富的NOSQL資料庫核心研發及最佳化經驗。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28285180/viewspace-2949418/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 百度基於雲原生的推薦系統設計與實踐
- Redis設計與實現Redis
- 《redis設計與實現》Redis
- 作業幫多雲架構設計與實踐架構
- 《Redis 設計與實踐》讀書筆記系列五:字典 rehashRedis筆記
- Redis使用與實踐Redis
- Redis 設計與實現 (九)--LuaRedis
- Redis 設計與實現 4:字典Redis
- Elasticsearch 索引容量管理實踐Elasticsearch索引
- 雲音樂FeatureStore建設與實踐REST
- react 設計模式與最佳實踐React設計模式
- RocketMQ Flink Catalog 設計與實踐MQ
- Redis 設計與實現 (七)--事務Redis
- <Redis設計與實現>筆記【轉】Redis筆記
- Redis 設計與實現:資料庫Redis資料庫
- Redis 設計與實現 3:字串 SDSRedis字串
- Redis | 第7章 Redis 伺服器《Redis設計與實現》Redis伺服器
- 從智慧光網到智慧光雲城市的探索與實踐
- Redis Cluster深入與實踐(續)Redis
- Redis核心原理與實踐--事務實踐與原始碼分析Redis原始碼
- JavaScript設計模式與實踐--代理模式JavaScript設計模式
- Django RESTful API設計與實踐指南DjangoRESTAPI
- 端遊HUD設計實踐與策略
- Redis | 第12章 Sentinel 哨兵模式《Redis設計與實現》Redis模式
- 實戰分享|雲信IM SDK介面設計實踐
- Redis 設計與實現 5:壓縮列表Redis
- 帶讀 |《Redis 設計與實現》(英文名:The Design and Implementation of Redis)Redis
- JavaScript設計模式與實踐–工廠模式JavaScript設計模式
- 微前端的設計理念與實踐初探前端
- JavaScript設計模式與實踐--工廠模式JavaScript設計模式
- 服務API版本控制設計與實踐API
- Redis(設計與實現):---釋出與訂閱介紹Redis
- 新一代雲原生日誌架構 - Loggie的設計與實踐架構
- Redis設計與實現學習筆記(一)Redis筆記
- Redis 設計與實現 (六)--釋出訂閱Redis
- 《Redis設計與實現》知識點目錄Redis
- Redis | 第5章 Redis 中的持久化技術《Redis設計與實現》Redis持久化
- 雲音樂預估系統建設與實踐