Redis-篇

  • Redis-篇已关闭评论
  • 151 次浏览
  • A+
所属分类:.NET技术
摘要

在一般业务中秒杀功能,存在并发问题如果两个线程同时执行插入操作导致数据库id 自增 同时为一个数 就会导致写入数据失败
全局Id生成器


实战篇 实现秒杀下单

全局唯一ID

在一般业务中秒杀功能,存在并发问题如果两个线程同时执行插入操作导致数据库id 自增 同时为一个数 就会导致写入数据失败
全局Id生成器
Redis-篇

点击查看代码
public static class RedisIdWork {     private readonly static long BEGIN_TIMSTAMP = 1678966413L;     private readonly static int COUNT_BITS = 32;     public static long nextId(string keyPrefix)     {         //1、生成时间戳         long nowTimeSeconds = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();         long timesamp = nowTimeSeconds - BEGIN_TIMSTAMP;         //2、生成序列号         string date = DateTime.Now.ToString("yyyyMMdd");         var redis = new RedisHelper();         long count = redis.database().StringIncrement("icr:" + keyPrefix + ":" + date, 1);         //3、拼接返回         return timesamp << COUNT_BITS | count;     }  } 

Redis-篇

秒杀超卖问题

同时间 抢购会导致库存超卖问题(多个线程交叉执行导致的)例如两个线程同时查询到库存为 1 (此时库存中满足大于0 所以两个都会执行扣减)

悲观锁 AND 乐观锁

悲观锁会认为线程安全一定会发生 所以在操作数据之前就先获取锁,确保线程串行执行
Redis-篇
主要说一下乐观锁,常见的处理方法
版本号法。乐观锁的关键就是判断之前查询到的数据是否有被修改过
Redis-篇
CAS 法 (可以说是版本号法的升级版)
如果说是一个减库存操作,可以使用库存数据作为版本标识

生成的Sql 语句

where id = ? and version > 0
为什么版本要大于0 而不是等于 (因为只要是在这个区间就可以 不小于0 即可)

一人一单秒杀
分布式锁

Redis-篇
Redis-篇

redis 分布式锁

场景:目的是为了解决多台相同服务之间同时工作产生的并发问题,(例如订单系统,假设订单系统部署在两台机器上,但是库存是固定的,接着每个订单系统实例都去数据库里查了一下,由于并发问题导致超卖,这肯定是不允许的)(当然并发特别大的话是需要进行分段数据,数据分段会导致整体业务流程更加复杂,如果没有这方面的需求建议不要使用)
SETNX LOCK Thread1
为了保证原子性 (带上过期时间) 如果不设置过期时间会出现死锁问题
Set lock thread1 EX 10 NX

高级篇

数据持久化

RDB模式

RDB (redis Database Backup file)数据备份文件
save # redis主进程执行备份,会阻塞所有命令
bgsave #开启子线程执行备份,避免主线程受到影响
save 5 1 (表示五秒内有一次修改就执行备份操作) 可以在redis.conf中修改
Redis-篇
bgsave fork主进程开启一个子进程,共享内存空间,(这时候物理内存是只读模式)
如果会有写入操作会拷贝一份数据
Redis-篇

AOF模式

AOF全称为 Append only file(追加文件),redis会处理每一个写入命令都会记录在aof文件中
AOf默认是关闭的
appendonly yes appendfilename "appendonly.aof"
Redis-篇

AOF和RDB两者区别

Redis-篇

分布式主从集群

搭建主从集群

单节点Redis并发能力邮上线,要提升并发能力需要搭建主从集群,实现读写分离(大部分业务都是读的业务)
一般写入到master 节点,同步到子节点
需要三台redis 服务器
Redis-篇

修改redis.conf文件