Skip to content

Commit 0124d4a

Browse files
committed
docs: update rueidislock/README.md and add a benchmark result to it
Signed-off-by: Rueian <[email protected]>
1 parent 6af9676 commit 0124d4a

File tree

1 file changed

+79
-9
lines changed

1 file changed

+79
-9
lines changed

rueidislock/README.md

+79-9
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ import (
1313

1414
func main() {
1515
locker, err := rueidislock.NewLocker(rueidislock.LockerOption{
16-
ClientOption: rueidis.ClientOption{InitAddress: []string{"node1:6379", "node2:6380", "node3:6379"}},
17-
KeyMajority: 2, // please make sure that all your `Locker`s share the same KeyMajority
16+
ClientOption: rueidis.ClientOption{InitAddress: []string{"localhost:6379"}},
17+
KeyMajority: 1, // Use KeyMajority=1 if you have only one Redis instance. Also make sure that all your `Locker`s share the same KeyMajority.
18+
NoLoopTracking: true, // Enable this to have better performance if all your Redis are >= 7.0.5.
1819
})
1920
if err != nil {
2021
panic(err)
@@ -37,21 +38,90 @@ func main() {
3738

3839
## Features backed by the Redis Client Side Caching
3940
* The returned `ctx` will be canceled automatically and immediately once the `KeyMajority` is not held anymore, for example:
40-
* Redis down.
41-
* Related keys has been deleted by other program or administrator.
42-
* The waiting `Locker.WithContext` will try acquiring the lock again automatically and immediately once it has been released by someone even from other program.
41+
* Redis are down.
42+
* Acquired keys has been deleted by other programs or administrators.
43+
* The waiting `Locker.WithContext` will try acquiring the lock again automatically and immediately once it has been released by someone or by another program.
4344

4445
## How it works
4546

4647
When the `locker.WithContext` is invoked, it will:
4748

48-
1. Try acquiring 3 keys (given that `KeyMajority` is 2), which are `rueidislock:0:my_lock`, `rueidislock:1:my_lock` and `rueidislock:2:my_lock`, by sending redis command `SET NX PXAT` or `SET NX PX` if `FallbackSETPX` is set.
49+
1. Try acquiring 3 keys (given that the default `KeyMajority` is 2), which are `rueidislock:0:my_lock`, `rueidislock:1:my_lock` and `rueidislock:2:my_lock`, by sending redis command `SET NX PXAT` or `SET NX PX` if `FallbackSETPX` is set.
4950
2. If the `KeyMajority` is satisfied within the `KeyValidity` duration, the invocation is successful and a `ctx` is returned as the lock.
50-
3. If the invocation is not successful, it will wait for client-side caching notification to retry again.
51-
4. If the invocation is successful, the `Locker` will extend the `ctx` validity periodically and also watch client-side caching notification for canceling the `ctx` if the `KeyMajority` is not held anymore.
51+
3. If the invocation is not successful, it will wait for client-side caching notifications to retry again.
52+
4. If the invocation is successful, the `Locker` will extend the `ctx` validity periodically and also watch client-side caching notifications for canceling the `ctx` if the `KeyMajority` is not held anymore.
5253

5354
### Disable Client Side Caching
5455

5556
Some Redis provider doesn't support client-side caching, ex. Google Cloud Memorystore.
5657
You can disable client-side caching by setting `ClientOption.DisableCache` to `true`.
57-
Please note that when the client-side caching is disabled, rueidislock will only try to re-acquire locks for every ExtendInterval.
58+
Please note that when the client-side caching is disabled, rueidislock will only try to re-acquire locks for every ExtendInterval.
59+
60+
## Benchmark
61+
62+
```bash
63+
▶ go test -bench=. -benchmem -run=.
64+
goos: darwin
65+
goarch: arm64
66+
pkg: rueidis-benchmark/locker
67+
Benchmark/rueidislock-10 20103 57842 ns/op 1849 B/op 29 allocs/op
68+
Benchmark/redislock-10 13209 86285 ns/op 8083 B/op 225 allocs/op
69+
PASS
70+
ok rueidis-benchmark/locker 3.782s
71+
```
72+
73+
```go
74+
package locker
75+
76+
import (
77+
"context"
78+
"testing"
79+
"time"
80+
81+
"github.com/bsm/redislock"
82+
"github.com/redis/go-redis/v9"
83+
"github.com/redis/rueidis"
84+
"github.com/redis/rueidis/rueidislock"
85+
)
86+
87+
func Benchmark(b *testing.B) {
88+
b.Run("rueidislock", func(b *testing.B) {
89+
l, _ := rueidislock.NewLocker(rueidislock.LockerOption{
90+
ClientOption: rueidis.ClientOption{InitAddress: []string{"127.0.0.1:6379"}},
91+
KeyMajority: 1,
92+
NoLoopTracking: true,
93+
})
94+
defer l.Close()
95+
b.ResetTimer()
96+
b.RunParallel(func(pb *testing.PB) {
97+
for pb.Next() {
98+
_, cancel, err := l.WithContext(context.Background(), "mylock")
99+
if err != nil {
100+
panic(err)
101+
}
102+
cancel()
103+
}
104+
})
105+
b.StopTimer()
106+
})
107+
b.Run("redislock", func(b *testing.B) {
108+
client := redis.NewUniversalClient(&redis.UniversalOptions{Addrs: []string{"127.0.0.1:6379"}})
109+
locker := redislock.New(client)
110+
defer client.Close()
111+
b.ResetTimer()
112+
b.RunParallel(func(pb *testing.PB) {
113+
for pb.Next() {
114+
retry:
115+
lock, err := locker.Obtain(context.Background(), "mylock", time.Minute, nil)
116+
if err == redislock.ErrNotObtained {
117+
goto retry
118+
} else if err != nil {
119+
panic(err)
120+
}
121+
lock.Release(context.Background())
122+
}
123+
})
124+
b.StopTimer()
125+
})
126+
}
127+
```

0 commit comments

Comments
 (0)