原文出處:http://weibo.com/p/1001643874615465508614
作者:畢建坤@bijiankun
微博平臺研發(fā)作為微博的底層數(shù)據(jù)及業(yè)務支撐部門,已經(jīng)經(jīng)歷了5年的發(fā)展歷程。伴隨著從數(shù)據(jù)及業(yè)務暴發(fā)式增長,我們在海量數(shù)據(jù)存儲方面遭遇了諸多挑戰(zhàn),與此同時也伴隨著豐富經(jīng)驗的積累。
? ?本次新兵訓練營,受眾在于應屆畢業(yè)生,目的在于讓新同學系統(tǒng)化并且有針對性的了解平臺的核心技術及核心業(yè)務,以使新同學在新兵訓練營結束后,能夠對平臺的底層架構與業(yè)務有一定的了解。
? ?本文主要面向新同學介紹平臺的核心技術之一——海量數(shù)據(jù)存儲,主要介紹在海量數(shù)據(jù)存儲在大規(guī)模分布式系統(tǒng)下的架構變遷與設計。
課程大綱:
1. ?了解存儲服務概況,以及RDBMS及NoSQL的差異
2. ?理解MySQL、Redis、HBase基本實現(xiàn)機制、特性、適用場景
3. ?理解幾種存儲產(chǎn)品的大規(guī)模分布式服務方案
4. ?學會使用平臺的MySQL、Redis?client組件
5. ?理解對于MySQL、Redis分布式系統(tǒng)設計想要注意的問題
6. ?了解平臺幾種典型案例
7. ?理解幾種存儲產(chǎn)品在平臺的定制修改與名詞術語
1. ?關系型數(shù)據(jù)庫是基于實體關系模型(Entity-Relationship Model)的數(shù)據(jù)服務,具備以下特點。
適合存儲結構化數(shù)據(jù)
查詢語言SQL,insert delete update select
主流關系型數(shù)據(jù)庫多是持久化存儲系統(tǒng),系統(tǒng)性能與機器性能相關性較大
幾類主流的 關系型數(shù)據(jù)庫
MySQL
Oracle
DB2
性能
局限于服務器性能,與其是磁盤性能
局限于數(shù)據(jù)復雜度
? ? 大型互聯(lián)網(wǎng)服務大多采用MySQL進行作為關系型數(shù)據(jù)庫,微博平臺的核心業(yè)務(如微博內(nèi)容用戶微博列表)也同樣如此
?? ? ? ?本次培訓也會著重介紹MySQL及其分布式架構方案。
2. ?NoSQL(Not only SQL)數(shù)據(jù)庫,泛指非關系型的數(shù)據(jù)庫,興起的契機在于傳統(tǒng)關系型數(shù)據(jù)庫應對大規(guī)模、高并發(fā)的能力有限,而NoSQL的普遍性能優(yōu)勢能夠彌補關系型數(shù)據(jù)庫在這方面的不足
存儲非結構化數(shù)據(jù)、半結構化數(shù)據(jù)
? ? 業(yè)界使用的NoSQL多為內(nèi)存集中型服務,受限于I/O及網(wǎng)絡,通常請求響應時間在毫秒級別,單機QPS在10萬級別(與數(shù)據(jù)大小及存儲復雜度相關)
常見的幾類NoSQL產(chǎn)品
K-V(Memcached、Redis),這類NoSQL產(chǎn)品在互聯(lián)網(wǎng)業(yè)內(nèi)應用范圍最廣。Memcached提供具備LRU淘汰策略的K-V內(nèi)存存儲;而Redis提供支持復雜結構(List、Hash等)的內(nèi)存及持久化存儲
Column(HBase、Cassandra),HBase是基于列式存儲的分布式數(shù)據(jù)庫集群系統(tǒng)
Document(MongoDb)
? ?web2.0時代,NoSQL產(chǎn)品在互聯(lián)網(wǎng)行業(yè)中的重要性隨著互聯(lián)網(wǎng)及移動互聯(lián)網(wǎng)的發(fā)展而與日劇增?? ? ??大型互聯(lián)網(wǎng)應用,為應對大規(guī)模、高并發(fā)訪問,大多都引入了NoSQL產(chǎn)品,其中Memcached、Redis以其高成熟度、高性能、高穩(wěn)定性而被廣泛使用。微博平臺也具備千臺規(guī)模的NoSQL集群,微博核心的Feed業(yè)務、關系業(yè)務也都依賴Memcached及Redis提供高性能服務
??本次培訓,會著重介紹Redis及其分布式架構
微博平臺核心業(yè)務的數(shù)據(jù)都存儲在MySQL上,目前具備千臺規(guī)模的集群,單個核心業(yè)務數(shù)據(jù)突破千億級,單個核心業(yè)務QPS峰值可達10萬級每秒,寫入也是萬級每秒。
在海量數(shù)據(jù)并且數(shù)據(jù)量持續(xù)增長的景下,在如何設計滿足 高并發(fā)(w/r)、低延時(10ms級別)、高可用性(99.99%)的分布式MySQL系統(tǒng)方面,我們已經(jīng)具備充足的經(jīng)驗并且依然在持續(xù)攻堅這一問題,而我們的課程也會著重介紹海量數(shù)據(jù)存儲之MySQL。
1. ?MySQL簡介
MySQL是一個關系型數(shù)據(jù)庫系統(tǒng)RDBMS
使用SQL作為查詢語言
開源
存儲引擎
Innodb?支持事務、行鎖,寫入性能稍差
MyIsam?不支持事務,讀寫性能略好
滿足ACID特性
主鍵、唯一鍵、外鍵(大規(guī)模系統(tǒng)一般不用)
Transaction,事務即一系列操作,要么完全地執(zhí)行,要么完全地不執(zhí)行
服務、端口、實例,都是指 服務端啟動的一個MySQL數(shù)據(jù)庫
性能
隨著磁盤性能升高,讀寫性能也逐步升高,但成本也隨之增加
數(shù)據(jù)庫的寫入性能:寫入tps隨著并發(fā)量增加而增加,但上升到一定瓶頸,增速放緩至并發(fā)數(shù)臨界點后 tps會急劇下滑
思考:如果對性能有更高(超出上述三種存儲介質并發(fā)量級)的要求怎么辦?
定制存儲:針對服務特點,定制存儲,定制更適合自己業(yè)務場景的存儲產(chǎn)品。然而一般業(yè)界成熟產(chǎn)品為考慮通用性而會犧牲部分性能
2. ?從單機到集群的架構變遷
業(yè)務上線初期,web服務規(guī)模較小,一般具備以下特點
服務原型時期,用戶基數(shù)小,多種業(yè)務公用資源,日均寫入百萬級別,讀取千萬級別
數(shù)據(jù)規(guī)模小,單機性能能夠滿足需求
用戶規(guī)模小,開發(fā)重心偏向迭代速度
考慮到上述小型業(yè)務特點,為節(jié)約資源成本及開發(fā)成本,可以采用多個業(yè)務混合部署形式
當用戶增多,數(shù)據(jù)量、訪問量升高(2倍以下),數(shù)據(jù)庫壓力較大,怎樣在有限程度提高MySQL吞吐量呢?
SQL優(yōu)化
壓力還在有限的范圍內(nèi)增長,通過簡單、低成本優(yōu)化,可以一定成都上提高有限的服務性能
業(yè)務持續(xù)發(fā)展,讀取性能出現(xiàn)瓶頸&&各業(yè)務互相影響,多個業(yè)務出 ? ? ?現(xiàn)資源搶占,如何快速解決業(yè)務搶占問題以提高服務性能?
垂直拆分——按業(yè)務進行數(shù)據(jù)拆分
?? ? ? ?按業(yè)務進行拆分,以使業(yè)務隔離,timeline的壓力增加,不會影響content數(shù)據(jù)庫服務性能;進行拆分后,資源增加,服務性能也相應提升。
隨著業(yè)務的繼續(xù)發(fā)展,讀取性能出現(xiàn)瓶頸,讀寫互相影響,如何確保讀請求量的增加,不要影響寫入性能?相反寫入請求量增加如何確保不影響讀取性能?(寫入性能出現(xiàn)問題會造成數(shù)據(jù)丟失)
讀寫分離,寫入僅寫master,master與slave自動同步;讀取僅以slave作為來源
?? ? ? ?讀寫分離后,slave僅專注于承擔讀請求,讀取性能得到優(yōu)化;同里獨立的master服務的寫入性能也得到優(yōu)化。
一臺/一對M-S服務器性能終歸是很有限的,當單實例服務性能無法承載線上的請求量時,如何進行優(yōu)化?
升級為一主多從架構
一個master承載所有寫入請求,理論上master性能不變
多個slave分擔讀取請求,讀取性能提升n倍
隨著業(yè)務量的增長,服務出現(xiàn)如下變化:
數(shù)據(jù)量增長,意味著原本的存儲空間不足
寫入量增長,意味著master寫入性能存在瓶頸
如何優(yōu)化以解決上述問題?
水平拆分
?? ? ? ?業(yè)務經(jīng)歷數(shù)據(jù)量的增長、讀寫請求量的增長,數(shù)據(jù)庫服務已經(jīng)演進為分布式架構,一個業(yè)務的數(shù)據(jù),怎樣合理的分布到上述復雜的分布式數(shù)據(jù)庫是下一個需要解決的問題
3. ?如何基于上述演進到最后的架構進行數(shù)據(jù)庫設計呢?
分布式數(shù)據(jù)庫設計
hash拆分方式,既按hash規(guī)則,將數(shù)據(jù)讀寫請求分散到多個實例上,見上述水平拆分示意圖
時間拆分方式,基于確定好的時間劃分規(guī)則,將數(shù)據(jù)按時間段分散存儲再多個實例中
數(shù)據(jù)分布到一個分布式數(shù)據(jù)庫內(nèi),一個實例存儲1/n的數(shù)據(jù),一個實例只需要一個數(shù)據(jù)庫就能夠滿足功能需求。
經(jīng)歷幾年的發(fā)展,數(shù)據(jù)規(guī)模會成倍增長,當需要再次水平擴容(4太→8臺),需要通過程序,將數(shù)據(jù)一分為二,數(shù)據(jù)遷移成本較高,需要開發(fā)人員介入。
如果在數(shù)據(jù)庫設計時,一個就預先建好2個數(shù)據(jù)庫 ,每個數(shù)據(jù)庫存儲1/n/2的數(shù)據(jù),需要水平擴容時,即可完整遷移一個數(shù)據(jù)庫,而無需開發(fā)人員干預。
在一個數(shù)據(jù)庫實例上,建立的多個數(shù)據(jù)庫,稱為邏輯庫。
邏輯庫設計
邏輯庫是相對與物理庫而言的概念:物理庫只數(shù)據(jù)庫服務的實例;邏輯庫指在一個數(shù)據(jù)庫實例上創(chuàng)建的多個database
定義邏輯庫的目的是便于擴容。假如4臺數(shù)據(jù)庫服務器,每臺上的物理庫包含8個邏輯庫,當系統(tǒng)出現(xiàn)容量、寫入量瓶頸時,可以新增一倍即4臺服務器,直接以同步方式同步數(shù)據(jù)庫,而不需要單獨編寫應用程序利用進行導入
4. ?基于上述分布式數(shù)據(jù)庫下的表拆分設計方式
hash拆分方式:按hash規(guī)則將一個數(shù)據(jù)庫的數(shù)據(jù),分散hash到多張表中
適合數(shù)據(jù)規(guī)模有限的數(shù)據(jù)集
結合數(shù)據(jù)庫的hash模型如圖:
按時間拆分方式,按時間規(guī)則將同一時段的數(shù)據(jù)存儲在一張表,多個時段時間存儲在多張表。例如按月劃分,每個月表存儲一個月的數(shù)據(jù),如果需要獲取全部數(shù)據(jù)需要跨越多個月表
適合存儲增速較快的數(shù)據(jù)集
結合數(shù)據(jù)庫的hash模型如圖:
思考一個問題:如何能夠快速定位,一個人的第1000條到1100條數(shù)據(jù)呢?
二級索引快速定位(一級)索引位置
描述數(shù)據(jù)在以及索引中的分布狀況
用于快速定位/縮小查詢范圍
一般情況字段列表:uid, date_time, min_id, count
?? 5. ?當一臺服務器宕機怎么辦?
Slave(一主多從)宕機?
剩余健康Slave無風險,則無需緊急操作,例行修復
切換流量到容災機房(如果具備容災機房)
緊急擴容[優(yōu)先]、重啟、替換
Master宕機?
由于master數(shù)據(jù)的唯一性,致使master出現(xiàn)異常會直接造成數(shù)據(jù)寫入失敗
快速下線master
下線一臺salve的讀服務(如果slave性能有風險,則同時快速擴容)
提升slave為master
?? 6. ?如此復雜的分布式數(shù)據(jù)庫+數(shù)據(jù)庫拆分+數(shù)據(jù)表拆分,client端如何便捷操作呢?
??多數(shù)使用分布式數(shù)據(jù)庫服務的團隊,都有各自實現(xiàn)的數(shù)據(jù)庫Client組件,微博平臺采用如下幾個層級的組建來進行分布式數(shù)據(jù)庫操作
? ?
7. ?注意事項
MySQL設計應該注意的問題
表字符集選擇UTF8
存儲引擎使用InnoDB
使用Varchar/Varbinary存儲變長字符串
不在數(shù)據(jù)庫中存儲圖片、文件等
每張表數(shù)據(jù)量控制在20000W以下
MySQL查詢應該遇到的問題
避免使用存儲過程、觸發(fā)器、函數(shù)等
讓數(shù)據(jù)庫做最擅長的事
避免使用大表的JOIN
MySQL最擅長的是單表的主鍵/索引查詢
避免在數(shù)據(jù)庫中進行數(shù)學運算
MySQL不擅長數(shù)學運算
減少與數(shù)據(jù)庫的交互次數(shù)
select條件查詢要利用索引
?? 8. ?MySQL練習題
設計一個每秒2000qps,1億條數(shù)據(jù)的用戶基本信息存儲數(shù)據(jù)庫。完成數(shù)據(jù)庫設計,數(shù)據(jù)庫搭建,web寫入查詢服務搭建。
定義用戶信息結構:uid,name,age,gender
給定2個mysql實例,每個實例創(chuàng)建2個數(shù)據(jù)庫
每個數(shù)據(jù)庫創(chuàng)建2長表
??微博作為web2.0時代具備代表性的SNS服務,具備龐大的用戶群體和億級的活躍用戶,同時也承擔著高并發(fā)、低延遲的服務性能壓力。
??Redis作為NoSQL系列的一個典型應用,以其高成熟度、高可用性、高性能而被用來解決web2.0時代關系型數(shù)據(jù)庫性能瓶頸問題。例如微博的計數(shù)服務的請求量以達到百萬級/s,數(shù)以百計的關系型數(shù)據(jù)庫才能應對如此高的QPS,而且請求耗時較高且波動較大;然而使用Redis這種NoSQL產(chǎn)品,僅僅需要10臺級別的集群即可應對,平均請求耗時5ms以下。
??這一章節(jié),為大家介紹Redis以及其大規(guī)模集群架構。
1. ?Redis簡介
Redis是一個支持內(nèi)存存儲及持久化存儲的K-V存儲系統(tǒng)
支持復雜數(shù)據(jù)結構,相比與Memcached僅支持簡單的key-value存儲,Redis原生支持幾類常用的存儲結構,例如
hash:存儲哈希結構數(shù)據(jù)
單線程
高性能,避免過多考慮并發(fā)、鎖、上下文切換
數(shù)據(jù)一致性好,例如對一個計數(shù)的并發(fā)操作,不會有‘讀者寫者’問題
單線程無法利用多核,單可以通過啟動多個實例方式,充分利用多核
原生支持Master-Slave
過期機制
被動過期——client訪問key時,判斷過期時間選擇是否過期
主動過期——默認使用valatile-lru
volatile-lru:從已設置過期時間的數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰
volatile-ttl:從已設置過期時間的數(shù)據(jù)集中挑選將要過期的數(shù)據(jù)淘汰
volatile-random:從已設置過期時間的數(shù)據(jù)集中任意選擇數(shù)據(jù)淘汰
allkeys-lru:從全部數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰
Redis的字典表結構
Key字典表hash table結構,有hash結構就意味著需要按需進行rehash,rehash的時間段內(nèi),對內(nèi)存是有成倍開銷的
Value結構,存儲Key對應的value
Expire表結構,存儲key的過期時間
額外開銷60B+
持久化方式
AOF
與MC的差異
平臺的定制CounterService
修改hash table為,增量擴展式的hash tables,例如每1億個key存儲在一個table中,數(shù)據(jù)超過1億(或者一個臨界比例)則開辟下一個1億空間的table
2. ?Redis的主要數(shù)據(jù)結構
String (key-value)
Hash (key-field-value)
List(key-values)
Set(key-members)
3. ?Redis的分布式部署方案是怎樣的?與MySQL有什么異同
Reids由于其M-S特性與MySQL類似,因此分布式部署方案同MySQL相當
單實例——小型業(yè)務 or 業(yè)務初期
主從——HA、讀寫分離
一主多從——讀取性能出現(xiàn)瓶頸
數(shù)據(jù)水平拆分——容量不足|寫入性能瓶頸
常用的分布式部署方案
?? 4. ?分布式Redis架構如何實現(xiàn)高可用(HA)?
采用M-S高可用方案,原因也式由于其Master-Slave的特性
5. ?基本容量規(guī)劃
空間=key數(shù)量*單條占用(K-V占用+額外空間) 用戶空間=5億用戶*200B(平均)=100G 微博計數(shù)器=(500億+預期2年新增300億)*10B=800G
6. ?CounterService
????微博具備龐大的數(shù)據(jù)基數(shù),因此所需要存儲的數(shù)據(jù)量級也極其龐大
??例如微博計數(shù)器,具有百億條紀錄,全部存儲在Redis中,需要T級別的空間,成本過高
因此我們對Redis進行定制化改造,以使其適合多數(shù)數(shù)據(jù)小,大小有固定限制的數(shù)據(jù)
優(yōu)化存儲空間
采用分段哈希桶的形式,進行存儲,避免rehash (分段存儲要求key為遞增序)
空間占用優(yōu)化效果
key:8B
7. ?如何支持上述分布式架構下的client訪問?(redis3.0+支持Redis Cluster)
Reids具有多個開源的client支持,我們所使用的是Jedis
Jedis除了提供client外,還提供了操作封裝以及M-S組件
我們所使用的Redis系列組件如下:
?? 8. ?Redis練習題
使用Redis,實現(xiàn)用戶受到的贊列表及贊計數(shù)功能
使用測試環(huán)境,啟動兩個Redis實例
使用Redis存儲用戶受到的贊列表[{uid, time}..]及贊計數(shù)uid-count
1. ?Memcache當容量到達瓶頸會 截取LRU鏈以釋放空間。上文介紹過Redis的key過期機制,思考以下幾個問題:
Redis滿了會發(fā)生什么?如何避免發(fā)生上述問題呢?
2. ?MySQL與Redis各自適合什么樣的場景?
數(shù)據(jù)冷熱?
數(shù)據(jù)大???
數(shù)據(jù)量級?
數(shù)據(jù)增長速度?
是否持久化?
訪問量(read/write)?
請求性能要求?
新兵訓練營簡介
微博平臺新兵訓練營活動是微博平臺內(nèi)部組織的針對新入職同學的團隊融入培訓課程,目標是團隊融入,包括人的融入,氛圍融入,技術融入。當前已經(jīng)進行4期活動,很多學員迅速成長為平臺技術骨干。
微博平臺是非常注重團隊成員融入與成長的團隊,在這里有人幫你融入,有人和你一起成長,也歡迎小伙伴們加入微博平臺,歡迎私信咨詢。
講師簡介
畢建坤,@bijiankun?微博平臺及大數(shù)據(jù)部——平臺研發(fā)系統(tǒng)研發(fā)工程師,2012年7月畢業(yè)于哈爾濱理工大學,校招入職微博工作至今,先后負責微博Feed、贊、評論等底層服務研發(fā)以及方案評審等工作。聚焦大規(guī)模系統(tǒng)的架構設計與優(yōu)化,以及大規(guī)模系統(tǒng)下的服務穩(wěn)定性保障。新兵訓練營第一期學員。
更多建議: