返回顶部
首页 > 资讯 > 前端开发 > node.js >etcd与分布式锁的介绍
  • 521
分享到

etcd与分布式锁的介绍

2024-04-02 19:04:59 521人浏览 八月长安
摘要

本篇内容主要讲解“etcd与分布式锁的介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“etcd与分布式锁的介绍”吧!1. 实现分布式锁的组件们在分布式系统中,

本篇内容主要讲解“etcd与分布式的介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“etcd与分布式锁的介绍”吧!

1. 实现分布式锁的组件们

分布式系统中,常用于实现分布式锁的组件有:RedisZooKeeper、etcd,下面针对各自的特性进行对比:

etcd与分布式锁的介绍

由上图可以看出三种组件各自的特点,其中对于分布式锁来说至关重要的一点是要求CP。但是,Redis集群却不支持CP,而是支持AP。虽然,官方也给出了redlock的方案,但由于需要部署多个实例(超过一半实例成功才视为成功),部署、维护比较复杂。所以在对一致性要求很高的业务场景下(电商、银行支付),一般选择使用zookeeper或者etcd。对比zookeeper与etcd,如果考虑性能、并发量、维护成本来看。由于etcd是用Go语言开发,直接编译为二进制可执行文件,并不依赖其他任何东西,则更具有优势。本文,则选择etcd来讨论某些观点。

2. 对于分布式锁来说AP为什么不好

在CAP理论中,由于分布式系统中多节点通信不可避免出现网络延迟、丢包等问题一定会造成网络分区,在造成网络分区的情况下,一般有两个选择:CP or  AP。

①  选择AP模型实现分布式锁时,client在通过集群主节点加锁成功之后,则立刻会获取锁成功的反馈。此时,在主节点还没来得及把数据同步给从节点时发生down机的话,系统会在从节点中选出一个节点作为新的主节点,新的主节点没有老的主节点对应的锁数据,导致其他client可以在新的主节点上拿到相同的锁。这个时候,就会导致多个进程/线程/协程来操作相同的临界资源数据,从而引发数据不一致性等问题。

②  选择CP模型实现分布式锁,只有在主节点把数据同步给大于1/2的从节点之后才被视为加锁成功。此时,主节点由于某些原因down机,系统会在从节点中选取出来数据比较新的一个从节点作为新的主节点,从而避免数据丢失等问题。

所以,对于分布式锁来说,在对数据有强一致性要求的场景下,AP模型不是一个好的选择。如果可以容忍少量数据丢失,出于维护成本等因素考虑,AP模型的Redis可优先选择。

3. 分布式锁的特点以及操作

对于分布式锁来说,操作的动作包含:

  1. 获取锁

  2. 释放锁

  3. 业务处理过程中过程中,另起线程/协程进行锁的续约

etcd与分布式锁的介绍

4. 关于etcd

etcd与分布式锁的介绍

官方文档永远是最好的学习资料,官方介绍etcd如是说:

  • 分布式系统使用etcd作为配置管理、服务发现和协调分布式工作的一致键值存储。许多组织使用etcd来实现生产系统,如容器调度器、服务发现服务和分布式数据存储。使用etcd的常见分布式模式包括leader选举、分布式锁和监视机器活动。

  • Distributed systems use etcd as a consistent key-value store for  configuration management, service discovery, and coordinating distributed work.  Many organizations use etcd to implement production systems such as container  schedulers, service discovery services, and distributed data storage. Common  distributed patterns using etcd include leader election, distributed locks, and  monitoring Machine liveness.

  • https://etcd.io/docs/v3.4/learning/why/

分布式锁仅是etcd可以实现众多功能中的一项,服务注册与发现在etcd中用的则会更多。

官方也对众多组件进行了对比,并整理如下:

etcd与分布式锁的介绍

通过对比可以看出各自的特点,至于具体选择哪一款,你心中可能也有了自己的答案。

5. etcd实现分布式锁的相关接口

对于分布式锁,主要用到etcd对应的添加、删除、续约接口。

// KV:键值相关操作 type KV interface {     // 存放.     Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error)     // 获取.     Get(ctx context.Context, key string, opts ...OpOption) (*GetResponse, error)     // 删除.     Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error)     // 压缩rev指定版本之前的历史数据.     Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error)     // 通用的操作执行命令,可用于操作集合的遍历。Put/Get/Delete也是基于Do.     Do(ctx context.Context, op Op) (OpResponse, error)     // 创建一个事务,只支持If/Then/Else/Commit操作.     Txn(ctx context.Context) Txn }   // Lease:租约相关操作 type Lease interface {     // 分配一个租约.     Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error)     // 释放一个租约.     Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error)     // 获取剩余TTL时间.     TimeToLive(ctx context.Context, id LeaseID, opts ...LeaseOption) (*LeaseTimeToLiveResponse, error)     // 获取所有租约.     Leases(ctx context.Context) (*LeaseLeasesResponse, error)     // 续约保持激活状态.     KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error)     // 仅续约激活一次.     KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAliveResponse, error)     // 关闭续约激活的功能.     Close() error }

 6. etcd实现分布式锁代码示例

package main  import (     "context"     "fmt"     "go.etcd.io/etcd/clientv3"     "time" )  var conf clientv3.Config  // 锁结构体 type EtcdMutex struct {     Ttl int64//租约时间      Conf   clientv3.Config    //etcd集群配置     Key    string//etcd的key     cancel context.CancelFunc //关闭续租的func      txn     clientv3.Txn     lease   clientv3.Lease     leaseID clientv3.LeaseID }  // 初始化锁 func (em *EtcdMutex) init() error {     var err error     var ctx context.Context      client, err := clientv3.New(em.Conf)     if err != nil {         return err     }      em.txn = clientv3.NewKV(client).Txn(context.TODO())     em.lease = clientv3.NewLease(client)     leaseResp, err := em.lease.Grant(context.TODO(), em.Ttl)      if err != nil {         return err     }      ctx, em.cancel = context.WithCancel(context.TODO())     em.leaseID = leaseResp.ID     _, err = em.lease.KeepAlive(ctx, em.leaseID)      return err }  // 获取锁 func (em *EtcdMutex) Lock() error {     err := em.init()     if err != nil {         return err     }      // LOCK     em.txn.If(clientv3.Compare(clientv3.CreateRevision(em.Key), "=", 0)).         Then(clientv3.OpPut(em.Key, "", clientv3.WithLease(em.leaseID))).Else()      txnResp, err := em.txn.Commit()     if err != nil {         return err     }      // 判断txn.if条件是否成立     if !txnResp.Succeeded {         return fmt.Errorf("抢锁失败")     }      returnnil }  //释放锁 func (em *EtcdMutex) UnLock() {     // 租约自动过期,立刻过期     // cancel取消续租,而revoke则是立即过期     em.cancel()     em.lease.Revoke(context.TODO(), em.leaseID)      fmt.Println("释放了锁") }  // groutine1 func try2lock1() {     eMutex1 := &EtcdMutex{         Conf: conf,         Ttl:  10,         Key:  "lock",     }      err := eMutex1.Lock()     if err != nil {         fmt.Println("groutine1抢锁失败")         return     }     defer eMutex1.UnLock()      fmt.Println("groutine1抢锁成功")     time.Sleep(10 * time.Second) }  // groutine2 func try2lock2() {     eMutex2 := &EtcdMutex{         Conf: conf,         Ttl:  10,         Key:  "lock",     }      err := eMutex2.Lock()     if err != nil {         fmt.Println("groutine2抢锁失败")         return     }      defer eMutex2.UnLock()     fmt.Println("groutine2抢锁成功") }  // 测试代码 func EtcdRunTester() {     conf = clientv3.Config{         Endpoints:   []string{"127.0.0.1:2379"},         DialTimeout: 5 * time.Second,     }      // 启动两个协程竞争锁     go try2lock1()     go try2lock2()      time.Sleep(300 * time.Second) }

 总结

可以提供分布式锁功能的组件有多种,但是每一种都有自己的脾气与性格。至于选择哪一种组件,则要看数据对业务的重要性,数据要求强一致性推荐支持CP的etcd、zookeeper,数据允许少量丢失、不要求强一致性的推荐支持AP的Redis。

到此,相信大家对“etcd与分布式锁的介绍”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: etcd与分布式锁的介绍

本文链接: https://lsjlt.com/news/67087.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • etcd与分布式锁的介绍
    本篇内容主要讲解“etcd与分布式锁的介绍”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“etcd与分布式锁的介绍”吧!1. 实现分布式锁的组件们在分布式系统中,...
    99+
    2024-04-02
  • Redis分布式锁介绍与使用
    目录分布式锁业务逻辑分析Redis命令代码实现分布式锁误删问题问题原因分析代码实现Lua脚本首先,使用idea模拟搭建一个tomcat服务器集群,并使用Nginx对集群中的服务器实现...
    99+
    2024-04-02
  • Golang分布式锁详细介绍
    目录进程内加锁trylock基于redis的setnx基于zk基于etcdredlock如何选择在单机程序并发或并行修改全局变量时,需要对修改行为加锁以创造临界区。为什么需要加锁呢?...
    99+
    2024-04-02
  • Redis分布式锁详细介绍
    目录分布式锁redis实现分布式锁的原理死锁问题超时问题锁误放问题可重入性Redlock分布式锁 在单进程应用中,当一段代码同一时间内只能由一个线程执行时, 多线程下可能会出错,例如...
    99+
    2024-04-02
  • Redis分布式锁的实现原理介绍
    这篇文章主要讲解了“Redis分布式锁的实现原理介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis分布式锁的实现原理介绍”吧!一、写在前面现在面试,一般都会聊聊分布式系统这块的东西...
    99+
    2023-06-02
  • go语言分布式id生成器及分布式锁介绍
    目录分布式 id 生成器worker_id 如何分配开源示例:标准雪花算法分布式锁进程内加锁尝试加锁 tryLock基于 Redis 的 setnx 分布式锁基于 ZooKeeper...
    99+
    2023-05-14
    go 分布式id生成器 锁 go 分布式锁
  • 巧用Redis实现分布式锁详细介绍
    目录前言手写Redis分布式锁Redissonlock()lock(long leaseTime, TimeUnit unit)tryLock(long waitTime, long...
    99+
    2024-04-02
  • redis分布式锁与zk分布式锁的对比分析
    目录Redis实现分布式锁原理能实现的锁类型注意事项 zk实现分布式锁原理能实现的锁类型两种锁的对比在分布式环境下,传统的jvm级别的锁会失效,那么分布式锁就是非常有必要的一个技术,一般我们可以通过redis,...
    99+
    2022-11-18
    redis分布式锁 分布式锁 zk分布式锁
  • 【分布式】分布式锁
    目录 一、分布式锁介绍二、基于 Redis 实现分布式锁1. 如何基于 Redis 实现一个最简易的分布式锁?2.为什么要给锁设置一个过期时间?3. 如何实现锁的优雅续期?4. 如何实现可重入锁? 一、分布式锁介绍 单机多线...
    99+
    2023-08-17
    分布式 java jvm
  • 分布式系统CAP的原理介绍
    CAP原理中,有三个要素: 一致性(Consistency) 可用性(Availability) 分区容错性(Partition tolerance) Consistency 一致性 一致性指“all ...
    99+
    2024-04-02
  • 分布式Netty源码分析EventLoopGroup及介绍
    目录EventLoopGroup介绍功能1:先来看看注册Channel功能2:执行一些Runnable任务EventLoop介绍NioEventLoop介绍EpollEventLoo...
    99+
    2024-04-02
  • 分布式框架Zookeeper api的使用介绍
    目录前言导入依赖建立会话创建节点获取节点数据修改节点数据删除节点前言 Zookeeper API共包含五个包,分别为: org.apache.zookeeperorg.apache....
    99+
    2024-04-02
  • Java分布式服务框架Dubbo介绍
    目录1、什么是Dubbo?2、Dubbo核心组件是?3、Dubbo的工作原理是?4、介绍一下Dubbo框架分层?5、Dubbo支持哪些协议?1.dubbo默认协议:2.rmi协议:3...
    99+
    2024-04-02
  • JEESZ分布式框架简介---技术介绍文档
     摘要: Jeesz主要定位于互联网企业架构,已内置企业信息化系统的基础功能和高效的代码生成工具,包括:系统权限组件、数据权限组件、数据字典组件、核心工具 组件、视图操作组件、工作流组件、代码生成...
    99+
    2024-04-02
  • DBA_2PC_PENDING中的分布式锁-解锁
     运行shell脚本后,会生成 roll.sql文件。...
    99+
    2023-06-06
  • Redisson分布式锁
    文章目录 一、Redisson简单介绍二、Redisson简单使用1. maven引用2. RedisConfig配置3. StockRedissonService4. 测试 三、Redisson源码1. 加锁2. 解锁3. 自...
    99+
    2023-08-19
    分布式 redis java 缓存
  • 分布式锁的原理及Redis怎么实现分布式锁
    这篇文章主要介绍“分布式锁的原理及Redis怎么实现分布式锁”,在日常操作中,相信很多人在分布式锁的原理及Redis怎么实现分布式锁问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解...
    99+
    2023-02-02
    redis
  • JEESZ分布式框架--技术介绍文档
     摘要: 1.Eclipse IDE:采用Maven项目管理,模块化。     2.代码生成:通过界面方式简单配置,自动生成相应代码,目前包括三种生成方式(...
    99+
    2024-04-02
  • Mysql中Binlog3种格式的介绍与分析
    一.Mysql Binlog格式介绍      Mysql binlog日志有三种格式,分别为Statement,MiXED,以及ROW! 1.Statement:...
    99+
    2022-05-26
    mysqlbinlog参数 mysql binlog mysql binlog解析
  • Go与Redis实现分布式互斥锁和红锁
    目录前言互斥锁TryLock和Unlock实现Lock实现实现看门狗机制看门狗实现红锁加锁实现看门狗实现解锁实现前言 在项目中我们经常有需要使用分布式锁的场景,而Redis是实现分布式锁最常见的一种方式,这篇文章主要是使...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作