layotto
layotto copied to clipboard
Add more components for distributed lock API
What would you like to be added:
Add more components for distributed lock API. Choose an open source component or cloud service (such as zookeeper) you like to implement distributed lock API References:pull request #100
- [x] redis standalone done
- [x] redis cluster (with redlock) . see https://github.com/mosn/layotto/pull/284
- [x] zookeeper assigned.see #111
- [x] etcd assigned.see #128
- [x] Consul see #140
- [x] Mongo. assigned to @LXPWing
- [ ] Cassandra
- [ ] anything else. e.g. some build block provided by AWS
chinese: 选择一个你喜欢的开源组件或云服务(比如zookeeper)实现分布式锁API 参考资料:pull request #100
Why is this needed:
Currently we only support standalone Redis as a distributed lock store.We need more components to make it useful
用zk实现分布式锁-我的设计方案: 要保证 trylock(expire)语义正确性 ,即在expire时间内自动实现解锁,自己删除zk 的节点的
话,且不会因为client的异常导致节点一直存在,只能用zk的临时节点。临时节点和zkclient的生命周期是绑定在一起的,且zk的临时节点不支持设置超时时间,只能自己保持zkclient的存活,所以我想到了下面两种方式:
@ZLBer 优秀! 第一个方案需要开一个新协程、执行延迟任务(在xx秒后删除临时节点) go语言实现延迟任务很简单,用time.After生成一个channel就行,比如https://studygolang.com/articles/20640
方案二是说trylock其实不用传过期时间,只要长连接没断就可以自动续租,长连接断了就停止续租 这是个很有意思的方案,可以抛出来大家讨论下、修改API 第二个方案有些细节要想下,比如:
- 怎么感知长连接断没断(grpc是用stream 还是靠连接报错?),
- 能否保证正确性(会不会网络抖动导致unlock失败了,但是长连接没断,或者虽然断了但是grpc默认帮我们重连了、我们没感知到,导致丢了unlock消息)、
- grpc会不会默认做一些连接断掉后重连之类的事情(我不知道啊猜的),
- 长连接断掉后又重新连上来,sidecar要不要帮忙重新续租?
- API spec依赖grpc的特性是否合适
- 以及建议把api改成啥样
很有启发,我明天查下grpc相关资料
@seeflood next i want to implement lock by consul, let me try !
@seeflood next i want to implement lock by consul, let me try !
Sure! I was moved by your passion 👍
用redis cliuster实现分布式锁-我的初步想法: 参考zk实现讨论,选择基于server TTL的无状态架构,redlock实现用的是redsync,redis cluster中的每个redis启动TTL
@LXPWing 啊不好意思这个issue没及时更新,“用redis cliuster实现分布式锁” 这个已经在做了,见https://github.com/mosn/layotto/pull/284 你感兴趣的话可以帮忙review下哈(我最近加班太苦了还没细看
或者你对其他组件实现分布式锁感兴趣么~
@seeflood 基于mongo实现分布式锁,我目前的想法是使用mongoDB的expire-data机制(TTL) https://docs.mongodb.com/manual/tutorial/expire-data/,或者有什么好的方案我们可以讨论下
@LXPWing 好呀,不过这样描述太简单了,可以描述下tryLock预计做哪些事情、unlock预计做哪些事情,像上面zk的讨论一样;当然如果你觉得这功能比较简单、不需要太多描述的话,可以直接把核心代码写出来、提个PR,大家好帮你看看实现的有没有问题~
另外,有些细节需要考虑:
- unlock需要compare-and-set 操作,看下mongo用哪个API
- 实现分布式锁,需要存储系统的写操作有强一致性,mongo能否保证
这些我也不太清楚(不太熟mongo),你可以在写代码之前先调研下哈
1.mongo在写时可以在客户端设置(Write Concern)mongo的写时一致性https://docs.mongodb.com/manual/reference/write-concern/ 2.trylock的时候启动客户端设置(Write Concern),进行cas更新数据 3.unlock时进行cas删除数据 4.关于compare-and-set 操作这个问题我需要调研mongo-go-driver的api文档 (第一次接触mongo-go) ,如果文档没给可能需要在代码层面上实现cas 5.使用server TTL(expire-data) 防止死锁 大致思路是这样,mongo数据库的具体细节我周末去调研下。
@LXPWing 棒,我修改下issue,这个assign给你哈 过程中遇到啥问题欢迎抛出来讨论~
go有embed mongodb或者适配mgo语法用于单元测试的数据库吗,谷歌搜了下没找到。真的没有的话我简单实现个的db用来单测
@LXPWing 可以搜搜看,我找到有个java实现的embed mongodb,没看到有go的 https://stackoverflow.com/questions/6437226/embedded-mongodb-when-running-integration-tests
没有的话不要紧,单测里把真正操作mongodb的部分mock掉即可;集成测试里(或者使用demo里)可以用docker启动个真的mongodb
@seeflood 我想请教下mongodb ut的mock应该从哪里入手(现在用的是本地测试),我提个pr #348
@LXPWing 感谢贡献!我留言了哈 https://github.com/mosn/layotto/pull/348#issuecomment-985604521
/good-first-issue cancel /help-wanted cancel
This issue has been automatically marked as stale because it has not had recent activity in the last 30 days. It will be closed in the next 7 days unless it is tagged (pinned, good first issue or help wanted) or other activity occurs. Thank you for your contributions.
This issue has been automatically closed because it has not had activity in the last 37 days. If this issue is still valid, please ping a maintainer and ask them to label it as pinned, good first issue or help wanted. Thank you for your contributions.