请各位大佬帮忙看看我的思路是不是有问题,如果能抛砖引玉得到更完善的思路那就更好了
我目前的思路是:
client 生成随机 token + 超时时间,用 setnx 获取锁
若获取成功则另外建立 readonly
的连接去读取锁所在的 master 节点对应的 slave 节点(假设有 N 个),检测是否同步锁同步成功(防止在同步前 master crash,slave 对外服务导致可以同时有两个 client 获取锁)当发现 N/2 + 1 的 slave 同步成功后停止检查返回成功
释放锁则使用 lua script 来做,只有在客户端 token 值等于锁当前值时才能释放锁(若持有锁的 client crash 了则等到超时自动释放),释放锁后同获取锁时一样检查 slave 内对应值是否还为 token 值,如果还为 token 值则认为锁没有释放成功
1
zhx1991 2017-09-25 22:27:32 +08:00
没太懂啊
都读主不就行了吗? 考虑从节点锁状态是否成功同步是做主会挂的准备吗? |
2
BBCCBB 2017-09-25 22:28:36 +08:00
直接看 redission 的实现思路, 或者 redis 作者的那个 redlock
|
3
zhx1991 2017-09-25 22:29:13 +08:00
这样依然是没法避免持有两把锁的
redis 本身的设计理念, 对于 CAP 来说是既不满足 C 也不满足 A 希望能有强一致的读写(锁永远不允许同时有两处获得)请用真正的 CP 系统比如 zk |
4
jason0916 OP @BBCCBB redisson 的话我简单看了下,可能有疏漏哈,貌似更多的是处理竞争这块,没怎么看到他对于主从模型的同步问题的解决,倒是跟 redis cluster 关系不大了。redlock 我有考虑过,这里对从节点的检查就是用的类似的思路(对于超时时间的处理还在考虑中)。主要是因为 redis cluster 里面没办法把一个 key hash 到不同的节点。而 redlock 算法更多的是给“由单点 redis 组成的集群”使用的,要求一个 key 可以 hash 到集群内不同的节点上。
|
6
BBCCBB 2017-09-25 23:34:12 +08:00
redission 文档里第一部分就介绍了支持集群模式,主从模型,哨兵模式,可以深入研究
|
7
orafy 2017-09-26 00:25:18 +08:00 via Android
可以用 etcd 呀
|
8
hand515 2017-09-26 08:12:59 +08:00
对一致性有要求的,我建议 zookeeper 或 etcd。
|
9
owt5008137 2017-09-26 08:42:39 +08:00 via Android
|
10
jason0916 OP @BBCCBB 嗯,我有看到他 wiki 里的配置,确实是支持 sentinel 和 cluster 的,所以研究他代码的时候就感觉很奇怪,貌似他的 redlock 的实现是由用户选择多个 key 来合并成一把锁,这样的话 key hash 的问题就交给用户去决定了,我就是对这一点抱有疑惑 [捂脸]
|
11
jason0916 OP |
12
jason0916 OP @owt5008137 etcd 我了解不多,不过 zk 的话因为有自带的逻辑时钟做 fencing,感觉一致性上比 redis 强一些。话说大佬你觉得我的实现方法可以用么?我想了几个场景目前想到可能出现的有两个问题,想听听你的看法。
1. redlock 里面用于获取多个 master node 锁的时间消耗被算到了超时时间内,比如说超时设了 5s,获取用了 3s,那么超时就只剩 2s 了,这个应该在我这边应该算进超时时间么(我比较倾向于算进去,但是不肯定) 2. 在较差的网络状况下是否应该 sleep 一段时间再去检查 slave node 以防止获取锁时同步延时过大导致所有客户端一直获取不到锁 |
13
owt5008137 2017-09-26 14:11:33 +08:00 via Android
@jason0916 我觉得思路上没什么问题。关于超时时间,我认为肯定是要算进去的呀,另外可以试试 value 里就记下超时时间。然后加容忍时间,如果有大于 N/2 的节点都成功后,检查超时时间是否在容忍值内,如果已经大于超时时间-容忍值了就视为加锁失败,然后加锁的时候也需要当前时间比原来的 value 的时间+容忍值大。一般内网的延迟大概都能估计出来吧。
这个肯定没有 zk 或者 etcd 一致性强的,极端情况下会有锁已经过期,但是 client 认为没过期的情况。但是很容易性能完爆它。 |
14
jason0916 OP @owt5008137 妥,谢谢大佬~
|