Redis生成分布式系統(tǒng)全局唯一ID的實(shí)現(xiàn)
分布式系統(tǒng)全局唯一ID
在互聯(lián)網(wǎng)系統(tǒng)中,并發(fā)越大的系統(tǒng),數(shù)據(jù)就越大,數(shù)據(jù)越大就越需要分布式,而大量的分布式數(shù)據(jù)就越需要唯一標(biāo)識來識別它們。
例如淘寶的商品系統(tǒng)有千億級別商品,訂單系統(tǒng)有萬億級別的訂單數(shù)據(jù),這些數(shù)據(jù)都是日漸增長,傳統(tǒng)的單庫單表是無法支撐這種級別的數(shù)據(jù),必須對其進(jìn)行分庫分表;一旦分庫分表,表的自增ID就失去了意義;故需要一個全局唯一的ID來標(biāo)識每一條數(shù)據(jù)(商品、訂單)。
e.g: 一張表1億條數(shù)據(jù),被分庫分表10張表,原先的ID就失去意義,所以需要全局唯一ID來標(biāo)識10張表的數(shù)據(jù)。
全局唯一的ID生成的技術(shù)方案有很多,業(yè)界比較有名的有 UUID、Redis、Twitter的snowflake算法、美團(tuán)Leaf算法。
基于Redis INCR 命令生成分布式全局唯一ID
INCR 命令主要有以下2個特征:
- Redis的INCR命令具備了“INCR AND GET”的原子操作
- Redis是單進(jìn)程單線程架構(gòu),INCR命令不會出現(xiàn)ID重復(fù)
基于以上2個特性,可以采用INCR命令來實(shí)現(xiàn)分布式全局ID生成。
采用Redis生成商品全局唯一ID
Project Directory

Maven Dependency
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.8.RELEASE</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.fool.redis</groupId>
<artifactId>redis-string-id</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.application.name=redis-spring-id server.port=8888 spring.redis.host=localhost spring.redis.port=6379 spring.redis.database=0 spring.redis.password= spring.redis.timeout=2000 spring.redis.pool.max-active=10 spring.redis.pool.max-wait=1000 spring.redis.pool.max-idle=10 spring.redis.pool.min-idle=5 spring.redis.pool.num-tests-per-eviction-run=1024 spring.redis.pool.time-between-eviction-runs-millis=30000 spring.redis.pool.min-evictable-idle-time-millis=60000 spring.redis.pool.soft-min-evictable-idle-time-millis=10000 spring.redis.pool.test-on-borrow=true spring.redis.pool.test-while-idle=true spring.redis.pool.block-when-exhausted=false
SRC
Application.java
package org.fool.redis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Product.java
package org.fool.redis.model;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class Product {
private Long id;
private String name;
private BigDecimal price;
private String detail;
}
IdGeneratorService.java
package org.fool.redis.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class IdGeneratorService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private static final String ID_KEY = "id:generator:product";
public Long incrementId() {
return stringRedisTemplate.opsForValue().increment(ID_KEY);
}
}
ProductController.java
package org.fool.redis.controller;
import lombok.extern.slf4j.Slf4j;
import org.fool.redis.model.Product;
import org.fool.redis.service.IdGeneratorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
@RequestMapping(value = "/product")
public class ProductController {
@Autowired
private IdGeneratorService idGeneratorService;
@PostMapping(value = "/create")
public String create(@RequestBody Product obj) {
//生成分布式id
long id = idGeneratorService.incrementId();
//使用全局id 代替數(shù)據(jù)庫的自增id
obj.setId(id);
//取模(e.g: 這里分為8張表,海量數(shù)據(jù)可以分為1024張表),計算表名
int table = (int) id % 8;
String tableName = "product_" + table;
log.info("insert to table: {}, with content: {}", tableName, obj);
return "insert to table: " + tableName + " with content: " + obj;
}
}
Test
curl --location --request POST 'http://localhost:8888/product/create' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Car",
"price": "300000.00",
"detail": "Lexus Style"
}'
Console Output

到此這篇關(guān)于Redis生成分布式系統(tǒng)全局唯一ID的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Redis生成分布式系統(tǒng)全局唯一ID內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis Cluster集群收縮主從節(jié)點(diǎn)詳細(xì)教程
集群收縮的源端就是要下線的主節(jié)點(diǎn),目標(biāo)端就是在線的主節(jié)點(diǎn),這篇文章主要介紹了Redis Cluster集群收縮主從節(jié)點(diǎn)詳細(xì)教程,需要的朋友可以參考下2021-11-11
批量導(dǎo)入txt數(shù)據(jù)到的redis過程
用戶通過將Redis命令逐行寫入txt文件,利用管道模式運(yùn)行客戶端,成功執(zhí)行批量刪除以"Product*"匹配的Key操作,提高了數(shù)據(jù)清理效率2025-08-08

