kvrocks
kvrocks copied to clipboard
Support Watch/Unwatch
I would like to use Watch and Unwatch for full transaction support.
yinqiwen/ardb has a working watch/unwatch impl in case that is useful as a reference.
https://github.com/yinqiwen/ardb
Sure, let's add to the 2.0 plan: https://github.com/KvrocksLabs/kvrocks/projects/1#card-63523056
@git-hulk any update about this feature?
Does implementing these two commands have a performance impact? @ShooterIT
Does implementing these two commands have a performance impact? @ShooterIT
Another concern was that we didn't implement multi-keys lock and it's ready now, maybe we can have a try.
I'd also like to get watch/unwatch implemented as it is required by https://juicefs.com/
2022/08/31 18:25:33.286338 juicefs[26231] <WARNING>: checking counter lastCleanupSessions: ERR unknown command watch [base.go:303] 2022/08/31 18:25:35.278170 juicefs[26231] <WARNING>: checking counter lastCleanupFiles: ERR unknown command watch [base.go:389] 2022/08/31 18:25:45.327653 juicefs[26231] <WARNING>: checking counter lastCleanupSessions: ERR unknown command watch [base.go:303]
@dirkpetersen Thanks for your feedback
Looking forward to this as well. Needed to implement a distributed counter / id generator
@0xgeert Thanks for your feedback, will add it to 2023 planning.
We would very much like to see this feature too. It would essentially make it a fully transactional DB. Ideally, it would be nice if it wouldn't affect the performance that much.
Our most common use case would be this:
WATCH key
GET key
MULTI
SET key modifiedValue
EXEC
@DenizPiri Thanks, we are also very eager to have this feature but didn't take much time to dive deep. I think it's time to do it now.
Consider some implemenation methods from scratch:
by snapshots: It seems to be more "elegant", but is more heavy: make snapshots by each watched key many affect many details in rocksdb, e.g. the GC process and more. And it has some different behavior than redis:
set a 1
watch a
set a 1
multi
get a
exec
Redis will return nil, while the snapshot method will continue to execute this redis txn (and return 1).
by command & key tracing: It seems a little complicated but more clean and has more less influence on storage.
I will try the second way these days, but maybe slow since I have lots of other things to do.
@git-hulk @ShooterIT @caipengbo
Thanks for @PragmaTwice driving this design.
Redis will return nil, while the snapshot method will continue to execute this redis txn (and return 1).
So we will check if the watched keys are modified by value, is it right?
So we will check if the watched keys are modified by value, is it right?
We will do this as what redis does: just trace commands by flags and key arguments instead of comparing by value, since the snapshot way is too heavy.
Got it, thanks for your explanation.
Personally, I thin using snapshot is too heavy, it may block record gc, and maintaining it is heavy, and logic of snapshot might be heavy.
Using watchkeys
as hashmap, and maintaining them seems ok, though it may meets some concurrent and performance related issue. I think this is ok and better.
Another way is, like replication, find these keys and ops from WAL.
Comparing to check keys in commands and wal, the first one may not has best performance, but it's easy and real-time. The later may have better performance, but user may get the message a bit later.
Hi, folks. This watch/unwatch command has been merged into unstable, welcome to have a try if you are interested.
@git-hulk We started utilizing this in one of our projects. We migrated from redis. It has been running for the last 2 days. It seems to be working very well so far. 🚀 Doing around 1500ops/sec, mostly single key WATCH -> GET -> MULTI -> SET -> EXEC commands.
If we were to use WATCH/UNWATCH support more widely in our other projects too, assuming that 99.9% of the time transactions will execute without any conflicts. Should we expect degraded performance, possibly because of a lock contention?
@DenizPiri Thanks for your feedback and give the credit to @PragmaTwice great work.
If we were to use WATCH/UNWATCH support more widely in our other projects too, assuming that 99.9% of the time transactions will execute without any conflicts. Should we expect degraded performance, possibly because of a lock contention?
Yes, it may have a performance issue since the MULTI-EXEC is an exclusive operation even though most of the commands are no conflicts. I'm also seeking a way to improve this situation, but you can have a simple benchmark before using it.
If we were to use WATCH/UNWATCH support more widely in our other projects too, assuming that 99.9% of the time transactions will execute without any conflicts. Should we expect degraded performance, possibly because of a lock contention?
I think compared to the performance downgrade of WATCH, the downgrade of MULTI-EXEC may be more large. So if you already use some MULTI-EXEC pattern, the runtime cost to use WATCH may be less.
You can try it in your case and share performance data with us if you like.