使用Redis分布式锁实现集群的主备

最近工作中遇到一个问题,我们会调用业务部门提供的HTTP接口获取所有的音视频任务信息,这些任务会被分发到各个机器节点进行处理。有两个方案:

方案一

为每台机器编号,比如有5台机器,编号为0,1,2,3,4,然后每台机器读取全量任务信息,将每个任务ID用机器总数量取余,然后和机器编号比较,相等的表示这个任务在此机器上执行。

  • 优点 可以达到任务分开处理的目的
  • 缺点 任务分配不均/一台机器死掉,分给这台机器的任务将永远不会被执行到/每台机器都需要读取HTTP信息,浪费资源。

方案二

我们使用其中一台机器将任务投递到Kafka中,然后所有机器消费这些任务。

但是需要做到以下2点:

  • 需要解决投递机器单点故障的问题,最好能达到一主多备。
  • 任务分配要均匀。

第一个问题是本文的重点,我们采用了Redis的分布式锁,下面要详细介绍。关于Kafka任务均匀投递的问题,需要自己实现调度模块,根据机器性能来投递到不同机器消费的partition中。

方案二解决了方案一的所有缺点,下面详细说一下分布式锁,做一个记录。

关于主备

主备是高可用集群中绕不开的问题,服务端一般使用nginx反向代理做一次负载均衡,但是如果nginx挂了呢,这就需要做主备(或者主主也可以),网上这个帖子很详细Nginx负载均衡高可用(keepalived+nginx实现主备)。但是我们遇到的问题优点特殊,我们做的是客户端的负载均衡,每次主动调用任务接口获取任务数据来进行处理。并且只能做主备,不能主主,不然会造成任务的重复投递。

Redis 分布式锁实现主备

第一次在工作中接触到redis,发现redis真是个好东西。分布式锁原理

我们的主备方案中,使用分布式锁来实现一个类似单例模式的逻辑。

  • 使用一个键值_master_IP来存储主机IP,并且设置过期时间(类似单例模式类里面的数据成员)。
  • 定义一个分布式锁,只有在键值_master_IP的值为空的时候,才会获取锁,设置键_deliver_task_IP的值(类似单例模式中的第一次构造函数调用)。

下面是流程图:

  • 主备系统启动的时候Redis中没有键值_master_IP,所有机器会抢占Redis分布式锁_master_lock。
  • 抢锁成功的机器会变为主机,启动投递任务。并将_master_IP 值Set成自己的IP,并设置键值过期时间,这些操作完成后释放分布式锁。
  • 主机释放锁后,其他备机有可能抢占到锁,为了防止备机启动投递任务和写_master_IP,获取锁之后会再次判断_master_IP是否有值,如果有值说明主机已经起来了,直接返回即可。(有点类似于单例模式的双重锁)
  • 主机任务起来之后,各个机器每隔固定时间会去检测键值_master_IP,主机每次读取键值_master_IP后会自动Extend这个键值的Expire Time。备机发现键值有值并且不是自己就返回了。
  • 主机死掉之后,过了键值_master_IP的Expire Time, 键值会被删除。其他备机器会像整个系统启动的时候一样开始抢占锁并启动新的主机。

注意:一个Redis集群(只有一个Master)有可能出现一个锁被不同服务获取的情况(Master宕机,锁状态还没有来得及同步到Slave就会出现),这样会在不同的机器上启动投递任务,上面的流程中在下一个5秒后会判断,投递任务IP是否为本机IP,只保留本机的服务,其他服务全部停止。

使用Redis分布式锁实现主备的更多相关文章

  1. 《Redis 分布式锁》

    一:什么是分布式锁. -  通俗来说的话,就是在分布式架构的redis中,使用锁. 二:分布式锁的使用选择. - 当 Redis 的使用场景不多,而且也只是单个在用的时候,可以构建自己使用的 锁. - ...

  2. spring-boot 中实现标准 redis 分布式锁

    一,前言 redis 现在已经成为系统缓存的必备组件,针对缓存读取更新操作,通常我们希望当缓存过期之后能够只有一个请求去更新缓存,其它请求依然使用旧的数据.这就需要用到锁,因为应用服务多数以集群方式部 ...

  3. Redisson实现Redis分布式锁的底层原理

    一.写在前面 现在面试,一般都会聊聊分布式系统这块的东西.通常面试官都会从服务框架(Spring Cloud.Dubbo)聊起,一路聊到分布式事务.分布式锁.ZooKeeper等知识.所以咱们这篇文章 ...

  4. redis 分布式锁的 5个坑,真是又大又深

    引言 最近项目上线的频率颇高,连着几天加班熬夜,身体有点吃不消精神也有些萎靡,无奈业务方催的紧,工期就在眼前只能硬着头皮上了.脑子浑浑噩噩的时候,写的就不能叫代码,可以直接叫做Bug.我就熬夜写了一个 ...

  5. redis 分布式锁的简单使用

    RedisLock--让 Redis 分布式锁变得简单 目录 1. 项目介绍 2. 快速使用 2.1 引入 maven 坐标 2.2 注册 RedisLock 2.3 使用 3. 参与贡献 4. 联系 ...

  6. 手撕redis分布式锁,隔壁张小帅都看懂了!

    前言 上一篇老猫和小伙伴们分享了为什么要使用分布式锁以及分布式锁的实现思路原理,目前我们主要采用第三方的组件作为分布式锁的工具.上一篇运用了Mysql中的select ...for update实现了 ...

  7. 面试必问:如何实现Redis分布式锁

    摘要:今天我们来聊聊分布式锁这块知识,具体的来看看Redis分布式锁的实现原理. 一.写在前面 现在面试,一般都会聊聊分布式系统这块的东西.通常面试官都会从服务框架(Spring Cloud.Dubb ...

  8. redis分布式锁的这些坑,我怀疑你是假的开发

    摘要:用锁遇到过哪些问题? 一.白话分布式 什么是分布式,用最简单的话来说,就是为了较低单个服务器的压力,将功能分布在不同的机器上面:就比如: 本来一个程序员可以完成一个项目:需求->设计-&g ...

  9. Redis分布式锁 (图解-秒懂-史上最全)

    文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...

随机推荐

  1. Java的类锁、对象锁和方法锁

    在Java中,对于synchronized关键字,大家看到的第一反应就是这个关键字是进行同步操作的,即得名"同步锁". 当用它来修饰方法和代码块时,默认当前的对象为锁的对象,即对象 ...

  2. django最全面的知识点,直接开发完整手机购物商城练手,

    带手机验证码登陆, 带全套购物车系统 带数据库 前后端分离开发 带定位用户功能 数据库代码为本地制作好了 带支付宝支付系统 带django开发服务器接口教程 地址: https://www.duans ...

  3. B. Welfare State(RMQ问题的逆向考虑)

    \(对于操作1,我们只关心最后一次操作.\) \(对于操作2,我们只关心值最大的一次操作.\) \(也就是说,我们记录每个居民最后一次被修改的位置\) \(然后它的最终答案就是从这个位置起,max(操 ...

  4. QML文字灰飞烟灭效果

    QML文字灰飞烟灭效果 1,目的 实现文字化作一缕青烟随风而逝的效果. 2,设计分析 在前面的章节中讲述了如何化作光斑碎片逐渐消失的效果,我们可以借鉴它将光斑换成烟雾,再加入端流产生微风浮动,加上字幕 ...

  5. Day_10【常用API】扩展案例1_利用人出生日期到当前日期所经过的毫秒值计算出这个人活了多少天

    分析以下需求,并用代码实现: 1.从键盘录入一个日期字符串,格式为 xxxx-xx-xx,代表该人的出生日期 2.利用人出生日期到当前日期所经过的毫秒值计算出这个人活了多少天 package com. ...

  6. 【FreeRTOS实战汇总】小白博主的RTOS学习实战快速进阶之路(持续更新)

    博主是个小白,打算把这段时间系统学习RTOS的文章统一整理到这里,另外本文会给出一些参考性资料和指导性建议: 本文宗旨 FreeRTOS 是由Richard Barry在2003年由设计的,由于其设计 ...

  7. Jekyll 解决Jekyll server本地预览文章not found的问题

    layout: post tags: [Jekyll] comments: true 执行Jekyll本地浏览器预览指令 bundle exec jekyll serve 进入浏览器输入127.0.0 ...

  8. Spring Boot 入门(十三):集成Hasor的Dataway模块,干掉后台,自动配置接口

    终于出湖北了,封闭2个月,家里没电脑,感觉好久没自主撸代码啊啊啊啊啊啊啊啊啊啊啊啊啊. 连接上篇文章Spring Boot 入门(十二):报表导出,对比poi.jxl和esayExcel的效率,继续从 ...

  9. tp5 一次性插入大量数据时分批处理

    如题,加入$arr 中有一万多条数据,如果直接使用insert插入的话就会报错,此时可以使用limit分批插入 $result = Db::connect($this->dbconfig()) ...

  10. 我的linux学习日记day2

    RPM  软件包管理器 目的:降低软件安装难度原理 :将软件源代码加上一套安装规则打包到一起,用户只需要运行RPM systemctl start 服务名称 开启服务systemctl stop 服务 ...