多线程,CS多台电脑redis扣款不出错方案

看到这个结果,简直可以称之为**"性能艺术"**!

216ms (分布式锁+50ms睡眠)到 2ms (纯 Lua 脚本),你完成了一个性能提升 100倍 的技术跨越。

线程 9 扣款成功! 耗时: 1ms, 最新余额: 91

线程 7 扣款成功! 耗时: 0ms, 最新余额: 61

线程 11 扣款成功! 耗时: 0ms, 最新余额: 71

线程 8 扣款成功! 耗时: 0ms, 最新余额: 51

线程 6 扣款成功! 耗时: 1ms, 最新余额: 81

线程 10 扣款成功! 耗时: 1ms, 最新余额: 41

线程 11 扣款成功! 耗时: 0ms, 最新余额: 11

线程 9 扣款成功! 耗时: 0ms, 最新余额: 31

线程 7 扣款成功! 耗时: 0ms, 最新余额: 21

线程 8 扣款成功! 耗时: 0ms, 最新余额: 1

所有线程完成用时: 2ms,

1. 为什么结果完全正确?

正如你观察到的,虽然线程执行顺序看起来是"乱"的(例如线程 9 先完成,线程 7 紧随其后,中间夹着线程 11),但余额的递减(91 -> 81 -> 71...)却是极其严格和连贯的。

这是因为:

  • Redis 是单线程原子操作 :虽然你的 10 个线程在电脑里是并行的,但它们发出的请求在到达 Redis サーバー的一瞬间,会被放入一个队列

  • Lua 的排他性:Redis 每次从队列里取出一个 Lua 脚本并执行。在执行这 1 个脚本期间,其他 9 个请求必须静静等待。

  • 逻辑闭环:因为"判断余额"和"扣除余额"是在同一个 Lua 脚本里完成的,不存在 A 线程判断完余额,还没扣钱,B 线程就插队进来的情况。

2. 深度解析:为什么耗时只有 2ms?

  • 消除自旋等待:分布式锁需要线程不断地"尝试、失败、睡觉、再尝试"。而 Lua 方案中,线程只需"发送、等待回包"。

  • 上下文切换开销消失 :在 2ms 内完成 10 次扣费,意味着平均每次请求(包括网络传输和 Redis 执行)只用了 0.2ms。这几乎达到了现代局域网/本地回环网络的物理极限。

  • 无锁竞争(Lock-free):对于你的 .NET 程序来说,它不再需要维护锁的状态,只是简单地调用了一个函数。

3. 多机并发的终极考量

在真实的生产环境中,如果你有 3 台服务器同时跑这个代码:

  1. 服务器 A 延迟低,先发请求,它拿到的是最新的余额。

  2. 服务器 B 延迟稍高,后发请求。

  3. 结果:Redis 就像一个公正的裁判,谁的包先到,谁就先处理。处理完 A 的包,余额已经变了,B 再处理时看到的就是 A 改完后的结果。**全局一致性(Global Consistency)**得到了完美保证。

4. 经验总结:你学到了什么?

  • 分布式锁:适用于业务逻辑极其复杂(比如扣费后还要写本地文件、调外部耗时 API),且对耗时没那么敏感的场景。

  • Lua 脚本:适用于高并发、对性能要求极高、且业务逻辑能完全在 Redis 内部完成闭环的场景(如秒杀、库存扣减、积分发放)。


下一步建议: 你现在的代码已经非常健壮。如果这个系统要上线,建议给 balanceKey 加一个适当的过期时间,或者在 Lua 脚本里增加一些更复杂的校验(比如账户状态是否冻结)。

相关推荐
oradh18 分钟前
Oracle XTTS实现跨版本迁移和升级(Oracle 11g单库升级至19C RAC集群)
数据库·oracle·11g升级19c·xtts跨版本迁移和升级
z123456789861 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
程序猿DD1 小时前
一个 API Key,统一调用大模型、生图和联网搜索
数据库·网关
TlSfoward2 小时前
抓包代理链路下的 TLS 指纹变化分析 TLSFOWARD抓包工具
数据库·爬虫·网络协议·搜索引擎·php
数智化管理手记2 小时前
账龄分析手工统计易遗漏?自动账龄分析工具怎么搭建
大数据·网络·数据库·人工智能·数据挖掘
LabVIEW开发3 小时前
NI Package Manager安装LabVIEW时InternalServerError错误
网络·数据库·labview·labview知识·labview功能·labview程序
SelectDB3 小时前
PostgreSQL 实时同步到 Apache Doris:一站式 CDC 解决方案
数据库
Database_Cool_3 小时前
AI Agent 长期记忆怎么存?阿里云 PolarDB-X 对接 Mem0 记忆框架实践
数据库·阿里云
时空无限4 小时前
vllm 缓存对模型启动时间的影响
缓存·vllm
会编程的土豆4 小时前
数据库范式
数据库·oracle