vlambda博客
学习文章列表

Redis 生成电商系统商品全局唯一 ID

业务场景

在互联网电商系统中通常有着千亿级别的商品数据,万亿级别的订单数据;而传统的单库单表是无法支撑这种级别的数据的,通常会采用分库分表。

但是一旦进行分库分表,数据库表中原先设计的自增 ID 就会失去意义,所以在分布式系统中通常需要一个全局唯一 ID 来标识每一条数据。

全局唯一 ID 生成的技术方案有很多,业界比较有名的有

  • UUID

  • Redis

  • Snowflake

  • Leaf


实战演练

这里我们使用 Redis INCR 命令来实现分布式系统全局唯一 ID

核心 Maven Dependency

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId></dependency>
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId></dependency>


核心 application.properties

spring.redis.host=localhostspring.redis.port=6379spring.redis.database=0spring.redis.password=spring.redis.timeout=2000spring.redis.lettuce.pool.max-active=50spring.redis.lettuce.pool.max-wait=2000spring.redis.lettuce.pool.max-idle=10spring.redis.lettuce.pool.min-idle=10


RedisConfiguration.java

package org.fool.springboot.config;
import org.springframework.cache.CacheManager;import org.springframework.cache.annotation.EnableCaching;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheConfiguration;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.cache.RedisCacheWriter;import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.RedisSerializationContext;import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Configuration@EnableCachingpublic class RedisConfiguration { @Bean public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory); GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; }
@Bean public CacheManager cacheManager(LettuceConnectionFactory connectionFactory) { RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration .defaultCacheConfig() .entryTtl(Duration.ofMinutes(30L)) .disableCachingNullValues() .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory)) .cacheDefaults(redisCacheConfiguration) .build(); }}


IdGeneratorService.java

package org.fool.springboot.service;
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.stereotype.Service;
@Servicepublic class IdGeneratorService { @Autowired private StringRedisTemplate stringRedisTemplate;
private static final String CACHE_MERCHANDISE_ID_KEY = "MERCHANDISE::ID";
public Long genId() { return stringRedisTemplate.opsForValue().increment(CACHE_MERCHANDISE_ID_KEY); }}


MerchandiseRequest.java

package org.fool.springboot.contract.request;
import lombok.Data;
@Datapublic class MerchandiseRequest { private Long id; private String name; private Double price; private String desc;}


MerchandiseController.java


Test

多次执行以下 curl 命令

curl --location --request POST 'http://localhost:8080/merchandise/create' \--header 'Content-Type: application/json' \--data-raw '{ "name": "Car", "price": 300000.00, "detail": "Lexus"}'



泰克风格 只讲干货 不弄玄虚