人生第一篇技术文章, redis 实现分布式阻塞非争抢锁

  • 时间:
  • 浏览:0
  • 来源:跟我学网络

这是一个创建于 259 天前的主题,其中的信息可能已经有所发展或是发生改变。

27 条回复    2020-03-15 10:16:37 +08:00

    1

momocraft   259 天前

思路不错

如果有防意外的方案可能更好 (我猜如果进程 1 得到锁后释放前崩溃, 其他线程都要永远阻塞)

    2

Lax   259 天前

持🔒的进程挂掉,🔒就丢了

    3

kkk212   259 天前

@

momocraft

嗯嗯,是的。redis 队列 pop 空了以后队列 key 就不存在了,完整的方案还需要再想想。

    4

fighterlyt   259 天前

这不是类似于传统的 linux 的 pid 防止并发? IT 行业已经根深叶茂了,没必要自己从 0 开始,站在巨人的肩上,才能走的更远

    6

fighterlyt   259 天前

分布式系统,所有操作,除了正常的成功、失败,还必须考虑因为网络分片等原因造成的通信中断等等问题

    7

kkk212   259 天前

@

fighterlyt

不局限在 id 并发业务,感觉这是并行转串行的另一种方案。有点同步消息队列的意思,epoll 思想的一种应用。

    14

kkk212   258 天前

@

fighterlyt

造轮子没啥不好,这样才能更好理解原理。不过这还没到造轮子水平,这个思路是借用 redis 的 epoll 机制和队列,实现分布式的同步排队锁。

    17

pabno   258 天前

这样会导致连接一直被占用,redis 默认最大连接数为 10000,当被阻塞的连接过多的时候会影响性能吧

    18

lasuar   258 天前

你这个不是锁了,而是把 redis 当做调度中间件了,只有从 list 中拿到数据的 process 才能往下执行,没有就阻塞,就类似于令牌桶算法或者 go 的 GPM 调度模型。

    19

kkk212   258 天前 via iPhone

@

pabno

brpop 可以设置最大阻塞时间,不过太高的并发这个思路是不适合的。可以前边再加上限流。

    20

kkk212   258 天前 via iPhone

@

pabno

可以设置最大阻塞时间,不过太高的并发这个思路是不适合的。可以前边再加上限流。

    21

fighterlyt   258 天前

@

kkk212

如果是刚入行或者 1-2 年经验,造这个轮子很正常,但是你都几年 PHP 了,才来造这样的轮子,有点晚了

    22

kkk212   258 天前 via iPhone

@

lasuar

操作系统的锁或者信号量,也需要进程的阻塞和唤醒。思路是利用 redis 的 epoll 机制,做分布式的阻塞和唤醒,也有点像进程间的通信和调度。

    23

kkk212   258 天前 via iPhone

令牌桶属于限流模型吧,感觉是限流和减少了并发,但是还存在并发。限流后的并发,还是需要一种解决方案。

    24

kkk212   258 天前 via iPhone

@

fighterlyt

不对呀,现在 php 并没有这样的轮子。令牌桶机制属于限流,限流后还会存在并发。系统调度是单机的,不是分布式的。然后消息队列是异步消费的,不是同步。

    25

kkk212   258 天前 via iPhone

@

lasuar

令牌桶属于限流模型吧,感觉是限流和减少了并发,但是还存在并发。限流后的并发,还是需要一种解决方案

    26

lasuar   258 天前

你往深了看。

令牌桶的原理是通过控制桶内令牌数量控制并发,相当于是一种调节 /调度机制,这种调度机制实现了限流的功能。转过来看看 brpop 这种方式,上游仍然可以通过 lpush 的频率控制下游执行的速率,这里是不是异曲同工呢,其实是实现了一样的功能,所以我说后者也是一种调度机制,用了 redis 就是做全局(分布式)的调度,同样可以不用 redis 而使用编程语言内部的队列框架实现这个机制(单机)。golang 的 GPM 模型比这个复杂一些,它的上游是操作系统(调度器),下游是 goroutine,goroutine 需要调度器分配 P(processor)和 M(内核线程)才能执行,否则就等待。

    27

kkk212   258 天前 via iPhone

@

lasuar

嗯嗯,相当于“调度”的一种应用,或者说分布式的进程间通信。不过令牌桶的算法是灵活限流,要是限制成比如多少 ms 放行一个进程,处理并发也不太适用。