作者回复: 我觉得学习技术可以分两个维度: 1、一个原理论上或者广度上的,通过了解技术的业务场景、解决问题的原理和方案,以及这个技术需要注意和思辨的地方来掌握这个技术,这样在我们碰到这个业务场景是,能立即明白这是什么问题,应该怎么解决,难度和注意点是什么。一般来说,一些技术上不正确的决策,都是由于这些知识盲区导致的。 2、另一个是实践上或者深度上的,在业务上确定需要这个技术的时候,依据之前的理论知识,对开源项目进行选型或者选择自研都可以。这一部分可以在有需要的时候再做,现在可以先快速拓宽知识的边界。 一般理论上的知识会比较稳定,不容易过时,而具体项目的实现,首先项目本身会迭代而改变,另外后面也会有其他新的项目出来,是会快速改变的。所以这个专栏主要是对技术原理上的讨论,这个部分是需要对这个方向有一定经验的人来总结的,如果你对某一个知识点非常感兴趣,那么在学习好技术原理后,可以对你感兴趣的一个或几个项目来做具体的分析,一定会受益匪浅。
作者回复: 👍👍
作者回复: 几乎不是要求非常高正确性的场景,都可以用Redis,不过业务量上来后,换成zk要好好评估,zk的性能比Redis要差了一个数量级。 比较好的方式还是以性能和正确性来选择分布式锁,课程中有讨论。
作者回复: 这里的意思是指互斥语义是一定能保证同一时刻有一个客户端能获取锁的,但是现在的情况是所有的客户端都不能获取到锁。
作者回复: 👍
作者回复: 可以在加锁成功的时候,写入当前获得锁的进程ID,这样父进程在子进程崩溃的时候,去检查一下当前锁是否为挂掉的子进程持有的,如果是的,就释放锁。
作者回复: 比如 a 操作或者锁了,并且版本号为 1,但是由于 GC 等原因,操作被挂起了。在 a 操作挂起的时候,锁过期了,b操作又获得了锁,版本号为 2,并且写入成功。这个时候,a 操作已经恢复了,再进行写入操作的时候,就会出现版本回退的问题。
作者回复: 我们往共享存储中写入数据的正确性: 一种是从外部通过 fencing token 来保证,其实是一种抽象泄漏。 另一种是由共享存储自身来保证,所有的分布式数据库都是这样做的,这样的抽象对使用者更友好。
作者回复: 比如 锁服务 的逻辑颁发锁成功,但是通过网络到客户端的时候发生丢包,还没有重试的时候,客户端已经超时了,或者是客户端已经收到锁,但是响应发送到锁服务的时候超时了。 对于锁服务来说,它不能区分超时是发生在客户端收到锁之前还是锁之后。
作者回复: etcd做分布式锁,在存储上的选择是没有问题,已经是一致性最好的存储了。 文章讨论的是分布式锁的正确性问题:一般在这种情况下,锁服务在进程加锁成功后,会设置一个超时时间,如果进程持有锁超时后,将锁再颁发给其他的进程,就会导致一把锁被两个进程持有的情况出现,使锁的互斥语义被破坏。