1. 如何設計一個短鏈接系統


接下啦, 打算研究一下短鏈接

1. 如何設計短鏈接系統

2. 短鏈接系統的盈利模式

3. 設計方案

 

今天開始第一部分: 如何設計短鏈接系統


1. 短鏈接有什么好處?

  a. 微博推文, 每次限制只能有140個字,如果連接字符很多, 那么可編輯的文字就少了

  b. 公司推廣短信, 本來一條短信就可以搞定, 但是由於短信連接過長, 導致要發兩條甚至3條. 假設1條短信1分錢, 3條就是3分錢, 假設有一百萬用戶, 發300萬條短信,就是30000塊錢, 你可以節省2w塊. 

2. 短鏈接跳轉的基本原理

  客戶端-->發出短鏈接請求--> 302跳轉到--->長連接

  這里說一下status code. 301和302的區別

    • 301: 代表永久重定向. 也就是第一次拿到請求重定向以后, 下次瀏覽器再次請求短鏈接的時候, 不會真正的請求短鏈接服務器, 而是從瀏覽器本地的緩存拿到長鏈接.  這樣一來, 通過瀏覽器本地緩存可以減少服務器的壓力, 但是也會帶來新的問題, 我們如果想要統計這個入口鏈接可以帶來多少的連接量. 使用301返回, 在server層就無法統計訪問量. 所以一般不使用301
    • 302: 代表臨時重定向, 每次斷連請求都會請求鍛煉服務器, 除非在響應頭標識了cache control expire ,這樣瀏覽器才會緩存, 這樣便於server統計點擊數.雖然使用302給短鏈服務器增加一些壓力, 但是數據異常重要的今天, 這點資源還是值得的. 所以,推薦使用302

3. 短鏈接生成的幾種方案

 比如這個短鏈接: http://n0i.cn/4dK5h

它是由域名http://n0i.cn/ 加上一串火星字符4dK5h構成

域名是固定的

火星字符是如何構成的呢?

我們可以使用hash生成, 可以是MD5, SHA. 這里, 我們不關心加密解密的難度. 我們更關心的是

1. 運算速度

2. 沖突概率

這里推薦google的hash算法, marmurhash. marmurhash算法是非加密hash函數. 適用於一般的hash檢索操作. 與其他流行的hash函數相比, 對於規律性較強的key, marmurhash的隨機分布特征表現更好. 非加密表示marmurhash比md5, sha這樣的函數有更高的性能. 

 

hash沖突了怎么辦?

雖然marmurhash發生沖突的概率很低, 但還是要考慮, 一旦發生沖突, 怎么辦?如何規避調.

短鏈接和長連接有一個對應關系, 保存這種對應關系有很多方案. 可以放在redis或者mysql. 如果放在mysql,我們的表結構應該是這樣的.

id 自增id
surl 短鏈接url
lurl 長鏈接url
gmt_create 時間

 


 

 

 

 

1. 長鏈接經過marmurhash算法, 得到短鏈接

2. 我們根據短鏈接去db中查詢,是否存在這樣的記錄

3. 如果不存在, 就進行存儲, 如果存在,說明已經有相關的記錄了. 取出長串, 在加上一個固定的字符串,比如bywind. 進行marmurhash, 獲得短鏈接地址

marmurhash(lurl + bywind) 

4. 在對整個字符串進行第一步的操作. 如果這個字符串還是重復, 那就在拼接一個字符串. 

5. 我們在最終獲取長連接的時候, 把追加的字符串移除, 就得到原本的長連接了

 以上操作, 一個操作需要兩次查詢, 如果出現高並發的情況, 是很容易產生性能瓶頸的. 如何優化呢?

1. 給短鏈接surl增加一個唯一性索引. 當長鏈接經過marmurhash得到短鏈接以后, 我們拿到長鏈接的映射, 去db里做檢索, 如果沒有找到就插入, 如果找到了, 就說明違反了唯一性索引. 這是在增加一個bywind字符串, 再次進行marmurhash處理, 然后保存到db.

增加唯一索引, 看上去效率有些低, 但marmurhash發生重復的概率是很低的 所以這種情況是可以接受的.

 

如果在高並發的情況下, 我們可以使用布隆過濾器來進行優化

 

 長連接經過hash生成短鏈接, 然后在布隆過濾器中校驗, 如果不存在,則保存到數據庫, 如果存在, 加上bywind常量字符串, 再次校驗. 直到不存在, 保存到數據庫.

 

2. 使用自增序列的方式生成短鏈接 -- mysql自增主鍵

優點: 簡單, 擴展方便

問題: 在高並發情況下, DB的寫壓力會過大, 這個時候怎么辦呢? 如何優化?

這個時候, 我們可以設置一個專門的發號表. 每插入一條記錄為短鏈id預留(主鍵id+1000-999)  到 (主鍵id*1000)的號段.

當長鏈接轉短鏈接的請求, 達到某台服務器上的時候, 先看這台服務器上是否分配了短鏈接號段. 如果沒有, 就往發號表里插入一條記錄, 則這台機為短鏈分配的范圍是start -- end. 如果當前分配的id>end, 說明這個區間段的id分配完了, 再往發號表里增加1條記錄

 

3. 如何防止多次相同的長連接生成不同的短鏈接. 這樣就要每次根據長鏈接查詢db, 看是否有相關的記錄, 一般做法是長鏈接加索引, 這樣索引的空間會很多, 這時我們可以對長鏈接進行適當的壓縮, 比如:md5. 在對長鏈接的md5加索引, 這樣索引就會變得很小. 這樣只需要根據常量的MD5去數據庫里查重就可以了.

 

4. 數據量比較巨大的話, 后期還可以考慮分庫分表.

 

 

 

 

 

 

 

 

 

 

 

a

 


免責聲明!

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



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