平時我們在上網的時候,印象最深刻的有一次是短鏈接的服務。例如:平時在微信上看一個網頁的時候,如果我們選擇在瀏覽器打開的時候,會看到很長的URL,我們分享的時候,會看到一個很短URL,這就是本次所說的短鏈接的應用之一。
長鏈接示例:https://mp.weixin.qq.com/s?__biz=MzAxNzMwOTQ0NA==&mid=2653355437&idx=1&sn=5901826ea638462ff71b7f2d06c6331d&chksm=8035d7c6b7425ed06661866af60657414bb71765d2ce915d14726736fa1e72ea8a529331c947&scene=0&key=34df968fd24033237ff036c7de8b6745e1968de9564cf2a8db689025dd0c3682848381771dab960824f506e6f9d484614746f9c0eecb48b884ce4320bb86470a77ce811cc5b401a8800b6fd6b36be097&ascene=0&uin=ODU5NDQ1NjI1&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.12.6+build(16G29)&version=12020810&nettype=WIFI&fontScale=100&pass_ticket=IvPqxUmCJqZg9%2B3GfAIQSbQ4IGRIHx796D0UwlCyUCu4b5P4bSsjlN89A0eRzSfL
我用短鏈接系統生成的(長期會失效):https://0x9.me/FAKcm
怎么把長鏈接轉換成短鏈接呢?
廢話少說,短鏈接就是我們很短的鏈接。我們的目的是要把長鏈接轉換成短鏈接。接下來我要提出一個問題:怎么把長鏈接轉換成短鏈接呢?
1.壓縮
實現一種算法,將長地址轉換成短地址。然后再實現一種逆運算,將短地址轉換成原來的地址。其實仔細的想一下,這是不可能的。
2.Hash算法
可能是大多數人都會想到的一種方法。有人會提出,將一個長URL進行Hash運算,然后將Hash值作為這個長鏈接的唯一標示。但是通常容易想到的不一定是最優的,我們知道Hash有可能產生碰撞,Hash碰撞的解決,會增強短鏈接系統的復雜度。
最優的算法
通過發號原理
顧名思義這個系統的第一個請求過來了,我們以微博為例,短鏈接系統的第一個請求我們可以給變為t.cn/0,第二個t.cn/1等等;
實現的方式也會很簡單
1、小型的系統用MySQL的自增索引就可以滿足。
2、大型系統可以考慮分布式key-value系統。
存儲原理
發號策略是這樣的,當一個新的鏈接過來時,發號器發一個號與之對應。往后只要有新鏈接過來,發號器不停發號就好。舉個例子,第一個進來的鏈接發號器發0號,對應的短鏈接為 xx.xxx/0,第二個進來的鏈接發號器發1號,對應的短鏈接為 xx.xxx/1,以此類推。
發號器發出的10進制號需要轉換成62進制,這樣可以大大縮短號碼轉換成字符串后的長度。比如發號器發出 10,000,000,000 這個號碼,如果不轉換成62進制,直接拼接在域名后面,得到這樣一個鏈接 xx.xxx/10000000000。將上面的號碼轉換成62進制,結果為AOYKUa,長度只有6位,拼接得到的鏈接為 xx.xxx/AOYKUa。可以看得出,進制轉換后得到的短鏈接長度變短了一些。6位62進制數,對應的號碼空間為626,約等于568億,所以基本上不用擔心發號器無號可發的情況。
高并發場景下
上面設計看起來有一個單點,那就是發號器。如果做成分布式的,那么多節點要保持同步加1,多點同時寫入。這樣難以避免產生單點性能瓶頸。因此我們可以考慮將單點變為多點。我們可以引入多個機器,我們可以設定機器A發號只發向100取余等于0的數字100n,同理機器B只發向100取余等于1數字 100n+1,以此類推,各個機器相互獨立互不干擾,我們可以隨時擴展我們的機器了。
同一長鏈接,每次轉成的短鏈接是否一樣
同一長鏈接,每次轉成的短鏈接不一定一樣,原因在于如果查詢緩存時,如果未命中,發號器會發新號給這個鏈接。需要說明的是,緩存應該緩存經常轉換的熱門鏈接,假設設定緩存過期時間為一小時,如果某個鏈接很活躍的話,緩存查詢命中后,緩存會刷新這個鏈接的存活時間,重新計時,這個鏈接就會長久存在緩存中。
我們也可以引入LRU算法。進行淘汰我們不經常使用到的鏈接。
重定向問題
選取301,還是302?
301是永久重定向,302是臨時重定向。
如果選擇301:短地址生成以后就不會變化,所以用301是符合http語義的。同時對服務器壓力也會有一定減少。這樣一來,我們就無法統計到短地址被點擊的次數了。
如果選擇302:選擇302雖然會增加服務器壓力,但是可以統計到短地址被點擊的次數了,我可以針對點擊的次數來進行后期的大數據處理,機器學習,以及推薦算法。
選擇302還是301,想必讀者心中有肯定有數了。