当前位置:网站首页>Redis(二)分布式锁与Redis集群搭建
Redis(二)分布式锁与Redis集群搭建
2022-06-25 09:37:00 【@@Mr.Fu】
一、 线程锁与分布式锁
线程锁 单体项目
- 单体项目
步骤
- 代码如下
//定义静态全局锁 private readonly static object _lock = new object(); // 控制器中添加代码 lock (_lock) { Stock sto = new Stock(); sto = demoDbContext.stock.Where(p => p.ID == 1).FirstOrDefault(); if (sto.count == 0) { Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "---秒杀结束,无库存"); return Ok("秒杀结束,无库存"); } Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "--秒杀成功;"); //库存减1 sto.count = sto.count - 1; demoDbContext.SaveChanges(); } return Ok("秒杀结束");
- 代码如下
数据库数量为10
如图:用jmeter并发10个线程
如图:运行结果如下:
- 单体项目
分布式锁
条件
- 启动两个实例 5000/5001
- Nginx
- jmeter
- redis
步骤
核心代码
public class RedisLock { public readonly ConnectionMultiplexer connectionMultiplexer; private IDatabase database = null; public RedisLock() { connectionMultiplexer = ConnectionMultiplexer.Connect("127.0.0.1:6380"); database = connectionMultiplexer.GetDatabase(0); } /// <summary> /// 加锁 /// </summary> public void Lock() { while (true) // { //redis_lock 锁名称 // Thread.CurrentThread.ManagedThreadId 线程名称 // TimeSpan.FromSeconds(10) 设置过期时间 防止死锁 bool flag = database.LockTake("redis_lock", Thread.CurrentThread.ManagedThreadId, TimeSpan.FromSeconds(10)); //true :加锁成功 false:加锁失败 if (flag) { break; } Thread.Sleep(10);//防止死锁 等待时间 释放资源。 } } /// <summary> /// 释放锁 /// </summary> public void UnLock() { database.LockRelease("redis_lock", Thread.CurrentThread.ManagedThreadId); connectionMultiplexer.Close(); } }
控制器中使用
[HttpGet] [Route("SubStock")] public IActionResult SubStock() { RedisLock redisLock = new RedisLock(); redisLock.Lock(); Stock sto = new Stock(); sto = demoDbContext.stock.Where(p => p.ID == 1).FirstOrDefault(); if (sto.count == 0) { Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "---秒杀结束,无库存"); //redisLock.UnLock(); return Ok("秒杀结束,无库存"); } Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "--秒杀成功;"); //库存减1 sto.count = sto.count - 1; demoDbContext.SaveChanges(); redisLock.UnLock(); return Ok("秒杀结束"); }
运行两个实例
如图:启动Nginx
如图:数据库库存
如图:jmeter并发10个线程
运行结果如下
分布式锁的使用场景
当集群系统中修改某个字段值时使用分布式锁。分布式锁的设计思路
比如并发两个进程,当第一个进程加锁后,第二个进程加锁会失败,会休眠(10毫秒),直到第一个进程执行完业务代码并释放锁,如果第一个进程处理业务代码超过10毫秒,redis的过期时间也是10毫秒,那么第二个进程进行加锁执行业务代码并释放锁。
备注:休眠的毫秒数可根据自己业务代码定义,毫秒数最好和redis过期时间一致。
二、Redis集群
- 第一代集群 主从集群
如图:
缺点
只有一个master,当maset宕机后,整个redis集群系统无法使用。
- 第二代集群 哨兵集群
如图
第二代集群比第一代集群多了一个sentinel监视的角色,当主节点宕机后,sentinel会从多个从节点中选择一个为主节点。
缺点
- 只有一个master,无法解决高并发写的问题。
- 无法存储海量数据。
- 第三代集群
如图:
优点与缺点
- 优点
- 解决高并发写。
- 存储海量数据。
- 缺点
- 消耗资源比较大。
- 优点
实现
- 条件
- windows 环境
- Redis
- 网盘下载地址
链接:https://pan.baidu.com/s/1-rdemcSLHHFSy3b03EnQsg
提取码:liiz
- 网盘下载地址
- Ruby
- 网盘下载地址
链接:https://pan.baidu.com/s/1NEnVoZzzMyROdm0qNeqw0g
提取码:lf10
- 网盘下载地址
- Ruby 驱动
- 网盘下载地址
链接:https://pan.baidu.com/s/1LkpTstTMenespCx4J0ZtWA
提取码:7wn6
- 网盘下载地址
- 分配主从工具
- 网盘下载地址
链接:https://pan.baidu.com/s/18ah0ePiGr9XCukRsRdIiXw
提取码:0e02
- 网盘下载地址
- 条件
步骤
配置集群文件 (6个实例) 配置6个配置文件【并将6个配置拷贝到redis根目录下】 配置不能有中文注释也不行!!!!
port 6380 #端口 bind 127.0.0.1 #IP地址 appendonly yes #数据保存格式为aof appendfilename "appendonly.6380.aof" #数据保存文件 cluster-enabled yes #是否开启集群 cluster-config-file nodes.6380.conf #集群节点配置文件 cluster-node-timeout 15000 #节点超时时间 cluster-slave-validity-factor 10 #验证slaver节点次数 cluster-migration-barrier 1 # cluster-require-full-coverage yes #master节点和slaver节点之间是否全量复制
执行所有实例
redis-server.exe redis.6380.conf redis-server.exe redis.6381.conf redis-server.exe redis.6382.conf redis-server.exe redis.6383.conf redis-server.exe redis.6384.conf redis-server.exe redis.6385.conf
如图:
安装 ruby
ruby --version #验证是否安装成功
redis-cluster 驱动安装命令
#进入 ruby安装目录bin文件下执行安装命令 ruby gem install --local D:\Assembly\redis\Windows\redis-cluster\redis-3.2.2.gem #驱动文件路径
执行分配主从工具脚本
ruby redis-trib.rb create --replicas 1 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385 #写入所有的实例地址和端口号 # --replicas 1:是否分配3主3从 一个主节点和从节点
如图:
查看是否分配成功
当6个实例不停输出日志,说明已经分配成功。
redis集群内部关系结构图
如图:在redis集群中,每个节点都是相互通信的,用的协议是Gossip协议。
redis集群内部数据存储原理
- Slot槽 主节点有槽[平均分配] 从节点没有槽 总共有16384个槽
ruby redis-trib.rb check 127.0.0.1:6380
- Hash算法
- 取模算法
当客户端将数据写入节点中时,节点会将key使用hash算法取到一个固定长度数值,然后对槽总数【16384】用取模算法进行取模,得到的数值后在到各个主节点中查看数值在哪个节点的槽数数值之间,在将数据写到那个主节点中。
- Slot槽 主节点有槽[平均分配] 从节点没有槽 总共有16384个槽
边栏推荐
- puzzle(019.2)六边锁
- Mengyou Technology: six elements of tiktok's home page decoration, how to break ten thousand dollars in three days
- Is it safe for Huatai Securities to open an account on it? Is it reliable?
- Question B of the East China Cup: how to establish a population immune barrier against novel coronavirus?
- Fluent: target support file /pods runner / pods runner frameworks Sh: permission denied - stack overflow
- Reza RA series - development environment construction
- How to "transform" small and micro businesses (II)?
- Swift recursively queries the array for the number closest to the specified value
- Minio基本使用与原理
- CyCa 2022 children's physical etiquette primary teacher class Shenzhen headquarters station successfully concluded
猜你喜欢
Jetpack compose layout (III) - custom layout
[zufe expense reimbursement] zhecai invoice reimbursement specification (taking Xinmiao reimbursement as an example), which can be passed in one trip at most
链表 删除链表中的节点
manhattan_ Slam environment configuration
Flutter dialog: cupertinoalertdialog
[competition - Rural Revitalization] experience sharing of Zhejiang Rural Revitalization creative competition
8、智慧交通项目(1)
x86的编码格式
Unique Wulin, architecture selection manual (including PDF)
[competition -kab micro entrepreneurship competition] KAB National College Students' micro entrepreneurship action participation experience sharing (including the idea of writing the application form)
随机推荐
Arduino bootloader burning summary
Oracle function trigger
【mysql学习笔记21】存储引擎
Applet cloud development joint table data query and application in cloud function
Flutter dialog: cupertinoalertdialog
js工具函数,自己封装一个节流函数
[buuctf.reverse] 121-125
使用EVO
Mengyou Technology: six elements of tiktok's home page decoration, how to break ten thousand dollars in three days
Neat Syntax Design of an ETL Language (Part 2)
Pytorch_Geometric(PyG)使用DataLoader报错RuntimeError: Sizes of tensors must match except in dimension 0.
(forwarding articles) after skipping multiple pages, shuttle returns to the first page and passes parameters
CYCA少儿形体礼仪 乐清市培训成果考核圆满落幕
PMP考试多少分算通过?
The problem of wirengpi program running permission
Creo makes a mobius belt in the simplest way
Jetpack compose layout (I) - basic knowledge of layout
The problem of automatic page refresh after the flyer WebView pops up the soft keyboard
Best producer consumer code
Cassava tree disease recognition based on vgg16 image classification