Redis生成全局唯一ID的實(shí)現(xiàn)方法
簡介:
全局唯一ID生成器是一種在分布式系統(tǒng)下用來生成全局唯一ID的工具
特性:
- 唯一性
- 高性能
- 安全性
- 高可用
- 遞增性
生成規(guī)則:
有時為了增加ID的安全性,我們可以不直接使用Redis自增的數(shù)值,而是拼接一些其他信息
ID組成部分:
- 符號位:1bit,永遠(yuǎn)為0
- 時間戳:31bit,以秒為單位,可以使用69年
- 序列號:32bit,秒內(nèi)的計數(shù)器,支持每秒產(chǎn)生2^32個不同ID
ID生成類:
package com.example.util; import org.springframework.beans.factory.annotation.Autowired; 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; /** ?* @Author DaBai ?* @Date 2022/3/17 下午 09:25 ?* @Version 1.0 ?*/ @Component public class RedisIDWorker { ? ? private static final long BEGIN_TIMESTAMP = 1640995200L; ? ? /** ? ? ?* 序列號位數(shù) ? ? ?*/ ? ? private static final int COUNT_BITS = 32; ? ? private StringRedisTemplate stringRedisTemplate; ? ? public RedisIDWorker(StringRedisTemplate stringRedisTemplate) { ? ? ? ? this.stringRedisTemplate = stringRedisTemplate; ? ? } ? ? public long nextID(String keyPrefix) { ? ? ? ? //1、生成時間戳 ? ? ? ? LocalDateTime now = LocalDateTime.now(); ? ? ? ? long nowScond = now.toEpochSecond(ZoneOffset.UTC); ? ? ? ? long timestamp = nowScond - BEGIN_TIMESTAMP; ? ? ? ? //2、生成序列號 ? ? ? ? // 2.1 獲取當(dāng)前日期,精確到天 ? ? ? ? String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd")); ? ? ? ? long count = stringRedisTemplate.opsForValue().increment("icr" + keyPrefix + ":" + date); ? ? ? ? //3、拼接字符串 ? ? ? ? // 時間戳左移32位,然后 或 序列號,有1為1 ? ? ? ? long ids = timestamp << COUNT_BITS | count; ? ? ? ? return ids; ? ? }
測試類:
@Resource ? ? RedisIDWorker redisIDWorker; ? ? private ExecutorService es = Executors.newFixedThreadPool(500); ? ? @Test ? ? public void ShowID() throws InterruptedException { ? ? ? ? CountDownLatch countDownLatch = new CountDownLatch(300); ? ? ? ? Runnable task = () -> { ? ? ? ? ? ? for (int i = 0; i < 100; i++) { ? ? ? ? ? ? ? ? long id = redisIDWorker.nextID("order"); ? ? ? ? ? ? ? ? System.out.println("id = " + id); ? ? ? ? ? ? } ? ? ? ? ? ? countDownLatch.countDown(); ? ? ? ? }; ? ? ? ? long startTime = System.currentTimeMillis(); ? ? ? ? for (int i = 0; i < 300; i++) { ? ? ? ? ? ? es.submit(task); ? ? ? ? } ? ? ? ? countDownLatch.await(); ? ? ? ? long end = System.currentTimeMillis(); ? ? ? ? System.out.println("time = " + (end - startTime)); ? ? }
到此這篇關(guān)于Redis生成全局唯一ID的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)Redis生成全局唯一ID內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析Redis中String數(shù)據(jù)類型及其底層編碼
這篇文章主要介紹?Redis?中?String?數(shù)據(jù)類型及其底層編碼,文中有詳細(xì)的代碼示例,對大家的工作及學(xué)習(xí)有一定的幫助,需要的朋友可以參考下2023-05-05在Centos?8.0中安裝Redis服務(wù)器的教程詳解
由于考慮到linux服務(wù)器的性能,所以經(jīng)常需要把一些中間件安裝在linux服務(wù)上,今天通過本文給大家介紹下在Centos?8.0中安裝Redis服務(wù)器的詳細(xì)過程,感興趣的朋友一起看看吧2022-03-03Redis筆記點(diǎn)贊排行榜的實(shí)現(xiàn)示例
探店筆記類似點(diǎn)評網(wǎng)站的評價,本文主要介紹了Redis筆記點(diǎn)贊排行榜的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01Linux安裝Redis、后臺運(yùn)行、系統(tǒng)自啟動的設(shè)置方法
Redis是用C語言編寫的開源免費(fèi)的高性能的分布式內(nèi)存數(shù)據(jù)庫,基于內(nèi)存運(yùn)行并支持持久化的NoSQL數(shù)據(jù)庫。這篇文章主要介紹了Linux安裝Redis、后臺運(yùn)行、系統(tǒng)自啟動,需要的朋友可以參考下2020-01-01