php 好几年了,突然觉得写文章记录很重要。一个能加深理解,一个能技术分享。看 redis 的 brpop 命令时候,突发奇想,这可以实现非争抢阻塞锁。于是有了这篇文章,看看这个锁帅不帅,欢迎拍砖。 在简书上: https://www.jianshu.com/p/6dbc44defd94
1
momocraft 2020-03-14 19:55:51 +08:00
思路不错
如果有防意外的方案可能更好 (我猜如果进程 1 得到锁后释放前崩溃, 其他线程都要永远阻塞) |
2
Lax 2020-03-14 20:00:50 +08:00
持🔒的进程挂掉,🔒就丢了
|
4
fighterlyt 2020-03-14 20:11:28 +08:00
这不是类似于传统的 linux 的 pid 防止并发? IT 行业已经根深叶茂了,没必要自己从 0 开始,站在巨人的肩上,才能走的更远
|
6
fighterlyt 2020-03-14 20:17:28 +08:00
分布式系统,所有操作,除了正常的成功、失败,还必须考虑因为网络分片等原因造成的通信中断等等问题
|
7
kkk212 OP @fighterlyt 不局限在 id 并发业务,感觉这是并行转串行的另一种方案。有点同步消息队列的意思,epoll 思想的一种应用。
|
8
kkk212 OP @fighterlyt 有个思路就先写出来了,用于项目还需要完善。
|
9
23571113 2020-03-14 20:25:35 +08:00 via Android
|
11
fighterlyt 2020-03-14 20:59:48 +08:00
@kkk212 并发都是资源竞争
|
12
kkk212 OP @fighterlyt 是竞争,用排队思路解决了争抢
|
13
fighterlyt 2020-03-14 21:35:32 +08:00
@kkk212 资源竞争最传统的解决思路就是排队,临界区,建议锁。你这是重复造了个轮子
|
14
kkk212 OP @fighterlyt 造轮子没啥不好,这样才能更好理解原理。不过这还没到造轮子水平,这个思路是借用 redis 的 epoll 机制和队列,实现分布式的同步排队锁。
|
15
fighterlyt 2020-03-14 21:46:49 +08:00
@kkk212 还有个重要的问题,brpop 并发量大,容易导致读取错误,个人经验,忘了出处了
|
16
kkk212 OP @fighterlyt 嗯嗯 这个没想到 我再看看
|
17
pabno 2020-03-15 00:20:26 +08:00
这样会导致连接一直被占用,redis 默认最大连接数为 10000,当被阻塞的连接过多的时候会影响性能吧
|
18
lasuar 2020-03-15 08:04:48 +08:00
你这个不是锁了,而是把 redis 当做调度中间件了,只有从 list 中拿到数据的 process 才能往下执行,没有就阻塞,就类似于令牌桶算法或者 go 的 GPM 调度模型。
|
19
kkk212 OP @pabno brpop 可以设置最大阻塞时间,不过太高的并发这个思路是不适合的。可以前边再加上限流。
|
21
fighterlyt 2020-03-15 09:29:06 +08:00
@kkk212 如果是刚入行或者 1-2 年经验,造这个轮子很正常,但是你都几年 PHP 了,才来造这样的轮子,有点晚了
|
22
kkk212 OP @lasuar 操作系统的锁或者信号量,也需要进程的阻塞和唤醒。思路是利用 redis 的 epoll 机制,做分布式的阻塞和唤醒,也有点像进程间的通信和调度。
|
23
kkk212 OP 令牌桶属于限流模型吧,感觉是限流和减少了并发,但是还存在并发。限流后的并发,还是需要一种解决方案。
|
24
kkk212 OP @fighterlyt 不对呀,现在 php 并没有这样的轮子。令牌桶机制属于限流,限流后还会存在并发。系统调度是单机的,不是分布式的。然后消息队列是异步消费的,不是同步。
|
25
kkk212 OP @lasuar 令牌桶属于限流模型吧,感觉是限流和减少了并发,但是还存在并发。限流后的并发,还是需要一种解决方案
|
26
lasuar 2020-03-15 10:05:31 +08:00
你往深了看。
令牌桶的原理是通过控制桶内令牌数量控制并发,相当于是一种调节 /调度机制,这种调度机制实现了限流的功能。转过来看看 brpop 这种方式,上游仍然可以通过 lpush 的频率控制下游执行的速率,这里是不是异曲同工呢,其实是实现了一样的功能,所以我说后者也是一种调度机制,用了 redis 就是做全局(分布式)的调度,同样可以不用 redis 而使用编程语言内部的队列框架实现这个机制(单机)。golang 的 GPM 模型比这个复杂一些,它的上游是操作系统(调度器),下游是 goroutine,goroutine 需要调度器分配 P(processor)和 M(内核线程)才能执行,否则就等待。 |