都9102年了,还在基于Redis/zookeeper/etcd自己实现分布式锁?

都9102年了,还在基于Redis/zookeeper/etcd自己实现分布式锁?

分布式锁

在分布式系统中,分布式锁的使用场景很多,比如多机部署但同一个时刻只希望单个节点运行,这是就需要用到分布式锁来实现,要实现好一个逻辑完备的分布式锁需要考虑的点很多:

  • 如何解决竞争问题
  • 如何防范惊群效应
  • 获取到锁的节点异常退出其他节点能否重新获取到锁

网上关于分布式锁的实现的文章很多,有基于Redis实现的、也有基于zookeeper/etcd的,实现逻辑也不太统一,真要从零实现工作量不算小,也不一定能实现得完全对,其实完全不用自己实现,etcd v3就提供了分布式锁的接口。

etcd提供的分布式锁

根据网上的描述,多少也能自己实现,但其实etcd本身提供了分布式锁代码,直接引入就能使用。轻轻松松十几行代码搞定。

https://github.com/etcd-io/etcd/blob/master/clientv3/concurrency/example_mutex_test.go

    cli, err := clientv3.New(clientv3.Config{Endpoints: endpoints})
	if err != nil {
		log.Fatal(err)
	}
	defer cli.Close()

	// create two separate sessions for lock competition
	s1, err := concurrency.NewSession(cli)
	if err != nil {
		log.Fatal(err)
	}
	defer s1.Close()
	m1 := concurrency.NewMutex(s1, "/my-lock/")

	// 获取锁  ,如果锁被其他进程占用,则进入阻塞状态
	if err := m1.Lock(context.TODO()); err != nil {
		log.Fatal(err)
	}
	fmt.Println("acquired lock for s1")
     // 释放锁
    if err := m1.Unlock(context.TODO()); err != nil {
		log.Fatal(err)
	}
	fmt.Println("released lock for s1")

实现原理

具体实现原理和基于redis或zookeeper比较类似,就不详细介绍,具体可看etcd实现源码。核心是通过Revision 机制比对以及心跳watch机器。

你可能感兴趣的:(后端)