一些業務場景,比如說簡訊、push需要帶上跳轉鏈接,這個時候就需要把長鏈轉換為短鏈 長鏈如何轉短鏈?其實長鏈和生成短鏈的過程是沒有任何關係的,唯一的聯繫就是生成以後做關聯 1:短鏈生成 結合實際工作中以及網上,大概兩種比較常規的方式,預設生成六位短鏈 方式一:通過移位+簡單的演算法生成一個隨機數 第一 ...
一些業務場景,比如說簡訊、push需要帶上跳轉鏈接,這個時候就需要把長鏈轉換為短鏈
長鏈如何轉短鏈?其實長鏈和生成短鏈的過程是沒有任何關係的,唯一的聯繫就是生成以後做關聯
1:短鏈生成
結合實際工作中以及網上,大概兩種比較常規的方式,預設生成六位短鏈
方式一:通過移位+簡單的演算法生成一個隨機數
第一步:做位移,並加上一個0,1隨機數
for (int i = 0; i < 36; i++) { int random = random.nextInt(2); randomNumber = random + (randomNumber << 1); }
加上0,1隨機數,是為了防止碰撞,這樣碰撞的幾率就差不多是1/2的36次方,屬於接收範圍
至於為什麼迴圈36次,後面會說;至此,一個隨機數randomNumber已經生成
第二步:用隨機數映射到6位的短鏈
for (int i = 0; i < 6; i++) { charList.append(char62[(int) (k & randomNumber )]);
randomNum = (randomNum >> 6);
}
K是什麼?K是63,16進位0x3F,和randomNumber做操作,得到一個62進位的數,然後取出來對應的那一位
62進位數組成:26位大寫字母+26位小寫字母+10個數字
然後randomNum右移6位,這就和上面的36次迴圈生成隨機數對應了
36次迴圈分成6份,每份隨機出來的0,1組合對應一個符號
方式二:信號發射器
這種方式藉助於資料庫的自增主鍵id,然後把ID映射為62進位數的6位,這篇文章介紹
https://blog.csdn.net/xlgen157387/article/details/80026452
這種方式,要考慮分散式生成的情況,還有數據壓力。個人想法可以參考美團的leaf生成器,分段拿
到這裡,已經生成了短鏈,但是短鏈和長鏈如何映射?
2:長鏈和短鏈的映射
對應關係肯定是要持久化到資料庫的,但是一旦併發量大的時候,資料庫壓力比較大,就需要考慮用緩存了;優先使用redis的時候,又沒法把全部的映射關係存起來,
覺得底層還是需要依賴分表來解決部分問題,用長鏈的md5和短鏈分表,分別做唯一鍵。這裡唯一鍵的作用就是防止短鏈碰撞,在短鏈碰撞的時候可以進行重試。
還有就是長鏈和短鏈的映射關係我們在緩存的時候,可以認為是符合最近使用的原則,也就是我們只保留“熱點”的長鏈和短鏈在緩存的映射關係,這樣可以大大減少緩存的大小