最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis實(shí)現(xiàn)全局唯一Id的使用示例

 更新時(shí)間:2023年12月19日 09:13:42   作者:伏加特遇上西柚  
全局唯一ID有多個(gè)方法可供選擇,其中一種是使用Redis,本文就來(lái)介紹一下Redis實(shí)現(xiàn)全局唯一Id的使用示例,具有一定的參考價(jià)值,感興趣的可以了解一下

一、全局唯一Id簡(jiǎn)介

系統(tǒng)當(dāng)中有些場(chǎng)景如果使用數(shù)據(jù)庫(kù)自增ID就存在一些問(wèn)題:

  • id的規(guī)律性太明顯
  • 受單表數(shù)據(jù)量的限制

場(chǎng)景分析:如果我們的id具有太明顯的規(guī)則,用戶或者說(shuō)商業(yè)對(duì)手很容易猜測(cè)出來(lái)我們的一些敏感信息,比如商城在一天時(shí)間內(nèi),賣出了多少單,這明顯不合適。

場(chǎng)景分析二:隨著我們商城規(guī)模越來(lái)越大,mysql的單表的容量不宜超過(guò)500W,數(shù)據(jù)量過(guò)大之后,我們要進(jìn)行拆庫(kù)拆表,但拆分表了之后,他們從邏輯上講他們是同一張表,所以他們的id是不能一樣的, 于是乎我們需要保證id的唯一性。

全局唯一ID生成策略:

  • UUID
  • Redis自增
  • snowflake算法
  • 數(shù)據(jù)庫(kù)自增

Redis自增ID策略:

  • 每天一個(gè)key,方便統(tǒng)計(jì)訂單量
  • ID構(gòu)造是 時(shí)間戳 + 計(jì)數(shù)器

全局ID生成器,是一種在分布式系統(tǒng)下用來(lái)生成全局唯一ID的工具,一般要滿足下列特性:

在這里插入圖片描述

為了增加ID的安全性,我們可以不直接使用Redis自增的數(shù)值,而是拼接一些其它信息:

在這里插入圖片描述

D的組成部分:符號(hào)位:1bit,永遠(yuǎn)為0

時(shí)間戳:31bit,以秒為單位,可以使用69年

序列號(hào):32bit,秒內(nèi)的計(jì)數(shù)器,支持每秒產(chǎn)生2^32個(gè)不同ID

二、Redis實(shí)現(xiàn)全局唯一Id實(shí)踐

2.1添加RedisIdWorker配置類

package com.example.idgenerate.config;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

@Component
public class RedisIdWorker {
    /**
     * 開始時(shí)間戳,此處的時(shí)間戳為預(yù)生成
     */
    private static final long BEGIN_TIMESTAMP = 1640995200L;
    /**
     * 序列號(hào)的位數(shù)
     */
    private static final int COUNT_BITS = 32;

    private StringRedisTemplate stringRedisTemplate;

    public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
      * 描述信息: 生成唯一id
      *
      * @date  2023/05/21
      * @param keyPrefix 前綴,用于區(qū)分不同的業(yè)務(wù)
      * @return long id
      **/
    public long nextId(String keyPrefix) {
        // 1.生成時(shí)間戳
        LocalDateTime now = LocalDateTime.now();
        long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
        long timestamp = nowSecond - BEGIN_TIMESTAMP;

        // 2.生成序列號(hào)
        // 2.1.獲取當(dāng)前日期,精確到天
        String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        // 2.2.自增長(zhǎng) key格式:icr:order:2023:05:21
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);

        // 3.拼接并返回,目的是讓時(shí)間戳存放在32上,序列號(hào)在低32位
        return timestamp << COUNT_BITS | count;
    }
}


在這里插入圖片描述

2.2測(cè)試類

 @Autowired
    private RedisIdWorker redisIdWorker;

    /**
      * 描述信息:將日期時(shí)間轉(zhuǎn)成秒級(jí)數(shù)字
      *
      * @date  2023/05/21
      * @return void
      **/
    @Test
    void contextLoads() {
        LocalDateTime time = LocalDateTime.of(2023, 5, 20, 0, 0,0);
        //將時(shí)間轉(zhuǎn)成秒數(shù)
        long second = time.toEpochSecond(ZoneOffset.UTC);
        System.out.println("second = " + second);
    }
    //實(shí)際項(xiàng)目中應(yīng)使用自定義的線程池
    private ExecutorService es = Executors.newFixedThreadPool(500);

    /**
      * 描述信息: 測(cè)試redis生成3w條id所需要的時(shí)間
      *
      * @date  2023/05/21
      * @return void
      **/
    @Test
    void testIdWorker() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(300);

        Runnable task = () -&gt; {
            for (int i = 0; i &lt; 100; i++) {
                long id = redisIdWorker.nextId("order");
                System.out.println("id = " + id);
            }
            latch.countDown();
        };
        long begin = System.currentTimeMillis();
        for (int i = 0; i &lt; 300; i++) {
            es.submit(task);
        }
        latch.await();
        long end = System.currentTimeMillis();
        System.out.println("time = " + (end - begin));
    }

在這里插入圖片描述

知識(shí)小貼士:關(guān)于countdownlatch

countdownlatch名為信號(hào)槍主要的作用是同步協(xié)調(diào)在多線程的等待于喚醒問(wèn)題

我們?nèi)绻麤]有CountDownLatch ,那么由于程序是異步的,當(dāng)異步程序沒有執(zhí)行完時(shí),主線程就已經(jīng)執(zhí)行完了,然后我們期望的是分線程全部走完之后,主線程再走,所以我們此時(shí)需要使用到CountDownLatch

CountDownLatch 中有兩個(gè)最重要的方法
1、countDown
2、await

await 方法是阻塞方法,我們擔(dān)心分線程沒有執(zhí)行完時(shí),main線程就先執(zhí)行,所以使用await可以讓main線程阻塞,那么什么時(shí)候main線程不再阻塞呢?當(dāng)CountDownLatch 內(nèi)部維護(hù)的 變量變?yōu)?時(shí),就不再阻塞,直接放行,那么什么時(shí)候CountDownLatch 維護(hù)的變量變?yōu)? 呢,我們只需要調(diào)用一次countDown ,內(nèi)部變量就減少1,我們讓分線程和變量綁定, 執(zhí)行完一個(gè)分線程就減少一個(gè)變量,當(dāng)分線程全部走完,CountDownLatch 維護(hù)的變量就是0,此時(shí)await就不再阻塞,統(tǒng)計(jì)出來(lái)的時(shí)間也就是所有分線程執(zhí)行完后的時(shí)間。

到此這篇關(guān)于Redis實(shí)現(xiàn)全局唯一Id的使用示例的文章就介紹到這了,更多相關(guān)Redis 全局唯一Id內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis網(wǎng)絡(luò)I/O模型的使用及說(shuō)明

    Redis網(wǎng)絡(luò)I/O模型的使用及說(shuō)明

    文章詳細(xì)介紹了Redis的網(wǎng)絡(luò)模型,包括單線程和多線程模型,以及I/O多路復(fù)用、事件通知機(jī)制、信號(hào)驅(qū)動(dòng)I/O和異步I/O等技術(shù),同時(shí)簡(jiǎn)要介紹了Redis的通信協(xié)議RESP
    2025-12-12
  • Redis實(shí)現(xiàn)UV統(tǒng)計(jì)的示例代碼

    Redis實(shí)現(xiàn)UV統(tǒng)計(jì)的示例代碼

    本文主要介紹了Redis實(shí)現(xiàn)UV統(tǒng)計(jì)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 詳細(xì)分析Redis集群故障

    詳細(xì)分析Redis集群故障

    這篇文章主要介紹了詳細(xì)分析Redis集群故障的相關(guān)內(nèi)容,具有一定的參考價(jià)值,這里分享給大家,供需要的朋友參考。
    2017-10-10
  • Redis+MQ高并發(fā)秒殺的技術(shù)方案與實(shí)現(xiàn)

    Redis+MQ高并發(fā)秒殺的技術(shù)方案與實(shí)現(xiàn)

    本文提出了一種基于Redis與消息隊(duì)列的高并發(fā)秒殺系統(tǒng)解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03
  • Spring?Boot?整合Redis?實(shí)現(xiàn)優(yōu)惠卷秒殺?一人一單功能

    Spring?Boot?整合Redis?實(shí)現(xiàn)優(yōu)惠卷秒殺?一人一單功能

    這篇文章主要介紹了Spring?Boot?整合Redis?實(shí)現(xiàn)優(yōu)惠卷秒殺?一人一單,在分布式系統(tǒng)下,高并發(fā)的場(chǎng)景下,會(huì)出現(xiàn)此類庫(kù)存超賣問(wèn)題,本篇文章介紹了采用樂(lè)觀鎖來(lái)解決,需要的朋友可以參考下
    2022-09-09
  • Redis實(shí)戰(zhàn)之Redis實(shí)現(xiàn)異步秒殺優(yōu)化詳解

    Redis實(shí)戰(zhàn)之Redis實(shí)現(xiàn)異步秒殺優(yōu)化詳解

    這篇文章主要給大家介紹了Redis實(shí)戰(zhàn)之Redis實(shí)現(xiàn)異步秒殺優(yōu)化方法,文章通過(guò)圖片和代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,感興趣的同學(xué)可以自己動(dòng)手試一下
    2023-09-09
  • 解決redis在linux上的部署的問(wèn)題

    解決redis在linux上的部署的問(wèn)題

    這篇文章主要介紹了redis在linux上的部署,本文分步驟給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • 多維度深入分析Redis的5種基本數(shù)據(jù)結(jié)構(gòu)

    多維度深入分析Redis的5種基本數(shù)據(jù)結(jié)構(gòu)

    此篇文章主要對(duì)Redis的5種基本數(shù)據(jù)類型,即字符串(String)、列表(List)、散列(Hash)、集合(Set)、有序集合(Sorted?Set),從使用場(chǎng)景和底層結(jié)構(gòu)出發(fā),進(jìn)行多維度深入分析。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-11-11
  • Redis在項(xiàng)目中的使用(JedisPool方式)

    Redis在項(xiàng)目中的使用(JedisPool方式)

    項(xiàng)目操作redis是使用的RedisTemplate方式,另外還可以完全使用JedisPool和Jedis來(lái)操作redis,本文給大家介紹Redis在項(xiàng)目中的使用,JedisPool方式,感興趣的朋友跟隨小編一起看看吧
    2021-12-12
  • Redisson分布式鎖之加解鎖詳解

    Redisson分布式鎖之加解鎖詳解

    這篇文章主要為大家介紹了Redisson分布式鎖加解鎖的詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03

最新評(píng)論

报价| 大理市| 三穗县| 容城县| 贵定县| 随州市| 麦盖提县| 隆林| 若羌县| 巨鹿县| 吴桥县| 延寿县| 泰来县| 比如县| 兴山县| 鱼台县| 衡阳市| 清镇市| 新邵县| 库车县| 乌苏市| 高邑县| 新源县| 同江市| 上林县| 个旧市| 鄢陵县| 双鸭山市| 雅江县| 丹东市| 华容县| 萨嘎县| 光泽县| 盈江县| 班玛县| 福建省| 利津县| 炎陵县| 莎车县| 贵南县| 扎囊县|