zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

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

Redis 实现 生成 ID 唯一 全局 分布式系统
2023-06-13 09:19:49 时间
分布式系统全局唯一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内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


我想要获取技术服务或软件
服务范围:MySQL、ORACLE、SQLSERVER、MongoDB、PostgreSQL 、程序问题
服务方式:远程服务、电话支持、现场服务,沟通指定方式服务
技术标签:数据恢复、安装配置、数据迁移、集群容灾、异常处理、其它问题

本站部分文章参考或来源于网络,如有侵权请联系站长。
数据库远程运维 Redis生成分布式系统全局唯一ID的实现