Redis自增计数

key

将 key 中储存的数字值增一

如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。

如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误

本操作的值限制在 64 位(bit)有符号数字表示之内

这是一个针对字符串的操作,因为 Redis 没有专用的整数类型,所以 key 内储存的字符串被解释为十进制 64 位有符号整数来执行 INCR 操作

可用版本:
>= 1.0.0
时间复杂度:
O(1)
返回值:
执行  INCR 命令之后  key 的值。
redis> SET page_view 20
OK

redis> INCR page_view
(integer) 21

redis> GET page_view    # 数字值在 Redis 中以字符串的形式保存
"21"

模式:计数器

计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令。

比如在一个 web 应用程序中,如果想知道用户在一年中每天的点击量,那么只要将用户 ID 以及相关的日期信息作为键,并在每次用户点击页面时,执行一次自增操作即可

比如用户名是 peter ,点击时间是 2012 年 3 月 22 日,那么执行命令 INCR peter::2012.3.22 。

可以用以下几种方式扩展这个简单的模式:

  • 可以通过组合使用 INCR 和 EXPIRE ,来达到只在规定的生存时间内进行计数(counting)的目的
  • 客户端可以通过使用 GETSET 命令原子性地获取计数器的当前值并将计数器清零,更多信息请参考 GETSET 命令。
  • 使用其他自增/自减操作,比如 DECR 和 INCRBY ,用户可以通过执行不同的操作增加或减少计数器的值,比如在游戏中的记分器就可能用到这些命令。
下面是 **基于 Redis 实现每日流水号重置** 的完整、可运行的 ✅ **Redis生成示例代码**,适用于 Spring Boot 项目。 这个示例会生成如:`202501010001`, `202501010002`, ..., `202501020001`(每天从 `0001` 开始)的编号。 --- ## ✅ 完整 Redis生成示例 ### 1. 添加依赖(Maven) ```xml <dependencies> <!-- Spring Boot Starter Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Boot Starter Data Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 可选:使用 Commons Pool2 连接池 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> </dependencies> ``` --- ### 2. 配置 `application.yml` ```yaml spring: redis: host: localhost port: 6379 database: 0 timeout: 5s lettuce: pool: max-active: 8 max-idle: 8 min-idle: 0 ``` --- ### 3. 创建工具类或 Service(核心逻辑) ```java import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.concurrent.TimeUnit; @Component public class SandCoreGenerator { private static final String KEY_PREFIX = "sandcore:"; private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); @Autowired private StringRedisTemplate redisTemplate; /** * 生成批次编号:yyyyMMdd + 4位流水号(每日重置) */ public String createSandCore(String transferCode) { // 获取当前日期字符串,例如 20250101 String dateStr = LocalDate.now().format(DATE_FORMATTER); String key = KEY_PREFIX + dateStr; // 原子自,如果 key 不存在则从 0 开始(+1 后为 1) Long sequence = redisTemplate.opsForValue().increment(key); // 设置过期时间:自动在两天后过期(防止长期占用内存) if (sequence == 1) { redisTemplate.expire(key, 2, TimeUnit.DAYS); } // 格式化为 4 位数字 return dateStr + String.format("%04d", sequence); } } ``` --- ### 4. 提供一个测试接口(用于验证) ```java @RestController @RequestMapping("/api/sand") public class TestController { @Autowired private SandCoreGenerator sandCoreGenerator; @GetMapping("/code") public String getCode() { return sandCoreGenerator.createSandCore(null); } } ``` --- ### 5. 启动并测试 启动应用后访问: ``` GET http://localhost:8080/api/sand/code ``` 首次返回: ``` 202504050001 ``` 第二次调用: ``` 202504050002 ``` 第二天再次使用(日期变为 `20250406`): ``` 202504060001 ``` ✅ 成功实现:**每日流水号从 `0001` 开始,自动重置** --- ## 🔍 Redis 中的数据样子 你可以通过 `redis-cli` 查看: ```bash > GET sandcore:20250405 "2" ``` 表示今天已经生成了 2 个编号。 --- ## ✅ 优点说明 | 特性 | 说明 | |------|------| | ✅ 分布式安全 | 多台服务器共用 Redis,不会重复 | | ✅ 高性能 | `INCR` 是原子操作,极快 | | ✅ 自动清理 | 设置 TTL,避免无效数据堆积 | | ✅ 易扩展 | 可加入前缀、业务类型等 | --- ## ✅ 扩展建议(进阶) 如果你想支持多个业务类型的独立流水号,可以这样改: ```java public String createSandCore(String transferCode) { String dateStr = LocalDate.now().format(DATE_FORMATTER); // 不同 transferCode 独立计数 String key = KEY_PREFIX + transferCode + ":" + dateStr; Long seq = redisTemplate.opsForValue().increment(key); if (seq == 1) { redisTemplate.expire(key, 2, TimeUnit.DAYS); } return dateStr + String.format("%04d", seq); } ``` 比如传入 `"TR"`,生成的就是 `202504050001`,但 `"PAY"` 有自己的序列。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值