長鏈生成短鏈的思考


一些業務場景,比如說短信、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和短鏈分表,分別做唯一鍵。這里唯一鍵的作用就是防止短鏈碰撞,在短鏈碰撞的時候可以進行重試。

還有就是長鏈和短鏈的映射關系我們在緩存的時候,可以認為是符合最近使用的原則,也就是我們只保留“熱點”的長鏈和短鏈在緩存的映射關系,這樣可以大大減少緩存的大小


免責聲明!

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



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