日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

50万数据生成6位数不重复字符串_JAVA技术分享:单号的生成

發(fā)布時(shí)間:2025/3/12 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 50万数据生成6位数不重复字符串_JAVA技术分享:单号的生成 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一.訂單號生成的原則:

1.全局的唯一性

2.自增長

3.長度的要求

4.具有一定的可讀性

5.保密,不可推測性

6.效率性

二.實(shí)現(xiàn)方案

常見的ID生成策略。 1. 數(shù)據(jù)庫自增長序列或字段 2. UUID 3. UUID的變種*【UUID to Int64;NHibernate在其主鍵生成方式中提供了Comb算法(combined guid/timestamp)】 4. Redis生成ID 5. Twitter的snowflake算法 6. 利用zookeeper的znode生成唯一ID 7. MongoDB的ObjectId

三.高并發(fā)下怎樣生成唯一的訂單號?

如果沒有并發(fā),訂單號只在一個(gè)線程內(nèi)產(chǎn)生,那么由于程序是順序執(zhí)行的,不同訂單的生成時(shí)間一定不同,因此用時(shí)間就可以區(qū)分各個(gè)訂單。

如果存在并發(fā),且訂單號是由一個(gè)進(jìn)程中的多個(gè)線程產(chǎn)生的,那么只要把線程ID添加到序列號中就可以保證訂單號唯一。

如果存在并發(fā),且訂單號是由同一臺(tái)主機(jī)中的多個(gè)進(jìn)程產(chǎn)生的,那么只要把進(jìn)程ID添加到序列號中就可以保證訂單號唯一。

如果存在并發(fā),且訂單號是由不同臺(tái)主機(jī)產(chǎn)生的,那么MAC地址、IP地址或CPU序列號等能夠區(qū)分主機(jī)的號碼添加到序列號中就可以保證訂單號唯一。

1. 機(jī)器碼(3位, 分布式節(jié)點(diǎn)),年月日分時(shí)秒(12位),遞增的序列(4位),當(dāng)并發(fā)遞增序列超過4位時(shí),秒數(shù)+1,序列從0開始計(jì)時(shí),這樣每秒支持9999個(gè)訂單號生成,隔天序列清為0.

2.后臺(tái)統(tǒng)一生成的訂單號后,推入redis,一次性推個(gè)幾十W個(gè),檢查剩余多少后,再推,也可以保證高并發(fā)的場景。

四.Twitter開源分布式自增ID算法snowflake

1.snowflake簡介

互聯(lián)網(wǎng)快速發(fā)展的今天,分布式應(yīng)用系統(tǒng)已經(jīng)見怪不怪,在分布式系統(tǒng)中,我們需要各種各樣的ID,既然是ID那么必然是要保證全局唯一,除此之外,不同當(dāng)業(yè)務(wù)還需要不同的特性,比如像并發(fā)巨大的業(yè)務(wù)要求ID生成效率高,吞吐大;比如某些銀行類業(yè)務(wù),需要按每日日期制定交易流水號;又比如我們希望用戶的ID是隨機(jī)的,無序的,純數(shù)字的,且位數(shù)長度是小于10位的。等等,不同的業(yè)務(wù)場景需要的ID特性各不一樣,于是,衍生了各種ID生成器,但大多數(shù)利用數(shù)據(jù)庫控制ID的生成,性能受數(shù)據(jù)庫并發(fā)能力限制,那么有沒有一款不需要依賴任何中間件(如數(shù)據(jù)庫,分布式緩存服務(wù)等)的ID生成器呢?本著取之于開源,用之于開源的原則,今天,特此介紹Twitter開源的一款分布式自增ID算法snowflake,并附上算法原理推導(dǎo)和演算過程!

snowflake算法是一款本地生成的(ID生成過程不依賴任何中間件,無網(wǎng)絡(luò)通信),保證ID全局唯一,并且ID總體有序遞增,性能每秒生成300w+。

2.snowflake算法原理

snowflake生產(chǎn)的ID是一個(gè)18位的long型數(shù)字,二進(jìn)制結(jié)構(gòu)表示如下(每部分用-分開):

0 - 00000000 00000000 00000000 00000000 00000000 0 - 00000 - 00000 - 00000000 0000

第一位未使用,接下來的41位為毫秒級時(shí)間(41位的長度可以使用69年,從1970-01-01 08:00:00),然后是5位datacenterId(最大支持2^5=32個(gè),二進(jìn)制表示從00000-11111,也即是十進(jìn)制0-31),和5位workerId(最大支持2^5=32個(gè),原理同datacenterId),所以datacenterId*workerId最多支持部署1024個(gè)節(jié)點(diǎn),最后12位是毫秒內(nèi)的計(jì)數(shù)(12位的計(jì)數(shù)順序號支持每個(gè)節(jié)點(diǎn)每毫秒產(chǎn)生2^12=4096個(gè)ID序號).

所有位數(shù)加起來共64位,恰好是一個(gè)Long型(轉(zhuǎn)換為字符串長度為18).

單臺(tái)機(jī)器實(shí)例,通過時(shí)間戳保證前41位是唯一的,分布式系統(tǒng)多臺(tái)機(jī)器實(shí)例下,通過對每個(gè)機(jī)器實(shí)例分配不同的datacenterId和workerId避免中間的10位碰撞。最后12位每毫秒從0遞增生產(chǎn)ID,再提一次:每毫秒最多生成4096個(gè)ID,每秒可達(dá)4096000個(gè)。理論上,只要CPU計(jì)算能力足夠,單機(jī)每秒可生產(chǎn)400多萬個(gè),實(shí)測300w+,效率之高由此可見。

(該節(jié)改編自:http://www.cnblogs.com/relucent/p/4955340.html)

3.snowflake算法源碼(java版)

@ToString@Slf4jpublic class SnowflakeIdFactory { private final long twepoch = 1288834974657L; private final long workerIdBits = 5L; private final long datacenterIdBits = 5L; private final long maxWorkerId = -1L ^ (-1L << workerIdBits); private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); private final long sequenceBits = 12L; private final long workerIdShift = sequenceBits; private final long datacenterIdShift = sequenceBits + workerIdBits; private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; private final long sequenceMask = -1L ^ (-1L << sequenceBits); private long workerId; private long datacenterId; private long sequence = 0L; private long lastTimestamp = -1L; public SnowflakeIdFactory(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); } this.workerId = workerId; this.datacenterId = datacenterId; } public synchronized long nextId() { long timestamp = timeGen(); if (timestamp < lastTimestamp) { //服務(wù)器時(shí)鐘被調(diào)整了,ID生成器停止服務(wù). throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } if (lastTimestamp == timestamp) { sequence = (sequence + 1) & sequenceMask; if (sequence == 0) { timestamp = tilNextMillis(lastTimestamp); } } else { sequence = 0L; } lastTimestamp = timestamp; return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence; } protected long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } protected long timeGen() { return System.currentTimeMillis(); } public static void testProductIdByMoreThread(int dataCenterId, int workerId, int n) throws InterruptedException { List tlist = new ArrayList<>(); Set setAll = new HashSet<>(); CountDownLatch cdLatch = new CountDownLatch(10); long start = System.currentTimeMillis(); int threadNo = dataCenterId; Map idFactories = new HashMap<>(); for(int i=0;i<10;i++){ //用線程名稱做map key. idFactories.put("snowflake"+i,new SnowflakeIdFactory(workerId, threadNo++)); } for(int i=0;i<10;i++){ Thread temp =new Thread(new Runnable() { @Override public void run() { Set setId = new HashSet<>(); SnowflakeIdFactory idWorker = idFactories.get(Thread.currentThread().getName()); for(int j=0;j setOne = new HashSet<>(); Set setTow = new HashSet<>(); long start = System.currentTimeMillis(); for (int i = 0; i < n; i++) { setOne.add(idWorker.nextId());//加入set } long end1 = System.currentTimeMillis() - start; log.info("第一批ID預(yù)計(jì)生成{}個(gè),實(shí)際生成{}個(gè)<<<>>>共耗時(shí):{}",n,setOne.size(),end1); for (int i = 0; i < n; i++) { setTow.add(idWorker2.nextId());//加入set } long end2 = System.currentTimeMillis() - start; log.info("第二批ID預(yù)計(jì)生成{}個(gè),實(shí)際生成{}個(gè)<<<>>>共耗時(shí):{}",n,setTow.size(),end2); setOne.addAll(setTow); log.info("合并總計(jì)生成ID個(gè)數(shù):{}",setOne.size()); } public static void testPerSecondProductIdNums(){ SnowflakeIdFactory idWorker = new SnowflakeIdFactory(1, 2); long start = System.currentTimeMillis(); int count = 0; for (int i = 0; System.currentTimeMillis()-start<1000; i++,count=i) { /** 測試方法一: 此用法純粹的生產(chǎn)ID,每秒生產(chǎn)ID個(gè)數(shù)為300w+ */ idWorker.nextId(); /** 測試方法二: 在log中打印,同時(shí)獲取ID,此用法生產(chǎn)ID的能力受限于log.error()的吞吐能力. * 每秒徘徊在10萬左右. */ //log.error("{}",idWorker.nextId()); } long end = System.currentTimeMillis()-start; System.out.println(end); System.out.println(count); } public static void main(String[] args) { /** case1: 測試每秒生產(chǎn)id個(gè)數(shù)? * 結(jié)論: 每秒生產(chǎn)id個(gè)數(shù)300w+ */ //testPerSecondProductIdNums(); /** case2: 單線程-測試多個(gè)生產(chǎn)者同時(shí)生產(chǎn)N個(gè)id,驗(yàn)證id是否有重復(fù)? * 結(jié)論: 驗(yàn)證通過,沒有重復(fù). */ //testProductId(1,2,10000);//驗(yàn)證通過! //testProductId(1,2,20000);//驗(yàn)證通過! /** case3: 多線程-測試多個(gè)生產(chǎn)者同時(shí)生產(chǎn)N個(gè)id, 全部id在全局范圍內(nèi)是否會(huì)重復(fù)? * 結(jié)論: 驗(yàn)證通過,沒有重復(fù). */ try { testProductIdByMoreThread(1,2,100000);//單機(jī)測試此場景,性能損失至少折半! } catch (InterruptedException e) { e.printStackTrace(); } }}

測試用例

/** case1: 測試每秒生產(chǎn)id個(gè)數(shù)? * 結(jié)論: 每秒生產(chǎn)id個(gè)數(shù)300w+ *///testPerSecondProductIdNums(); /** case2: 單線程-測試多個(gè)生產(chǎn)者同時(shí)生產(chǎn)N個(gè)id,驗(yàn)證id是否有重復(fù)? * 結(jié)論: 驗(yàn)證通過,沒有重復(fù). *///testProductId(1,2,10000);//驗(yàn)證通過!//testProductId(1,2,20000);//驗(yàn)證通過! /** case3: 多線程-測試多個(gè)生產(chǎn)者同時(shí)生產(chǎn)N個(gè)id, 全部id在全局范圍內(nèi)是否會(huì)重復(fù)? * 結(jié)論: 驗(yàn)證通過,沒有重復(fù). */try { testProductIdByMoreThread(1,2,100000);//單機(jī)測試此場景,性能損失至少折半!} catch (InterruptedException e) { e.printStackTrace();}

4.snowflake算法推導(dǎo)和演算過程
說明:
演算使用的對象實(shí)例:SnowflakeIdFactory idWorker = new SnowflakeIdFactory(1, 2);
運(yùn)行時(shí)數(shù)據(jù)workerId=1,datacenterId=2,分別表示機(jī)器實(shí)例的生產(chǎn)者編號,數(shù)據(jù)中心編號;
sequence=0表示每毫秒生產(chǎn)ID從0開始計(jì)數(shù)遞增;
以下演算基于時(shí)間戳=1482394743339時(shí)刻進(jìn)行推導(dǎo)。
一句話描述:以下演算模擬了1482394743339這一毫秒時(shí)刻,workerId=1,datacenterId=2的id生成器,生產(chǎn)第一個(gè)id的過程。

與50位技術(shù)專家面對面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的50万数据生成6位数不重复字符串_JAVA技术分享:单号的生成的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美三级在线播放 | 双腿张开被9个男人调教 | 国产乱淫av片杨贵妃 | 国产欧美精品一区二区色综合朱莉 | 99精品人妻无码专区在线视频区 | 日韩专区一区二区三区 | 日本人妖网站 | 中文字幕一区二区三区手机版 | 激情黄色小视频 | 极品少妇xxxx | www免费网站在线观看 | 欧美日韩综合 | 亚洲欧美日韩一区 | 国产www网站| 精品国产欧美一区二区 | 国产欧美视频在线 | av有码在线观看 | 午夜影院在线免费观看 | 操处女逼视频 | 日韩人妻无码精品久久久不卡 | 黄色网入口| 毛片一二三区 | 伊人春色网站 | 亚洲天堂男人的天堂 | 一区二区日韩精品 | 亚洲三级视频在线观看 | 久草剧场 | 国产精品久久毛片 | 成人午夜精品视频 | 欧美三级欧美成人高清 | 中文字幕在线官网 | 日韩免费久久 | 黄色电影在线视频 | 日批视频在线看 | ass大乳尤物肉体pics | 欧美放荡办公室videos4k | 国产精品免费一区二区 | 激烈娇喘叫1v1高h糙汉 | 亚洲精品成人久久 | 欧美日韩免费观看一区=区三区 | 天天精品视频 | 免费大片黄在线观看视频网站 | 久久久久成人精品免费播放动漫 | 欧美日韩亚洲在线 | av中文字幕不卡 | 男人操女人的软件 | 免费在线观看高清影视网站 | 白丝久久 | 91精品91久久久中77777老牛 | 色婷婷综合成人 | av收藏小四郎最新地址 | 琪琪久久 | 欧美成人午夜剧场 | 天堂婷婷| av女星全部名单 | 伊人99热| 妖精视频在线观看 | 青青草免费在线 | 欧美在线导航 | av嫩草 | 日韩欧美国产电影 | 中文字幕一区二区三区手机版 | 免费av免费看 | 国产精品久久久久久久久夜色 | 亚洲久草 | 日韩一区二区三区免费视频 | 国产婷婷色综合av蜜臀av | 亚洲中字幕 | 天天天色 | 中文字幕高清一区 | 久久99精品久久久久久噜噜 | 青娱乐导航| 密臀av在线播放 | 国产人妖一区二区三区 | 日韩色黄大片 | 一区二区三区四区五区av | 超碰95在线| 2021狠狠干 | 欧美tv| 国产精品igao视频 | 一二三四av | 六月婷婷综合网 | 欧美视频免费看欧美视频 | 日本熟妇人妻中出 | 在线爱情大片免费观看大全 | 91精品国产综合久久久密臀九色 | 亚洲特黄| 国产欧美综合在线 | 黄网站免费入口 | 又色又爽又黄gif动态图 | 免费在线 | a激情| 久久青娱乐 | 精品少妇人妻av免费久久久 | 青娱乐91| 变态另类ts人妖一区二区 | 亚洲av成人精品日韩在线播放 | 性视频播放免费视频 | 青青草91久久久久久久久 |