經典系統設計面試題解析:如何設計TinyURL(一)

原文鏈接:https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR

​​原文鏈接:
https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR

 

編者注:本文以一道經典的系統設計面試題:《如何設計TinyURL》的參考答案和解析爲例,幫助讀者更深入地瞭解在系統需求分析和設計中,需要考慮的各個方面的細節。

 

本文將爲大家詳細講解如何設計一個類似於TinyURL的URL縮短服務。URL縮短服務提供一個非常短小的URL以代替原來的可能較長的URL,將長的URL地址縮短。

 

類似的服務有:bit.ly,goo.gl,qlink.me,等等。

 

一、爲什麼需要URL縮短服務?

 

URL縮短服務是用來爲長URL創建簡短別名的。我們稱這些縮短的別名爲“短網址”。當用戶點擊這些短網址時,能夠重定向到原始的URL。相較於原始URL,短網址在顯示、打印、發送消息或微博時能夠節省大量空間。另外,用戶輸錯短網址的可能性也比較小。

 

舉個例子,如果我們通過TinyURL來縮短下面這個網址:

 

https://www.educative.io/collection/page/5668639101419520/5649050225344512/5668600916475904/

 

我們可以得到以下的短網址:

 

http://tinyurl.com/jlg8zpc

 

上面這個短網址的長度幾乎只有實際URL的三分之一。

 

URL縮短用於優化跨設備的鏈接,通過跟蹤單個鏈接來分析受衆和活動性能,並隱藏關聯的原始URL。

 

如果你以前沒有使用過http://tinyurl.com/這個網站,請嘗試設計並創建一個新的網址縮短系統,然後,花一些時間瀏覽它們提供的各種服務選項。這會幫助你更好地理解本章節的內容。
 

二、系統的需求和目標

 

設計的URL縮短系統應符合以下需求:

 

功能性需求:

 

1、給定一個原始URL,該系統能夠生成一個較短且唯一的短網址。這個短網址的長度應該足夠短,以便輕鬆複製和粘貼到應用程序中。

 

2、當用戶訪問一個短網址時,該系統應該將它們重定向到原始鏈接。

 

3、用戶可以爲他們的URL選擇一個自定義的短網址。

 

4、在標準的默認時間間隔後,對應的短網址過期。過期時間允許用戶設置。

 

非功能性需求:

 

1、該系統必須是高度可用的。因爲一旦我們的服務宕機,那麼所有的URL重定向都會失敗。

 

2、URL重定向應該在最小延遲的情況下實時進行。

 

3、短網址應該是不可預測

 

擴展需求:

 

1、能夠進行分析;例如,重定向發生了多少次。

 

2、其他系統可以通過REST API訪問我們的服務。

 

三、容量估計及限制

 

設計的系統將包含大量讀取操作。與新的URL縮短相比,將會有大量的重定向請求。假設讀和寫的比率爲100:1。

 

流量估計:

 

假設每個月將有5億個新的短網址產生,讀/寫比率爲100:1的話,預計在同一時期將有500億個重定向請求:

 

100 * 5 億  ≥ 500 億

 

對於我們設計的系統,每秒查詢數(QPS)又是多少呢?每秒新的短網址數:

 

5 億 / (30 天 * 24 小時 * 3600 秒 ) ≌ 200 URLs/s

 

考慮到100:1的讀/寫比例,每秒URL重定向請求數將是:

 

100 * 200 URLs/s = 20 K/s

 

存儲估計:

 

假設將每個短網址請求存儲5年,每個月將有5 億個新的短網址產生,由此可以得出,預計存儲的對象總數將達到300億個:

 

5 億 * 5 年 * 12 月 = 300 億

 

假設每個存儲對象的大小大約是500 字節(這只是一個大致的估計——我們稍後將深入研究它)。那我們需要15 TB 的總存儲:

 

300 億 * 500 字節 = 15 TB

 

帶寬估計:

 

對於寫請求,前面我們計算出,預計每秒有200個新短網址產生,由此得出,總輸入數據將爲100 KB/s:

 

200 * 500 字節 ≌ 100 KB/s

 

對於讀請求,前面我們計算出,預計每秒URL重定向請求是2 萬個,由此得出,總輸出數據爲10MB/s:

 

2 萬 * 500 字節 ≌10 MB/s

 

內存估計:

 

如果想緩存一些經常訪問的熱門URL,那需要多少內存來存儲它們呢?

 

這裏,我們遵循80-20規則,也就是說20%的URL產生80%的流量,我們想要緩存這20%的熱門URL。

 

由於每秒有2萬個重定向請求,那麼每天收到的重定向請求有17億個:

 

2 萬 * 3600 秒 * 24 小時 ≌ 17 億

 

緩存其中20%的請求所需要的內存則爲170 GB:

 

0.2 * 17 億 * 500 字節 ≌ 170GB

 

這裏需要注意一點,由於會有許多重複的請求(也就是相同的URL),因此,實際內存使用量將少於170 GB。

 

高級別估計:

 

假設每月有5億個新URL,讀/寫比例100:1,下面是對此服務的估計概要:

 

四、系統API

 

一旦確定了系統的需求,那麼定義系統API總是一個好主意。它應該明確地說明我們對系統的期望。

 

我們可以使用SOAP或REST API來公開服務的功能。以下是用於創建和刪除URL的API的定義:

 

<section style="margin-top: 10px;margin-bottom: 20px;"><code class=""><span style="font-size: 15px;">createURL(api_dev_key, original_url, custom_alias=None, user_name=None, expire_date=None)</span></code></section>

 

相關參數:

 

api_dev_key(字符串):註冊賬戶的API開發人員密鑰。除此之外,它還將用於根據分配的配額限制用戶。

 

original_url(字符串):要縮短的原始URL。

 

custom_alias(字符串):URL的可選自定義鍵。

 

user_name(字符串):可選的用戶名,用於編碼。

 

expire_date(字符串):可選過期日期的縮短URL。

 

返回:(字符串)

 

成功插入將返回短網址;否則,將返回錯誤代碼。

 

<section style="margin-top: 10px;margin-bottom: 20px;"><code class=""><span style="font-size: 15px;">deleteURL(api_dev_key, url_key)</span></code></section>

 

其中“url_key”表示的是要檢索的縮短URL的字符串。成功刪除將返回“URL Removed”。

 

那我們要如何發現和防止濫用呢?惡意用戶可以通過使用當前設計中的所有URL密鑰讓我們失去業務。爲了防止濫用,我們可以通過api_dev_key來限制用戶。每個api_dev_key可以在某個時間段內限制URL創建和重定向的數量(每個開發人員密鑰可以設置爲不同的持續時間)。

 

五、數據庫設計

 

對於我們將要存儲的數據,對其性質做一些觀察:

 

1、需要存儲數十億的記錄。

 

2、存儲的每個對象都很小(小於1K)。

 

3、除了存儲創建URL的用戶之外,記錄之間沒有任何關係。

 

4、需要大量的讀取操作。

 

數據庫架構:

 

我們需要兩個表:一個用於存儲有關URL映射的信息,另一個用於存儲創建短網址的用戶數據。

preview

 

 

那我們應該使用什麼樣的數據庫呢?因爲我們預計存儲數十億的數據,而且我們不需要使用對象之間的關係,所以像DynamoDB,Cassandra或者Riak這樣的通過key-value形式存儲的NoSQL是更好的選擇。選擇NoSQL也更容易進行擴展。

 

(未完待續)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章