分布式系統訂單號唯一策略


1、分布式集群架構

2、分布式高並發環境的訂單號要求

  • 全局唯一
  • 訂單號信息要安全
  • 趨勢遞增

3、訂單號生成策略總結

策略 優點 缺點 格式
uuid 實現簡單不占用帶寬 無序、不可讀、查詢慢 32位
db自增 無代碼、遞歸 DB單點故障、擴展有瓶頸
snowflake 不占用帶寬、低位趨勢遞增 依賴服務器時間 18位
redis 無單點故障、性能優於DB遞增 占用帶寬、Redis集群需要維護 12位

3.1、策略一:UUID(通用唯一識別碼)

組成:當前日期+時間+時鍾序列+機器識別號(MAC地址或其他)
分布式系統中,所有元素(web服務器)都不需要通過中央控制端來判斷數據唯一性。

3.2、策略二:數據庫自增ID

關系型數據庫都實現數據庫自增ID;mysql通過auto_increment實現、oralce通過sequence實現。
在數據庫集群環境下,不同數據庫節點可設置不同起步值、相同步長值來實現集群下生成全局唯一、遞增ID。

3.3、策略三:snowflake算法

組成:41位時間戳+10為機器ID+12位序列號(自增),轉換位長度為18的長整型。
twitter位滿足每秒上萬條消息的創建,每條消息都必須分配全局唯一id,這些id要趨勢遞增,方便客戶排序。
github上可以下載到snowflake源碼

3.4、策略四:Redis自增ID

  • redis的api: incr(key) 若key存在,則將key的value遞增1並返回,如果key不存在則將改key對應的value初始化為0並返回。
  • 自增格式:前綴+自增id 。
  • 超時時間:使用超時時間是為了防止自增到9999時訂單號的位數變長。

redis集群示意圖
public class RedisUtil {
    @Autowired
    JedisPool jedisPool;
    
public long getIncr(String key, int timeout) {
    Jedis redis = null;
    try {
        redis = jedisPool.getResource();
        // 當key不存在時,創建一個值為0的key
        long id = redis.incr(key);
        if (timeout > 0) {
            // 設置超時時間
            redis.expire(key, timeout);
            return id;
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (redis != null) {
            redis.close();
        }
    }
    return -1;
 }
}
使用redis自增的java代碼示例
## 4、四種ID自增的格式示例 * uuid:205f1537-7991-4ed3-a2c7-c05aa8f8428b * 數據庫自增:自增id * snowflake:386992679587676176 * redis:173372100001


免責聲明!

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



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