新闻动态
新闻动态
NEWS INFORMATION

Redis生成分布式系统全局唯一ID的实现

发布日期:2022-01-29 17:05 | 文章来源:CSDN

分布式系统全局唯一ID

在互联网系统中,并发越大的系统,数据就越大,数据越大就越需要分布式,而大量的分布式数据就越需要唯一标识来识别它们。

例如淘宝的商品系统有千亿级别商品,订单系统有万亿级别的订单数据,这些数据都是日渐增长,传统的单库单表是无法支撑这种级别的数据,必须对其进行分库分表;一旦分库分表,表的自增ID就失去了意义;故需要一个全局唯一的ID来标识每一条数据(商品、订单)。

e.g: 一张表1亿条数据,被分库分表10张表,原先的ID就失去意义,所以需要全局唯一ID来标识10张表的数据。

全局唯一的ID生成的技术方案有很多,业界比较有名的有 UUID、Redis、Twitter的snowflake算法、美团Leaf算法。

基于Redis INCR 命令生成分布式全局唯一ID

INCR 命令主要有以下2个特征:

  • Redis的INCR命令具备了“INCR AND GET”的原子操作
  • Redis是单进程单线程架构,INCR命令不会出现ID重复

基于以上2个特性,可以采用INCR命令来实现分布式全局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 代替数据库的自增id
        obj.setId(id);
        //取模(e.g: 这里分为8张表,海量数据可以分为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

到此这篇关于Redis生成分布式系统全局唯一ID的实现的文章就介绍到这了,更多相关Redis生成分布式系统全局唯一ID内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

香港快速服务器

版权声明:本站文章来源标注为YINGSOO的内容版权均为本站所有,欢迎引用、转载,请保持原文完整并注明来源及原文链接。禁止复制或仿造本网站,禁止在非www.yingsoo.com所属的服务器上建立镜像,否则将依法追究法律责任。本站部分内容来源于网友推荐、互联网收集整理而来,仅供学习参考,不代表本站立场,如有内容涉嫌侵权,请联系alex-e#qq.com处理。

实时开通

自选配置、实时开通

免备案

全球线路精选!

全天候客户服务

7x24全年不间断在线

专属顾问服务

1对1客户咨询顾问

在线
客服

在线客服:7*24小时在线

客服
热线

400-630-3752
7*24小时客服服务热线

关注
微信

关注官方微信
顶部