短連結服務架構設計與實現
場景
整個互動流程如下:
設計要點
-
短連結生成演算法
(1)利用放號器,初始值為0,對於每一個短連結生成請求,都遞增放號器的值,再將此值轉換為62進位制(a-zA-Z0-9),比如第一次請求時放號器的值為0,對應62進製為a,第二次請求時放號器的值為1,對應62進製為b,第10001次請求時放號器的值為10000,對應62進製為sBc。
(2)將短連結伺服器域名與放號器的62進位制值進行字串連線,即為短連結的URL,比如:t.cn/sBc。
-
重定向過程
生成短連結之後,需要儲存短連結到長連結的對映關係,即sBc -> URL,瀏覽器訪問短連結伺服器時,根據URL Path取到原始的連結,然後進行302重定向。對映關係可使用K-V儲存,比如Redis或Memcache。
優化方案
-
演算法優化
採用以上演算法,對於同一個原始URL,每次生成的短連結是不同的,這樣就會浪費儲存空間,因為需要儲存多個短連結到同一個URL的對映,如果能將相同的URL對映成同一個短連結,這樣就可以節省儲存空間了。
(1)方案1:查表
每次生成短連結時,先在對映表中查詢是否已有原始URL的對映關係,如果有,則直接返回結果。很明顯,這種方式效率很低。
(2)方案2:使用LRU本地快取,空間換時間
使用固定大小的LRU快取,儲存最近N次的對映結果,這樣,如果某一個連結生成的非常頻繁,則可以在LRU快取中找到結果直接返回,這是儲存空間和效能方面的折中。
-
可伸縮和高可用
如果將短連結生成服務單機部署,缺點一是效能不足,不足以承受海量的併發訪問,二是成為系統單點,如果這臺機器宕機則整套服務不可 用,為了解決這個問題,可以將系統叢集化,進行“分片”。
在以上描述的系統架構中,如果發號器用Redis實現,則Redis是系統的瓶頸與單點,因此,利用資料庫分片的設計思想,可部署多個發號器例項,每個例項負責特定號段的發號,比如部署10臺Redis,每臺分別負責號段尾號為0-9的發號,注意此時發號器的步長則應該設定為10(例項個數)。
另外,也可將長連結與短連結對映關係的儲存進行分片,由於沒有一箇中心化的儲存位置,因此需要開發額外的服務,用於查詢短連結對應的原始連結的儲存節點,這樣才能去正確的節點上找到對映關係。