layotto icon indicating copy to clipboard operation
layotto copied to clipboard

Add more components for distributed lock API

Open seeflood opened this issue 3 years ago • 14 comments

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

seeflood avatar Jul 02 '21 03:07 seeflood

用zk实现分布式锁-我的设计方案: 要保证 trylock(expire)语义正确性 ,即在expire时间内自动实现解锁,自己删除zk 的节点的 话,且不会因为client的异常导致节点一直存在,只能用zk的临时节点。临时节点和zkclient的生命周期是绑定在一起的,且zk的临时节点不支持设置超时时间,只能自己保持zkclient的存活,所以我想到了下面两种方式: image

ZLBer avatar Jul 02 '21 14:07 ZLBer

@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 avatar Jul 02 '21 15:07 seeflood

@seeflood next i want to implement lock by consul, let me try !

ZLBer avatar Jul 04 '21 13:07 ZLBer

@seeflood next i want to implement lock by consul, let me try !

Sure! I was moved by your passion 👍

seeflood avatar Jul 04 '21 13:07 seeflood

用redis cliuster实现分布式锁-我的初步想法: 参考zk实现讨论,选择基于server TTL的无状态架构,redlock实现用的是redsync,redis cluster中的每个redis启动TTL 95bcc2563a264be0facb3653e9ab196

LXPWing avatar Nov 04 '21 15:11 LXPWing

@LXPWing 啊不好意思这个issue没及时更新,“用redis cliuster实现分布式锁” 这个已经在做了,见https://github.com/mosn/layotto/pull/284 你感兴趣的话可以帮忙review下哈(我最近加班太苦了还没细看

或者你对其他组件实现分布式锁感兴趣么~

seeflood avatar Nov 04 '21 15:11 seeflood

@seeflood 基于mongo实现分布式锁,我目前的想法是使用mongoDB的expire-data机制(TTL) https://docs.mongodb.com/manual/tutorial/expire-data/,或者有什么好的方案我们可以讨论下

LXPWing avatar Nov 22 '21 07:11 LXPWing

@LXPWing 好呀,不过这样描述太简单了,可以描述下tryLock预计做哪些事情、unlock预计做哪些事情,像上面zk的讨论一样;当然如果你觉得这功能比较简单、不需要太多描述的话,可以直接把核心代码写出来、提个PR,大家好帮你看看实现的有没有问题~

另外,有些细节需要考虑:

  • unlock需要compare-and-set 操作,看下mongo用哪个API
  • 实现分布式锁,需要存储系统的写操作有强一致性,mongo能否保证

这些我也不太清楚(不太熟mongo),你可以在写代码之前先调研下哈

seeflood avatar Nov 22 '21 12:11 seeflood

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 avatar Nov 22 '21 14:11 LXPWing

@LXPWing 棒,我修改下issue,这个assign给你哈 过程中遇到啥问题欢迎抛出来讨论~

seeflood avatar Nov 22 '21 15:11 seeflood

go有embed mongodb或者适配mgo语法用于单元测试的数据库吗,谷歌搜了下没找到。真的没有的话我简单实现个的db用来单测

LXPWing avatar Nov 30 '21 14:11 LXPWing

@LXPWing 可以搜搜看,我找到有个java实现的embed mongodb,没看到有go的 https://stackoverflow.com/questions/6437226/embedded-mongodb-when-running-integration-tests

没有的话不要紧,单测里把真正操作mongodb的部分mock掉即可;集成测试里(或者使用demo里)可以用docker启动个真的mongodb

seeflood avatar Nov 30 '21 15:11 seeflood

@seeflood 我想请教下mongodb ut的mock应该从哪里入手(现在用的是本地测试),我提个pr #348

LXPWing avatar Dec 03 '21 14:12 LXPWing

@LXPWing 感谢贡献!我留言了哈 https://github.com/mosn/layotto/pull/348#issuecomment-985604521

seeflood avatar Dec 03 '21 15:12 seeflood

/good-first-issue cancel /help-wanted cancel

Xunzhuo avatar Mar 06 '23 05:03 Xunzhuo

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.

github-actions[bot] avatar Apr 07 '23 02:04 github-actions[bot]

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.

github-actions[bot] avatar Apr 15 '23 02:04 github-actions[bot]