redis distributed lock
redis 分布式锁实现, 原理:redis 分布式锁实现
lock的超时时间:timeout_ms
Lock & UnLock
lockkey:="lock-key"timeout_ms:=3000locked, ex:=rddlock.Lock(rds, lockkey, timeout_ms)
deferreelock.UnLock(rds, lockkey, ex)LockRetry
重试retry_times次,尝试获得锁
retry_times:=10locked, ex:=reelock.LockRetry(rds, lockkey, timeout_ms, retry_times) // get lock by retrydeferreelock.UnLock(rds, lockkey, ex)UnLockUnsafe
locked, _:=rddlock.Lock(rds, lockkey, timeout_ms)
deferreelock.UnLockUnsafe(rds, lockkey)UnLockSafe
预留安全时间,释放锁。
locked, _:=rddlock.Lock(rds, lockkey, timeout_ms)
safeDelTime_ms:=40deferreelock.UnLockSafe(rds, lockkey, safeDelTime_ms)SyncDo
err:=SyncDo(rds, lockkey, timeout_ms, func(timeoutchanbool) chanbool {
ret:=make(chanbool, 1)
gofunc() {
fmt.Println("doing...")
// TODO SOMETHINGselect {
case<-timeout:
// do the rollbackbreakcaseret<-true:
fmt.Println("success end.")
}
}()
returnret
})package main
import (
"fmt""github.com/everfore/rddlock""gopkg.in/ezbuy/redis-orm.v1/orm"
redis "gopkg.in/redis.v5"
)
funcmain() {
// rds, err := orm.NewRedisClient("localhost", 32768, "", 0)rds, err:=orm.NewRedisClusterClient(&redis.ClusterOptions{
Addrs: []string{"XXX", "XXX", "XXX"},
})
iferr!=nil {
panic(err)
}
lock_key:="lock-key"locked, ex:=rddlock.Lock(rds, lock_key, 5)
iflocked {
fmt.Printf("LOCK %s: %+v\n", lock_key, locked)
unlocked:=rddlock.UnLock(rds, lock_key, ex)
ifunlocked {
fmt.Printf("UNLOCK %s: %+v\n", lock_key, unlocked)
} else {
unlocked=rddlock.UnLockUnsafe(rds, lock_key)
fmt.Printf("UNLOCK-UNSAFE %s: %+v\n", lock_key, unlocked)
}
}
// retry lock// 1. lock the key firstlocked, _=rddlock.Lock(rds, lock_key, 5)
fmt.Printf("FIRST step, LOCK %s:%+v\n", lock_key, locked)
// 2. retry to lock the locked keylocked, _=rddlock.LockRetry(rds, lock_key, 100, 100)
fmt.Printf("SECOND step, LOCK-RETRY %s:%+v\n", lock_key, locked)
}
// Output// LOCK lock-key: true// UNLOCK lock-key: true// FIRST step, LOCK lock-key:true// SECOND step, LOCK-RETRY lock-key:truesuccess:200, avg:1.1074123 ms
failed:0, avg:NaN ms
--- PASS: TestLockTime (10.59s)
#local-redis
=== RUN TestLockRetryTime
success:200, avg:1.1741205 ms
failed:0, avg:NaN ms
--- PASS: TestLockRetryTime (10.58s)
#uat-redis
=== RUN TestLockRetryTime
success:200, avg:12.572702 ms
failed:0, avg:NaN ms
--- PASS: TestLockRetryTime (10.59s)