系统设计面试题思路综述
在正式介紹基礎知識之前,我先羅列幾個常見的系統設計相關的筆試面試題。
(1) 要求設計一個DNS的Cache結構,要求能夠滿足每秒5000以上的查詢,滿足IP數據的快速插入,查詢的速度要快。(題目還給出了一系列的數據,比如:站點數總共為5000萬,IP地址有1000萬,等等)
(2) 有N臺機器,M個文件,文件可以以任意方式存放到任意機器上,文件可任意分割成若干塊。假設這N臺機器的宕機率小于1/3,想在宕機時可以從其他未宕機的機器中完整導出這M個文件,求最好的存放與分割策略。
(3) 假設有三十臺服務器,每個上面都存有上百億條數據(有可能重復),如何找出這三十臺機器中,根據某關鍵字,重復出現次數最多的前100條?要求用Hadoop來做。
(4) 設計一個系統,要求寫速度盡可能高,說明設計原理。
(5) 設計一個高并發系統,說明架構和關鍵技術要點。
(6) 有25T的log(query->queryinfo),log在不段的增長,設計一個方案,給出一個query能快速反回queryinfo
以上所有問題中凡是不涉及高并發的,基本可以采用google的三個技術解決,分別為:GFS,MapReduce,Bigtable,這三個技術被稱為“google三駕馬車”,google只公開了論文而未開源代碼,開源界對此非常有興趣,仿照這三篇論文實現了一系列軟件,如:Hadoop、HBase、HDFS、Cassandra等。
在google這些技術還未出現之前,企業界在設計大規模分布式系統時,采用的架構往往是database+sharding+cache,現在很多公司(比如taobao,weibo.com)仍采用這種架構。在這種架構中,仍有很多問題值得去探討。如采用什么數據庫,是SQL界的MySQL還是NoSQL界的Redis/TFS,兩者有何優劣? 采用什么方式sharding(數據分片),是水平分片還是垂直分片?據網上資料顯示,weibo.com和taobao圖片存儲中曾采用的架構是Redis/MySQL/TFS+sharding+cache,該架構解釋如下:前端cache是為了提高響應速度,后端數據庫則用于數據永久存儲,防止數據丟失,而sharding是為了在多臺機器間分攤負載。最前端由大塊大塊的cache組成,要保證至少99%(該數據在weibo.com架構中的是自己猜的,而taobao圖片存儲模塊是真實的)的訪問數據落在cache中,這樣可以保證用戶訪問速度,減少后端數據庫的壓力,此外,為了保證前端cache中數據與后端數據庫中數據一致,需要有一個中間件異步更新(為啥異步?理由簡單:同步代價太高。異步有缺定,如何彌補?)數據,這個有些人可能比較清楚,新浪有個開源軟件叫memcachedb(整合了Berkeley DB和Memcached),正是完成此功能。另外,為了分攤負載壓力和海量數據,會將用戶微博信息經過片后存放到不同節點上(稱為“sharding”)。
這種架構優點非常明顯:簡單,在數據量和用戶量較小的時候完全可以勝任。但缺定早晚一天暴露出來,即:擴展性和容錯性太差,維護成本非常高,尤其是數據量和用戶量暴增之后,系統不能通過簡單的增加機器解決該問題。
于是乎,新的架構便出現了。主要還是google的那一套東西,下面分別說一下:
GFS是一個可擴展的分布式文件系統,用于大型的、分布式的、對大量數據進行訪問的應用。它運行于廉價的普通硬件上,提供容錯功能。現在開源界有HDFS(Hadoop Distributed File System),該文件系統雖然彌補了數據庫+sharding的很多缺點,但自身仍存在一些問題,比如:由于采用master/slave架構,因而存在單點故障問題;元數據信息全部存放在master端的內存中,因而不適合存儲小文件,或者說如果存儲的大量小文件,那么存儲的總數據量不會太大。
MapReduce是針對分布式并行計算的一套編程模型。他最大的優點是:編程接口簡單,自動備份(數據默認情況下會自動備三份),自動容錯和隱藏跨機器間的通信。在Hadoop中,MapReduce作為分布計算框架,而HDFS作為底層的分布式存儲系統,但MapReduce不是與HDFS耦合在一起的,你完全可以使用自己的分布式文件系統替換掉HDFS。當前MapReduce有很多開源實現,如Java實現Hadoop MapReduce,C++實現Sector/sphere等,甚至有些數據庫廠商將MapReduce集成到數據庫中了。
BigTable俗稱“大表”,是用來存儲結構化數據的,個人覺得,BigTable在開源界最火爆,其開源實現最多,包括:HBase,Cassandra,levelDB等,使用也非常廣泛。
除了google的這三家馬車,還有其他一些技術:
Dynamo:亞馬遜的key-value模式的存儲平臺,可用性和擴展性都很好,采用DHT(Distributed Hash Table)對數據分片,解決單點故障問題,在Cassandra中,也借鑒了該技術,在BT和電驢的中,也采用了類似算法。
虛擬節點技術:該技術常用于分布式數據分片中。具體應用場景是:有一大坨數據(maybe TB級或者PB級),我們需按照某個字段(key)分片存儲到幾十(或者更多)臺機器上,同時想盡量負載均衡且容易擴展。傳統的做法是:Hash(key) mod N,這種方法最大缺點是不容易擴展,即:增加或者減少機器均會導致數據全部重分布,代價忒大。于是乎,新技術誕生了,其中一種是上面提到的DHT,現在已經被很多大型系統采用,還有一種是對“Hash(key) mod N”的改進:假設我們要將數據分不到20臺機器上,傳統做法是hash(key) mod 20,而改進后,N取值要遠大于20,比如是20000000,然后我們采用額外一張表記錄每個節點存儲的key的模值,比如:
node1:0~1000000
node2:1000001~2000000
。。。。。。
這樣,當添加一個新的節點時,只需將每個節點上部分數據移動給新節點,同時修改一下這個表即可。
Thrift:Thrift是一個跨語言的RPC框架,分別解釋一下“RPC”和“跨語言”,RPC是遠程過程調用,其使用方式與調用一個普通函數一樣,但執行體發生在遠程機器上。跨語言是指不同語言之間進行通信,比如c/s架構中,server端采用C++編寫,client端采用PHP編寫,怎樣讓兩者之間通信,thrift是一種很好的方式。
文章最前面的幾道題均可以映射到以上幾個系統中的某個模塊中,如:
(1) 關于高并發系統設計。主要有以下幾個關鍵技術點:緩存,索引,數據分片,鎖粒度盡可能小。
(2) 問題2涉及到現在通用的分布式文件系統的副本存放策略。一般是將大文件切分成小的block(如64MB)后,以block為單位存放三份到不同的節點上,這三份數據的位置需根據網絡拓撲結構配置,一般而言,如果不考慮跨數據中心,可以這樣存放:兩個副本存放在同一個機架的不同節點上,而另外一個副本存放在另一個機架上,這樣從效率和可靠性上,都是最優的(這個google公布的文檔中有專門的證明,有興趣的可參閱一下。)。如果考慮跨數據中心,可將兩份存在一個數據中心的不同機架上,另一份放到另一個數據中心。
(3)問題4涉及到BigTable的模型。主要思想是將隨機寫轉化為順序寫,進而大大提高寫速度。具體是:由于磁盤物理結構的獨特設計,其并發的隨機寫(主要是因為磁盤尋道時間長)非常慢,考慮到這一點,在BigTable模型中,首先會將并發寫的大批數據放到一個內存表(稱為“memtable”)中,當該表大到一定程度后,會順序寫到一個磁盤表(稱為“SSTable”)中,這種寫是順序寫,效率極高。說到這,可能有讀者問,隨機讀可不可以這樣優化?答案是:看情況。通常而言,如果讀并發度不高,則不可以這么做,因為如果將多個讀重新排列組合后再執行,系統的響應時間太慢,用戶可能接受不了,而如果讀并發度極高,也許可以采用類似機制。
本文暫時寫到這,讀者如果有不清楚的地方,歡迎聯系我,與我探討。
原創文章,轉載請注明:?轉載自董的博客
本文鏈接地址:?http://dongxicheng.org/search-engine/system-designing-in-finging-jobs/
總結
以上是生活随笔為你收集整理的系统设计面试题思路综述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 算法之图搜索算法(一)
- 下一篇: 数据结构之位图