愛奇藝的數(shù)據(jù)庫(kù)選型大法,實(shí)用不糾結(jié)!

作者:郭磊濤,愛奇藝數(shù)據(jù)庫(kù)和中間件負(fù)責(zé)人,TiDB User Group Ambassador。本文系 TUG 北京區(qū) 9 月線下活動(dòng) “不同業(yè)務(wù)場(chǎng)景下的數(shù)據(jù)庫(kù)技術(shù)選型思路” 分享實(shí)錄。

我是愛奇藝的數(shù)據(jù)庫(kù)和中間件負(fù)責(zé)人郭磊濤,今天主要向大家分享數(shù)據(jù)庫(kù)選型方面的思路,供大家參考和學(xué)習(xí)。我們進(jìn)行數(shù)據(jù)庫(kù)選型的時(shí)候要考慮哪些問題?有哪些需求?待選用的數(shù)據(jù)庫(kù)是否和需求對(duì)的上?是不是直接就可以拿來用?需不需要一些額外的開發(fā)?這些都會(huì)在今天的分享中提及。

1 WX20191014-202421@2x.png

我們做選型的時(shí)候首先要問:

誰選型?是負(fù)責(zé)采購(gòu)的同學(xué)、 DBA 還是業(yè)務(wù)研發(fā)?

如果選型的是采購(gòu)的同學(xué),他們更注重成本,包括存儲(chǔ)方式、網(wǎng)絡(luò)需求等。

如果選型的是 DBA 同學(xué),他們關(guān)心的:

  • 首先是運(yùn)維成本,包括監(jiān)控告警是否完善、是否有備份恢復(fù)機(jī)制、升級(jí)和遷移的成本是否高、社區(qū)是否穩(wěn)定、是否方便調(diào)優(yōu)、排障是否簡(jiǎn)易等;
  • 其次DBA會(huì)關(guān)注穩(wěn)定性,包括是否支持?jǐn)?shù)據(jù)多副本、服務(wù)高可用、多寫多活等;
  • 第三是性能,包括延遲、QPS 以及是否支持更高級(jí)的分級(jí)存儲(chǔ)功能等;
  • 第四是擴(kuò)展性,如果業(yè)務(wù)的需求不確定,是否容易橫向擴(kuò)展和縱向擴(kuò)容;最后是安全,需要符合審計(jì)要求,不容易出現(xiàn) SQL 注入或拖庫(kù)情況。

除了采購(gòu)和 DBA之外,后臺(tái)應(yīng)用研發(fā)的同學(xué)同樣會(huì)關(guān)注穩(wěn)定性、性能、擴(kuò)展性等問題,同時(shí)也非常關(guān)注數(shù)據(jù)庫(kù)接口是否便于開發(fā),是否便于修改數(shù)據(jù)庫(kù) schema 等問題。

2 WX20191014-202454@2x.png

接下來我們來看一下愛奇藝使用的數(shù)據(jù)庫(kù)類型。

  1. MySQL, 互聯(lián)網(wǎng)業(yè)務(wù)必備系統(tǒng);
  2. TiDB;愛奇藝的 TiDB 實(shí)踐會(huì)有另外的具體介紹;
  3. Redis, KV 數(shù)據(jù)庫(kù),互聯(lián)網(wǎng)公司標(biāo)配;
  4. Couchbase,這個(gè)在愛奇藝用的比較多,但國(guó)內(nèi)互聯(lián)網(wǎng)公司用的比較少,接下來的部分會(huì)詳細(xì)說明;
  5. 其他,比如 MongoDB、圖數(shù)據(jù)庫(kù)、自研 KV 數(shù)據(jù)庫(kù) HiKV 等;
  6. 大數(shù)據(jù)分析相關(guān)系統(tǒng),比如 Hive、Impala 等等。

可以看到愛奇藝的數(shù)據(jù)庫(kù)種類還是很多的,這會(huì)造成業(yè)務(wù)開發(fā)的同學(xué)可能不太清楚在他的業(yè)務(wù)場(chǎng)景下應(yīng)該選用哪種數(shù)據(jù)庫(kù)系統(tǒng)。那么,我們先對(duì)這些數(shù)據(jù)庫(kù)按照接口(SQL,NoSQL)和面向的業(yè)務(wù)場(chǎng)景(OLTP, OLAP)這兩位維度進(jìn)行一個(gè)簡(jiǎn)單非嚴(yán)謹(jǐn)?shù)姆诸悺?/p>

左上角是面向 OLTP、支持 SQL 的這樣一類系統(tǒng),例如 MySQL,一般支持事務(wù)不同的隔離級(jí)別, QPS 要求比較高,延時(shí)比較低,主要用于交易信息和關(guān)鍵數(shù)據(jù)的存儲(chǔ),比如訂單、VIP 信息等。

左下角是 NoSQL 數(shù)據(jù)庫(kù),是一類針對(duì)特殊場(chǎng)景做優(yōu)化的系統(tǒng),schema 一般比較簡(jiǎn)單,吞吐量較高、延遲較低,一般用作緩存或者 KV 數(shù)據(jù)庫(kù)。

整個(gè)右側(cè)都是 OLAP 的大數(shù)據(jù)分析系統(tǒng),包括 Clickhouse、Impala等,一般支持SQL、不支持事務(wù),擴(kuò)展性比較好,可以通過加機(jī)器增加數(shù)據(jù)的存儲(chǔ)量,響應(yīng)延遲較長(zhǎng)。

還有一類數(shù)據(jù)庫(kù)是比較中立的,在數(shù)據(jù)量比較小的時(shí)候性能比較好,在數(shù)據(jù)量較大或復(fù)雜查詢的時(shí)候性能也不差,一般通過不同的存儲(chǔ)引擎和查詢引擎來滿足不同的業(yè)務(wù)需求,我們把它叫做 HTAP,TiDB 就是這樣一種數(shù)據(jù)庫(kù)。

3 WX20191014-202519@2x.png

前面我們提到了很多種的數(shù)據(jù)庫(kù),那么接下來就和大家介紹一下在愛奇藝我們是怎么使用這些數(shù)據(jù)庫(kù)的。

MySQL 在愛奇藝的使用

首先是 MySQL。MySQL 基本使用方式是 master-slave + 半同步,支持每周全備+每日增量備份。我們做了一些基本功能的增強(qiáng),首先是增強(qiáng)了數(shù)據(jù)恢復(fù)工具 Xtrabackup 的性能。之前遇到一個(gè)情況,我們有一個(gè)全量庫(kù)是 300G 數(shù)據(jù),增量庫(kù)每天 70G 數(shù)據(jù),總數(shù)據(jù)量 700G 左右。我們當(dāng)時(shí)只需要恢復(fù)一個(gè)表的數(shù)據(jù),但該工具不支持單表恢復(fù),且整庫(kù)恢復(fù)需要 5 個(gè)小時(shí)。針對(duì)這個(gè)情況我們具體排查了原因,發(fā)現(xiàn)在數(shù)據(jù)恢復(fù)的過程中需要進(jìn)行多次寫盤的 IO 操作并且有很多串行操作,所以我們做了一些優(yōu)化,例如刪減過程中的一些寫盤操作,減少落盤并將數(shù)據(jù)處理并行化,優(yōu)化后整庫(kù)恢復(fù)耗時(shí)減少到 100 分鐘,而且可以直接恢復(fù)單表數(shù)據(jù)。

第二是適配 DDL 和 DML 工具到內(nèi)部系統(tǒng),gh-ostt 和 oak-online-alter-table 在數(shù)據(jù)量大的時(shí)候會(huì)造成 master-slave 延時(shí),所以我們?cè)谑褂霉ぞ叩臅r(shí)候也增加了延時(shí)上的考慮,實(shí)時(shí)探測(cè)Master-Slave 庫(kù)之間延時(shí)的情況,如果延時(shí)較大會(huì)暫停工具的使用,恢復(fù)到正常水平再繼續(xù)。

第二是 MySQL 高可用。Master-slave 加上半同步這種高可用方式不太完善,所以我們參照了 MHA 并進(jìn)行了改動(dòng),采用 master + agent 的方式。Agent 在每一個(gè)物理機(jī)上部署,可以監(jiān)控這個(gè)物理機(jī)上的所有實(shí)例的狀態(tài),周期性地向 master 發(fā)送心跳,Master 會(huì)實(shí)時(shí)監(jiān)測(cè)各個(gè)Agent的狀態(tài)。如果 MySQL故障,會(huì)啟動(dòng) Binlog 補(bǔ)償機(jī)制,并切換訪問域名完成 failover??紤]到數(shù)據(jù)庫(kù)跨機(jī)房跨地區(qū)部署的情況,MHA 的 master 我們也做了高可用設(shè)計(jì),眾多 master 會(huì)通過 raft 組成一個(gè) raft group,類似 TiDB 的 PD 模塊。目前 MySQL failover 策略支持三種方式:同機(jī)房、同地域跨機(jī)房以及跨地域。

第三是提高M(jìn)ySQL擴(kuò)展能力,以提供更大容量的數(shù)據(jù)存儲(chǔ)。擴(kuò)展方式有 SDK,例如開源的 ShardingSphere,在愛奇藝的使用也比較廣泛。另外就是 Proxy,開源的就更多了。但是 SDK 和 Proxy 使用的問題是支持的 SQL 語句簡(jiǎn)單,擴(kuò)容難度大,依賴較多且運(yùn)維復(fù)雜,所以部分業(yè)務(wù)已經(jīng)遷移至 TiDB。

第四是審計(jì)。我們?cè)?MySQL 上做了一個(gè)插件獲取全量 SQL 操作,后端打到 Kafka,下游再接入包括 Clickhouse 等目標(biāo)端進(jìn)行 SQL 統(tǒng)計(jì)分析。除此之外還有安全策略,包括主動(dòng)探索是否有 SQL 注入及是否存在拖庫(kù)情況等,并觸發(fā)對(duì)應(yīng)的告警。 MySQL 審計(jì)插件最大的問題是如何降低對(duì) MySQL 性能的影響,對(duì)此我們進(jìn)行了一些測(cè)試,發(fā)現(xiàn)使用 General Log 對(duì)性能損耗較大,有 10%~20% 的降低。于是我們通過接口來獲取 MySQL 插件里的監(jiān)控項(xiàng),再把監(jiān)控項(xiàng)放到 buffer 里邊,用兩級(jí)的 RingBuffer 來保證數(shù)據(jù)的寫入不會(huì)有鎖資源競(jìng)爭(zhēng)。在這個(gè)插件里再啟動(dòng)一個(gè)線程,從 RingBuffer 里讀取數(shù)據(jù)并把數(shù)據(jù)打包寫到 FIFO 管道里。我們?cè)诿颗_(tái) MySQL 的物理機(jī)里再啟動(dòng)一個(gè) Agent,從管道里阻塞地讀取數(shù)據(jù)發(fā)至 Kafka。優(yōu)化后我們?cè)俅芜M(jìn)行壓測(cè),在每臺(tái)機(jī)器上有 15 萬的更新、刪除或插入操作下不會(huì)丟失數(shù)據(jù),性能損耗一般情況下小于 2%。目前已經(jīng)在公司內(nèi)部的集群上線了一年時(shí)間,運(yùn)行比較穩(wěn)定,上線和下線對(duì)業(yè)務(wù)沒有影響。

第五是分級(jí)存儲(chǔ)。MySQL 里會(huì)存一些過程性的數(shù)據(jù),即只需要讀寫最近一段時(shí)間存入的數(shù)據(jù),過段時(shí)間這些數(shù)據(jù)就不需要了,需要進(jìn)行定時(shí)清理。分級(jí)存儲(chǔ)就是在 MySQL 之上又用了其他存儲(chǔ)方式,例如 TiDB 或其他 TokuDB,兩者之間可以進(jìn)行數(shù)據(jù)自動(dòng)搬遷和自動(dòng)歸檔,同時(shí)前端通過 SDK + Proxy 來做統(tǒng)一的訪問入口。這樣一來,業(yè)務(wù)的開發(fā)同學(xué)只需要將數(shù)據(jù)存入 MySQL 里,讀取時(shí)可能從后端接入的任意數(shù)據(jù)庫(kù)讀出。這種方式目前只是過渡使用,之后會(huì)根據(jù) TiDB 的特性進(jìn)行逐步遷移。

4 WX20191014-202559@2x.png

Redis 在愛奇藝的使用

接下來是 Redis。Redis 也是使用 master - slave 這種方式,由于網(wǎng)絡(luò)的復(fù)雜性我們對(duì) Sentinel 的部署進(jìn)行了一些特殊配置,在多機(jī)房的情況下每個(gè)機(jī)房配置一定數(shù)量 Sentinel 來避免腦裂。

備份恢復(fù)方面介紹一個(gè)我們的特殊場(chǎng)景,雖然 Redis 是一個(gè)緩存,但我們發(fā)現(xiàn)不少的業(yè)務(wù)同學(xué)會(huì)把它當(dāng)做一個(gè) KVDB 來使用,在某些情況下會(huì)造成數(shù)據(jù)的丟失。所以我們做了一個(gè) Redis 實(shí)時(shí)備份功能,啟動(dòng)一個(gè)進(jìn)程偽裝成 Redis 的 Slave 實(shí)時(shí)獲取數(shù)據(jù),再放到后端的 KV 存儲(chǔ)里,例如 ScyllaDB,如果要恢復(fù)就可以從 ScyllaDB 里把數(shù)據(jù)拉出來。我們?cè)谟?Redis 時(shí)最大的痛點(diǎn)就是它對(duì)網(wǎng)絡(luò)的延遲或抖動(dòng)非常敏感。如有抖動(dòng)造成 Redis Master 超時(shí),會(huì)由 Sentinel 重新選出一個(gè)新的節(jié)點(diǎn)成為 Master,再把該節(jié)點(diǎn)上的數(shù)據(jù)同步到所有 Slave 上,此過程中數(shù)據(jù)會(huì)放在 Master 節(jié)點(diǎn)的 Buffer 里,如果寫入的 QPS 很高會(huì)造成 Buffer 滿溢。如果 Buffer 滿后 RDB 文件還沒有拷貝過去,重建過程就會(huì)失敗。

基于這種情況,我們對(duì) Redis 告警做了自動(dòng)化優(yōu)化,如有大量 master - slave 重建失敗,我們會(huì)動(dòng)態(tài)調(diào)整一些參數(shù),例如把 Buffer 臨時(shí)調(diào)大等, 此外我們還做了 Redis 集群的自動(dòng)擴(kuò)縮容功能。

我們?cè)谧?Redis 開發(fā)時(shí)如果是 Java 語言都會(huì)用到 Jedis。用 Jedis 訪問客戶端分片的 Redis 集群,如果某個(gè)分片發(fā)生了故障或者 failover,Jedis 就會(huì)對(duì)所有后端的分片重建連接。如果某一分片發(fā)生問題,整個(gè) Redis 的訪問性能和 QPS 會(huì)大幅降低。針對(duì)這個(gè)情況我們優(yōu)化了 Jedis,如果某個(gè)分片發(fā)生故障,就只針對(duì)這個(gè)分片進(jìn)行重建。

在業(yè)務(wù)訪問 Redis 時(shí)我們會(huì)對(duì) Master 綁定一個(gè)讀寫域名,多個(gè)從庫(kù)綁定讀域名。但如果我們進(jìn)行 Master failover,會(huì)將讀寫域名從某舊 Master 解綁,再綁定到新 Master 節(jié)點(diǎn)上。DNS 本身有一個(gè)超時(shí)時(shí)間,所以數(shù)據(jù)庫(kù)做完 failover 后業(yè)務(wù)程序里沒有立刻獲取到新的 Master 節(jié)點(diǎn)的 IP的話,有可能還會(huì)連到原來的機(jī)器上,造成訪問失敗。我們的解決方法是把 DNS 的 TTL 縮短,但對(duì) DNS 服務(wù)又會(huì)造成很大的壓力,所以我們?cè)?SDK 上提供 Redis 的名字服務(wù) RNS,RNS 從 Sentinel 里獲取集群的拓?fù)浜屯負(fù)涞淖兓闆r,如果集群 failover,Sentinel 會(huì)接到通知,客戶端就可以通過 RNS 來獲取新的 Master 節(jié)點(diǎn)的 IP 地址。我們?nèi)サ粲蛎?,通過 IP 地址來訪問整個(gè)集群,屏蔽了 DNS 的超時(shí),縮短了故障的恢復(fù)時(shí)間。SDK 上還做了一些功能,例如 Load Balance 以及故障檢測(cè),比如某個(gè)節(jié)點(diǎn)延時(shí)較高的話會(huì)被臨時(shí)熔斷等。

客戶端分片的方式會(huì)造成 Redis 的擴(kuò)容非常痛苦,如果客戶端已經(jīng)進(jìn)行了一定量的分片,之后再增加就會(huì)非常艱難。Redis 在 3.0 版本后會(huì)提供 Redis Cluster,因?yàn)楣δ苁芟拊趷燮嫠噾?yīng)用的不是很多,例如不支持顯示跨 DC 部署和訪問,讀寫只在主庫(kù)上等。我們某些業(yè)務(wù)場(chǎng)景下會(huì)使用 Redis 集群,例如數(shù)據(jù)庫(kù)訪問只發(fā)生在本 DC,我們會(huì)在 DC 內(nèi)部進(jìn)行 Cluster 部署。但有些業(yè)務(wù)在使用的過程中還是想做 failover,如果集群故障可以切換到其他集群。根據(jù)這種情況我們做了一個(gè) Proxy,讀寫都通過它來進(jìn)行。寫入數(shù)據(jù)時(shí) Proxy 會(huì)做一個(gè)旁路,把新增的數(shù)據(jù)寫在 Kafka 里,后臺(tái)啟用同步程序再把 Kafka 里的數(shù)據(jù)同步到其他集群,但存在一些限制,比如我們沒有做沖突檢測(cè),所以集群間數(shù)據(jù)需要業(yè)務(wù)的同學(xué)做單元化。線上環(huán)境的Redis Cluster 集群間場(chǎng)景跨 DC 同步 需要 50 毫秒左右的時(shí)間。

5 WX20191014-202651@2x.png

Couchbase 在愛奇藝的使用

Redis 雖然提供 Cluster 這種部署方式,但存在一些問題。所以數(shù)據(jù)量較大的時(shí)候(經(jīng)驗(yàn)是 160G),就不推薦 Redis 了,而是采用另一種存儲(chǔ)方式 Couchbase。

Couchbase 在國(guó)內(nèi)互聯(lián)網(wǎng)公司用的比較少,一開始我們是把他當(dāng)做一個(gè) Memcached 來使用的,即純粹的緩存系統(tǒng)。但其實(shí)它性能還是比較強(qiáng)大的,是一個(gè)分布式高性能的 KV 系統(tǒng),支持多種存儲(chǔ)引擎 (bucket)。第一種是 Memcached bucket,使用方式和 Memcached 一樣為 KV 存儲(chǔ),不支持?jǐn)?shù)據(jù)持久化也沒有數(shù)據(jù)副本,如果節(jié)點(diǎn)故障會(huì)丟失數(shù)據(jù);第二種是 Couchbase bucket,支持?jǐn)?shù)據(jù)持久化,使用 Json 寫入,有副本,我們一般會(huì)在線上配置兩個(gè)副本,如果新加節(jié)點(diǎn)會(huì)對(duì)數(shù)據(jù)進(jìn)行 rebalance,愛奇藝使用的一般是 Couchbase bucket 這種配置。Couchbase 數(shù)據(jù)的分布如右圖,數(shù)據(jù)寫入時(shí)在客戶端上會(huì)先進(jìn)行一次哈希運(yùn)算,運(yùn)算完后會(huì)定位 Key 在哪一個(gè) vBucket (相當(dāng)于數(shù)據(jù)庫(kù)里的某個(gè)分片)。之后客戶端會(huì)根據(jù) Cluster Map 發(fā)送信息至對(duì)應(yīng)的服務(wù)端,客戶端的 Cluster Map 保存的是 vBucket 和服務(wù)器的映射關(guān)系,在服務(wù)端數(shù)據(jù)遷移的過程中客戶端的 Cluster Map 映射關(guān)系會(huì)動(dòng)態(tài)更新,因此客戶端對(duì)于 服務(wù)端的 failover 操作不需要做特殊處理,但可能在 rebalance 過程中會(huì)有短暫的超時(shí),導(dǎo)致的告警對(duì)業(yè)務(wù)影響不大。

Couchbase 在愛奇藝應(yīng)用比較早,2012 年還沒有 Redis Cluster 的時(shí)候就開始使用了。集群管理使用 erlang 語言開發(fā),最大功能是進(jìn)行集群間的復(fù)制,提供多種復(fù)制方式:?jiǎn)蜗?、雙向、星型、環(huán)式、鏈?zhǔn)降?。愛奇藝從最初?1.8 版本使用到如今的 5.0 版本,正在調(diào)研 6.0。中間也遇到了很多坑,例如 NTP 時(shí)間配置出錯(cuò)會(huì)導(dǎo)致崩潰,如果每個(gè)集群對(duì)外 XDCR 并發(fā)過高導(dǎo)致不穩(wěn)定,同步方向變更會(huì)導(dǎo)致數(shù)據(jù)丟失等等,我們通過運(yùn)維和一些外部工具來進(jìn)行規(guī)避。

Couchbase 的集群是獨(dú)立集群,集群間的數(shù)據(jù)同步通過 XDCR,我們一般配置為雙向同步。對(duì)于業(yè)務(wù)來說,如果 Cluster 1 寫入, Cluster 2 不寫入,正常情況下客戶端會(huì)寫 Cluster 1。如果 Cluster 1 有故障,我們提供了一個(gè) Java SDK,可以在配置中心把寫入更改到 Cluster 2,把原來到 Cluster 1 的連接逐步斷掉再與Cluster 2 新建連接。這種集群 failover 的過程對(duì)于客戶端來說是相對(duì)透明和無感的。

6 WX20191014-202717@2x.png

愛奇藝自研數(shù)據(jù)庫(kù) HiKV 的使用

Couchbase 雖然性能非常高,并且數(shù)據(jù)的存儲(chǔ)可以超過內(nèi)存。但是,如果數(shù)據(jù)量超過內(nèi)存 75% 這個(gè)閾值,性能就會(huì)下降地特別快。在愛奇藝,我們會(huì)把數(shù)據(jù)量控制在可用內(nèi)存的范圍之內(nèi),當(dāng)做內(nèi)存數(shù)據(jù)庫(kù)使用。但是它的成本非常高,所以我們后面又開發(fā)了一個(gè)新的數(shù)據(jù)庫(kù)—— HiKV。

開發(fā) HiKV 的目的是為了把一些對(duì)性能要求沒那么高的 Couchbase 應(yīng)用遷移到 HiKV 上。HiKV 基于開源系統(tǒng) ScyllaDB,主要使用了其分布式數(shù)據(jù)庫(kù)的管理功能,增加了單機(jī)存儲(chǔ)引擎 HiKV。 ScyllaDB 比較吸引人的是它宣稱性能高于 Cassandra 十倍,又完全兼容 Cassandra 接口,設(shè)計(jì)基本一致,可以視為 C++ 版 Cassandra 系統(tǒng)。 ScyllaDB 性能的提升主要是使用了一些新的技術(shù)框架,例如 C++ 異步框架 seastar,主要原理是在j每臺(tái)物理機(jī)的核上會(huì) attach 一個(gè)應(yīng)用線程,每個(gè)核上有自己獨(dú)立的內(nèi)存、網(wǎng)絡(luò)、IO 資源,核與核之間沒有數(shù)據(jù)共享但可以通信,其最大的好處是內(nèi)存訪問無鎖,沒有沖突過程。當(dāng)一個(gè)數(shù)據(jù)讀或?qū)懙竭_(dá) ScyllaDB 的 server 時(shí),會(huì)按照哈希算法來判斷請(qǐng)求的 Key 是否是該線程需要處理的,如果是則本線程處理,否則會(huì)轉(zhuǎn)發(fā)到對(duì)應(yīng)線程上去。除此之外,它還支持多副本、多數(shù)據(jù)中心、多寫多活,功能比較強(qiáng)大。

在愛奇藝,我們基于 SSD 做了一個(gè) KV 存儲(chǔ)引擎。Key 放在內(nèi)存里,Value 放在盤上的文件里,我們?cè)谧x和寫文件時(shí),只需要在內(nèi)存索引里定位,再進(jìn)行一次盤的 IO 開銷就可以把數(shù)據(jù)讀出來,相比 ScyllaDB 原本基于 LSM Tree 的存儲(chǔ)引擎方式對(duì) IO 的開銷較少。索引數(shù)據(jù)全部放在內(nèi)存中,如果索引長(zhǎng)度較長(zhǎng)會(huì)限制單機(jī)可存儲(chǔ)的數(shù)據(jù)量,于是我們通過開發(fā)定長(zhǎng)的內(nèi)存分布器,對(duì)于比較長(zhǎng)的 Key 做摘要縮短長(zhǎng)度至 20 字節(jié),采用紅黑樹索引,限制每條記錄在內(nèi)存里的索引長(zhǎng)度至為 64 字節(jié)。內(nèi)存數(shù)據(jù)要定期做 checkpoint,客戶端要做限流、熔斷等。

HiKV 目前在愛奇藝應(yīng)用范圍比較大,截至目前已經(jīng)替換了 30% 的 Couchbase,有效地降低了存儲(chǔ)成本。

8 WX20191014-202800@2x.png

愛奇藝的數(shù)據(jù)庫(kù)運(yùn)維管理

愛奇藝數(shù)據(jù)庫(kù)種類較多,如何高效地運(yùn)維和管理這些數(shù)據(jù)庫(kù)也是經(jīng)歷了不同的階段。

最初我們通過 DBA 寫腳本的方式管理,如果腳本出問題就找 DBA,導(dǎo)致了 DBA 特別忙碌。

第二個(gè)階段我們考慮讓大家自己去查問題的答案,于是在內(nèi)部構(gòu)建了一個(gè)私有云,通過 Web 的方式展示數(shù)據(jù)庫(kù)運(yùn)行狀態(tài),讓業(yè)務(wù)的同學(xué)可以自己去申請(qǐng)集群,一些簡(jiǎn)單地操作也可以通過自服務(wù)平臺(tái)實(shí)現(xiàn),解放了 DBA。一些需要人工處理的大型運(yùn)維操作經(jīng)常會(huì)造成一些人為故障,敲錯(cuò)參數(shù)造成數(shù)據(jù)丟失等。

于是在第三個(gè)階段我們把運(yùn)維操作 Web 化,通過網(wǎng)頁(yè)點(diǎn)擊可以進(jìn)行 90% 的操作。

第四個(gè)階段讓經(jīng)驗(yàn)豐富的 DBA 把自身經(jīng)驗(yàn)變成一些工具,比如有業(yè)務(wù)同學(xué)說 MySQL master-slave 延時(shí)了,DBA 會(huì)通過一系列操作排查問題。現(xiàn)在我們把這些操作串起來形成一套工具,出問題時(shí)業(yè)務(wù)的同學(xué)可以自己通過網(wǎng)頁(yè)上的一鍵診斷工具去排查,自助進(jìn)行處理。除此之外我們還會(huì)定期做預(yù)警檢查,對(duì)業(yè)務(wù)集群里潛在的問題進(jìn)行預(yù)警報(bào)告;開發(fā)智能客服,回答問題;通過監(jiān)控的數(shù)據(jù)對(duì)實(shí)例打標(biāo)簽,進(jìn)行削峰填谷地智能調(diào)度,提高資源利用率。

9 WX20191014-202824@2x.png

實(shí)用數(shù)據(jù)庫(kù)選型樹:快速進(jìn)行數(shù)據(jù)庫(kù)選型

最后來說一些具體數(shù)據(jù)庫(kù)選型建議。這是 DBA 和業(yè)務(wù)一起,通過經(jīng)驗(yàn)得出來的一些結(jié)論。對(duì)于關(guān)系型數(shù)據(jù)庫(kù)的選型來說,可以從數(shù)據(jù)量和擴(kuò)展性兩個(gè)維度考慮,再根據(jù)數(shù)據(jù)庫(kù)有沒有冷備、要不要使用 Toku 存儲(chǔ)引擎,要不要使用 Proxy 等等進(jìn)行抉擇。

13.jpg

NoSQL 也是什么情況下使用 master-slave,什么情況下使用客戶端分片、集群、Couchbase、HiKV 等,我們內(nèi)部自服務(wù)平臺(tái)上都有這個(gè)選型樹信息。

14.jpg

一些思考

我們?cè)谶x形時(shí)先思考需求,判斷需求是否真實(shí)。你可以從數(shù)據(jù)量、QPS、延時(shí)等方面考慮需求,但這些都是真實(shí)需求嗎?是否可以通過其他方式把這個(gè)需求消耗掉,例如在數(shù)據(jù)量大的情況下可以先做數(shù)據(jù)編碼或者壓縮,數(shù)據(jù)量可能就降下來了。不要把所有需求都推到數(shù)據(jù)庫(kù)層面,它其實(shí)是一個(gè)兜底的系統(tǒng)。

第二個(gè)思考的點(diǎn)是對(duì)于某個(gè)數(shù)據(jù)庫(kù)系統(tǒng)或是某個(gè)技術(shù)選型我們應(yīng)該考慮什么?是因?yàn)闊衢T嗎?還是因?yàn)榧夹g(shù)上比較先進(jìn)?但是不是能真正地解決你的問題?如果你數(shù)據(jù)量不是很大的話就不需要選擇可以存儲(chǔ)大數(shù)據(jù)量的系統(tǒng)。

第三是放棄,當(dāng)你放棄一個(gè)系統(tǒng)時(shí)真的是因?yàn)椴缓糜脝幔窟€是沒有用好?放棄一個(gè)東西很難,但在放棄時(shí)最好有一個(gè)充分的理由,包括實(shí)測(cè)的結(jié)果。

第四是自研,在需要自己開發(fā)數(shù)據(jù)庫(kù)時(shí)可以參考和使用一些成熟的產(chǎn)品,但不要盲目自研。

最后是開源,要有擁抱開源的態(tài)度。

12 WX20191014-202856@2x.png

文章首發(fā)于 TiDB User Group (TUG) 線上問答社區(qū) AskTUG:https://asktug.com/t/topic/1396

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容