系統設計總結


如何處理一個系統面試題---基本套路:

4S分析法:Scenario場景、Service、Storage、Scale:

  • 程序 = 算法 + 數據結構
  • 系統 = 服務 + 數據存儲

核心思想:trade-off分析,用這種設計有什么不好,有什么好

三大步驟

  1. 向面試官提問:分析功能/需求/QPS/存儲容量
  2. 畫圖:根據分析結果設計可行方案:Service + Storage
  3. 優化:研究可能遇到的問題,怎么樣scale
  • 過程
    • Scenario 場景

      • 和面試官討論

      • 搞清楚需要設計哪些功能

      • 並分析出所設計的系統大概所需要支持的 Concurrent Users / QPS / Memory / Storage 等

    • Service 服務

      • 合並需要設計功能,相似的功能整合為一個Service
    • Storage 存儲

      • 對每個 Service 選擇合適的存儲結構

      • 細化數據表單

      • 畫圖展示數據存儲和讀取的流程

    • 得到一個 Work Solution 而不是 Perfect Solution

    • 這個Work Solution 可以存在很多待解決的缺陷


1.Scenario : 描述使用場景,約束和假設

  1. 問清楚自己要做哪些功能
  2. 問清楚或者說清楚自己要handle多大用戶量,面試官起碼得給你確認這么幾個信息,否則聊不下去。
    • 一個是你平均每天handle多少用戶
    • 一個是你峰值(最多?不太精確但是形容一下)每天handle多少用戶
  3. 自己把自己要算的東西都算出來:
    • QPS存儲size,不非得一口氣全部算完,但是記住最基本的用戶量,然后再說然后的。

分析出QPS的作用:

• QPS = 100
• 用你的筆記本做 Web 服務器就好了
• QPS = 1k
• 用一台好點的 Web 服務器就差不多了
• 需要考慮 Single Point Failure
• QPS = 1m
• 需要建設一個1000台 Web 服務器的集群
• 需要考慮如何 Maintainance(某一台掛了怎么辦)
• QPS和 Web Server (服務器) / Database (數據庫) 之間的關系
• 一台 Web Server 約承受量是 1k 的 QPS (考慮到邏輯處理時間以及數據庫查詢的瓶頸)
• 一台 SQL Database 約承受量是 1k 的 QPS(如果 JOIN 和 INDEX query比較多的話,這個值會更小)
• 一台 NoSQL Database (Cassandra) 約承受量是 10k 的 QPS
• 一台 NoSQL Database (Memcached) 約承受量是 1M 的 QPS

2.創建設計概要

使用所有重要的組件來描繪出一個概要設計。搭架子,我的系統要干嘛,為了做這件事情,我們需要什么組件,怎么安排。這里一切最簡單,保證這個東西可以work,不要有明顯的優化還不做。

這里可以說出要設計哪些服務Service,比如設計一個音樂播放系統,則需要這幾個服務:

  • User Service
  • Channel Service
  • Music Service

3.設計核心組件:Service、Storage服務和存儲

  • 將大系統划分為小服務
  • 為每個服務選擇合適的存儲結構,以及設計數據庫的表結構

4.Scale度量你的設計

確認和處理瓶頸以及一些限制。舉例來說就是你需要下面的這些來完成拓展性的議題嗎?

  • 負載均衡
  • 水平擴展
  • 緩存
  • 數據庫分片

題目1: 設計一個用戶系統,實現功能包括注冊、登陸、用戶信息查詢、好友關系存儲:

  1. 詢問需求、場景:估算QPS

  2. 設計可行解:有哪些Service 和Storage,數據流流向是怎樣?

    • (1) AuthService : 負責登錄注冊

      • 用戶是如何實現登陸和保持登陸的?
        會話表Session,將session_key作為cookie返回給瀏覽器 => 瀏覽器保存cookie => 之后用戶每次向服務器發送訪問,都會自動帶上cookie => 此時服務器會檢測到請求中的cookie中的session_key,得到這個用戶信息.
        數據庫中存有一個Session_Table

      • Cache-Aside和Cache-Through:

        • Memcached 是一個 Cache-aside 型的 Database

        服務器分別與 DB 和 Cache 進行溝通 DB 和 Cache之間不直接溝通 業界典型代表:Memcached + MySQL

        • Redis 是讀寫操作都很快的 Cache-through 型 Database

        服務器只和 Cache 溝通 Cache 負責 DB 去溝通,把數據持久化 業界典型代表:Redis(可以理解為 Redis 里包含了一個 Cache 和一個 DB)

    • (2) UserService : 負責用戶信息存儲與查詢

    • (3) FriendshipService: 負責好友關系存儲

      • 怎么存?SQL vs NOSQL

      SQL一條數據以row為單位;
      NOSQL的column是動態的,可以無限大,可以隨意添加;一條數據以grid為單位, row_key + column_key + value = 一條數據

      • 以Cassandra為例剖析典型的NoSQL數據結構
  3. 優化

    • how to scale?
      • 單點失效:數據庫sharding和replication
        • sharding:
        • 縱向切分:直接不同的表存在不同的機器上
        • 橫向切分:粗暴的方法直接按照user_id % 10 進行拆分;好的方法:一致性Hash算法

題目2: 設計一個TinyURL

  1. 詢問需求、場景:估算QPS (一天有24 * 60 * 60 = 86400秒)
    • 詢問面試官日活躍用戶,假設100m
    • 推算寫一條TinyRUL的QPS:
      • 假設每個用戶每天發0.1條帶tinyUrl的微博,則100M * 0.1 / 86400 ~ 10M / 100k ~ 約等於100
      • 峰值Peak QPS: 100 * 2 ~ 200 (假設峰值大概是平時的2倍)
    • 推算讀一條TinyURL的QPS:
      • 假設每個用戶每天點擊1條帶tinyUrl的微博,則100M * 1 / 86400 ~ 1k
      • 峰值Peak QPS: 2k (假設峰值大概是平時的2倍)
    • 推算每天產生的TinyURL所占的存儲:
      • 100M * 0.1 ~ 10M條,每條url長度100算,一共1G

可以看出來這題流量並不是很大,所以不需要考慮很多的高性能,只要設計出可行解,主要是說明出Service,是怎么存的,怎么取的.

  1. 設計可行解:有哪些Service 和Storage,數據流流向是怎樣?

    • (1) UrlService:

      • UrlService.encode(long_url)
      • UrlService.decode(short_url)
      • 訪問端口設計:首先將長網址encode為短網址,然后用戶輸入這個短網址,瀏覽器會重定向才到decode后的真正的url
    • (2) Storage數據存取:

      • SQL vs NoSQL

      • 是否需要支持 Transaction?——不需要。NoSQL +1
      • 是否需要豐富的 SQL Query?——不需要。NoSQL +1
      • 是否想偷懶?——Tiny URL 需要寫的代碼並不復雜。NoSQL+1
      • 對QPS的要求有多高?—— 經計算,2k QPS並不高,而且2k讀可以用Cache,寫很少。SQL +1
      • 對Scalability的要求有多高?—— 存儲和QPS要求都不高,單機都可以搞定。SQL+1
      • 是否需要Sequential ID?—— 取決於你的算法是什么

    • (3) long2short hash算法:

      • 算法1: 進制轉換:Base62,根據數據庫的自增id來, 將這個整數id轉化成6位的62進制的數(0-9, a-z, A-Z)
      • 算法2: 隨機生成: 隨機生成一個6位的shortURL,在數據庫查一遍,如果沒用過,則使用;
  2. 優化:
    (1)緩存memchache:
    (2) sharding

  3. 知識點:

    一致性Hash算法

    • 在橫向擴展時,減少數據的移動

    • 原理:

      • 一個簡單的一致性Hash算法:

      • 將 key 模一個很大的數,比如 360
      • 將 360 分配給 n 台機器,每個機器負責一段區間
      • 區間分配信息記錄為一張表存在 Web Server 上
      • 新加一台機器的時候,在表中選擇一個位置插入,勻走相鄰兩台機器的一部分數據

      • Consistent Hashing —— 更實用的方法 : 
        思想:就是將機器看成1000個虛擬節點,利用key的hash值找key在的機器
        具體算法:

        • 將整個 Hash 區間看做環
        • 這個環的大小從 0~359 變為 0~2 64 -1
        • 將機器和數據都看做環上的點
        • 引入 Micro shards / Virtual nodes 的概念 \

        • 一台實體機器對應 1000 個虛擬點 Micro shards / Virtual nodes

        • 每個 virtual node 對應 Hash 環上的一個點
        • 每新加入一台機器,就在環上隨機撒 1000 個點作為 virtual nodes
        • 需要計算某個 key 所在服務器時 \

        • • 計算該key的hash值——得到0~2 64 -1的一個數,對應環上一個點
          • 順時針找到第一個virtual node
          • 該virtual node 所在機器就是該key所在的數據庫服務器 \

        • 新加入一台機器做數據遷移時 \

        • • 1000 個 virtual nodes 各自向順時針的一個 virtual node 要數據

    數據庫備份 -- Replica 數據備份

    • Replica
      • 是實時的, 在數據寫入的時候,就會以復制品的形式存為多份
      • 當數據丟失的時候,可以馬上通過其他的復制品恢復
      • Replica 用作在線的數據服務,分攤讀

    • MySQL Replica

    Master-Slave模式:Master 負責寫,Slave負責讀


題目3: 設計一個推特

  1. 詢問需求、場景:

    • (1) 估算QPS

      • 日活用戶:150M,每個用戶每天平均請求次數:60,則QPS = 150M * 60 / 86400 ~ 100k
      • 峰值Peak = 100k * 3 ~ 300k
      • 讀頻率:300k
      • 寫頻率:5k
    • (2) 設計功能

      • Post / Share a tweet
      • Timeline / News Feed
      • Follow / Unfollow a user
      • Register / Login
      • User Profile Display / Edit
  2. 設計可行解:有哪些Service 和Storage,數據流流向是怎樣?將大系統拆分為小服務

    • (1) Service

      • User Service
      • Tweet Service
      • Media Service
      • Friendship Service
    • (2) Storage

      • Pull Model: 獲得每個關注對象發的推特,然后在內存中merge
        復雜度:O(N) N為關注的好友,為N次DB Reads時間

        • 缺點:查詢O(N)哥個關注對象的過程是阻塞的,會非常慢
      • Push Model: 為每個用戶見一個news feed list,用戶發一個帖子時,將帖子推送到關注該用戶的news feed list中;關鍵詞: Fanout;所以那個用戶get的時候直接從news feed list中取就行了,不用再查數據庫了;

        • 優點:可以將Post tweet到news feed list中的過程變為異步的:不再用戶發帖的過程中執行,無需用戶等待;

        • 缺點:不及時,fanout執行可能帶來延遲,

        • 數據表設計:News Feed Table

        id、owner_id、tweet_id、created_time
        
        • push模型系統結構圖:

        push模型

  3. 優化

    • (1)加Cache:最慢的部分發生在用戶讀請求時(需要耗費用戶等待時間),在 DB 訪問之前加入Cache :Cache 每個用戶的 Timeline


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM