golang,go,博客,开源,编程

golang每日一库之bsm/redislock

Updated on with 0 views and 0 comments

bsm/redislock 是一个用于 在 Go 语言中实现基于 Redis 的分布式锁(distributed lock) 的开源库,由 bsm 组织开发和维护。

它实现了基于 Redis 的 SET NX PX 命令模式的分布式锁,兼容 Redlock 算法的核心思想,但更简单和轻量。


简介

  • 基于 Redis 单实例实现分布式锁
  • 遵循 Redis 官方推荐的 SET resource-name value NX PX max-lock-time 模式
  • 简洁、高性能、线程安全
  • 支持锁自动过期
  • 支持锁续约(可选)
  • 没有依赖复杂的 Redlock 多主节点算法,更适合大多数实际应用

安装方法

go get github.com/bsm/redislock

示例

import (
  "context"
  "fmt"
  "log"
  "time"

  "github.com/bsm/redislock"
  "github.com/redis/go-redis/v9"
)

func main() {
	// Connect to redis.
	client := redis.NewClient(&redis.Options{
		Network:	"tcp",
		Addr:		"127.0.0.1:6379",
	})
	defer client.Close()

	// Create a new lock client.
	locker := redislock.New(client)

	ctx := context.Background()

	// Try to obtain lock.
	lock, err := locker.Obtain(ctx, "my-key", 100*time.Millisecond, nil)
	if err == redislock.ErrNotObtained {
		fmt.Println("Could not obtain lock!")
	} else if err != nil {
		log.Fatalln(err)
	}

	// Don't forget to defer Release.
	defer lock.Release(ctx)
	fmt.Println("I have a lock!")

	// Sleep and check the remaining TTL.
	time.Sleep(50 * time.Millisecond)
	if ttl, err := lock.TTL(ctx); err != nil {
		log.Fatalln(err)
	} else if ttl > 0 {
		fmt.Println("Yay, I still have my lock!")
	}

	// Extend my lock.
	if err := lock.Refresh(ctx, 100*time.Millisecond, nil); err != nil {
		log.Fatalln(err)
	}

	// Sleep a little longer, then check.
	time.Sleep(100 * time.Millisecond)
	if ttl, err := lock.TTL(ctx); err != nil {
		log.Fatalln(err)
	} else if ttl == 0 {
		fmt.Println("Now, my lock has expired!")
	}

}

支持锁续约

你可以对锁进行续期以延长其有效期:

err := lock.Refresh(ctx, 10*time.Second, nil)

配置选项

  • RetryStrategy:设置重试策略(如使用 backoff 重试机制)
  • Metadata:设置锁的元数据(可选)

示例:

opts := &redislock.Options{
    RetryStrategy: redislock.LinearBackoff(500 * time.Millisecond),
}
lock, err := locker.Obtain(ctx, "my-key", 10*time.Second, opts)

锁是否仍然有效

ok, err := lock.Valid(ctx)

如果 ok == false,表示锁已经过期或被其他客户端释放/抢占。


缺点

  • 不是 Redlock 多 Redis 节点实现,不适合对高可用性强依赖的分布式系统。
  • 更适合内部服务、微服务之间的协调、任务调度等不要求高强一致性的场景。

标题:golang每日一库之bsm/redislock
作者:mooncakeee
地址:http://blog.dd95828.com/articles/2025/05/23/1747978638082.html
联系:scotttu@163.com