负载均衡下如何有效实现锁机制?

1、加锁多点

负载均衡下的锁机制

定义:加锁多点,是通过对每个服务进程进行加锁控制的方式来实现多点部署,达到负载均衡的目的。

优势

扩展性:无限制的扩展性,扩展服务进程后,只须设定唯一的锁标签即可。

容错性:通过监控服务的死锁唤醒,可以对数据进行补偿处理。

负载均衡:通过控制批量的量,可以达到较好的负载均衡。

架构

锁的结构

字段 名称 类型
ServiceLockTag 锁标签 Guid
ModifyOn 变更时间 DateTime

负载均衡下的锁机制

主要步骤

批量加锁:每个服务在处理数据之前,先进行批量加锁数据,批量的多少以单个服务进程的处理能力为准,所加锁为乐观锁,这样保证多个服务并发加锁数据时,数据最终能够成功为最后的服务加锁,每个服务进程都有自己的锁标签,作为区分于其它服务进程的标识,锁标签可在配置文件中设置。

加锁查询:批量加锁后,服务进程查询对应标签的数据。

批量解锁:数据处理完成后进行解锁处理,可单条处理,也可批量处理。

死锁唤醒:对加锁超过一定时限的数据进行解锁处理,这样可防止单个服务进程异常造成数据无法处理的状况。

2、分布式锁

应用场景

负载均衡下的锁机制

秒杀场景:防止商品超卖。

表单重复提交:避免重复提交表单。

接口幂等性:确保接口幂等性。

调度任务:避免调度任务在多台机器重复执行。

缓存过期:所有请求都去加载数据库。

主要特性

互斥:同一时刻只能有一个线程获得锁。

可重入:当一个线程获取锁后,还可以再次获取这个锁,避免死锁发生。

高可用:当小部分节点挂掉后,仍然能够对外提供服务。

高性能:要做到高并发、低延迟。

支持阻塞和非阻塞:Synchronized是阻塞的,ReentrantLock.tryLock()就是非阻塞的。

支持公平锁和非公平锁:Synchronized是非公平锁,ReentrantLock(boolean fair)可以创建公平锁。

实现方式

MySQL实现分布式锁

数据库表设计

            CREATE TABLEdistributed_lock (id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',resource_name varchar(200) NOT NULL DEFAULT '' COMMENT '资源名称(唯一索引)',owner varchar(200) NOT NULL DEFAULT '' COMMENT '锁持有者(机器码+线程名称)',lock_count int NOT NULL DEFAULT '0' COMMENT '加锁次数',expire_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '锁过期时间',
              PRIMARY KEY (id),
              UNIQUE KEYuk_resource_name (resource_name)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='分布式锁';

锁的实现原理:将用来竞争的资源名称设置为表的唯一索引,获取锁的时候,就插入一条记录,插入成功就代表获取到锁,插入失败就代表获取锁失败,释放锁的时候,就删除这条记录。

支持阻塞和非阻塞:可以用while循环直到插入成功,不过自旋也会占用CPU。

支持可重入:使用锁持有者owner和加锁次数字段lock_count实现可重入:获取锁,次数加一,释放锁,次数减一,次数为零就删除这把锁。

支持过期时间:使用过期时间expire_time字段,通过异步任务检测避免因程序异常或机器宕机导致锁无法释放。

支持锁续期:获取锁的同时,启动一个异步任务,每当业务执行到三分之一时间,也就是6秒中的第2秒的时候,就自动延长锁过期时间,继续延长到6秒,这样就能保证业务逻辑处理完成之前锁不会过期。

Redis实现分布式锁

获取锁并设置过期时间

            // 获取锁
            redis.setnx('resource_name1', 'owner1')
            // 增加锁过期时间
            redis.expire('resource_name1', 6, TimeUnit.SECONDS)

释放锁

            // 释放锁
            if ('owner1'.equals(redis.get('resource_name1'))){ 
               redis.del('resource_name1')
            }

原子操作:但是setnx和expire两条命令不是原子的,可能获取锁之后还没来得及设置过期时间就宕机了,所以可以使用Redis 2.6.12之后提供的一条复合命令:

            redis.set('resource_name1', 'owner1',"NX" "EX", 6)

释放锁判断锁的持有者:释放锁时判断锁的持有者,可以避免把其他线程持有的锁给掉了,但是get和del两条命令不是原子操作,需要引入Lua脚本把两条命令打包成一条发给Redis执行:

            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
            redis.eval(script, Collections.singletonList('resource_name1'), Collections.singletonList('owner1'))

锁续期功能:可以使用Redis客户端的Redisson的WatchDog功能,在我们调用lock自动唤醒WatchDog。

Zookeeper实现分布式锁

节点类型:zookeeper采用树形节点,类似Linux目录文件结构,同一目录下的节点名称不能重复,节点有分为四种类型:持久节点、临时节点、持久顺序节点、临时顺序节点。

监听通知机制:zookeeper还有个监听-通知机制,客户端可以在资源节点上创建watch事件,当节点发生变化,会通知客户端,客户端可以根据变化做相应的业务处理。

利用临时顺序节点创建分布式锁:由于创建的临时节点,断开连接后自动删除,所以无需设置锁超时时间,也就不用考虑不释放和锁续期。

实现逻辑:在资源/resource1目录下创建临时顺序节点node;获取/resource1目录下的所有节点,如果当前节点序号最小,代表加锁成功;如果不是,就watch监听序号最小的节点。

负载均衡下的锁机制主要包括加锁多点和分布式锁两种实现方式,加锁多点通过对每个服务进程进行加锁控制来实现多点部署和负载均衡,具有扩展性、容错性和负载均衡的优势,分布式锁则用于解决多台机器之间的资源竞争问题,具有互斥、可重入、高可用、高性能等特性,分布式锁可以通过MySQL、Redis和Zookeeper等多种方式实现,每种方式都有其特点和适用场景。

以上就是关于“负载均衡下的锁机制”的问题,朋友们可以点击主页了解更多内容,希望可以够帮助大家!

【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!

(0)
热舞的头像热舞
上一篇 2024-11-09 15:20
下一篇 2024-11-09 16:10

相关推荐

  • 负载均衡中如何实现TCP会话保持?

    负载均衡TCP会话保持是指在负载均衡器上实现的一种机制,通过该机制可以确保来自同一客户端的请求被转发到同一台后端服务器进行处理,这种机制对于需要保持用户会话的应用系统尤为重要,例如电子商务网站中的购物车功能或需要进行用户身份认证的在线系统,会话保持的定义与重要性会话保持是指将同一个客户端的所有请求都转发到同一台……

    2024-11-25
    0030
  • 负载均衡与主备,如何确保系统高可用性?

    负载均衡与主备背景介绍在现代计算机网络中,随着业务量的不断增长和用户数量的激增,单台服务器往往难以承受巨大的访问压力,这时,就需要引入负载均衡技术,将请求分发到多台服务器上,以提高系统的整体性能和可用性,为了确保系统的高可用性,还需要配置主备模式,以防止单点故障导致整个系统瘫痪,本文将详细介绍负载均衡与主备的基……

    2024-11-11
    007
  • 如何安装服务器配置?

    服务器配置的安装涉及多个步骤,从硬件准备到操作系统安装,再到基本配置和常用软件的安装,以下是一个详细的指南:一、准备工作1、服务器硬件:确保服务器硬件已经到位,包括CPU、内存、硬盘等,2、操作系统镜像:下载所需的操作系统镜像文件(如CentOS、Ubuntu等),3、网络连接:确保服务器能够连接到网络,以便下……

    2024-12-04
    003
  • 为何我总是被服务器完美踢出?

    您的问题似乎与服务器踢出有关,但您没有提供关于“完美”的详细信息。请提供更多关于问题的详细描述,以便我能更好地理解您的问题并提供帮助。

    2024-08-12
    0097

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

广告合作

QQ:14239236

在线咨询: QQ交谈

邮件:asy@cxas.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信