软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 架构设计 -> 使用ZooKeeper实现Redis订阅消息的排他式处理 -> 正文阅读

[架构设计]使用ZooKeeper实现Redis订阅消息的排他式处理


前面咱们讨论过Redis Sentinel环境下Key过期事件消息订阅的问题,在演示程序中,由KeyExpiresMessageListener监听Redis发布出来的Key过期消息。
在生产环境下,这样的处理机制通常需要由一组独立部署的KeyExpiresMessageListener来构成高可用,但是当订阅消息发布出来时,所有的KeyExpiresMessageListener都能接收到,这样就会造成业务逻辑的重复处理,甚至可能导致系统逻辑错误,这就需要对各KeyExpiresMessageListener的工作进行全局的排他式控制,利用ZooKeeper我们可以很好地解决这个问题。
ZooKeeper是近几年广为应用的分布式协调框架,它使用类似Paxos协议的ZAB协议(ZooKeeper Atomic Broadcast)完成分布式系统一致性保障。分布式应用程序可以基于ZooKeeper实现数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁、分布式队列等功能。
ZooKeeper提供以下分布式一致性特性:
  • 顺序一致性

从同一个客户端发起的事务请求,最终将会严格地按照其发起顺序被应用到ZooKeeper中。
  • 原子性

所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的。
  • 单一视图

无论客户端连接的是哪个ZooKeeper服务器,其看到的服务端数据模型都是一致的。
  • 可靠性

一旦服务端成功地应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会被一直被保留下来,除非有另一个事务又对其进行了变更。
  • 实时性

ZooKeeper保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。
下面我们来部署由三个节点192.168.112.81、192.168.112.82、192.168.112.83组成的ZooKeeper集群,部署版本是3.4.8。
首先分别在三台服务器上解压zookeeper-3.4.8.tar.gz并设置好环境变量ZOOKEEPER_HOME,然后把conf/zoo_sample.cfg复制一份为zoo.cfg,这是ZooKeeper默认读取的配置文件。在安装目录下新建data子目录,并在三个节点上分别用echo x > data/myid(x=1/2/3)创建节点标识文件。然后打开zoo.cfg,修改如下:
[img]http://img.blog.csdn.net/20160330212853452?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
然后进入安装目录,在三个节点分别执行以下命令启动ZooKeeper:
[img]http://img.blog.csdn.net/20160330212933078?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

这样,ZooKeeper集群就准备好了。
如前文所述,ZooKeeper可以提供的功能之一是分布式锁。分布式锁是控制分布式系统之间同步访问共享资源的一种方式,当不同系统或者同一个系统之内的不同节点访问同一个或一组资源的时候,需要通过互斥手段来防止相互之间的干扰,以保证一致性。
分布式锁的其中一种是排他锁或独占锁,当事务A对资源R加上了排它锁,那么在加锁期间,一致性系统将只允许事务A对资源R进行读取和更新操作,其他事务都不能对资源R进行任何类型的操作,直到事务A释放了资源R。我们的应用实践正是基于这种原理。
在ZooKeeper中,可以用一个数据节点来表示一个锁,比如:/a/lock,这是一个临时节点。ZooKeeper定义了三个大类的四种节点,以满足不同的需要:
  • 持久节点(PERSISTENT)

被创建后就一直存在于ZooKeeper中,直到有操作主动删除它。
  • 持久顺序节点(PERSISTENT_SEQUENTIAL)

持久性与持久节点一致,此外ZooKeeper会自动为该类型的节点名后面加上一个顺序数字后缀。
  • 临时节点(EPHEMERAL)

临时节点的生命周期相对短暂,它的存在与客户端的会话绑定在一起,一旦会话失效,则临时节点会被自动清除。
  • 临时顺序节点(EPHEMERAL_SEQUENTIAL)

也就是会被添加顺序数字后缀的临时节点。
会使临时节点被清除的会话时效,包括两种形式:
  1. ZooKeeper系统重启
  2. 客户端主动关闭会话


此外,客户端也可以主动删除临时节点来清除它。
我们利用临时节点来实现一个各应用节点处理接收到的订阅消息的排它锁,机制是:当所有应用节点上的KeyExpiresMessageListener同时收到Key过期消息的时候,这些应用节点会随即尝试在ZooKeeper中创建一个锁节点,基于ZooKeeper良好的一致性保证,确保只有一个应用节点会创建锁节点成功,那么,后续的事务处理就只由这个幸运的应用节点来继续完成。
假设我们的业务是,接收Redis中订单数据Key过期的消息,并根据过期数据Key名字中包含的订单号来进行后续处理,订单数据Key形如EK_UPBO_15001。下面我们来看一下用于测试的程序。
首先是之前见过的AppConfig.java,定义了用来接收订阅消息的各种Bean:
[img]http://img.blog.csdn.net/20160330213754221?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
然后是加入了ZooKeeper元素的改进版的KeyExpiresMessageListener.java,使用ApacheCurator-2.10.0作为访问ZooKeeper的客户端:
[img]http://img.blog.csdn.net/20160330222755116?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

[img]http://img.blog.csdn.net/20160330213428814?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
还有工作线程类ZkThread.java:
[img]http://img.blog.csdn.net/20160330213951378?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
最后,为了模拟多个应用节点,我们同时启动两个主程序,Main1和Main2:
[img]http://img.blog.csdn.net/20160330214158129?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
好了,一切准备就绪,让我们启动两个主程序:
[img]http://img.blog.csdn.net/20160330214304630?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

日志输出显示,程序已经连接上ZooKeeper。
现在在Redis里设置一个过期时间为5秒的Key:
[img]http://img.blog.csdn.net/20160330214426115?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
5秒之后,Main1和Main2的Console输出分别为:
[img]http://img.blog.csdn.net/20160330214534381?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
[img]http://img.blog.csdn.net/20160330214545756?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

可以看到,本次竞争,Main2成功创建了排他锁,胜出:)
再观察一下ZooKeeper中的排他锁节点路径情况:
[img]http://img.blog.csdn.net/20160330214456583?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

可以看到,由于我们在程序里设置了5秒的模拟业务处理耗时,所以临时节点/sasp/order/UPBO/15001也只短短存在了5秒钟就被删除掉了。
ZooKeeper是一个非常有用的框架,是Hadoop、HBase、Storm、Solr、Dubbo等众多大型分布式系统的核心组件,用于进行分布式协调。除此之外,ZooKeeper还有很多用途,本文只是抛砖引玉,更多的有趣实践请朋友们自己去探索吧!
......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-04-01 16:50:07  
架构设计 最新文章
Opengl教程之读取obj并绘制在picturecontro
读《企业应用架构模式》第五章并发
StepbyStepintoSpring(IOC)
设计模式(2)用例图之一
使用实体组件系统(ECS)开发”吃方块”游戏实
编程学习之简单工厂模式与策略模式
Invalidprojectdescription.
基于Redis实现分布式消息队列(2)
《开源框架那点事儿15》:借船下海还是造船
原型模式——浅复制和深复制
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年1日历
2018-1-17 9:25:11
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --