目录
- 分布式系统全局唯一id
- 基于redis incr 命令生成分布式全局唯一id
- 采用redis生成商品全局唯一id
分布式系统全局唯一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内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!