微博分布式存儲作業實現方法

Lui9oFu2r 8年前發布 | 9K 次閱讀 微博 軟件架構

可能通過「高可用架構」聽說過在微博的系統中,單張 MySQL 在線業務表 60 億條數據的場景。很多關注互聯網架構的工程師也非常關注如何如何設計類似系統。下面是一道微博新兵訓練營的分布式存儲課堂練習,要設計合格才能上崗。

考慮到網上有很多架構師也在討論,補充題目一些說明如下。

1、訪問場景

由于上面題目的應用場景,用戶一般情況下,主要查看用戶查看自己收到的最新的微博,以及某個特定用戶 profile 的所有微博。

  • 收到的微博,考慮微博以拉為主的模式,則需要訪問關注用戶最近 n 條最新的微博。
  • 用戶 profile,需要訪問用戶歷史上所有發表的微博,而且支持分頁查看,可以直接跳轉到某一頁或者某個時間段, 因此需要適當考慮分頁的效率 (可參考擴展閱讀)。

訪問特征

  • 從上面描述以及社交網絡的用戶訪問特點來看,用戶大部分情況( > 90% )是訪問最近 7 天的數據。

不需要考慮的點

  • 此題主要是存儲層的設計,因此不需要考慮緩存如何設計。
  • 由于微博是 異步寫入 的,在某種程度可以起到錯峰作用,所以作業暫時不需要考慮寫入的峰值。
  • 不需要考慮 id 如何產生,假定已經有發號服務。
  • 不需要考慮用戶收到的微博怎么聚合,那個是更上層服務層的職責。

2、設計需要考慮的點

Scale-out 擴展性

  • 將數據拆分到多個獨立的單元存儲
  • 可以在適當時機進一步拆分,拆分時候需要繼續提供在線訪問
  • 存儲在廉價硬件上,考慮到數據規模比較大,需要適當考慮方案的整體成本,因此不要假定默認全部使用 SSD 存儲。

Cost 成本

  • 不同訪問級別的數據存儲在不同訪問速度(成本)的硬件上。

High availability 高可用,以及  Reliability 可靠性 – 復制

在當前場景下,主要通過 MySQL replication 來解決可用性、以及分擔讀的請求。

3、Sharding 策略

Shard 常用策略

range based:根據用戶 uid 來分布,相鄰 uid 的數據保存在一起。hash based:根據某個 hash 函數,將一個用戶 uid 的數據保存在指定的分片。

Re-Sharding 拆分設計

當數據持續增長,原先存儲的數據(或者訪問量)超過當前節點的容量上限,則需要對節點進行進一步拆分。

如何確定shard數量

db buffer > hot data

容量規劃

  • 預規劃: 容納未來一段時間的數據
  • 2 的指數倍: shard 數量變更簡單

Tradeoff

  • 分片多:影響 IO 效率;
  • 分片少:擴容頻繁、復雜

4、擴展閱讀

5、部分投稿案例

案例一:使用 user id range 作為分片

案例二:使用user id hash作為分片

方案三 (via 張亮)

歷史數據:

1. 每半年根據日期分庫,如:2015.01-2015.06為一個庫。每天增加1億數據,半年180億,約為0.72T數據,可以保留在1T的磁盤中。

2. 根據 uid 取模分庫(表),便于查詢和分散數據。

當前 n 日數據:

1. 暫定n為10,存儲10億數據。

2. 根據uid + 權重的hash算法分庫。權重可以根據每個uid的微博id數量,粉絲數等指標離線計算。

hash算法需保證:

1. 同一uid需落在一個庫。

2. 權重接近的用戶盡量均勻的落在不同庫。

3. 為了應對突然發生的事件導致訪問量激增,需要考慮2級甚至3級分片,而不宜直接做re-sharding導致數據遷移。多級分片可考慮讀取一個標記,放在zk中。根據標記確定分片的hash算法加入小時等維度。

查詢索引:

1. 增加發帖索引字段,記錄每個用戶的每個帖子的索引。

2. 增加發帖總數統計表,以用戶為維度,每個用戶發一次貼則發帖總數++。

3. 增加二級索引表,記錄每個用戶,每次分片庫的發帖索引。如:uid 1的用戶,在2015年第一帖是該用戶發帖的總數的第10貼,2015年最后一貼是該用戶發帖總數的第50貼。

4. 分頁查詢使用二級索引表,先查到該查哪個真實庫(可能是多個),再到真實庫中獲取數據。

總結:

1. 通過靈活的運用時間維度分片,免去因uid分片數量不足導致的大規模遷移,使用外部flag靈活的控制分片策略。而且用時間維度分片更易做到冷熱分離。

分片邏輯可以靈活到,zk中記錄時間段,某個時間段內,按月分,某個時間段,按年分,之類。

2. 通過離線計算權重的方式均勻分散數據訪問。權重周期性調整,對于調整權重的用戶,需要重點考慮當前n日數據的數據遷移方案。但由于調整權重的用戶屬于少量,所以遷移應該數據變動較小。歷史數據不需權重概念,無需數據遷移。

3. 查詢使用二級索引。使用修改btree結構去掉二級索引能有效減少數據量,但實現難度較大,可以在之后的局部優化中實現,對總體數據庫結構影響不大。

4. 將前n日數據和當天數據整合在一起,之前對微博的場景理解不深,以為有首屏顯示這樣的概念。

來自: http://timyang.net/architecture/feed-sharding-practice/

 本文由用戶 Lui9oFu2r 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!