日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線(xiàn)咨詢(xún)客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

KV 存儲(chǔ)

在大數(shù)據(jù)時(shí)代,數(shù)據(jù)量呈指數(shù)級(jí)增長(zhǎng),預(yù)計(jì)到2025年,全球的數(shù)據(jù)總量將達(dá)175ZB,非結(jié)構(gòu)化和半結(jié)構(gòu)化數(shù)據(jù)已占據(jù)主導(dǎo)地位。像騰訊微信、字節(jié)頭條、B站、快手、小紅書(shū)等眾多的UGC社交平臺(tái),這些平臺(tái)普遍的都存在搜索、推薦、廣告和風(fēng)控服務(wù)都以人為核心,服務(wù)強(qiáng)依賴(lài)用戶(hù)的畫(huà)像、行為和筆記。UGC數(shù)據(jù)的高效存儲(chǔ)和查詢(xún)是支持推廣搜一體化工程的基礎(chǔ)設(shè)施,而這種典型的屬性和值的鍵值對(duì)結(jié)構(gòu)正式我們今天要討論的分布式KV系統(tǒng)。

KV存儲(chǔ)系統(tǒng)對(duì)非結(jié)構(gòu)化和半結(jié)構(gòu)化數(shù)據(jù)進(jìn)行高效存儲(chǔ),提供了很好的解決方案:

 

  • KV存儲(chǔ)系統(tǒng)具有靈活的數(shù)據(jù)模型,數(shù)據(jù)表示為Key, Value對(duì)形式,為任意數(shù)據(jù)類(lèi)型,且長(zhǎng)度不定;
  •  
  • KV存儲(chǔ)的訪(fǎng)存接口非常簡(jiǎn)單,向外提供Put、Get、Scan等簡(jiǎn)單的接口進(jìn)行數(shù)據(jù)讀寫(xiě);
  •  
  • KV存儲(chǔ)還具備高可擴(kuò)展性,數(shù)據(jù)基于Key進(jìn)行劃分和索引,無(wú)需維護(hù)額外的元數(shù)據(jù)。

 

由于KV存儲(chǔ)系統(tǒng)具有上述諸多優(yōu)點(diǎn),因此被廣泛應(yīng)用在了NewSQL和NoSQL產(chǎn)品中。比如目前常見(jiàn)的KV存儲(chǔ)系統(tǒng):LevelDB、RocksDB、Cassandra、TiKV等。


 

目前主流的持久化KV存儲(chǔ)系統(tǒng)都采用LSM-tree(log-structured merge tree)架構(gòu)作為存儲(chǔ)引擎,其具有高效的寫(xiě)入效率,但同時(shí)存在嚴(yán)重的讀寫(xiě)放大問(wèn)題。


 

如圖,KV數(shù)據(jù)首先緩存在內(nèi)存并進(jìn)行排序,然后以批量追加的方式將數(shù)據(jù)寫(xiě)入磁盤(pán)上,形成磁盤(pán)上的一個(gè)SSTable文件,SSTable文件中的數(shù)據(jù)是按Key有序的,這種寫(xiě)入方式可以將大量的隨機(jī)寫(xiě)轉(zhuǎn)換為順序?qū)懀瑥亩浞掷么疟P(pán)順序?qū)懙膸拑?yōu)勢(shì),獲得高效的寫(xiě)入效率。

為兼顧讀性能,磁盤(pán)上的數(shù)據(jù)被組織成多層形式,且容量逐層遞增,并且除第0層以外,其他每層的數(shù)據(jù)是完全有序的。通過(guò)維護(hù)這樣一個(gè)多層有序的架構(gòu),LSM-tree可以獲得高效的寫(xiě)入和范圍查詢(xún)性能,并且提供高可擴(kuò)展性,當(dāng)需要擴(kuò)展存儲(chǔ)容量時(shí),可以通過(guò)簡(jiǎn)單的增加LSM-tree的層數(shù)來(lái)實(shí)現(xiàn)高效的擴(kuò)展。

然而,LSM-tree多層的數(shù)據(jù)組織結(jié)構(gòu)導(dǎo)致查詢(xún)操作需要逐層搜索,從第0層開(kāi)始,直到找到查詢(xún)的數(shù)據(jù)為止,并且寫(xiě)入期間需要執(zhí)行頻繁的Compaction操作,具體Compaction操作需要從LSM-tree中讀取相鄰兩層的數(shù)據(jù),然后執(zhí)行合并排序操作,再將合并后的有效數(shù)據(jù)寫(xiě)回磁盤(pán)。因此,當(dāng)我們將數(shù)據(jù)從第0層逐漸合并到較高層時(shí),需要將數(shù)據(jù)頻繁的讀出并且寫(xiě)回,進(jìn)而導(dǎo)致嚴(yán)重的讀寫(xiě)放大問(wèn)題,且嚴(yán)重消耗磁盤(pán)的IO帶寬。

數(shù)據(jù)分片策略:當(dāng)前流行的KV存儲(chǔ)產(chǎn)品對(duì)Key的劃分方法有兩種:

 

  • 將Key的空間劃分成多個(gè)Partition/Shard。連續(xù)的Key在同一個(gè)Partition/Shard內(nèi),或者跨兩個(gè)Partition。
  • 創(chuàng)建一定數(shù)目的Partition/Shard。將Key hash打散到不同的Partition/Shard上。

 

那如何評(píng)價(jià)一個(gè)KV產(chǎn)品是否足夠優(yōu)秀呢,筆者認(rèn)為可以從以下特性功能進(jìn)行對(duì)比評(píng)價(jià):

 

  • 數(shù)據(jù)的可靠性SLA
  • 服務(wù)穩(wěn)定性SLA
  • 讀寫(xiě)性能
  • 大規(guī)模集群的彈性原地?cái)U(kuò)縮容能力
  • 服務(wù)平滑升級(jí)的不可用時(shí)間(毛刺)
  • 支持與大數(shù)據(jù)生態(tài)互通(在線(xiàn)、離線(xiàn))
  • 跨云多活(多區(qū)多Region)
KV 引擎 - Rocksdb

 

KV系統(tǒng)對(duì)外提供的接口比較統(tǒng)一,即點(diǎn)查、范圍查詢(xún)。而當(dāng)今作為L(zhǎng)SM-Tree最穩(wěn)定、應(yīng)用最廣泛即最成熟的引擎就是Rocksdb。

RocksDB 是由 Facebook 基于 google LevelDB 開(kāi)發(fā)的一款提供鍵值存儲(chǔ)與讀寫(xiě)功能的 LSM-tree 架構(gòu)引擎。用戶(hù)寫(xiě)入的鍵值對(duì)會(huì)先寫(xiě)入磁盤(pán)上的 WAL (Write Ahead Log),然后再寫(xiě)入內(nèi)存中的跳表(SkipList,這部分結(jié)構(gòu)又被稱(chēng)作 MemTable)。LSM-tree 引擎由于將用戶(hù)的隨機(jī)修改(插入)轉(zhuǎn)化為了對(duì) WAL 文件的順序?qū)懀虼司哂斜?B 樹(shù)類(lèi)存儲(chǔ)引擎更高的寫(xiě)吞吐。

內(nèi)存中的數(shù)據(jù)達(dá)到一定閾值后,會(huì)刷到磁盤(pán)上生成 SST 文件 (Sorted String Table),SST 又分為多層(默認(rèn)至多 6 層),每一層的數(shù)據(jù)達(dá)到一定閾值后會(huì)挑選一部分 SST 合并到下一層,每一層的數(shù)據(jù)是上一層的 10 倍(因此 90% 的數(shù)據(jù)存儲(chǔ)在最后一層)。

RocksDB 允許用戶(hù)創(chuàng)建多個(gè) ColumnFamily ,這些 ColumnFamily 各自擁有獨(dú)立的內(nèi)存跳表以及 SST 文件,但是共享同一個(gè) WAL 文件,這樣的好處是可以根據(jù)應(yīng)用特點(diǎn)為不同的 ColumnFamily 選擇不同的配置,但是又沒(méi)有增加對(duì) WAL 的寫(xiě)次數(shù)。

互聯(lián)網(wǎng)KV 產(chǎn)品

小米 Pegasus - 2015 ★

小米云平臺(tái)長(zhǎng)期以來(lái)一直使用開(kāi)源的Apache HBase來(lái)存儲(chǔ)結(jié)構(gòu)化/半結(jié)構(gòu)化數(shù)據(jù),但是HBase并不是十全十美的,它的架構(gòu)、語(yǔ)言、實(shí)現(xiàn)等決定了它具有一些難以克服的不足:

- HBase實(shí)現(xiàn)采用的JAVA語(yǔ)言,雖然開(kāi)發(fā)上效率比較高,但是運(yùn)行性能并不如C/C++這樣的語(yǔ)言。

- Java GC時(shí)可能造成進(jìn)程進(jìn)入假死狀態(tài),導(dǎo)致Region Server無(wú)法提供讀寫(xiě)服務(wù),造降低系統(tǒng)可用性。

- HBase宕機(jī)恢復(fù)時(shí)間比較長(zhǎng)(分鐘級(jí)),在這段時(shí)間內(nèi)服務(wù)是不可用的。其原因是:

- HBase數(shù)據(jù)存儲(chǔ)在分布式文件hdfs上,上層的RegionServer僅僅是服務(wù)點(diǎn)。為了保證數(shù)據(jù)一致性,HBase要求每個(gè)Region在同一時(shí)刻只能由一個(gè)RegionServer服務(wù)。當(dāng)某個(gè)RegionServer宕機(jī),必須選一個(gè)新的RegionServer來(lái)服務(wù)該Region。恢復(fù)過(guò)程中需要做較多處理,包括日志的傳輸、切分、重放,這個(gè)過(guò)程比較耗時(shí)。

- HBase依賴(lài)ZooKeeper來(lái)探測(cè)宕機(jī)問(wèn)題,而由于Java的GC問(wèn)題存在,Zookeeper的session timeout不能設(shè)得太短,典型地設(shè)為30秒。如果設(shè)得太短,Java GC的假死機(jī)就容易造成session超時(shí),觸發(fā)RegionServer不必要的自殺。因此從RegionServer宕機(jī)到被發(fā)現(xiàn),這中間可能就需要幾十秒。

- HBase的分層架構(gòu)使數(shù)據(jù)服務(wù)點(diǎn)和存儲(chǔ)位置分離,對(duì)Data Locality不夠友好,也是影響其讀性能的一個(gè)原因。

以上這些原因造成了HBase的可用性和性能都存在一些不足,難以滿(mǎn)足對(duì)服務(wù)可用性和延遲都很敏感的一些在線(xiàn)業(yè)務(wù)的需求,譬如廣告業(yè)務(wù)。

從2015年開(kāi)始,小米開(kāi)始開(kāi)發(fā)Pegasus系統(tǒng)。Pegasus系統(tǒng)的整體架構(gòu)如下圖所示,一共分為四個(gè)部分:


 

ReplicaServer

ReplicaServer主要負(fù)責(zé)數(shù)據(jù)存儲(chǔ)和存取,以replica為單位進(jìn)行服務(wù):服務(wù)的replica既可能是PrimaryReplica,也可能是SecondaryReplica。底層使用RocksDB來(lái)存儲(chǔ)數(shù)據(jù)管理commit log,并實(shí)現(xiàn)replication協(xié)議,提供數(shù)據(jù)一致性保證

MetaServer

MetaServer:MetaServer采用一主多備模式(one master, multiple backups),所有的狀態(tài)都會(huì)持久化到Zookeeper上;同時(shí)通過(guò)Zookeeper進(jìn)行選主。當(dāng)master故障后,另一臺(tái)backup立即搶到鎖,然后從Zookeeper上恢復(fù)狀態(tài),成為新的master。

MetaServer負(fù)責(zé)的功能包括:

 

  • 系統(tǒng)初始化
  • ReplicaServer的管理
  • Replica的分配、管理和負(fù)載均衡調(diào)度
  • Table的創(chuàng)建與刪除
  • 響應(yīng)Client請(qǐng)求,向Client提供最新的路由表

 

Zookeeper

系統(tǒng)元信息存儲(chǔ)

MetaServer選主

ClientLib

ClientLib對(duì)用戶(hù)提供數(shù)據(jù)存儲(chǔ)接口

接口簡(jiǎn)潔:對(duì)用戶(hù)提供最簡(jiǎn)單的接口,將尋址和容錯(cuò)等細(xì)節(jié)封裝在內(nèi)部

配置簡(jiǎn)單:用戶(hù)只需通過(guò)配置文件指定MetaServer地址列表,就可以訪(fǎng)問(wèn)集群,類(lèi)似于Zookeeper

盡量直接與ReplicaServer進(jìn)行交互,盡量少地訪(fǎng)問(wèn)MetaServer以避免熱點(diǎn)問(wèn)題,不依賴(lài)Zookeeper

騰訊 Tendis - 2015/8 ★

Tendis 是集騰訊眾多海量 KV 存儲(chǔ)優(yōu)勢(shì)于一身的 redis 存儲(chǔ)解決方案, 并 100% 兼容 Redis 協(xié)議和 Redis4.0 所有數(shù)據(jù)模型。作為一個(gè)高可用、高性能的分布式 KV 存儲(chǔ)數(shù)據(jù)庫(kù), 從訪(fǎng)問(wèn)時(shí)延、持久化需求、整體成本等不同維度的考量, Tendis 推出了 緩存版 、 混合存儲(chǔ)版 和 存儲(chǔ)版 三種不同產(chǎn)品形態(tài),并將存儲(chǔ)版開(kāi)源。

在版本迭代過(guò)程中,不斷的業(yè)務(wù)接入,成為游戲業(yè)務(wù)和平臺(tái)業(yè)務(wù)的主存儲(chǔ)。


 

Tendis存儲(chǔ)版集群架構(gòu)★

Tendis存儲(chǔ)版使用去中心化集群架構(gòu),每個(gè)數(shù)據(jù)節(jié)點(diǎn)都擁有全部的路由信息。

 

  • 用戶(hù)可以訪(fǎng)問(wèn)集群中的任意節(jié)點(diǎn),并且通過(guò)redis的MOVE協(xié)議,最終路由到正確的節(jié)點(diǎn)。
  • 每個(gè)Tendis存儲(chǔ)版節(jié)點(diǎn)維護(hù)屬于各自的slot數(shù)據(jù),任意兩個(gè)master節(jié)點(diǎn)之間的slot不重復(fù)
  • Tendis存儲(chǔ)版的主備節(jié)點(diǎn)之間通過(guò)binlog進(jìn)行復(fù)制
  • 任意兩個(gè)節(jié)點(diǎn)之間通過(guò)gossip協(xié)議進(jìn)行通訊
  • master節(jié)點(diǎn)之間支持基于slot的數(shù)據(jù)搬遷

 


 

Tendis存儲(chǔ)節(jié)點(diǎn)采用單進(jìn)程多實(shí)例的部署形態(tài),默認(rèn)單進(jìn)程使用10個(gè)rocksdb實(shí)例。


 

Key采用Hash打散的方式分片存儲(chǔ)在KvStore中,每個(gè)KvStore是一個(gè)單進(jìn)程多實(shí)例的Rocksdb。


 

Tendis存儲(chǔ)版 vs 其他開(kāi)源實(shí)現(xiàn) ★

 

  • 完全兼容redis cluster訪(fǎng)問(wèn)和管理模式的類(lèi)redis存儲(chǔ)方案
  • 完善的運(yùn)維和管理指令,info,slaveof等管理指令完全兼容
  • 命令兼容度高,幾乎所有命令和redis語(yǔ)義保持一致
  • 強(qiáng)大的數(shù)據(jù)搬遷能力,支持?jǐn)?shù)據(jù)在節(jié)點(diǎn)中的隨意搬遷,不影響原服務(wù)。
  • 強(qiáng)大的集群自治管理能力,支持自動(dòng)failover,故障自動(dòng)恢復(fù)等,運(yùn)維成本低

 

360 PiKa 2015/11 ★

Pika是一個(gè)可持久化的大容量redis存儲(chǔ)服務(wù),兼容string、hash、list、zset、set的絕大部分接口(兼容詳情),解決redis由于存儲(chǔ)數(shù)據(jù)量巨大而導(dǎo)致內(nèi)存不夠用的容量瓶頸,并且可以像redis一樣,通過(guò)slaveof命令進(jìn)行主從備份,支持全同步和部分同步,pika還可以用在twemproxy或者codis中來(lái)實(shí)現(xiàn)靜態(tài)數(shù)據(jù)分片(pika已經(jīng)可以支持codis的動(dòng)態(tài)遷移slot功能,目前在合并到master分支。


 

PiKa 2種模式 ★

經(jīng)典模式(Classic): 即1主N從同步模式,1個(gè)主實(shí)例存儲(chǔ)所有的數(shù)據(jù),N個(gè)從實(shí)例完全鏡像同步主實(shí)例的數(shù)據(jù),每個(gè)實(shí)例支持多個(gè)DBs。DB默認(rèn)從0開(kāi)始,Pika的配置項(xiàng)databases可以設(shè)置最大DB數(shù)量。DB在Pika上的物理存在形式是一個(gè)文件目錄。


 

分布式模式(Sharding): Sharding模式下,將用戶(hù)存儲(chǔ)的數(shù)據(jù)集合稱(chēng)為T(mén)able,每個(gè)Table切分成多個(gè)分片,每個(gè)分片稱(chēng)為Slot,對(duì)于某一個(gè)KEY的數(shù)據(jù)由哈希算法計(jì)算決定屬于哪個(gè)Slot。將所有Slots及其副本按照一定策略分散到所有的Pika實(shí)例中,每個(gè)Pika實(shí)例有一部分主Slot和一部分從Slot。在Sharding模式下,分主從的是Slot而不再是Pika實(shí)例。Slot在Pika上的物理存在形式是一個(gè)文件目錄。

Pika可以通過(guò)配置文件中的instance-mode配置項(xiàng),設(shè)置為classic和sharding,來(lái)選擇運(yùn)行經(jīng)典模式(Classic)還是分布式模式(Sharding)的Pika。


 

美團(tuán) Cellar 2015 ★

Squirrel:基于Redis Cluster(2015 年發(fā)布),演進(jìn)出全內(nèi)存、高吞吐、低延遲的 KV 存儲(chǔ)。
迭代:自研和社區(qū)并重,盡量兼容官方。
應(yīng)用:數(shù)據(jù)量小,對(duì)延遲敏感

Cellar:基于 Tair,演進(jìn)出持久化、大容量、數(shù)據(jù)高可靠KV 存儲(chǔ)。
迭代:完全靠自研。和 Squirrel 在解決同樣的問(wèn)題時(shí)也選取了不同的設(shè)計(jì)方案。
應(yīng)用:數(shù)據(jù)量大,對(duì)延遲不特別敏感

目前美團(tuán)內(nèi)部每天的調(diào)用量均已突破萬(wàn)億,請(qǐng)求峰值突破每秒億級(jí)

Cellar持久化KV架構(gòu) ★


 

跟阿里開(kāi)源的 Tair 主要有兩個(gè)架構(gòu)上的不同。第一個(gè)是OB,第二個(gè)是 ZooKeeper。我們的 OB 跟 ZooKeeper 的 Observer 是類(lèi)似的作用,提供 Cellar 中心節(jié)點(diǎn)元數(shù)據(jù)的查詢(xún)服務(wù)。它可以實(shí)時(shí)與中心節(jié)點(diǎn)的 Master 同步最新的路由表,客戶(hù)端的路由表都是從 OB 去拿。 這樣做的好處主要有兩點(diǎn):

第一,把大量的業(yè)務(wù)客戶(hù)端跟集群的大腦 Master 做了天然的隔離,防止路由表請(qǐng)求影響集群的管理。

第二,因?yàn)?OB 只供路由表查詢(xún),不參與集群的管理,所以它可以進(jìn)行水平擴(kuò)展,極大地提升了我們路由表的查詢(xún)能力。

另外,我們引入了 ZooKeeper 做分布式仲裁,解決我剛才提到的 Master、Slave 在網(wǎng)絡(luò)分割情況下的“腦裂”問(wèn)題,并且通過(guò)把集群的元數(shù)據(jù)存儲(chǔ)到 ZooKeeper,我們保證了元數(shù)據(jù)的高可靠。

Celler功能 ★

Cellar 節(jié)點(diǎn)容災(zāi)

如果 A 節(jié)點(diǎn)宕機(jī)了,會(huì)觸發(fā) Handoff 機(jī)制,這時(shí)候中心節(jié)點(diǎn)會(huì)通知客戶(hù)端 A節(jié)點(diǎn)發(fā)生了故障,讓客戶(hù)端把分片 1 的請(qǐng)求也打到 B 上。B 節(jié)點(diǎn)正常處理完客戶(hù)端的讀寫(xiě)請(qǐng)求之后,還會(huì)把本應(yīng)該寫(xiě)入 A 節(jié)點(diǎn)的分片 1&2 數(shù)據(jù)寫(xiě)入到本地的 Log 中。


 

如果 A 節(jié)點(diǎn)宕機(jī)后 3~5 分鐘,或者網(wǎng)絡(luò)抖動(dòng) 30~50 秒之后恢復(fù)了,A 節(jié)點(diǎn)就會(huì)上報(bào)心跳到中心節(jié)點(diǎn),中心節(jié)點(diǎn)就會(huì)通知 B 節(jié)點(diǎn):“ A 節(jié)點(diǎn)恢復(fù)了,你去把它不在期間的數(shù)據(jù)傳給它。”這時(shí)候,B 節(jié)點(diǎn)就會(huì)把本地存儲(chǔ)的 Log 回寫(xiě)到 A 節(jié)點(diǎn)上。等到 A 節(jié)點(diǎn)擁有了故障期間的全量數(shù)據(jù)之后,中心節(jié)點(diǎn)就會(huì)告訴客戶(hù)端,A 節(jié)點(diǎn)已經(jīng)徹底恢復(fù)了,客戶(hù)端就可以重新把分片 1 的請(qǐng)求打回 A 節(jié)點(diǎn)。


 

通過(guò)這樣的操作,我們可以做到秒級(jí)的快速節(jié)點(diǎn)摘除,而且節(jié)點(diǎn)恢復(fù)后加回,只需補(bǔ)齊少量的增量數(shù)據(jù)。另外如果 A 節(jié)點(diǎn)要做升級(jí),中心節(jié)點(diǎn)先通過(guò)主動(dòng) Handoff 把 A 節(jié)點(diǎn)流量切到 B 節(jié)點(diǎn),A 升級(jí)后再回寫(xiě)增量 Log,然后切回流量加入集群。這樣通過(guò)主動(dòng)觸發(fā) Handoff 機(jī)制,我們就實(shí)現(xiàn)了靜默升級(jí)的功能。


 

Cellar 跨地域容災(zāi)

以下圖一個(gè)北京主集群、上海從集群的跨地域場(chǎng)景為例,比如說(shuō)客戶(hù)端的寫(xiě)操作到了北京的主集群 A 節(jié)點(diǎn),A 節(jié)點(diǎn)會(huì)像正常集群內(nèi)復(fù)制一樣,把它復(fù)制到 B 和 D 節(jié)點(diǎn)上。同時(shí) A 節(jié)點(diǎn)還會(huì)把數(shù)據(jù)復(fù)制一份到從集群的 H 節(jié)點(diǎn)。H 節(jié)點(diǎn)處理完集群間復(fù)制寫(xiě)入之后,它也會(huì)做從集群內(nèi)的復(fù)制,把這個(gè)寫(xiě)操作復(fù)制到從集群的 I 、K 節(jié)點(diǎn)上。通過(guò)在主從集群的節(jié)點(diǎn)間建立這樣一個(gè)復(fù)制鏈路,我們完成了集群間的數(shù)據(jù)復(fù)制,并且這個(gè)復(fù)制保證了最低的跨地域帶寬占用。同樣的,集群間的兩個(gè)節(jié)點(diǎn)通過(guò)配置兩個(gè)雙向復(fù)制的鏈路,就可以達(dá)到雙向同步異地多活的效果。


 

Cellar 強(qiáng)一致

目前業(yè)界主流的解決方案是基于 Paxos 或 Raft 協(xié)議的強(qiáng)一致復(fù)制。我們最終選擇了 Raft 協(xié)議。主要是因?yàn)?Raft 論文是非常詳實(shí)的,是一篇工程化程度很高的論文。業(yè)界也有不少比較成熟的 Raft 開(kāi)源實(shí)現(xiàn),可以作為我們研發(fā)的基礎(chǔ),進(jìn)而能夠縮短研發(fā)周期。

下圖是現(xiàn)在 Cellar 集群 Raft 復(fù)制模式下的架構(gòu)圖,中心節(jié)點(diǎn)會(huì)做 Raft 組的調(diào)度,它會(huì)決定每一個(gè) Slot 的三副本存在哪些節(jié)點(diǎn)上。


 

Cellar 智能遷移


 

Cellar 快慢列隊(duì)

拆線(xiàn)程池、拆隊(duì)列。我們的網(wǎng)絡(luò)線(xiàn)程在收到包之后,會(huì)根據(jù)它的請(qǐng)求特點(diǎn),是讀還是寫(xiě),快還是慢,分到四個(gè)隊(duì)列里。讀寫(xiě)請(qǐng)求比較好區(qū)分,但快慢怎么分開(kāi)?我們會(huì)根據(jù)請(qǐng)求的 Key 個(gè)數(shù)、Value大小、數(shù)據(jù)結(jié)構(gòu)元素?cái)?shù)等對(duì)請(qǐng)求進(jìn)行快慢區(qū)分。然后用對(duì)應(yīng)的四個(gè)工作線(xiàn)程池處理對(duì)應(yīng)隊(duì)列的請(qǐng)求,就實(shí)現(xiàn)了快慢讀寫(xiě)請(qǐng)求的隔離。這樣如果我有一個(gè)讀的慢請(qǐng)求,不會(huì)影響另外三種請(qǐng)求的正常處理。不過(guò)這樣也會(huì)帶來(lái)一個(gè)問(wèn)題,我們的線(xiàn)程池從一個(gè)變成四個(gè),那線(xiàn)程數(shù)是不是變成原來(lái)的四倍?其實(shí)并不是的,我們某個(gè)線(xiàn)程池空閑的時(shí)候會(huì)去幫助其它的線(xiàn)程池處理請(qǐng)求。所以,我們線(xiàn)程池變成了四個(gè),但是線(xiàn)程總數(shù)并沒(méi)有變。我們線(xiàn)上驗(yàn)證中這樣的設(shè)計(jì)能把服務(wù) TP999 的延遲降低 86%,可大幅降低超時(shí)率。


 

Cellar 熱點(diǎn) Key

中心節(jié)點(diǎn)加了一個(gè)職責(zé),多了熱點(diǎn)區(qū)域管理,它現(xiàn)在不只負(fù)責(zé)正常的數(shù)據(jù)副本分布,還要管理熱點(diǎn)數(shù)據(jù)的分布,圖示這個(gè)集群在節(jié)點(diǎn) C、D 放了熱點(diǎn)區(qū)域。我們通過(guò)讀寫(xiě)流程看一下這個(gè)方案是怎么運(yùn)轉(zhuǎn)的。如果客戶(hù)端有一個(gè)寫(xiě)操作到了 A 節(jié)點(diǎn),A 節(jié)點(diǎn)處理完成后,會(huì)根據(jù)實(shí)時(shí)的熱點(diǎn)統(tǒng)計(jì)結(jié)果判斷寫(xiě)入的 Key 是否為熱點(diǎn)。如果這個(gè) Key 是一個(gè)熱點(diǎn),那么它會(huì)在做集群內(nèi)復(fù)制的同時(shí),還會(huì)把這個(gè)數(shù)據(jù)復(fù)制有熱點(diǎn)區(qū)域的節(jié)點(diǎn),也就是圖中的 C、D 節(jié)點(diǎn)。同時(shí),存儲(chǔ)節(jié)點(diǎn)在返回結(jié)果給客戶(hù)端時(shí),會(huì)告訴客戶(hù)端,這個(gè) Key 是熱點(diǎn),這時(shí)客戶(hù)端內(nèi)會(huì)緩存這個(gè)熱點(diǎn) Key。當(dāng)客戶(hù)端有這個(gè) Key 的讀請(qǐng)求時(shí),它就會(huì)直接去熱點(diǎn)區(qū)域做數(shù)據(jù)的讀取。


 

滴滴Fusion 2016★

Fusion 是滴滴自研的分布式 NoSQL 數(shù)據(jù)庫(kù),完全兼容 Redis 協(xié)議,支持超大規(guī)模數(shù)據(jù)持久化和高性能讀寫(xiě)。在滴滴內(nèi)部支撐了數(shù)百個(gè)業(yè)務(wù),具有 PB 級(jí)別的數(shù)據(jù)存儲(chǔ)量,是使用最廣泛的主存儲(chǔ)服務(wù)之一。在支持滴滴業(yè)務(wù)高速發(fā)展過(guò)程中,積累了很多分布式存儲(chǔ)領(lǐng)域的經(jīng)驗(yàn),孵化了離線(xiàn)到在線(xiàn)的高速數(shù)據(jù)導(dǎo)入方案、NewSQL 方案、跨機(jī)房同步等,一路解決了 Redis 容量限制、 離線(xiàn)數(shù)據(jù)在線(xiàn)打通、數(shù)據(jù)庫(kù)擴(kuò)展性差、異地多活容災(zāi)等問(wèn)題。


 

Fusion架構(gòu) ★

采用 hash 分片的方式來(lái)做數(shù)據(jù) sharding。從上往下看,用戶(hù)通過(guò) Redis 協(xié)議的客戶(hù)端(jedis、redigo、hiredis 等)就可以訪(fǎng)問(wèn) Fusion,首先會(huì)經(jīng)過(guò) VIP 做負(fù)載均衡,然后轉(zhuǎn)發(fā)到具體 proxy,再由 proxy 轉(zhuǎn)發(fā)數(shù)據(jù)到后端 Fusion 的數(shù)據(jù)節(jié)點(diǎn)。proxy 到后端數(shù)據(jù)節(jié)點(diǎn)的轉(zhuǎn)發(fā),是根據(jù)請(qǐng)求的 key 計(jì)算 hash 值,然后對(duì) slot 分片數(shù)取余,得到一個(gè)固定的 slotid,每個(gè) slotid 會(huì)固定的映射到一個(gè)存儲(chǔ)節(jié)點(diǎn),以此解決數(shù)據(jù)路由問(wèn)題。


 

FastLoad - 離線(xiàn)灌數(shù)據(jù) ★

在FastLoad 服務(wù)器上,創(chuàng)建一個(gè) DTS 任務(wù),該任務(wù)會(huì)在 Hadoop 配置中心注冊(cè)一個(gè)調(diào)度任務(wù)(周期性或一次性,由用戶(hù)決定),然后 FastLoad 服務(wù)器根據(jù)用戶(hù)上傳的數(shù)據(jù)存儲(chǔ)路徑或 Hive 表(我們支持的數(shù)據(jù)源有:HDFS 上的 JSON 文件和 Hive 結(jié)構(gòu)的數(shù)據(jù)),按照用戶(hù)提交的拼 key 方式,我們啟動(dòng) map/reduce 任務(wù)直接構(gòu)造 Fusion 底層存儲(chǔ)在文件系統(tǒng)上的文件 SST,并把它們構(gòu)造好相互之間的排序,避免重復(fù),構(gòu)造好后通知 Fusion 存儲(chǔ)節(jié)點(diǎn),下載 SST 文件,然后 load 到 Fusion 數(shù)據(jù)庫(kù)中。此后,用戶(hù)就可以通過(guò) Redis-Client 訪(fǎng)問(wèn)我們幫它加載的數(shù)據(jù)了。


 

此外,F(xiàn)usion 還支持二級(jí)索引和多區(qū)數(shù)據(jù)復(fù)制

新浪LaserDB - 2019★

LaserDB 是微博設(shè)計(jì)開(kāi)源的高性能分布式 KV 數(shù)據(jù)庫(kù),在滿(mǎn)足傳統(tǒng) KV 存儲(chǔ)的高性能的基礎(chǔ)上,提供了大容量分布式存儲(chǔ)解決方案。 并且為了滿(mǎn)足大數(shù)據(jù)、人工智能特征模型快速加載更新,LaserDB 原生支持了快速批量、增量導(dǎo)入功能,LaserDB 不僅可以滿(mǎn)足一般 的工程業(yè)務(wù)應(yīng)用,并且很好的支撐了機(jī)器學(xué)習(xí)模型、特征數(shù)據(jù)存儲(chǔ)需求。

LaserDB 整體架構(gòu)★

深入了解 LaserDB 的整體架構(gòu)可以更好的使用、運(yùn)維 LaserDB, LaserDB 主要包括三大核心組件:Laser Server, Laser Client 和 Laser Control, 此外還有適配 Redis 協(xié)議的 Laser Proxy 以及滿(mǎn)足數(shù)據(jù)批量導(dǎo)入的 Laser Transform。在具體部署時(shí)用戶(hù)可以根據(jù)自己的需求選擇部署 Laser Proxy 和 Laser Transform


 

Laser Server

LaserDB 的存儲(chǔ)服務(wù)核心組件,負(fù)責(zé)接收 thrift 請(qǐng)求并且處理對(duì)應(yīng)的請(qǐng)求。除了負(fù)責(zé)對(duì)外的服務(wù)請(qǐng)求處理以外,還負(fù)責(zé)具體的數(shù)據(jù)存儲(chǔ)、數(shù)據(jù)分片、數(shù)據(jù)同步等功能

Laser Control

負(fù)責(zé)集群數(shù)據(jù)表、數(shù)據(jù)表配置以及集群分片信息的管理,提供分片可視化、動(dòng)態(tài)擴(kuò)容、動(dòng)態(tài)縮容

Laser Client

主要是負(fù)責(zé)和 Server 進(jìn)行接口交互,并且實(shí)現(xiàn) LaserDB 整體請(qǐng)求路由機(jī)制,對(duì) Server 端提供的 API 接口進(jìn)行封裝,實(shí)現(xiàn) mget, mset 等批量操作的客戶(hù)端層并行化, 目前提供 C++, Golang 版本的 SDK 可以直接 與 Laser server 交互獲得更好的性能,其他語(yǔ)言的業(yè)務(wù)可以選擇 Laser Proxy 代理,最終通過(guò) redis 客戶(hù)端操作

Laser Proxy

Laser Proxy 主要是負(fù)責(zé)實(shí)現(xiàn) Redis 協(xié)議的大部分常用命令支持,Proxy 通過(guò)調(diào)用 Laser Client 與 Laser Server 交互,對(duì)于 Proxy 來(lái)說(shuō)是一個(gè)完全無(wú)狀態(tài)的服務(wù),可以將 Proxy 當(dāng)做一個(gè)存儲(chǔ)容量特別大的 Redis server 來(lái)看 。對(duì)于原有業(yè)務(wù)是 Redis 的,獲取不方便直接使用 Laser Client SDK 調(diào)用的業(yè)務(wù)場(chǎng)景可以選用

Laser Proxy

Laser Transform

Laser Transform 主要是負(fù)責(zé)實(shí)現(xiàn)數(shù)據(jù)的批量導(dǎo)入功能,對(duì)于有數(shù)據(jù)快速批量導(dǎo)入的需求,需要部署 Laser Transform 服務(wù),并且 Laser Server 環(huán)境需要有 hdfs 客戶(hù)端支持,Transform 服務(wù)主要負(fù)責(zé)定時(shí)調(diào)度提交 MapReduce 任務(wù),將原始格式的數(shù)據(jù)轉(zhuǎn)化為 Laser Server 可以識(shí)別的數(shù)據(jù)

字節(jié)ABase 2016

自 2016 年以來(lái),為了支撐在線(xiàn)推薦的存儲(chǔ)需求而誕生的——字節(jié)跳動(dòng)自研高可用 KV 存儲(chǔ) Abase,逐步發(fā)展成支撐包括推薦、廣告、搜索、抖音、西瓜、飛書(shū)、游戲等公司內(nèi)幾乎所有業(yè)務(wù)線(xiàn)的 90% 以上的 KV 存儲(chǔ)場(chǎng)景,已成為公司內(nèi)使用最廣泛的在線(xiàn)存儲(chǔ)系統(tǒng)之一。ABase2 2019年替換ABase1

ABase2架構(gòu) ★


 

Abase2 的整體架構(gòu)主要如上圖所示,在用戶(hù)、管控面、數(shù)據(jù)面三種視角下主要包含 5 組核心模塊。

RootServer

線(xiàn)上一個(gè)集群的規(guī)模大約為數(shù)千臺(tái)機(jī)器,為管理各個(gè)集群,我們研發(fā)了 RootServer 這個(gè)輕量級(jí)組件。顧名思義,RootServer 擁有全集群視角,它可以更好地協(xié)調(diào)各個(gè)集群之間的資源配比,支持租戶(hù)在不同集群之間的數(shù)據(jù)遷移,提供容災(zāi)視圖并合理控制爆炸半徑。

MetaServer

Abase2 是多租戶(hù)中心化架構(gòu),而 MetaServer 則是整個(gè)架構(gòu)的總管理員,它主要包括以下核心功能:

 

  • 管理元信息的邏輯視圖:包括 Namespace,Table,Partition,Replica 等狀態(tài)和配置信息以及之間的關(guān)系;
  • 管理元信息的物理視圖:包括 IDC,Pod,Rack,DataNode,Disk,Core 的分布和 Replica 的位置關(guān)系;
  • 多租戶(hù) QoS 總控,在異構(gòu)機(jī)器的場(chǎng)景下根據(jù)各個(gè)租戶(hù)與機(jī)器的負(fù)載進(jìn)行副本 Balance 調(diào)度;
  • 故障檢測(cè),節(jié)點(diǎn)的生命管理,數(shù)據(jù)可靠性跟蹤,在此基礎(chǔ)上進(jìn)行節(jié)點(diǎn)的下線(xiàn)和數(shù)據(jù)修復(fù)。

 


 

物理視圖


 

邏輯視圖

DataNode

DataNode 是數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)。部署時(shí),可以每臺(tái)機(jī)器或者每塊盤(pán)部署一個(gè) DataNode,為方便隔離磁盤(pán)故障,線(xiàn)上實(shí)際采用每塊盤(pán)部署一個(gè) DataNode 的方式。

DataNode 的最小資源單位是 CPU Core(后簡(jiǎn)稱(chēng) Core),每個(gè) Core 都擁有一個(gè)獨(dú)立的 Busy Polling 協(xié)程框架,多個(gè) Core 共享一塊盤(pán)的空間與 IO 資源。


 

一個(gè) Core 包含多個(gè) Replica,每個(gè) Replica 的請(qǐng)求只會(huì)在一個(gè) Core 上 Run-to-Complete,可以有效地避免傳統(tǒng)多線(xiàn)程模式中上下文切換帶來(lái)的性能損耗。

Replica 核心模塊如下圖所示,整個(gè) Partition 為 3 層結(jié)構(gòu):

 

  • 數(shù)據(jù)模型層:如上文提到的 String, Hash 等 Redis 生態(tài)中的各類(lèi)數(shù)據(jù)結(jié)構(gòu)接口。
  • 一致性協(xié)議層:在多主架構(gòu)下,多點(diǎn)寫(xiě)入勢(shì)必會(huì)造成數(shù)據(jù)不一致,Anti-Entropy 一方面會(huì)及時(shí)合并沖突,另一方面將協(xié)調(diào)沖突合并后的數(shù)據(jù)下刷至引擎持久化層并協(xié)調(diào) WAL GC。
  • 數(shù)據(jù)引擎層:數(shù)據(jù)引擎層首先有一層輕量級(jí)數(shù)據(jù)暫存層(或稱(chēng) Conflict Resolver)用于存儲(chǔ)未達(dá)成一致的數(shù)據(jù);下層為數(shù)據(jù)數(shù)據(jù)引擎持久化層,為滿(mǎn)足不同用戶(hù)多樣性需求,Abase2 引設(shè)計(jì)上采用引擎可插拔模式。對(duì)于有順序要求的用戶(hù)可以采用 RocksDB,TerarkDB 這類(lèi) LSM 引擎,對(duì)于無(wú)順序要求點(diǎn)查類(lèi)用戶(hù)采用延遲更穩(wěn)定的 LSH 引擎。

 


 

Client/Proxy/SDK

Client 模塊是用戶(hù)側(cè)視角下的核心組件,向上提供各類(lèi)數(shù)據(jù)結(jié)構(gòu)的接口,向下一方面通過(guò) MetaSync 與 MetaServer 節(jié)點(diǎn)通信獲取租戶(hù) Partition 的路由信息,另一方面通過(guò)路由信息與存儲(chǔ)節(jié)點(diǎn) DataNode 進(jìn)行數(shù)據(jù)交互。此外,為了進(jìn)一步提高服務(wù)質(zhì)量,我們?cè)?Client 的 IO 鏈路上集成了重試、Backup Request、熱 Key 承載、流控、鑒權(quán)等重要 QoS 功能。

結(jié)合字節(jié)各類(lèi)編程語(yǔ)言生態(tài)豐富的現(xiàn)狀,團(tuán)隊(duì)基于 Client 封裝了 Proxy 組件,對(duì)外提供 Redis 協(xié)議(RESP2)與 Thrift 協(xié)議,用戶(hù)可根據(jù)自身偏好選擇接入方式。此外,為了滿(mǎn)足對(duì)延遲更敏感的重度用戶(hù),我們也提供了重型 SDK 來(lái)跳過(guò) Proxy 層,它是 Client 的簡(jiǎn)單封裝。

DTS (Data Transfer Service)

DTS 主導(dǎo)了 Abase 生態(tài)系統(tǒng)的發(fā)展,在一二代透明遷移、備份回滾、Dump、訂閱等諸多業(yè)務(wù)場(chǎng)景中起到了非常核心的作用,由于篇幅限制,本文不做更多的詳細(xì)設(shè)計(jì)敘述。

小紅書(shū)RedKV - 2019

小紅書(shū)是年輕人的生活記錄、分享平臺(tái),用戶(hù)可以通過(guò)短視頻、圖文等形式記錄生活點(diǎn)滴,分享生活方式。在當(dāng)前的業(yè)務(wù)模型下,用戶(hù)的畫(huà)像數(shù)據(jù)和筆記數(shù)據(jù)用來(lái)做風(fēng)險(xiǎn)控制和內(nèi)容推薦。存儲(chǔ)數(shù)據(jù)具有對(duì)象-屬性的特征、維度多,畫(huà)像數(shù)據(jù)量已經(jīng)達(dá)到數(shù)十TB, 在線(xiàn)業(yè)務(wù)對(duì)畫(huà)像和筆記數(shù)據(jù)的訪(fǎng)問(wèn)P99 時(shí)延要求非常高。

RedKV2 架構(gòu) ★

RedKV整體架構(gòu)分3層,接入層兼容Redis協(xié)議,支持各種語(yǔ)言的社區(qū)版SDK和公司定制的中間件版;接入代理層支持千萬(wàn)QPS的讀寫(xiě)能力,無(wú)狀態(tài)擴(kuò)展;存儲(chǔ)層提供高可靠讀寫(xiě)服務(wù)。


 

Client接入層

RedKV集群部署完成后,通過(guò)公司內(nèi)部提供的Service Mesh組件做服務(wù)發(fā)現(xiàn),對(duì)Client提供服務(wù)。

Proxy

Proxy層由一個(gè)無(wú)狀態(tài)CorvusPlus進(jìn)程組成。它兼容老的Redis Client,擴(kuò)縮容、升級(jí)對(duì)無(wú)Client和后端集群無(wú)感,支持多線(xiàn)程、IO多路復(fù)用和端口復(fù)用特性。對(duì)比開(kāi)源版本,CorvusPlus增強(qiáng)了自我防護(hù)和可觀測(cè)特性,實(shí)現(xiàn)了可在線(xiàn)配置的功能特性:

 

  • Proxy限流
  • 數(shù)據(jù)在線(xiàn)壓縮
  • 線(xiàn)程模型優(yōu)化
  • backup-read優(yōu)化長(zhǎng)尾
  • 大key檢測(cè)

 

基于Shard管理的中心架構(gòu)能更好的支持?jǐn)?shù)據(jù)遷移和集群擴(kuò)縮容,存儲(chǔ)節(jié)點(diǎn)采用單進(jìn)程多實(shí)例部署,在多活場(chǎng)景中可以支持副本數(shù)彈性擴(kuò)展。


 

關(guān)鍵特性 ★

數(shù)據(jù)復(fù)制

與傳統(tǒng)解決方案引入同步組件的方式不同,我們快速實(shí)現(xiàn)了單向數(shù)據(jù)同步以及集群擴(kuò)容需求,整體架構(gòu)去除了對(duì)第三方組件的依賴(lài),通過(guò)擴(kuò)展Redis復(fù)制協(xié)議實(shí)現(xiàn)了RedKV數(shù)據(jù)節(jié)點(diǎn)的直接復(fù)制,如圖10。單向復(fù)制的限制是擴(kuò)容需要基于做節(jié)點(diǎn)同步,擴(kuò)容完成后后臺(tái)任務(wù)根據(jù)3.3.3中定義的key的分片刪除不是本節(jié)點(diǎn)的數(shù)據(jù)。

在多活的部署形態(tài)下,多云集群的一對(duì)多的數(shù)據(jù)復(fù)制采用單向復(fù)制對(duì)主集群性能侵入較大,因此我們實(shí)現(xiàn)了基于中心管控的數(shù)據(jù)復(fù)制策略。該策略支持多個(gè)集群的分片異構(gòu)部署,通過(guò)Checkpoint方式定向同步數(shù)據(jù),不再需要額外的后臺(tái)任務(wù)去做數(shù)據(jù)淘汰,能很好的支持多對(duì)多的多云集群數(shù)據(jù)復(fù)制、數(shù)據(jù)破環(huán)和擴(kuò)縮容。


 

數(shù)據(jù)批量導(dǎo)入

小紅書(shū)大量的離線(xiàn)業(yè)務(wù)數(shù)據(jù)存儲(chǔ)在S3 Hive中,每天會(huì)有部分?jǐn)?shù)據(jù)需要增量更新,其他的數(shù)據(jù)會(huì)被淘汰。這類(lèi)場(chǎng)景有幾個(gè)挑戰(zhàn):

 

  • 批量導(dǎo)入:如小紅書(shū)的筆記數(shù)據(jù),一般需要小時(shí)級(jí)別甚至天級(jí)別的更新,所以業(yè)務(wù)需要有快捷的批量導(dǎo)入功能。
  • 快速更新:特征數(shù)據(jù)的特點(diǎn)就是數(shù)據(jù)量特別大,以筆記為例,全量筆記在TB 級(jí)別數(shù)據(jù)量。如果通過(guò) Jedis SDK 寫(xiě)入,那么存儲(chǔ)集群需要支持百萬(wàn)QPS的機(jī)器資源。當(dāng)下小紅書(shū)數(shù)據(jù)平臺(tái)支持業(yè)務(wù)把數(shù)據(jù)從hive通過(guò)工作流直接導(dǎo)入RedKV,一般是每天凌晨開(kāi)始寫(xiě)數(shù)據(jù),等到晚高峰時(shí)大量讀取。這種方法實(shí)踐下來(lái),經(jīng)常導(dǎo)致 RedKV集群的集群內(nèi)存OOM,影響穩(wěn)定性。
  • 性能及穩(wěn)定:數(shù)據(jù)在導(dǎo)入的過(guò)程中不能影響讀的性能

 


 

數(shù)據(jù)批量導(dǎo)出

小紅書(shū)的業(yè)務(wù)模型訓(xùn)練數(shù)據(jù)通過(guò)Hash存儲(chǔ)在RedKV集群中,業(yè)務(wù)下游需要對(duì)訓(xùn)練結(jié)果進(jìn)行離線(xiàn)分析,希望RedKV具有和Hive數(shù)據(jù)流通的能力。RedKV本身是不支持Schema的,如果要將KV數(shù)據(jù)導(dǎo)入Hive表,則需要將Hash的KKV數(shù)據(jù)轉(zhuǎn)化為一個(gè)Table。

RedKV的內(nèi)部數(shù)據(jù)按hash打散,導(dǎo)入Hive表則需要提供table關(guān)鍵字,先按前綴掃描的方式掃描存儲(chǔ)節(jié)點(diǎn),再生成Hive識(shí)別的文件,最后通過(guò)Hive Load進(jìn)行加載。為了更好的兼容其他spark任務(wù),我們選擇Hive支持的標(biāo)準(zhǔn)parquet列式存儲(chǔ)文件


 

B站KV 2019

在B站的業(yè)務(wù)場(chǎng)景中,存在很多種不同模型的數(shù)據(jù),有些數(shù)據(jù)關(guān)系比較復(fù)雜像:賬號(hào)、稿件信息。有些數(shù)據(jù)關(guān)系比較簡(jiǎn)單,只需要簡(jiǎn)單的kv模型即可滿(mǎn)足。此外,又存在某些讀寫(xiě)吞吐比較高的業(yè)務(wù)場(chǎng)景,該場(chǎng)景早期的解決方案是通過(guò)MySQL來(lái)進(jìn)行數(shù)據(jù)的持久化存儲(chǔ),同時(shí)通過(guò)redis來(lái)提升訪(fǎng)問(wèn)的速度與吞吐。但是這種模式帶來(lái)了兩個(gè)問(wèn)題,其一是存儲(chǔ)與緩存一致性的問(wèn)題,該問(wèn)題在B站通過(guò)canal異步更新緩存的方式得以解決,其二則是開(kāi)發(fā)的復(fù)雜度,對(duì)于這樣一套存儲(chǔ)系統(tǒng),每個(gè)業(yè)務(wù)都需要額外維護(hù)一個(gè)任務(wù)腳本來(lái)消費(fèi)canal數(shù)據(jù)進(jìn)行緩存數(shù)據(jù)的更新。基于這種場(chǎng)景,業(yè)務(wù)需要的其實(shí)是一個(gè)介于Redis與MySQL之間的提供持久化高性能的kv存儲(chǔ)。此外對(duì)象存儲(chǔ)的元數(shù)據(jù),對(duì)數(shù)據(jù)的一致性、可靠性與擴(kuò)展性有著很高的要求。

基于此背景,我們對(duì)自研KV的定位從一開(kāi)始就是構(gòu)建一個(gè)高可靠、高可用、高性能、高拓展的系統(tǒng)。對(duì)于存儲(chǔ)系統(tǒng),核心是保證數(shù)據(jù)的可靠性,當(dāng)數(shù)據(jù)不可靠時(shí)提供再高的可用性也是沒(méi)用的。可靠性的一個(gè)核心因素就是數(shù)據(jù)的多副本容災(zāi),通過(guò)raft一致性協(xié)議保證多副本數(shù)據(jù)的一致性。

整體架構(gòu) ★


 

整個(gè)系統(tǒng)核心分為三個(gè)組件:

Metaserver用戶(hù)集群元信息的管理,包括對(duì)kv節(jié)點(diǎn)的健康監(jiān)測(cè)、故障轉(zhuǎn)移以及負(fù)載均衡。

Node為kv數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn),用于實(shí)際存儲(chǔ)kv數(shù)據(jù),每個(gè)Node上保存數(shù)據(jù)的一個(gè)副本,不同Node之間的分片副本通過(guò)raft保證數(shù)據(jù)的一致性,并選出主節(jié)點(diǎn)對(duì)外提供讀寫(xiě),業(yè)務(wù)也可以根據(jù)對(duì)數(shù)據(jù)一致性的需求指定是否允許讀從節(jié)點(diǎn),在對(duì)數(shù)據(jù)一致性要求不高的場(chǎng)景時(shí),通過(guò)設(shè)置允許讀從節(jié)點(diǎn)可以提高可用性以及降低長(zhǎng)尾。

Client模塊為用戶(hù)訪(fǎng)問(wèn)入口,對(duì)外提供了兩種接入方式,一種是通過(guò)proxy模式的方式進(jìn)行接入,另一種是通過(guò)原生的SDK直接訪(fǎng)問(wèn),proxy本身也是封裝自c++的原生SDK。SDK從Metaserver獲取表的元數(shù)據(jù)分布信息,根據(jù)元數(shù)據(jù)信息決定將用戶(hù)請(qǐng)求具體發(fā)送到哪個(gè)對(duì)應(yīng)的Node節(jié)點(diǎn)。同時(shí)為了保證高可用,SDK還實(shí)現(xiàn)了重試機(jī)制以及backoff請(qǐng)求。

部署形態(tài)


 

集群的拓?fù)浣Y(jié)構(gòu)包含了幾個(gè)概念,分別是Pool、Zone、Node、Table、Shard 與Replica。

 

  • Pool為資源池連通域,包含多個(gè)可用區(qū)。也可用于業(yè)務(wù)資源隔離域。
  • Zone為可用區(qū),同一個(gè)pool內(nèi)部的zone是網(wǎng)路聯(lián)通并且故障隔離的。通常為一個(gè)機(jī)房或者一個(gè)交換機(jī)
  • Node為實(shí)際的物理主機(jī)節(jié)點(diǎn),負(fù)責(zé)具體的數(shù)據(jù)存儲(chǔ)邏輯與數(shù)據(jù)持久化。
  • Table對(duì)應(yīng)到具體的業(yè)務(wù)表,類(lèi)似MySQL里的表。
  • Shard為邏輯分片,通過(guò)將table分為多個(gè)shard將數(shù)據(jù)打散分布。
  • Replica為shard的副本,同一個(gè)shard的不同副本不能分布在同一個(gè)zone,必須保證故障隔離。每一個(gè)replica包含一個(gè)engine,engine存儲(chǔ)全量的業(yè)務(wù)數(shù)據(jù)。engine的實(shí)現(xiàn)包含rocksdb和sparrowdb。其中sparrowdb是針對(duì)大value寫(xiě)放大的優(yōu)化實(shí)現(xiàn)。

 

關(guān)鍵特性 ★

binlog支持(多活)

類(lèi)似于MySQL的binlog,我們基于raftlog日志實(shí)現(xiàn)了kv的binlog. 業(yè)務(wù)可以根據(jù)binlog進(jìn)行實(shí)時(shí)的事件流訂閱,同時(shí)為了滿(mǎn)足事件流回溯的需求,我們還對(duì)binlog數(shù)據(jù)進(jìn)行冷備。通過(guò)將binlog冷備到對(duì)象存儲(chǔ),滿(mǎn)足了部分場(chǎng)景需要回溯較長(zhǎng)事件記錄的需求。


 

直接復(fù)用raftlog作為用戶(hù)行為的binlog,可以減少binlog產(chǎn)生的額外寫(xiě)放大,唯一需要處理的是過(guò)濾raft本身的配置變更信息。learner通過(guò)實(shí)時(shí)監(jiān)聽(tīng)不斷拉取分片產(chǎn)生的binlog到本地并解析。根據(jù)learner配置信息決定將數(shù)據(jù)同步到對(duì)應(yīng)的下游。同時(shí)binlog數(shù)據(jù)還會(huì)被異步備份到對(duì)象存儲(chǔ),當(dāng)業(yè)務(wù)需要回溯較長(zhǎng)時(shí)間的事件流的時(shí)候,可以直接指定位置從S3拉取歷史binlog進(jìn)行解析。

分區(qū)分裂

基于不同的業(yè)務(wù)場(chǎng)景,我們同時(shí)支持了range分區(qū)和hash分區(qū)。對(duì)于range場(chǎng)景,隨著用戶(hù)數(shù)據(jù)的增長(zhǎng),需要對(duì)分區(qū)數(shù)據(jù)進(jìn)行分裂遷移。對(duì)于hash分區(qū)的場(chǎng)景,使用上通常會(huì)根據(jù)業(yè)務(wù)的數(shù)據(jù)量做幾倍的冗余預(yù)估,然后創(chuàng)建合適的分片數(shù)。

bulk load

離線(xiàn)平臺(tái)只需要根據(jù)kv的存儲(chǔ)格式離線(xiàn)生成對(duì)應(yīng)的SST文件,然后上傳到對(duì)象存儲(chǔ)服務(wù)。kv直接從對(duì)象存儲(chǔ)拉取SST文件到本地,然后直接加載SST文件即可對(duì)外提供讀服務(wù)。bulk load的另外一個(gè)好處是可以直接在生成SST后離線(xiàn)進(jìn)行compaction,將compaction的負(fù)載offload到離線(xiàn)的同時(shí)也降低了空間的放大。

有贊ZanKV

在有贊早期的時(shí)候,當(dāng)時(shí)只有 MySQL 做存儲(chǔ),codis 做緩存,隨著業(yè)務(wù)發(fā)展,某些業(yè)務(wù)數(shù)據(jù)用 MySQL 不太合適, 而 codis 由于當(dāng)緩存用, 并不適合做存儲(chǔ)系統(tǒng), 因此, 急需一款高性能的 NoSQL 產(chǎn)品做補(bǔ)充。考慮到當(dāng)時(shí)運(yùn)維和開(kāi)發(fā)人員都非常少, 我們需要一個(gè)能快速投入使用, 又不需要太多維護(hù)工作的開(kāi)源產(chǎn)品。 當(dāng)時(shí)對(duì)比了幾個(gè)開(kāi)源產(chǎn)品, 最終選擇了 aerospike 作為我們的 KV 存儲(chǔ)方案。

然而隨著有贊的快速發(fā)展, 單純的 aerospike 集群慢慢開(kāi)始無(wú)法滿(mǎn)足越來(lái)越多樣的業(yè)務(wù)需求。 雖然性能和穩(wěn)定性依然很優(yōu)秀, 但是由于其索引必須加載到內(nèi)存, 對(duì)于越來(lái)越多的海量數(shù)據(jù), 存儲(chǔ)成本會(huì)居高不下。 更多的業(yè)務(wù)需求也決定了我們將來(lái)需要更多的數(shù)據(jù)類(lèi)型來(lái)支持業(yè)務(wù)的發(fā)展。 為了充分利用已有的 aerospike 集群, 并考慮到當(dāng)時(shí)的開(kāi)源產(chǎn)品并無(wú)法滿(mǎn)足我們所有的業(yè)務(wù)需求, 因此我們需要構(gòu)建一個(gè)能滿(mǎn)足有贊未來(lái)多年的 KV 存儲(chǔ)服務(wù)。

整體架構(gòu) ★

設(shè)計(jì)目標(biāo):

 

  • 在設(shè)計(jì)這樣一個(gè)能滿(mǎn)足未來(lái)多年發(fā)展的底層 KV 服務(wù), 我們需要考慮以下幾個(gè)方面:
  • 需要盡量使用有大廠背書(shū)并且活躍的開(kāi)源產(chǎn)品, 避免過(guò)多的工作量和太長(zhǎng)的周期
  • 避免完全依賴(lài)和耦合一個(gè)開(kāi)源產(chǎn)品, 使得無(wú)法適應(yīng)未來(lái)某個(gè)開(kāi)源產(chǎn)品的不可控變化, 以及無(wú)法享受將來(lái)的技術(shù)迭代更新和升級(jí)
  • 避免使用過(guò)于復(fù)雜的技術(shù)棧, 增加后期運(yùn)維成本
  • 由于業(yè)務(wù)需要, 我們需要有能力做方便的擴(kuò)展和定制
  • 未來(lái)的業(yè)務(wù)需求發(fā)展多樣, 單一產(chǎn)品無(wú)法滿(mǎn)足所有的需求, 可能需要整合多個(gè)開(kāi)源產(chǎn)品來(lái)滿(mǎn)足復(fù)雜多樣的需求
  • 允許 KV 服務(wù)后端的技術(shù)變化的同時(shí), 對(duì)業(yè)務(wù)接口應(yīng)該盡量穩(wěn)定, 后繼升級(jí)不應(yīng)該帶來(lái)過(guò)多的遷移成本。

 


 

自研 ZanKV 有如下特點(diǎn):

 

  • 使用Go語(yǔ)言開(kāi)發(fā), 利用其高效的開(kāi)發(fā)效率, 也能減少后期維護(hù)難度, 方便后期定制。
  • 使用大廠且成熟活躍的開(kāi)源組件 etcd raft,RocksDB 等構(gòu)建, 減少開(kāi)發(fā)工作量
  • CP 系統(tǒng)和現(xiàn)有 aerospike 的 AP 系統(tǒng)結(jié)合滿(mǎn)足不同的需求
  • 提供更豐富的數(shù)據(jù)結(jié)構(gòu)
  • 支持更大的容量, 和 aerospike 結(jié)合在不損失性能需求的前提下大大減少存儲(chǔ)成本

 

自研 ZanKV 的整體架構(gòu)圖如下所示:


 

整個(gè)集群由 placedriver + 數(shù)據(jù)節(jié)點(diǎn) datanode + etcd + rsync 組成。 各個(gè)節(jié)點(diǎn)的角色如下:

 

  • PD node: 負(fù)責(zé)數(shù)據(jù)分布和數(shù)據(jù)均衡, 協(xié)調(diào)集群里面所有的 zankv node 節(jié)點(diǎn), 將元數(shù)據(jù)寫(xiě)入 etcd
  • datanode: 負(fù)責(zé)存儲(chǔ)具體的數(shù)據(jù)
  • etcd: 負(fù)責(zé)存儲(chǔ)元數(shù)據(jù), 元數(shù)據(jù)包括數(shù)據(jù)分布映射表以及其他用于協(xié)調(diào)的元數(shù)據(jù)
  • rsync: 用于傳輸 snapshot 備份文件

 

AppleFoundationDB

整體架構(gòu) ★

如圖所示,F(xiàn)DB 的架構(gòu)中規(guī)中矩,大的模塊可以分成三部分:

 

  • 客戶(hù)端接口 Client
  • 控制平面 Control Plane
  • 數(shù)據(jù)平面 Data Plane

 


 

Control Plane

Control Plane 負(fù)責(zé)管理集群的元數(shù)據(jù),使用 Active Disk Paxos 來(lái)保證高可用。Control Plane 分成以下幾個(gè)部分:

 

  • Coordinator:幾個(gè) coordinator 進(jìn)程組成一個(gè) paxos group,其中有一個(gè) leader,稱(chēng)為 cluster controller。Cluster controller 負(fù)責(zé)故障檢測(cè),管理各種進(jìn)程的角色,匯集、傳遞整個(gè)集群的各種信息。同時(shí),cluster controller 是整個(gè)集群訪(fǎng)問(wèn)的入口點(diǎn)。Client 通過(guò)一個(gè)保存有 coordinator 的 IP:Port 的配置文件訪(fǎng)問(wèn)集群,并從 cluster controller 獲取最新的 proxy 列表。
  • DataDistributor:DataDistributor 負(fù)責(zé)監(jiān)控 StorageServer 的故障情況和數(shù)據(jù)的平衡調(diào)度。
  • Ratekeeper:Ratekeeper 通過(guò)控制單調(diào)遞增時(shí)間戳的分配速度來(lái)進(jìn)行過(guò)載保護(hù)。
  •  

 

Data Plane

Data Plane 大體上可以劃分成三大部分:

 

  • Transaction System 負(fù)責(zé)實(shí)現(xiàn) serializable snapshot isolation 級(jí)別的分布式事務(wù)。
  • Log System 負(fù)責(zé)日志的復(fù)制,保證系統(tǒng)的高可用。
  • Storage System 保存實(shí)際數(shù)據(jù),或者說(shuō)狀態(tài)機(jī),會(huì)從 Log System 異步拉取日志進(jìn)行 apply。目前單機(jī)存儲(chǔ)引擎是使用一個(gè)修改過(guò)的 SQLite。

 

Transaction System 較為復(fù)雜,大體上可以分層三個(gè)模塊:

 

  • Proxy 作為事務(wù)系統(tǒng)面向 client 的代理接口,事務(wù)請(qǐng)求都需要通過(guò) proxy 獲取 read version,獲取 key ranges 對(duì)應(yīng)的 storage server 的信息,提交事務(wù)。
  • Sequencer 負(fù)責(zé)分配遞增的 read version 和 commit version。
  • Resolver 負(fù)責(zé) SSI 級(jí)別的事務(wù)沖突檢測(cè)。

 

另外FDB還支持事務(wù)特性,這個(gè)需要閱讀論文區(qū)詳細(xì)理解,這里不在展開(kāi)

AWS DynamoDB - 2004★

Amazon DynamoDB 是一種完全托管的 NoSQL 數(shù)據(jù)庫(kù)服務(wù),提供快速而可預(yù)測(cè)的性能,能夠?qū)崿F(xiàn)無(wú)縫擴(kuò)展。DynamoDB 可以從表中自動(dòng)刪除過(guò)期的項(xiàng),從而幫助您降低存儲(chǔ)用量,減少用于存儲(chǔ)不相關(guān)數(shù)據(jù)的成本。


 


 

DynamoDB工作原理 ★

DynamoDB 架構(gòu)


 

在DynamoDB中核心組件是表、項(xiàng)目和屬性。表是項(xiàng)目的集合,項(xiàng)目是屬性的集合,DynamoDB使用主鍵來(lái)標(biāo)識(shí)表中的每個(gè)項(xiàng)目,還提供了二級(jí)索引來(lái)提供更大的查詢(xún)靈活性,還可以使用DynamoDB流來(lái)捕獲DynamoDB表中的數(shù)據(jù)修改事件。

表、項(xiàng)目和屬性:

 

  • 表 DynamoDB將數(shù)據(jù)存儲(chǔ)在表中,表是某類(lèi)數(shù)據(jù)的集合,例如People表、Cars表。
  • 項(xiàng)目 每個(gè)表包含多個(gè)項(xiàng)目,項(xiàng)目是一組屬性,具有不同于所有其他項(xiàng)目的唯一標(biāo)識(shí),項(xiàng)目類(lèi)似與SQL中的行、記錄或元組。
  • 屬性 每個(gè)項(xiàng)目包含一個(gè)或多個(gè)屬性,屬性是基本的數(shù)據(jù)元素,屬性類(lèi)似與SQL中的字段或列。
    People表示例

 


 

DynamoDB未開(kāi)源,可參考的2篇論文:

 

  • Amazon DynamoDB – a Fast and Scalable NoSQL Database Service Designed for Inte.NET Scale Applications.
  • https://www.allthingsdistributed.com/2012/01/amazon-dynamodb.html
  • Amazon DynamoDB: A Scalable, Predictably Performant, and Fully Managed NoSQL Database Service: https://www.usenix.org/system/files/atc22-elhemali.pdf
  • https://www.infoq.cn/article/aEUY5kcI1a3iqGUyGzUy

分享到:
標(biāo)簽:公司
用戶(hù)無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定