
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 分布式系统,所有操作,除了正常的成功、失败,还必须考虑因为网络分片等原因造成的通信中断等等问题 |
&bsp; 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(内核线程)才能执行,否则就等待。 |