你好,歡迎進入江蘇優(yōu)軟數(shù)字科技有限公司官網(wǎng)!
發(fā)布時間:2023-12-03
瀏覽次數(shù):0
選擇數(shù)據(jù)庫時我們應該考慮哪些問題? 有什么需求? 所選擇的數(shù)據(jù)庫是否滿足需求? 可以直接使用嗎? 是否需要一些額外的開發(fā)? 這些都會在本文的分享中提到。
1、選擇數(shù)據(jù)庫技術(shù)時的思考維度
當我們進行選擇時,我們首先要問:
誰選擇? 是負責采購的同學、DBA、還是業(yè)務研發(fā)?
如果是購買學生來選擇,他們更注重成本,包括存儲方式、網(wǎng)絡(luò)要求等。
如果您是 DBA 學生,他們會擔心:
① 運行維護成本
首先是運維成本,包括監(jiān)控報警是否齊全,是否有備份恢復機制,升級遷移成本是否高,社區(qū)是否穩(wěn)定,是否方便調(diào)優(yōu),是否排查問題簡單等;
② 穩(wěn)定性
其次,DBA會關(guān)注穩(wěn)定性,包括是否支持數(shù)據(jù)多副本、服務高可用性、多次寫入和多次活躍等;
③性能
三是性能,包括延遲、QPS以及是否支持更高級的分層存儲功能;
④ 擴展性
第四是可擴展性。 如果業(yè)務需求不確定,橫向和縱向擴展是否容易?
⑤安全
最后是安全性,需要符合審計要求,不易出現(xiàn)SQL注入或數(shù)據(jù)庫拖拽。
⑥ 其他
除了采購和DBA之外,后端應用開發(fā)的同學也會關(guān)注穩(wěn)定性、性能、擴展性等問題。 他們也會非常關(guān)注數(shù)據(jù)庫接口是否容易開發(fā),是否容易修改數(shù)據(jù)庫。
接下來我們看一下愛奇藝使用的數(shù)據(jù)庫類型:
可以看到,愛奇藝的數(shù)據(jù)庫類型還是比較多的,這可能會導致業(yè)務開發(fā)同學在自己的業(yè)務場景中不知道該選擇哪種數(shù)據(jù)庫系統(tǒng)。
那么,我們首先按照接口(SQL、NoSQL)和面向業(yè)務場景(OLTP、OLAP)兩個維度對這些數(shù)據(jù)庫做一個簡單、不嚴格的分類。
下圖中,左上角是一類面向OLTP、支持SQL的系統(tǒng),比如MySQL,一般支持不同的事務隔離級別,QPS要求比較高,延遲較低,主要用于交易信息和關(guān)鍵數(shù)據(jù)的存儲。 如訂單、VIP信息等。
左下角是NoSQL數(shù)據(jù)庫,這是針對特殊場景優(yōu)化的一類系統(tǒng)。 一般比較簡單,吞吐量高,延遲低,一般用作緩存或者KV數(shù)據(jù)庫。
整個右側(cè)是一個OLAP大數(shù)據(jù)分析系統(tǒng),包括OLAP等,一般支持SQL,不支持事務。 它具有良好的可擴展性。 可以通過添加機器來增加數(shù)據(jù)的存儲容量,響應延遲較長。
還有一類數(shù)據(jù)庫是相對中性的。 當數(shù)據(jù)量比較小時它有比較好的性能,當數(shù)據(jù)量很大或者查詢復雜的時候也還不錯。 它一般采用不同的存儲引擎和查詢引擎來滿足不同的業(yè)務需求。 ,我們稱之為HTAP,TiDB就是這樣一個數(shù)據(jù)庫。
2、愛奇藝對數(shù)據(jù)庫的優(yōu)化和完善
前面我們提到了很多種數(shù)據(jù)庫,下面給大家介紹一下我們在愛奇藝是如何使用這些數(shù)據(jù)庫的。
1、MySQL在愛奇藝的使用
①MySQL
第一個是MySQL。 MySQL的基本用法是-slave+半同步,支持每周全備份+每日增量備份。 我們做了一些基本的功能增強。 首先是增強數(shù)據(jù)恢復工具的性能。
我們之前遇到過一個情況。 我們有一個全量數(shù)據(jù)庫,每天有300G數(shù)據(jù)intellij idea 數(shù)據(jù)庫關(guān)系圖,還有一個增量數(shù)據(jù)庫,每天有70G數(shù)據(jù)。 總數(shù)據(jù)量約700G。 我們只需要恢復一張表的數(shù)據(jù),但是該工具不支持單表恢復,整個數(shù)據(jù)庫恢復需要5個小時。
我們專門排查了造成這種情況的原因,發(fā)現(xiàn)在數(shù)據(jù)恢復過程中,需要多次磁盤寫IO操作,串行操作較多,所以我們做了一些優(yōu)化。 例如,減少刪除過程中的一些磁盤寫操作,并行化數(shù)據(jù)處理。 優(yōu)化后,整個數(shù)據(jù)庫恢復時間縮短至100分鐘,單表數(shù)據(jù)可直接恢復。
然后是DDL和DML工具對內(nèi)部系統(tǒng)的適配。 gh-ostt和oak--alter-table在數(shù)據(jù)量較大時會造成-slave延遲,所以我們在使用工具時也加入了延遲考慮。 ,實時檢測從庫之間的延遲。 如果延遲較大,該工具的使用將暫停并恢復到正常水平,然后再繼續(xù)。
② MySQL高可用
其次是MySQL的高可用。 -slave加半同步的高可用方式并不完美,所以我們參考MHA做了修改,采用+agent的方式。 Agent部署在每臺物理機上,可以監(jiān)控該物理機上所有實例的狀態(tài)。 它定期向服務器發(fā)送心跳,實時監(jiān)控各個Agent的狀態(tài)。
如果MySQL出現(xiàn)故障,將啟動補償機制,切換訪問域名完成。 考慮到數(shù)據(jù)庫是跨機房、跨區(qū)域部署的,我們MHA也做了高可用的設(shè)計,很多會通過raft形成一個raft group,類似于TiDB的PD模塊。 目前MySQL策略支持同機房、同地域、跨機房、跨地域三種方式。
③ MySQL擴展能力
三是提高MySQL的擴展能力,提供更大容量的數(shù)據(jù)存儲。 擴展方式包括SDK,比如開源,在愛奇藝也廣泛使用。 另一種是Proxy,還有更多開源的。 但使用 SDK 和 Proxy 的問題是支持的 SQL 語句簡單、擴展困難、依賴項多、運維復雜,所以部分業(yè)務已經(jīng)遷移到 TiDB 上。
④ 審核
四是審計。 我們在MySQL上做了一個插件,獲取所有的SQL操作,后端發(fā)送到Kafka,然后下游連接包含目標端進行SQL統(tǒng)計分析。 另外還有安全策略,包括主動探查是否存在SQL注入、是否存在數(shù)據(jù)庫拖拽情況等,并觸發(fā)相應的警報。
MySQL審計插件最大的問題是如何減少對MySQL性能的影響。 我們進行了一些測試,發(fā)現(xiàn)使用Log的性能損失很大,降低了10%到20%。
所以我們通過接口獲取MySQL插件中的監(jiān)控項,然后將監(jiān)控項放到里面,使用兩級來保證寫入數(shù)據(jù)時不會競爭鎖資源。 在這個插件中啟動另一個線程,從中讀取數(shù)據(jù)并將數(shù)據(jù)打包并寫入到 FIFO 管道中。
我們在每臺MySQL物理機中啟動另一個Agent,從管道中讀取數(shù)據(jù),并以阻塞的方式發(fā)送到Kafka。 優(yōu)化后,我們再次進行壓力測試,發(fā)現(xiàn)每臺機器上15萬次更新、刪除、插入操作都不會丟失數(shù)據(jù),性能損失一般在2%以內(nèi)。
公司內(nèi)部集群已經(jīng)上線一年了,運行比較穩(wěn)定。 線上線下對業(yè)務沒有影響。
⑤ 分層存儲
五是分層存儲。 MySQL中會存儲一些程序性數(shù)據(jù),即只需要讀寫最近一段時間存儲的數(shù)據(jù)。 一段時間后,這些數(shù)據(jù)將不再需要,需要定期清理。
分層存儲使用 MySQL 之上的其他存儲方法,例如 TiDB 或其他。 數(shù)據(jù)可以在兩者之間自動重新定位和歸檔。 同時前端采用SDK+Proxy的方式提供統(tǒng)一的訪問入口。 這樣,業(yè)務開發(fā)同學只需要將數(shù)據(jù)存儲在MySQL中,讀取時可以從后端連接的任何數(shù)據(jù)庫中讀取。 該方式目前僅用于過渡,后續(xù)會根據(jù) TiDB 的特點逐步遷移。
2、Redis在愛奇藝的使用
接下來是Redis。 Redis也采用slave方式。 由于網(wǎng)絡(luò)的復雜性,我們?yōu)椴渴鹱隽艘恍┨厥獾呐渲谩?在多個機房的情況下intellij idea 數(shù)據(jù)庫關(guān)系圖,每個機房都配置一定的數(shù)量,避免腦裂。
在備份和恢復方面,我們介紹一個我們的特殊場景。 雖然Redis是一個緩存,但是我們發(fā)現(xiàn)很多商學院的同學把它當作KVDB使用,在某些情況下可能會導致數(shù)據(jù)丟失。
所以我們做了一個Redis實時備份功能,啟動一個偽裝成Redis Slave的進程實時獲取數(shù)據(jù),然后放入后端KV存儲。 例如,如果你想恢復,你可以把數(shù)據(jù)拉出來。
我們使用Redis時最大的痛點是它對網(wǎng)絡(luò)延遲或抖動非常敏感。 如果抖動導致Redis超時,則會選擇一個新的節(jié)點,并將該節(jié)點上的數(shù)據(jù)同步到所有Slave。 在這個過程中,數(shù)據(jù)會被放置到節(jié)點中。 如果寫入的QPS很高,就會造成溢出。 如果 RDB 文件已滿時尚未復制,則重建過程將失敗。
基于這種情況,我們對Redis報警進行了自動優(yōu)化。 如果大量slave重建失敗,我們會動態(tài)調(diào)整一些參數(shù),比如暫時增加大小。 另外,我們還實現(xiàn)了Redis集群的自動擴縮容功能。
我們在做Redis開發(fā)的時候,如果是Java語言的話,我們就會使用Jedis。 使用 Jedis 訪問客戶端分片的 Redis 集群。 如果某個分片發(fā)生故障或失敗,Jedis 將重新建立與所有后端分片的連接。 如果某個分片出現(xiàn)問題,整個Redis的訪問性能和QPS都會明顯下降。 我們針對這種情況對 Jedis 進行了優(yōu)化。 如果某個分片出現(xiàn)故障,則只有該分片會被重建。
當業(yè)務訪問Redis時,我們會綁定一個讀寫域名和多個從數(shù)據(jù)庫來讀取域名。 但如果繼續(xù)下去,讀寫域名就會從舊節(jié)點解綁,然后綁定到新節(jié)點。
DNS本身有超時時間,因此如果業(yè)務程序在數(shù)據(jù)庫完成后沒有立即獲取新節(jié)點的IP,則可能仍然連接到原來的機器,導致訪問失敗。
我們的解決方案是縮短DNS的TTL,但這會給DNS服務帶來很大的壓力,所以我們在SDK上提供了Redis名稱服務RNS。 RNS 獲取集群拓撲并從中獲取拓撲變化。 如果是集群,會收到通知,客戶端可以通過RNS獲取新節(jié)點的IP地址。 我們?nèi)サ袅擞蛎?,通過IP地址訪問整個集群,阻斷了DNS超時,縮短了故障恢復時間。
SDK還具有一些功能,例如負載和故障檢測。 比如某個節(jié)點延遲很高,就會暫時被燒斷。
客戶端分片的方式會讓Redis的擴展變得非常痛苦。 如果客戶端已經(jīng)進行了一定量的分片,以后再增加就非常困難了。
Redis將在3.0版本之后提供。 由于功能有限,在愛奇藝并未得到廣泛應用。 例如不支持跨DC部署和訪問,讀寫只能在主庫上。
我們在一些業(yè)務場景中會用到Redis集群。 例如,數(shù)據(jù)庫訪問只發(fā)生在這個DC中,我們將其部署在DC內(nèi)部。
但有些商家在使用過程中還是想這么做。 如果集群出現(xiàn)故障,可以切換到其他集群。 基于這種情況,我們做了一個Proxy,通過它進行讀寫。 當寫入數(shù)據(jù)時,Proxy會做一個旁路,將新數(shù)據(jù)寫入Kafka中。 后臺啟用同步程序,然后將Kafka中的數(shù)據(jù)同步到其他集群。 然而,也有一些限制。 比如我們不做沖突檢測,所以集群的數(shù)據(jù)需要商科學生進行單元化。 線上環(huán)境Redis集群間場景跨DC同步耗時約50毫秒。
3.在愛奇藝上使用
雖然Redis提供了這種部署方式,但是也存在一些問題。 因此,當數(shù)據(jù)量較大時(經(jīng)驗是160G),不建議使用Redis,而是使用另一種存儲方式。
國內(nèi)互聯(lián)網(wǎng)公司很少使用。 最初,我們將其用作純緩存系統(tǒng)。
但事實上,它的性能還是比較強大的。 它是一個分布式高性能KV系統(tǒng),支持多種存儲引擎()。 第一種使用方式和KV存儲一樣,不支持數(shù)據(jù)持久化,也沒有數(shù)據(jù)副本。 如果某個節(jié)點發(fā)生故障,數(shù)據(jù)將會丟失;
二是支持數(shù)據(jù)持久化,使用Json寫入,并且有副本。 我們通常在線配置兩份。 如果添加新節(jié)點,則會處理數(shù)據(jù)。 愛奇藝一般采用此配置。
數(shù)據(jù)分布如下圖所示。 數(shù)據(jù)寫入時,首先在客戶端進行哈希運算。 操作完成后,key就被定位了(相當于數(shù)據(jù)庫中的某個分片)。 之后,客戶端會根據(jù)Map向相應的服務器發(fā)送信息。 客戶端的Map保存了與服務器端的映射關(guān)系。 服務器數(shù)據(jù)遷移過程中,客戶端的Map映射關(guān)系會動態(tài)更新。 因此,客戶端對服務器的操作不需要特殊處理,但過程中可能會出現(xiàn)短暫的超時,產(chǎn)生的報警對業(yè)務影響不大。
愛奇藝應用比較早,2012年開始使用,當時Redis還不存在。 集群管理是使用語言開發(fā)的,其最大的功能就是集群之間的復制。 提供多種復制方式:單向、雙向、星型、環(huán)型、鏈型等。
愛奇藝從最初的版本到目前的5.0版本一直使用1.8版本。 正在考察的6.0在過程中也遇到了很多坑。 例如,NTP時間配置錯誤會導致崩潰。 如果各個集群的外部XDCR并發(fā)度過高,會導致不穩(wěn)定和不同步。 方向改變會導致數(shù)據(jù)丟失等,我們通過運維和一些外部工具來避免這種情況。
集群是一個獨立的集群,集群之間的數(shù)據(jù)同步是通過XDCR進行的。 我們一般將其配置為雙向同步。 對于業(yè)務來說,如果寫1,不寫2,一般情況下客戶端都會寫1。 如果1有問題,我們提供Java SDK。 可以在配置中心將寫入改為2,逐漸斷開原來與1的連接,然后再與2建立新的連接。這個集群過程相對透明,對客戶端不敏感。
4、愛奇藝自研數(shù)據(jù)庫HiKV的使用
但性能非常高,并且數(shù)據(jù)可以存儲在內(nèi)存之外。 但是,如果數(shù)據(jù)量超過75%內(nèi)存閾值,性能就會下降得特別快。 在愛奇藝,我們會控制可用內(nèi)存內(nèi)的數(shù)據(jù)量,并將其用作內(nèi)存數(shù)據(jù)庫。 但它的成本非常高,所以我們后來開發(fā)了一個新的數(shù)據(jù)庫——HiKV。
開發(fā)HiKV的目的是為了將一些性能要求不那么高的應用遷移到HiKV上。 HiKV基于開源系統(tǒng),主要利用其分布式數(shù)據(jù)庫管理功能,增加了獨立的存儲引擎HiKV。
更吸引人的是,它號稱性能提升十倍,接口完全兼容,設(shè)計基本一致,可以看作是C++版本的系統(tǒng)。
性能的提升主要得益于一些新的技術(shù)框架的使用,比如C++異步框架。 主要原理是每個物理機的核心上都會有一個應用線程,每個核心都有自己獨立的內(nèi)存、網(wǎng)絡(luò)、IO資源。 核心之間沒有數(shù)據(jù)共享,但它們可以通信。 最大的好處是內(nèi)存訪問沒有鎖定,也沒有進程沖突。
當有讀或?qū)憯?shù)據(jù)到達時,會通過哈希算法來判斷請求的Key是否需要線程處理。 如果有則由本線程處理,否則轉(zhuǎn)發(fā)給對應線程。
另外還支持多副本、多數(shù)據(jù)中心、多寫多活,功能比較強大。
在愛奇藝,我們構(gòu)建了基于SSD的KV存儲引擎。 Key放在內(nèi)存中,Value放在磁盤上的文件中。 當我們讀寫文件時,只需要在內(nèi)存索引中定位,然后執(zhí)行磁盤的IO開銷來讀取數(shù)據(jù)。 與原來的基于 LSM Tree 的存儲引擎方法相比,IO 開銷較小。
所有索引數(shù)據(jù)都存儲在內(nèi)存中。 如果索引長度過長,就會限制單機可以存儲的數(shù)據(jù)量。 因此,我們開發(fā)了一個固定長度的內(nèi)存分配器,對于相對較長的鍵,使用紅色和黑色將摘要的長度縮短到20字節(jié)。 樹索引將內(nèi)存中每條記錄的索引長度限制為64字節(jié)。 需要定期處理內(nèi)存數(shù)據(jù),客戶端需要做限流、斷路器等。
HiKV目前在愛奇藝廣泛使用,目前已經(jīng)替代了30%,有效降低了存儲成本。
5、愛奇藝的數(shù)據(jù)庫運維管理
愛奇藝數(shù)據(jù)庫種類繁多,如何高效運營、維護和管理這些數(shù)據(jù)庫經(jīng)歷了不同的階段。
最初,我們通過 DBA 編寫腳本來管理它。 如果腳本有問題,我們就會打電話給DBA,這讓DBA非常忙碌。
第二階段我們考慮讓大家自己檢查問題答案,所以我們內(nèi)部搭建了一個私有云,通過Web展示數(shù)據(jù)庫運行狀態(tài),讓商學院的同學可以自己申請集群,一些簡單的操作就可以也可以通過自助平臺的實現(xiàn)解放DBA。 一些需要人工處理的大規(guī)模運維操作,往往會造成一些人為失誤、參數(shù)錯誤導致數(shù)據(jù)丟失等。
所以第三階段我們把運維操作做成了Web化,90%的操作都可以通過點擊網(wǎng)頁來進行。
第四階段讓有經(jīng)驗的DBA將自己的經(jīng)驗轉(zhuǎn)化為一些工具。 比如業(yè)務同學說MySQL-slave延遲了,DBA會通過一系列的操作來排查問題。 現(xiàn)在我們將這些操作串在一起形成一套工具。 當出現(xiàn)問題時,商科學生可以利用網(wǎng)頁上的一鍵診斷工具自行排查和處理。
此外,我們還會定期進行預警排查,針對業(yè)務集群潛在問題做出預警報告; 開發(fā)智能客服解答問題; 通過監(jiān)控數(shù)據(jù)對實例進行標簽,進行調(diào)峰填谷智能調(diào)度,提高資源利用率。 速度。
3、不同場景下數(shù)據(jù)庫選型建議
1. 實用數(shù)據(jù)庫選擇樹
最后說一下一些具體的數(shù)據(jù)庫選擇建議。 這些是DBA和業(yè)務共同通過經(jīng)驗得出的一些結(jié)論。
對于關(guān)系型數(shù)據(jù)庫的選擇,可以從數(shù)據(jù)量和可擴展性兩個維度來考慮,然后根據(jù)數(shù)據(jù)庫是否有冷備份、是否使用Toku存儲引擎、是否使用Proxy等來做出決定。
NoSQL還解釋了何時使用-slave,何時使用客戶端分片、集群、HiKV等。這個選擇樹信息可以在我們內(nèi)部的自助服務平臺上獲得。
2.一些想法
① 需求
在選擇型號時,我們首先思考需求,判斷需求是否真實。
你可以從數(shù)據(jù)量、QPS、延遲等方面考慮需求,但這些是真正的需求嗎? 這個需求可以通過其他方式消耗嗎? 例如,如果數(shù)據(jù)量較大,可以先進行數(shù)據(jù)編碼或壓縮,可以減少數(shù)據(jù)量。
不要將所有需求都推到數(shù)據(jù)庫級別,它實際上是一個隱蔽的系統(tǒng)。
② 選擇
第二點思考是我們在選擇某種數(shù)據(jù)庫系統(tǒng)或者某種技術(shù)時應該考慮什么? 是因為受歡迎嗎? 還是因為技術(shù)更先進? 但這并不能真正解決你的問題嗎? 如果你的數(shù)據(jù)量不是很大,就沒有必要選擇能夠存儲大量數(shù)據(jù)的系統(tǒng)。
③ 放棄
第三是放棄。 當你放棄一個系統(tǒng)時,真的是因為它不起作用嗎? 還是工作不順利? 放棄一些東西是很難的,但放棄時最好有充分的理由,包括實際測量的結(jié)果。
④ 自主研發(fā)
四是自主研究。 當需要開發(fā)自己的數(shù)據(jù)庫時,可以參考和使用一些成熟的產(chǎn)品,但不要盲目自研。
⑤ 開源
最后一件事是開源。 你必須有擁抱開源的態(tài)度。
選擇數(shù)據(jù)庫時您會考慮哪些因素? 歡迎留言告訴大家你的想法~
如有侵權(quán)請聯(lián)系刪除!
Copyright ? 2023 江蘇優(yōu)軟數(shù)字科技有限公司 All Rights Reserved.正版sublime text、Codejock、IntelliJ IDEA、sketch、Mestrenova、DNAstar服務提供商
13262879759
微信二維碼