CN113722127A - 高效轻量易用的分布式网络消息中间件 - Google Patents
高效轻量易用的分布式网络消息中间件 Download PDFInfo
- Publication number
- CN113722127A CN113722127A CN202111124609.6A CN202111124609A CN113722127A CN 113722127 A CN113722127 A CN 113722127A CN 202111124609 A CN202111124609 A CN 202111124609A CN 113722127 A CN113722127 A CN 113722127A
- Authority
- CN
- China
- Prior art keywords
- message
- node
- time
- queue
- nodes
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Withdrawn
Links
- 238000000034 method Methods 0.000 claims abstract description 137
- 238000012545 processing Methods 0.000 claims abstract description 55
- 230000007246 mechanism Effects 0.000 claims abstract description 17
- 230000002688 persistence Effects 0.000 claims abstract description 16
- 238000013461 design Methods 0.000 claims abstract description 13
- 238000005457 optimization Methods 0.000 claims abstract description 7
- 230000008569 process Effects 0.000 claims description 67
- 230000005540 biological transmission Effects 0.000 claims description 58
- 238000001514 detection method Methods 0.000 claims description 36
- 238000004364 calculation method Methods 0.000 claims description 26
- 238000012790 confirmation Methods 0.000 claims description 20
- 230000008859 change Effects 0.000 claims description 17
- 238000012546 transfer Methods 0.000 claims description 16
- 230000003111 delayed effect Effects 0.000 claims description 12
- 230000008901 benefit Effects 0.000 claims description 10
- 230000001360 synchronised effect Effects 0.000 claims description 10
- 238000010276 construction Methods 0.000 claims description 9
- 230000006870 function Effects 0.000 claims description 9
- 238000012544 monitoring process Methods 0.000 claims description 9
- 230000003068 static effect Effects 0.000 claims description 8
- 230000004044 response Effects 0.000 claims description 6
- 238000012216 screening Methods 0.000 claims description 6
- 238000007781 pre-processing Methods 0.000 claims description 5
- 230000007717 exclusion Effects 0.000 claims description 3
- 238000004321 preservation Methods 0.000 claims description 3
- 238000004064 recycling Methods 0.000 claims description 3
- 125000004122 cyclic group Chemical group 0.000 claims description 2
- 235000003642 hunger Nutrition 0.000 claims description 2
- 238000000638 solvent extraction Methods 0.000 claims description 2
- 230000037351 starvation Effects 0.000 claims description 2
- 238000010586 diagram Methods 0.000 description 9
- 238000002474 experimental method Methods 0.000 description 8
- 238000013507 mapping Methods 0.000 description 8
- 238000007726 management method Methods 0.000 description 6
- 238000011084 recovery Methods 0.000 description 6
- 238000004891 communication Methods 0.000 description 5
- 230000006872 improvement Effects 0.000 description 5
- 238000004458 analytical method Methods 0.000 description 3
- 238000013459 approach Methods 0.000 description 3
- 238000011161 development Methods 0.000 description 3
- 238000012423 maintenance Methods 0.000 description 3
- 241000283973 Oryctolagus cuniculus Species 0.000 description 2
- 238000013500 data storage Methods 0.000 description 2
- 230000007423 decrease Effects 0.000 description 2
- 230000001934 delay Effects 0.000 description 2
- 239000000523 sample Substances 0.000 description 2
- 238000012360 testing method Methods 0.000 description 2
- 239000002699 waste material Substances 0.000 description 2
- 230000009286 beneficial effect Effects 0.000 description 1
- 230000000903 blocking effect Effects 0.000 description 1
- 230000019771 cognition Effects 0.000 description 1
- 230000008878 coupling Effects 0.000 description 1
- 238000010168 coupling process Methods 0.000 description 1
- 238000005859 coupling reaction Methods 0.000 description 1
- 238000000354 decomposition reaction Methods 0.000 description 1
- 230000007547 defect Effects 0.000 description 1
- 238000012217 deletion Methods 0.000 description 1
- 230000037430 deletion Effects 0.000 description 1
- 238000005315 distribution function Methods 0.000 description 1
- 230000002349 favourable effect Effects 0.000 description 1
- 238000001914 filtration Methods 0.000 description 1
- 238000013467 fragmentation Methods 0.000 description 1
- 238000006062 fragmentation reaction Methods 0.000 description 1
- 230000006698 induction Effects 0.000 description 1
- 230000010354 integration Effects 0.000 description 1
- 238000010606 normalization Methods 0.000 description 1
- 238000005192 partition Methods 0.000 description 1
- 238000012913 prioritisation Methods 0.000 description 1
- 230000000644 propagated effect Effects 0.000 description 1
- 238000011895 specific detection Methods 0.000 description 1
- 230000000007 visual effect Effects 0.000 description 1
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/54—Interprogram communication
- G06F9/546—Message passing systems or structures, e.g. queues
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/22—Indexing; Data structures therefor; Storage structures
- G06F16/2228—Indexing structures
- G06F16/2246—Trees, e.g. B+trees
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/22—Indexing; Data structures therefor; Storage structures
- G06F16/2228—Indexing structures
- G06F16/2255—Hash tables
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/23—Updating
- G06F16/2308—Concurrency control
- G06F16/2336—Pessimistic concurrency control approaches, e.g. locking or multiple versions without time stamps
- G06F16/2343—Locking methods, e.g. distributed locking or locking implementation details
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/23—Updating
- G06F16/2365—Ensuring data consistency and integrity
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/28—Databases characterised by their database models, e.g. relational or object models
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/50—Allocation of resources, e.g. of the central processing unit [CPU]
- G06F9/5083—Techniques for rebalancing the load in a distributed system
- G06F9/5088—Techniques for rebalancing the load in a distributed system involving task migration
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/52—Program synchronisation; Mutual exclusion, e.g. by means of semaphores
- G06F9/526—Mutual exclusion algorithms
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F2209/00—Indexing scheme relating to G06F9/00
- G06F2209/54—Indexing scheme relating to G06F9/54
- G06F2209/547—Messaging middleware
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F2209/00—Indexing scheme relating to G06F9/00
- G06F2209/54—Indexing scheme relating to G06F9/54
- G06F2209/548—Queue
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Software Systems (AREA)
- Databases & Information Systems (AREA)
- Data Mining & Analysis (AREA)
- Computer Security & Cryptography (AREA)
- Computer And Data Communications (AREA)
Abstract
本申请设计实现高效消息收发调度中间件模型,包括融合PUSH和PULL方式的消息快速收发和多优先级分发引擎、消息队列持久化优化策略、定时备份和容错处理机制,针对消息中间件在高网络延迟情况下会出现判定准确率低的问题,提出基于主观结论的结点失效判定算法,改进多叉树对一致性哈希算法实施进一步优化,克服传统方法结点负载不均匀问题;且为保证集群中数据访问的一致性,改进原有基于单结点的分布式锁,提高分布式锁在集群中的安全性。实验结果证明,本申请拥有更高的判定准确率,集群结点负载更为均衡,同时在消息的收发速度上也有较好的表现,是一种更为高效、轻量化、易用的分布式网络消息队列中间件。
Description
技术领域
本申请涉及一种分布式网络消息中间件,特别涉及一种高效轻量易用的分布式网络消息中间件,属于网络消息中间件技术领域。
背景技术
软件产品在开发过程中,随着需求的多样化,系统功能越来越复杂,应用复杂度的不断增长使得开发和维护的成本急剧提高,为解决这个问题,需降低系统内部的耦合度。消息中间件应运而生,通过对系统功能的分解,充分利用异步通讯方式实现消息的互相传递,从而实现业务的并行处理和系统整体负载均衡,以此提高系统的可扩展性和可维护性。
随着移动互联网高速发展,网络应用的复杂度也不断上升。互联网产品相对于传统软件产品,对并发量、吞吐量、实时性和安全性等方面都有更高要求,同时必须应对多种操作系统、异构的网络互联环境和不同的应用平台。传统的消息中间件系统是为企业应用而设计的,其核心是满足企业级应用对准确性、规范化和通用性的要求。互联网应用需同时处理大量请求,面对的是海量数据和数个异构系统的互联,同时互联网应用对数据一致性要求也较弱。针对不同的应用场景,适用的中间件产品也不尽相同,需要结合实际情况对一些问题进行针对性处理,从而在整体上提高系统性能。
相较于传统软件功能上大而全的特征,新兴软件产品向着更轻量化、专一化的方向发展,这一特征有利于软件产品更好得完成自身的任务,彼此之间分工明确,构建出一个更高效的系统。在当前移动互联网的大环境下,对消息中间件也提出了更高的要求。构建一种更简单易用、高性能、同时具备良好事务支持和分布式环境的轻量级消息中间件系统具有很现实的应用价值。
消息中间件是一种由消息传递体系或消息队列模式组成的数据交流,并基于数据通信进行分布式系统集成。通过采用消息中间件,可以将应用的模块进行解耦并部署到异构的分布式平台上,从而降低跨平台、跨网络软件开发的复杂度。在传输方式上,消息中间件既支持同步方式,又支持异步的方式。如果采用异步方式发送消息,就不会阻塞其它请求,特别是在处理大量请求时可大幅缓解系统的压力,提高系统的吞吐量。
对于一个消息中间件,其核心功能上需要解决以下问题:一是消息模型的选取:消息中间件运行在分布式的系统中,消息收发双方可能是处在完全异构的平台、操作系统甚至网络环境中,如何保证一个消息从发送方发出并被接收方顺利无误的接收,消息如何进行路由,是需要解决的问题。二是消息的持久化和安全性:消息在发送的过程中,任何一个环节出问题,都可能导致消息的丢失或泄露,消息若能在适当的时机进行持久化,可大幅提高消息收发的准确性,减少消息重传的次数。三是同步传输与异步传输:这是需要解决的核心问题之一,相对于传统的请求应答模式软件,通过消息中间件重组的软件架构可以更好的利用异步消息通信实现业务的并行化处理。四是消息传递的顺序性:通过消息中间件实现具有优先级的消息传递,甚至可用于支持延迟任务的实现,对消息进行合理的优先级划分,在应对复杂业务的过程中显得更为重要。在实现上述功能的前提下,消息中间件系统可能还需要关注一些额外的问题,包括:消息传输性能、消息广播支持、提供事务支持、消息收发失败时的恢复处理等。
现有技术的消息中间件通常更适合配合传统的企业级应用,如果拿来直接应对互联网环境,不会有很好的表现。同时由于需要考虑中间件的通用性,这些软件通常非常庞大臃肿且不易采用,整个应用在消息传输层中花费了很大开销,需要找到一种更为轻量级的消息中间件来应对高并发、大吞吐量和实时性的网络应用环境。
Lamoth是一个专门针对于在线角色扮演游戏设计的消息中间件,利用Redis提供的Pub/Sub操作实现消息广播,同时结合Redis基于内存的快速读写能力,实现多结点之间的通信。但只是针对于单Redis结点的环境,数据量成为了重要的瓶颈,需要将其扩展到分布式环境中,同时,Lamoth也没有考虑到消息的持久化策略。
针对于物联网环境,现有技术专门针对物联网的消息中间件,通过对不同类型的物联网设备分配不同的频道,实现了彼此之间的直接数据交换。但模型并没有考虑到在分布式环境下可能遇到的负载均衡、并发控制等问题。
对于传统的消息中间件ActiveMQ,现有技术指出了其存在着管理落后、采用繁琐等问题。提出了相应的改进消息队列模型,将消息队列和若干个消息服务器通过映射关联起来,但这种改进只是在原有ActiveMQ的基础上进行了一次封装,并没有涉及性能低下的本质问题。
综上所述,现有技术的网络消息中间件存在不足,本申请的难点和待解决的问题主要集中在以下方面:
第一,软件复杂度的提升使得原有的架构模式已经无法适应多变的环境,对复杂软件的解耦是解决问题的关键。为实现软件的解耦操作,产生了基于消息中间件的分布式架构。互联网应用相对于企业级应用,在数据吞吐量、并发性和实时性方面均有更高的要求,而在数据一致性方面要求相对较低,现有技术的消息队列中间件系统由于过多考虑一致性需求,会较为庞大,效率、可扩展性和易用性低下,同时Redis在实现集群部署存在失效判定、负载均衡和同步访问等一系列问题,因此,当前迫切需要构建一个更为高效、轻量化、易用的分布式网络消息队列中间件;
第二,现有技术的PUSH模型需要发送端对每一个发送的结果依次进行确认,必然导致效率的低下,同时需要保证收发双方时刻保持连接状态,一旦无法保证收发双方时刻互连或遇到了很差的网络情况,PUSH模型就不能很好的完成任务。现有技术基于PULL方式的消息收发实时性差,且由于是由客户端进行请求,较多的无效请求会造成很大带宽浪费,采用轮询的方式来实现消息的接收存在以下两大缺点:一是如果出现空的消息队列,服务器端和客户端会有大量无用的命令执行,这些命令只会返回NULL值;二是消息接收端如果从队列中取到相应的值时,还需要判断当前值是否为NULL,带来处理延迟;
第三,将消息队列中间件系统扩展到分布式的环境中,在获取性能和灵活性的同时也会遇到一系列的问题,这些问题包括了以下方面:一是集群中任意结点都有可能宕机或失效,最终导致系统整体变为不可用,如何准确找出失效的结点并进行适当处理;二是集群中数据的负载的分布问题,如何有效的将处理请求和数据存储平均分发到各个结点处;三是多结点对关键数据的并发访问问题,如何在分布式环境下统一管理实现对关键数据的读写操作,保证数据的一致性和安全性,而现有技术的结点失效判定方法存在明显的不足;
第四,Redis数据时刻保存在内存中,而单机内存容量有限,对于一个超出单机内存容量的数据,如何将其自动划分并储存在多个结点上是实现分布式部署的核心问题,解决这个问题的一种方法是采用一致性哈希,原生的一致性哈希算法存在一系列问题,总结归纳有:一是当环内结点数量较少时,无法合理平均的划分区域,造成数据分布不均问题;二是当结点被移除或有新结点加入时,原先的负载平衡就可能被打破,造成数据倾斜,并且随着结点的不断移除和加入,这种数据倾斜的情况会成指数级增长;三是即使进行平均划分,还是存在部分点可能会出现模糊定位的问题,即某个点处于两个划分中间位置的情况;
第五,多个用户同时访问统一块数据,可能会造成数据的不一致,为解决这个问题,现有技术通常的做法是对数据加锁,在修改或读取数据时,先要获取到相应的锁,再访问数据,最后释放锁,在多线程环境下实现共享内存访问。相比较而言,Redis则提供一种更简单的乐观锁,一旦发现在操作期间这块内存区域被其它的客户端修改,就会导致整个操作全部失效,但这种方式存在两方面的问题:一是没有提供任何机制来限制数据在同一时刻内只能被一个对象访问,二是这种限制访问方式必然导致在大并发情况下,一次成功的操作伴随多次尝试,导致整体执行效率低下。
发明内容
本申请在对现有技术的消息队列中间件系统和基于内存的非关系型数据库的基础上,结合Redis自身的特征和不足,提出基于Redis实现的高效消息收发调度中间件模型,有效解决了传统消息中间件系统所遇到的效率、可扩展性和易用性低下的问题,同时针对Redis在实现集群部署遇到失效判定、负载均衡和同步访问等一系列问题,提出了优化解决算法。一是提出基于Redis实现的高效消息收发调度中间件模型,融合PUSH方式和PULL方式优化实现消息传递,改进消息的收发操作,为提高消息中间件的吞吐量,根据消息传输过程中的等待和处理的时间设计实现更优化的调度方法,同时给出延迟消息收发的解决方案,按照高效消息收发调度中间件模型中各个组成部分数据结构的特征进行类型划分,对不同的类型制定相应的持久化策略,提高消息队列的可靠性,完成对消息的备份和恢复;二是针对在分布式部署时可能出现的结点失效问题,为解决传统的基于法定人数的结点失效算法中存在的问题,提出全新的基于主观结论的结点失效判定算法,大幅提升失效结点判定的准确率,减少整体的故障转移的次数;三是提出基于多叉树维护的结点探测序列,实现轻量级的快速消息收发时,有着显著的优势,是一种更为高效、轻量化、易用的分布式网络消息队列中间件。
为实现以上技术特征,本申请所采用的技术方案如下:
高效轻量易用的分布式网络消息中间件,包括高效消息收发调度中间件模型和分布式网络消息队列并发控制方法,设计融合PUSH和PULL方式的消息快速收发和多优先级分发引擎、消息队列持久化优化策略、定时备份和容错处理机制,提出基于主观结论的结点失效判定算法,改进多叉树对一致性哈希算法实施进一步优化,克服传统方法结点负载不均匀问题,并改进原有基于单结点的分布式锁,提高分布式锁在集群中的安全性;
高效消息收发调度中间件模型基于Redis构建三个方面的内容特征,分别为:消息收发、优先级分发和持久化,具体包括:
第1步,对消息收发进行统一管理,首先定义消息的结构,然后基于Redis设计PUSH-PULL模型的消息收发体系,并采用Redis的SET数据结构设计消息接收确认机制;
第2步,提出一种静态优先级调度方法与一种动态优先级调度方法来满足不同的应用场景,在原有的实时消息队列的基础上,改进存储数据结构,构建具备延迟的队列模型;
第3步,优化Redis的数据持久化能力,通过存储设计和定时备份使得在故障发生后消息丢失的损失尽量降到最低,提高消息队列的整体可用性;
第4步,改进Redis在实现层面的部分细节,结合自身特征对消息收发调度中间件模型进行深度优化;
分布式网络消息队列并发控制方法包括:一是针对消息队列系统在分布式环境中的结点失效问题,结合Redis提供的哨兵机制给出的主观结论,基于观点一致性理论改进原有的基于法定人数的结点失效判定算法,减少不必要的故障转移次数,提高集群整体的稳定性;二是采用虚拟结点改进一致性哈希算法,对于不论是传统算法还是改进后的算法都存在的负载均匀问题,基于多叉树实现一种绝对均衡的划分算法;三是对集群中可能出现的同步互斥问题,设计基于分布式的Redis加锁算法,限制数据的访问,保证数据的安全性和有效性。
高效轻量易用的分布式网络消息中间件,进一步的,本申请综合两者的优点提出一种全新的PUSH-PULL消息推送模型,首先同时采用PUSH方式和PULL方式来实现一次探测性消息的收发操作,根据服务器端和客户端在收发消息的时间点因子来计算消息模型的推送变化率TsC,计算式为:
首先由服务器端发送一条PUSH探测消息,记录发送的时间X(t),客户端在收到消息之后记录接收时间X’(t),在发送完成PUSH消息一定时间延迟后,在服务器端采用PULL方式生成一条探测消息,存入队列中,记录时间S(t),当客户端收到PULL消息时就记录对应的时间点S’(t),在PUSH-PULL模型中消息传输方式融合PUSH方式和PULL方式,在服务器端和客户端同时调用PUSH-PULL*PUSH算法和PUSH-PULL*PULL算法;
在消息队列开启之后,记录每次PUSH操作和PULL操作的传输时间,定期更新计算相应的传输时延,根据计算得到的传输时延,结合变化率因子来动态决定每次消息传输所采用的传输方式,当前传输时延表示为Delay,其计算式为:
其中,Yci表示的是在第i次传输成功后计算得到的时延,Ri表示在第i次传输过程中所花费的时间。
高效轻量易用的分布式网络消息中间件,进一步的,基于令牌环的接收确认设计:采用Sets容器来控制各个接收端的确认情况,用SETQr-L表示对名为L的消息队列的确认,假设存在M个接收端,第i个接收端记录用Ti表示,对名为L的消息队列中的广播消息收发情况确认包含了以下步骤:
步骤一:发送端产生一条新的消息,为当前消息生成一个全局唯一的编号NID,并采用LPUSH指令将其存入消息队列LISTL中;
步骤二:保存形式为{<NID,[<T1,0>,...,<Tm,0>]}的数据到SETQr-L中,其中0表示接收方还未确认;
步骤三:当编号为Ti的接收端发现列表数据不为空时,将消息取出,并更新SETQr-L中的值,将键为Ti的值更新为1,表示已经接收到消息;
步骤四:每次对Sets中的值完成更新,都会检测当前消息的所有接收标识,如果存在值为0的标识,需要将消息重新存入队列中,等待另一个接收端发现并取出;否则表明本次消息发送已全部完成,清除SETQr-L中键值为NID的记录,表示已完成所有消息的发送任务;
在PUSH-PULL消息收发模型实现中,本申请采用一个Lists作为消息队列暂存消息,设计确认机制来保证消息接收的确认,设置一个Lists来保存消息的订阅情况,每次执行步骤二时都会从这个订阅情况集合中读取当前需要发送的目标接收端编号,用LISTJl-L表示所有订阅消息队列L的接收端记录情况,其数据结构形如[T1,T 2,…,Ti,…,Tm],其中Ti表示第i个订阅队列中消息的接收端记录;
消息接收过程中,保证在某一时刻只有一个接收端T,在其完成接收确认后再允许其它接收端进行确认,对于接收端Ti(1≤i≤m),本申请保证其上运行一个监控进程,将所有的接收端进行编号后组成环形结构,环上有m个结点表示有m个接收端,环内部存在且仅存在一个令牌标识,且保证令牌时刻在接收端进程之间相互传递。
高效轻量易用的分布式网络消息中间件,进一步的,构建多优先级消息队列:采用Redis的一组命令BLPOP/BRPOP,同时操作多个LIST,在一组LIST中找到第一个存在数据项的LIST,并弹出该队列中的最左/右的元素并返回,多优先级的队列对应的是多个LIST,实现一个多优先级的消息队列,在保证效率的同时最大化简化设计;
设定三个优先级:上级、中级、下级,其中上级优先级队列中的任务必须优先被执行,只有当上级优先级队列中没有任务时,中级优先级队列中的任务才能被执行,下级优先级队列只有在前两个队列中都不存在任务时才会被采用,分别将三个队列命名为up、centre和down,在静态优先级情况下,本申请消息队列转变为(LISTup,LISTcentre,LISTdown)的形式。
高效轻量易用的分布式网络消息中间件,进一步的,基于最先截止期的优先级调度方法:同时设计一种动态的消息分发调度方法,解决低优先级的消息可能出现的饿死问题;
每条消息的处理时间不完全相同,但同类型的消息的处理时间处于一个范围区间内,将消息进行分类,记录统计每种类型消息的处理时间,计算平均值将其作为当前消息处理时间的参考,实时得到每条新入队消息的到达时间和消息处理时间,以此计算出消息的优先级,在消息队列中,一次消息收发的操作过程中包括了以下属性:
属性一,消息的产生时间R:消息队列一条消息从服务器端被发送的时间点;
属性二,消息的等待时间A:消息从R时刻到最终到达一个客户端所经历的时间;
属性三,消息的处理时间X:消息从被客户端接收到最终处理完成消耗的时间;
采用一个Hashes记录不同类型消息的处理时间,HashinT格式为:(<typeID,{time,count}>),typeID是消息类型,根据消息的不同用途划分,time为当前类型消息执行的总时间消耗,count为该类型消息被执行的总次数,计算得到的类型为typeID的消息处理时间inTT公式为:
在消息队列刚启动时,每个类型的消息的被执行的次数和时间都为0,消息处理时间不通过公式得到,而是采用一个默认值,每次当一个消息被处理完成,需要更新HashinT中的记录,增加执行次数和总执行时间,用一个Hashes来记录当前的消息队列内部的消息时间信息,记为Hashtime,每当有一条新的消息被加入时,更新Hashtime中的数据,重新计算得到优先级最高的消息,Hashtime的结构为:<NID,{reach,inT}>,其中NID为消息编号,reach表示为消息的到达时间,inT是消息的处理时间,消息分发的优先级划分根据消息的截止时间A,消息的截止时间越近,消息的优先级就越高,消息的截止时间越远,优先级越低,消息编号为NID的截止时间的计算式为:
ANID=Hashtime[NID].inT+Hashtime[NID].reach 式4
为充分利用已知条件使得系统整体吞吐量达到最优,综合考虑R、X和A的值,动态计算每条消息在队列中的优先级,其计算公式定义为:
YxNID为消息在队列中的优先级,YcNID为传输时延。
高效轻量易用的分布式网络消息中间件,进一步的,构建具备延迟的队列模型:另一种数据结构记录额外的延迟时间,并找到最近的延迟请求进行分发,对于一个名为L带延迟的消息队列,本申请用YYsL来表示,YYsL中的成员唯一,但score可重复,基于有序集结构特征,本申请设计一种延迟队列的实现方法,具体包括:
第一,有序集根据记录的score自动排序,将延迟消息需要被执行的时间戳作为YYsL的score值,而消息体作为成员储存到一个YYsL的项中,解决延迟消息存储问题;
第二,消息的分发需要一个工作进程进行轮询,每隔100毫秒进行一次判断,取出YYsL中当前score最小的项,与当前时间戳进行比较,如果小于当前时间戳,则将当前项从YYsL中删除,并将消息加入执行队列;
第三,对于带优先级的延迟消息,在将消息加入执行队列时采用RPUSH命令直接将待处理的消息加入到队列的最右端,确保消息处理的响应时间的最小化;
采用YYsL保存延迟消息,采用一个工作进程轮询实现延迟消息的分发,每当到达延迟时间时,工作进程都会将消息从延迟队列中移出添加到实时的执行队列中,所有消息信息不论是否延迟最终都会进入执行队列,再根据其优先级进行分发,确保消息数据的一致性和可控性。
高效轻量易用的分布式网络消息中间件,进一步的,基于主观结论的结点失效鉴别:采用以下定义来描述一个包含m个结点的集群:
定义1,结点主观结论:集群中每个结点内部都存在一个哨兵,用于监控其它结点的状态,状态结论的集合可以用一个m位的数字来表示,则对于集群中第i个结点的哨兵,其主观结论ODi表示为式6:
ODi=[g1,g2,…,gi,…,gm] 式6
其中,gi是当前哨兵对于第i个结点失效状态的结论,0表示为失效状态,1表示为运行正常状态;
定义2,观点一致性:对于集群中的任意两个结点i和j,定义其拥有统一的观点,当且仅当i和j的主观结论满足式7:
ODigj&ODjgi==1 式7
其中,ODigj为第i个结点对第j个结点失效状态的主观判定结论,&符号表示对两个值做位与操作;
定义3,失效支持率:对于持有统一观点的结点集合V,集合内部包含w个结点,定义当前集合对于结点i的失效支持率Vsupt-i计算式为:
如果集群中出现失效现象,按照半数通过的原则找到可能的失效结点集合,本申请进一步利用上述定义筛选得到更为精确的失效结点候选集合;
通过对失效结点的筛选,确保每次都只是在一个有限的范围内对可控数量的结点进行有效的故障转移,在完成一轮故障转移之后,再循环调用候选失效节点获取算法,继续检测集群的状态。
高效轻量易用的分布式网络消息中间件,进一步的,基于多叉树改进的一致性哈希算法:将原先的一致性哈希算法中环上的真实物理结点都替换成并不真实存在的服务器虚拟结点,多个虚拟结点对应为同一个物理结点,这样即使在集群中服务器较少的情况下,也能保证环上有足够多的结点保证平均的弧度划分;
采用虚拟结点的方式无法保证在物理结点增加时得到一个绝对平均的弧度划分,实现时采用数量级较大的虚拟结点来减小误差,为得到完全平均的划分,本申请提出一种基于线性探测的划分算法来实现物理结点增加时绝对平均的弧度划分,设计一种多叉树结构来得到数据结点储存位置的探测序列,这棵树的根结点包含两个孩子,其后每一层的孩子数量都比其父层的孩子个数多一,从根结点到每条叶子的路径上都有相应的数字标示,结合计算得到的哈希值得到相应的探测序列,采用多叉树的形式进行结点划分包括两部分,一是树构造过程,二是探测序列获取过程,其中,树构造过程只在当前集群中有新结点加入时才进行,会动态增长,构造完成后变化不大;探测序列的获取过程在每次查询时都会进行,其具体的计算过程为:
过程一,对数据Key值采用哈希函数计算得到哈希值,得到结果t=r(Key);
过程二,从多叉树Tree的根结点开始进行查询,取a=2,计算c=t MOD a,其中MOD为取余计算,按照得到的结果c选取匹配对应的路径,同时更新t的值使得t=t/a;
过程三,每向下一层,令a的值加1,重复过程二的过程直到到达树的叶子结点,得到最终的探测序列;
过程四,数据的查询顺序会按照得到的探测序列;
根据探测序列,依次按照顺序去相应的结点中查找结果数据,当需要增加新的物理结点是,只需要在原有的树形结构中动态增加一层叶子结点,得到一个全新的平均划分;当删除结点时,需要将原先树缩减一层即可。
高效轻量易用的分布式网络消息中间件,进一步的,基于锁体系的并发控制生成:本申请设计一种分布式锁体系实现对数据的同步访问,采用一种中心化的方式组织和管理在分布式环境下各个结点的锁分配情况,采用Redis的SETNX命令,设置一个键值对<key,value>,当且仅当key值不存在时,命令才能成功,在一个实例的全局范围内统一管理所有被请求的锁对象,对请求加锁的对象采用一套统一的命名规范,随机生成一个序列串作为解锁的密钥,一个锁对象在形式上表现为<锁名称,密钥>的键值对,方便的判断某个对象的加锁情况。
高效轻量易用的分布式网络消息中间件,进一步的,基于单实例的情况,中心化的分布式锁的管理方案为:现假设集群中存在M个主结点,彼此间相互独立,在真正实现锁分配之前需要做一些额外的预处理工作,包括对集群中的结点进行统一编号和对结点进行唯一性分组,除去叶子结点的操作后,更上一层的支配分组中的分配情况取决于当前层中的多数意见,循环判定直到树根,找到最终唯一的一个锁分配方案,客户端才能真正获取到这个分布式锁,每一个支配分组中都有一个数字编号,表示的意义是当前支配分组的决策结果所存储在的集群中的哪个结点,该值动态计算,一旦集群中出现失效的结点,值就顺延,当值操作当前集群结点数时表示这个支配分组下的所有集群都已失效,此时默认其总是服从同层的其它支配的决策情况;
通过对键值对设置相应的过期时间来控制每个锁对象的被获取的最大时间,以此实现锁对象的自动释放,实现一个带超时的分布式锁来限制对数据并发访问。
与现有技术相比,本申请的创新点和优势在于:
第一,本申请构建了一个更为高效、轻量化、易用的分布式网络消息队列中间件,设计实现高效消息收发调度中间件模型,包括融合PUSH和PULL方式的消息快速收发和多优先级分发引擎、消息队列持久化优化策略、定时备份和容错处理机制,此外,传统消息中间件在高网络延迟情况下会出现判定准确率较低的问题,本申请提出基于主观结论的结点失效判定算法,改进多叉树对一致性哈希算法实施进一步优化,克服传统方法结点负载不均匀问题;并且,为保证集群中数据访问的一致性,本申请改进原有基于单结点的分布式锁,提高分布式锁在集群中的安全性;实验结果证明,改进后的算法拥有更高的判定准确率,集群中的结点数量在出现变动后的负载更为均衡,同时在消息的收发速度上也有较好的表现,具备较高的可用性和稳定性;
第二,提出基于Redis实现的高效消息收发调度中间件模型,融合PUSH方式和PULL方式优化实现消息传递,改进消息的收发操作,为提高消息中间件的吞吐量,根据消息传输过程中的等待和处理的时间设计实现更优化的调度方法,同时给出延迟消息收发的解决方案,按照高效消息收发调度中间件模型中各个组成部分数据结构的特征进行类型划分,对不同的类型制定相应的持久化策略,提高消息队列的可靠性,完成对消息的备份和恢复,提高其稳定性和可用性;
第三,针对在分布式部署时可能出现的结点失效问题,需要自动判定失效结点,进行相应的故障转移操作,为解决传统的基于法定人数的结点失效算法中存在的问题,本申请提出全新的基于主观结论的结点失效判定算法,大幅提升失效结点判定的准确率,减少整体的故障转移的次数;
第四,提出基于多叉树的一致性哈希算法,在现有技术的一致性哈希算法中,如果出现新结点的添加或删除操作,原有结点的负载均衡情况就必定被打破,无法保证各个结点的平均承担负载,本申请的基于多叉树维护的结点探测序列有效解决了结点负载不均匀问题;并且,为保证集群中数据访问的一致性,本申请改进原有基于单结点的分布式锁,提高分布式锁在集群中的安全性。本申请实现轻量级的快速消息收发时,有着显著的优势,是一种更为高效、轻量化、易用的分布式网络消息队列中间件。
附图说明
图1是本申请高效消息收发调度中间件模型的结构图。
图2是基于视觉认知编组的文物特征线连接的基本步骤示意图。
图3是PUSH-PULL方法探测消息的收发示意图。
图4是消息收发调度中间件模型的消息传输流程图。
图5是现有技术结点失效判定算法存在问题的集群示意图。
图6是从传统的一致性哈希算法到基于虚拟结点的改进示意图。
图7是添加新结点g,h后得到的环结果示意图。
图8是多叉树的探测序列树具体形式示意图。
图9是基于锁体系的并发控制集群节点分组示意图。
具体实施方法
下面结合附图,对本申请提供的高效轻量易用的分布式网络消息中间件的技术方案进行进一步的描述,使本领域的技术人员能够更好的理解本申请并能够予以实施。
软件复杂度的提升使得原有的架构模式已经无法适应多变的环境,对复杂软件的解耦是解决问题的关键。为实现软件的解耦操作,产生了基于消息中间件的分布式架构。互联网应用相对于企业级应用,在数据吞吐量、并发性和实时性方面均有更高的要求,而在数据一致性方面要求相对较低,传统的消息队列中间件系统由于过多考虑一致性需求,会较为庞大,在性能和易用性方面也表现不佳。因此,本申请构建一个更为高效、轻量化、易用的分布式网络消息队列中间件。
本申请在数据库Redis的基础上,设计实现高效消息收发调度中间件模型,包括融合PUSH和PULL方式的消息快速收发和多优先级分发引擎、消息队列持久化优化策略、定时备份和容错处理机制,此外,传统消息中间件在高网络延迟情况下会出现判定准确率较低的问题,本申请提出基于主观结论的结点失效判定算法,改进多叉树对一致性哈希算法实施进一步优化,克服传统方法结点负载不均匀问题;并且,为保证集群中数据访问的一致性,本申请改进原有基于单结点的分布式锁,提高分布式锁在集群中的安全性。
最后,本申请进行了消息收发实验,并在模拟的高网络延迟集群环境下测试了结点失效判定算法。实验结果证明,改进后的算法拥有更高的判定准确率,集群中的结点数量在出现变动后的负载更为均衡,同时在消息的收发速度上也有较好的表现。综上,本申请设计并实现的基于分布式网络消息中间件系统具备了较高的可用性和稳定性。
一、高效消息收发调度中间件模型
高效消息收发调度中间件模型基于Redis构建三个方面的内容特征,分别为:消息收发、优先级分发和持久化。每个方面包含的内容特征见图1所示。
第1步,对消息收发进行统一管理,首先定义消息的结构,然后基于Redis设计PUSH-PULL模型的消息收发体系,并采用Redis的SET数据结构设计消息接收确认机制;
第2步,提出一种静态优先级调度方法与一种动态优先级调度方法来满足不同的应用场景,在原有的实时消息队列的基础上,改进若干存储数据结构,构建具备延迟的队列模型;
第3步,针对消息队列在运行过程中可能出现的故障失效,优化Redis的数据持久化能力,通过存储设计和定时备份使得在故障发生后消息丢失的损失尽量降到最低,提高消息队列的整体可用性;
第4步,为了优化消息收发调度中间件模型性能,提高其稳定性和可用性,本申请改进Redis在实现层面的部分细节,结合自身特征对消息收发调度中间件模型进行深度优化。
(一)PUSH-PULL消息传输方式
1.构建消息队列
定义一:一个消息定义为一个三元祖N=<Y,E,L>,其中:
(1)Y为消息头,内部保存在整个消息传输过程中不会变化的数据,通过解析消息头,快速获得当前消息的基本信息;
(2)E为消息体,保存需要传输的数据本身,在消息传输过程中,不会有任何一个结点会更改这些数据;
(3)L为消息质量信息,包括发送的消息当前的优先级,发送的目标地址信息,在发送过程中随不同情况发生变化。
每一条消息都唯一,都存在一个唯一的编号,在整个消息队列系统中,根据消息的这个唯一编号,迅速定位到对应的消息信息。
定义二,形式化的定义基本数据类型:
(1)一个Redis中字符串类型的数据表示为C#var,其中var为变量名称;
(2)一个Redis中List类型的数据表示为[List1,List2,…],其中Listi为列表中存储的项;
(3)一个Redis中Sets类型的数据表示为{Sets1,Sets2,…},其中Setsi为集合中存储的项;
(4)一个Redis中Hashes类型的数据表示为(<w1,u1>,<w2,u2>,…),其中wi为第i项键,ui为第i项的值;
(5)一个Redis中Sorted Sets类型的数据表示为{Sets1#score1,Sets2#score2,…},其中Setsi为第i项的数据,scorei为第i项的得分。
为实现消息在不同服务器结点之间的传输,在消息收发过程中的参与者根据消息的流入流出情况被划分为发送端和接收端,将消息的收发方式分为PUSH和PULL两种,在PUSH模型中,发送端主动将消息传递给接收端,并确保收发过程和结果的正确性;在PULL模型中,消息的获取操作由每个接收端主动进行,需要被接收的消息被事先存放在一个容器中,发送端只需将产生的消息存入相应容器中。
1)PUSH模型:PUSH模型的消息收发方式非常有用,但由于需要发送端对每一个发送的结果依次进行确认,必然导致效率的低下。一个更大的问题是,采用PUSH模型时,需要保证收发双方时刻保持连接状态。一旦无法保证收发双方时刻互连或者遇到了很差的网络情况,PUSH模型就不能很好的完成任务。
2)PULL模型
相对于PUSH方式,基于PULL方式的消息收发实时性差,且由于是由客户端进行请求,较多的无效请求会造成很大带宽浪费。消息队列模型如图2所示,正常情况下,采用RPOP指令从List中取出消息信息,完成分发处理。但在消息队列为空的情况,当前没有消息需要被分发,采用RPOP指令会返回一个NULL值。此时,消息的接收端需要在之后的一段时间后再继续重复请求队列,采用轮询的方式来实现消息的接收存在以下两大缺点:一是如果出现空的消息队列,服务器端和客户端会有大量无用的命令执行,这些命令只会返回NULL值;二是消息接收端如果从队列中取到相应的值时,还需要判断当前值是否为NULL,带来处理延迟。采用Redis的ERPOP指令实现一个阻塞等待,避免采用轮询所带来的额外开销,将超时时间设置为0,永不超时。
2.PUSH-PULL方法
采用PUSH方式进行消息收发具有较高的准确性,但收发效率很差;采用PULL方式能够大幅提高消息收发效率,但无法保证消息收发的准确性,基于这两种收发模型的特征,本申请综合两者的优点提出一种全新的PUSH-PULL消息推送模型,首先同时采用PUSH方式和PULL方式来实现一次探测性消息的收发操作,根据服务器端和客户端在收发消息的时间点因子来计算消息模型的推送变化率TsC,计算式为:
具体探测过程如图3所示,首先由服务器端发送一条PUSH探测消息,记录发送的时间X(t),客户端在收到消息之后记录接收时间X’(t),在发送完成PUSH消息一定时间延迟后,在服务器端采用PULL方式生成一条探测消息,存入队列中,记录时间S(t),当客户端收到PULL消息时就记录对应的时间点S’(t),在PUSH-PULL模型中消息传输方式融合PUSH方式和PULL方式,在服务器端和客户端同时调用PUSH-PULL*PUSH算法和PUSH-PULL*PULL算法。
在消息队列开启之后,记录每次PUSH操作和PULL操作的传输时间,定期更新计算相应的传输时延,根据计算得到的传输时延,结合变化率因子来动态决定每次消息传输所采用的传输方式,当前传输时延表示为Delay,其计算式为:
其中,Yci表示的是在第i次传输成功后计算得到的时延,Ri表示在第i次传输过程中所花费的时间。
3.基于令牌环的接收确认设计
采用Redis的发布/订阅模式实现的消息收发,发送方无法判断消息是否被正确接收,是否存在消息丢失的情况,为了对发送的结果进行确认,本申请设计一种消息传输机制确认收发情况,采用Sets容器来控制各个接收端的确认情况,用SETQr-L表示对名为L的消息队列的确认,假设存在M个接收端,第i个接收端记录用Ti表示,对名为L的消息队列中的广播消息收发情况确认包含了以下步骤:
步骤一:发送端产生一条新的消息,为当前消息生成一个全局唯一的编号NID,并采用LPUSH指令将其存入消息队列LISTL中;
步骤二:保存形式为{<NID,[<T1,0>,...,<Tm,0>]}的数据到SETQr-L中,其中0表示接收方还未确认;
步骤三:当编号为Ti的接收端发现列表数据不为空时,将消息取出,并更新SETQr-L中的值,将键为Ti的值更新为1,表示已经接收到消息;
步骤四:每次对Sets中的值完成更新,都会检测当前消息的所有接收标识,如果存在值为0的标识,需要将消息重新存入队列中,等待另一个接收端发现并取出;否则表明本次消息发送已全部完成,清除SETQr-L中键值为NID的记录,表示已完成所有消息的发送任务。
在PUSH-PULL消息收发模型实现中,本申请采用一个Lists作为消息队列暂存消息,设计确认机制来保证消息接收的确认,以外,为保存消息的收发关系,还需要一个Lists来保存消息的订阅情况,每次执行步骤二时都会从这个订阅情况集合中读取当前需要发送的目标接收端编号,用LISTJl-L表示所有订阅消息队列L的接收端记录情况,其数据结构形如[T1,T2,…,Ti,…,Tm],其中Ti表示第i个订阅队列中消息的接收端记录。
消息接收过程中,会出现多个客户端同时请求一个消息队列的情况,最后同时进行接收确认的写操作,为避免出现数据不一致的问题,保证在某一时刻只有一个接收端T,在其完成接收确认后再允许其它接收端进行确认,对于接收端Ti(1≤i≤m),本申请保证其上运行一个监控进程,将所有的接收端进行编号后组成环形结构,环上有m个结点表示有m个接收端,环内部存在且仅存在一个令牌标识,且保证令牌时刻在接收端进程之间相互传递。
(二)具备延迟的优先级调度
1.构建多优先级消息队列
在处理客户端请求时,由于操作复杂度不同,每个请求所需要执行的时间也不尽相同,为得到一个最优的服务器端响应,需要对不同级别的请求划分不同的优先级,在完成一项任务时,某些特定操作的执行必须先于其它操作,一个好的消息队列中间件应该能够提供足够的支持来实现具备优先级的消息分发功能。
采用Redis的一组命令BLPOP/BRPOP,同时操作多个LIST,在一组LIST中找到第一个存在数据项的LIST,并弹出该队列中的最左/右的元素并返回,多优先级的队列对应的是多个LIST,实现一个多优先级的消息队列,在保证效率的同时最大化简化设计。
设定三个优先级:上级、中级、下级,其中上级优先级队列中的任务必须优先被执行,只有当上级优先级队列中没有任务时,中级优先级队列中的任务才能被执行,下级优先级队列只有在前两个队列中都不存在任务时才会被采用,分别将三个队列命名为up、centre和down,在静态优先级情况下,本申请消息队列转变为(LISTup,LISTcentre,LISTdown)的形式,静态优先级调度策略,实现简单,但缺乏灵活性,不利于系统扩展,一旦连续出现多个优先级较高的任务需要被执行,低优先级的任务在很长时间内始终无法得到响应,其中较低优先级的队列中的消息增长的速度远高于高优先级队列中的消息增长速度。
2.基于最先截止期的优先级调度方法
本申请同时设计一种动态的消息分发调度方法,解决低优先级的消息可能出现的饿死问题,动态调度相对于静态调度方法,最大的区别是优先级在运行过程中会发生变化,优先级调度针对任务,一个任务包括到达时间和执行时间,一个消息同样存在到达时间和消息处理时间,区别在于消息的到达时间明确,处理时间则不确定。
每条消息的处理时间不完全相同,但同类型的消息的处理时间处于一个范围区间内,将消息进行分类,记录统计每种类型消息的处理时间,计算平均值将其作为当前消息处理时间的参考,实时得到每条新入队消息的到达时间和消息处理时间,以此计算出消息的优先级,在消息队列中,一次消息收发的操作过程中包括了以下属性:
属性一,消息的产生时间R:消息队列一条消息从服务器端被发送的时间点;
属性二,消息的等待时间A:消息从R时刻到最终到达一个客户端所经历的时间;
属性三,消息的处理时间X:消息从被客户端接收到最终处理完成消耗的时间;
采用一个Hashes记录不同类型消息的处理时间,HashinT格式为:(<typeID,{time,count}>),typeID是消息类型,根据消息的不同用途划分,time为当前类型消息执行的总时间消耗,count为该类型消息被执行的总次数,计算得到的类型为typeID的消息处理时间inTT公式为:
在消息队列刚启动时,每个类型的消息的被执行的次数和时间都为0,消息处理时间不通过公式得到,而是采用一个默认值,每次当一个消息被处理完成,需要更新HashinT中的记录,增加执行次数和总执行时间,用一个Hashes来记录当前的消息队列内部的消息时间信息,记为Hashtime,每当有一条新的消息被加入时,更新Hashtime中的数据,重新计算得到优先级最高的消息,Hashtime的结构为:<NID,{reach,inT}>,其中NID为消息编号,reach表示为消息的到达时间,inT是消息的处理时间,消息分发的优先级划分根据消息的截止时间A,消息的截止时间越近,消息的优先级就越高,消息的截止时间越远,优先级越低,消息编号为NID的截止时间的计算式为:
ANID=Hashtime[NID].inT+Hashtime[NID].reach 式4
为充分利用已知条件使得系统整体吞吐量达到最优,综合考虑R、X和A的值,动态计算每条消息在队列中的优先级,其计算公式定义为:
YxNID为消息在队列中的优先级,YcNID为传输时延。
3.构建具备延迟的队列模型
基于Lists实现的消息队列是实时的,队列内的消息会及时的分发和处理,但在一些情况下,希望能够延迟处理一些请求,基于Lists实现的消息队列无法满足这个需求,需要另一种数据结构记录额外的延迟时间,并找到最近的延迟请求进行分发,对于一个名为L带延迟的消息队列,本申请用YYsL来表示,YYsL中的成员唯一,但score可重复,基于有序集结构特征,本申请设计一种延迟队列的实现方法,具体包括:
第一,有序集根据记录的score自动排序,将延迟消息需要被执行的时间戳作为YYsL的score值,而消息体作为成员储存到一个YYsL的项中,解决延迟消息存储问题;
第二,消息的分发需要一个工作进程进行轮询,每隔100毫秒进行一次判断,取出YYsL中当前score最小的项,与当前时间戳进行比较,如果小于当前时间戳,则将当前项从YYsL中删除,并将消息加入执行队列;
第三,对于带优先级的延迟消息,在将消息加入执行队列时采用RPUSH命令直接将待处理的消息加入到队列的最右端,确保消息处理的响应时间的最小化;
采用YYsL保存延迟消息,采用一个工作进程轮询实现延迟消息的分发,每当到达延迟时间时,工作进程都会将消息从延迟队列中移出添加到实时的执行队列中,所有消息信息不论是否延迟最终都会进入执行队列,再根据其优先级进行分发,确保消息数据的一致性和可控性,通过以上建模过程,一条消息从产生到最终被接收的工作流程如图4所示。
二、分布式网络消息队列并发控制方法
将消息队列中间件系统扩展到分布式的环境中,在获取性能和灵活性的同时也会遇到一系列的问题,这些问题包括了以下方面:一是集群中任意结点都有可能宕机或失效,最终导致系统整体变为不可用,如何准确找出失效的结点并进行适当处理;二是集群中数据的负载的分布问题,如何有效的将处理请求和数据存储平均分发到各个结点处;三是多结点对关键数据的并发访问问题,如何在分布式环境下统一管理实现对关键数据的读写操作,保证数据的一致性和安全性。针对以上三点,本申请提出新的算法或改进现有的方法,从而克服消息中间件系统在分布式环境下面临的问题。
(一)基于主观结论的结点失效鉴别
1.现有技术的结点失效判定方法
现有技术结点失效判定算法的核心思想基于以下这个假设:若某一个结点失效,则其它哨兵就无法监听到其心跳包,一旦集群中存在多数哨兵判定得出某一个结点失效时,在客观上认定了这个结点已经失效。采用这个算法确实能够找出集群中失效的结点,但也存在一些问题。如图5所示,这是一个由五个结点A、B、C、D、E构成的一个集群,结点之间的连线表示数据通路,由于网络延迟,可能导致各个结点之间通信不畅,C、D之间和D、E之间的弧形曲线表示可能存在网络延迟或网络故障,在这种情况下采用传统算法,左层的三个结点的哨兵会一致认为C、E两个结点同时失效,而右层的两个结点则会持有完全相反的结论,由于左层的结点数量较多且超过半数,导致了右层的所有结点都会被认定为存在客观失效,最终结果就是C和E点都进行了故障转移,但事实情况是,在C和E结点之间只需要其中的任意一个结点进行一次故障转移就可以完成整个集群的恢复。
2.失效结点的过滤计算
采用以下定义来描述一个包含m个结点的集群:
定义1,结点主观结论:集群中每个结点内部都存在一个哨兵,用于监控其它结点的状态,状态结论的集合可以用一个m位的数字来表示,则对于集群中第i个结点的哨兵,其主观结论ODi表示为式6:
ODi=[g1,g2,…,gi,…,gm] 式6
其中,gi是当前哨兵对于第i个结点失效状态的结论,0表示为失效状态,1表示为运行正常状态;
定义2,观点一致性:对于集群中的任意两个结点i和j,定义其拥有统一的观点,当且仅当i和j的主观结论满足式7:
ODigj&ODjgi==1 式7
其中,ODigj为第i个结点对第j个结点失效状态的主观判定结论,&符号表示对两个值做位与操作。
定义3,失效支持率:对于持有统一观点的结点集合V,集合内部包含w个结点,定义当前集合对于结点i的失效支持率Vsupt-i计算式为:
如果集群中出现失效现象,按照半数通过的原则找到可能的失效结点集合,本申请进一步利用上述定义筛选得到更为精确的失效结点候选集合,候选失效节点获取算法的伪代码为:
Input:主观结论集合OD,集群节点集合Nodes,集群中节点数量M
Output:失效节点集合FailNodes
3.Foreach node in Nodes do
4.countFail←所有其它结点中判定node结点为失效的结点个数
5.If countFailt>M/2then
6.Insert nodes into Candicates //找出候选的失效节点集合
7.EndForeach
8.Set Clusters={}
9.Foreach candicate in Candicates do
10.isFind=False
11.Foreach v in Clusters do
12.If candicate与v中节点观点统一then
13.Insert candicates into v //将失效结点按照观点一致性聚类
14.isFind=True
15.continue
16.EndForeach
17.If not isFind then //未找到同类
18.newV←{candicate}
19.Insert newV into Clusters
20.EndForeach
21.Foreach v in Clusters do
22.failNode←v中失效支持率最大的结点
23.Insert failNode into FailNodes //聚类中失效支持率最高的结点
24.EndForeach
25.Return FailNodes
通过对失效结点的筛选,确保每次都只是在一个有限的范围内对可控数量的结点进行有效的故障转移,在完成一轮故障转移之后,再循环调用候选失效节点获取算法,继续检测集群的状态。
哨兵机制为Redis集群部署提供了很好的自动化管理辅助,使得一个主从模式的Redis集群能够更稳定的完成任务,保证结点的可靠性,但这种模式还没有真正实现Redis集群的完全分布式部署,主服务和从服务中的数据时一致的,仅满足了数据的安全性和快速恢复的要求。以下本申请解决如何通过一致性哈希分片的方式解决数据分块问题。
(二)基于多叉树改进的一致性哈希算法
Redis数据时刻保存在内存中,而单机内存容量有限,对于一个超出单机内存容量的数据,如何将其自动划分并储存在多个结点上是实现分布式部署的核心问题,解决这个问题的一种方法是采用一致性哈希,通过对数据的键值采用一致性哈希算法,将不同键值的数据分组映射到各不同的服务器上,保证每组的键值对数据量在一个可控的范围内,从而实现数据的分布式部署。
原生的一致性哈希算法存在一系列问题,总结归纳有:一是当环内结点数量较少时,无法合理平均的划分区域,造成数据分布不均问题;二是当结点被移除或有新结点加入时,原先的负载平衡就可能被打破,造成数据倾斜,并且随着结点的不断移除和加入,这种数据倾斜的情况会成指数级增长;三是即使进行平均划分,还是存在部分点可能会出现模糊定位的问题,即某个点处于两个划分中间位置的情况。
将原先的一致性哈希算法中环上的真实物理结点都替换成并不真实存在的服务器虚拟结点,多个虚拟结点对应为同一个物理结点,这样即使在集群中服务器较少的情况下,也能保证环上有足够多的结点保证平均的弧度划分。如图6(a)所示,集群中原先有3个结点,在这种情况下如果结点X失效,Y就替代了X,失效部分的结点上的数据负载被迁移到了Y上,造成Y的负载是其它结点的两倍。现在采用虚拟结点替代物理结点,将环上的结点数量扩展为6个,如图6(b)所示。为保证平均划分,其中会有2个结点指向同一个物理结点,在这个例子中虚拟结点和物理结点的映射关系中,虚拟节点a,d;b,e;c,f分别对应物理节点X;Y;Z。同时为保证数据分布的均匀性,X、Y、Z所对应的虚拟结点排列方式保证两两间隔,并且保证每两个的组合种类出现两次,环的结点排列方式为:[X、Y、Z,X、Z、Y],当X结点失效时,虚拟结点同样会找到其相邻的下一个结点,X结点的负载就被平均分摊到了Y和Z结点上,这样就解决了负载均衡不一致的问题。如果是新增物理结点的操作,添加新的虚拟结点,并增加其与物理结点的映射关系,对于每一个物理结点,都会保证环上存在w个虚拟结点与之对应,在图6的例子中,w=2,在进行虚拟结点增加操作时,为使添加操作的结果对集群中数据的影响程度降到最低,之前的结点位置不能发生变化,基于这个前提,在完成结点添加操作之后,每个结点所占的弧度划分就不会再保证是绝对平均。如图7所示,在原有集群中新加入一个物理结点γ,用2个虚拟结点g和h映射这个物理结点。从图中可以清晰的看出,在原有集群中加入新的虚拟结点后必然导致各个不同区域弧度划分不再保证绝对的均匀,这必然会导致各个结点所承担的负载会有差异,被重新划分的弧度中最大部分与均值之间的比值随着w值得增长而逐渐降低,最终趋向于一致,即当环上虚拟结点的数量越多,每次结点增加对整体的影响就越小。
相对于传统的一致性哈希算法,采用虚拟结点的改进方法额外维护一张映射表来快速查询得到虚拟结点到物理结点的映射关系,本申请采用二叉树的方式维护这个映射,综上,一次完成的查询操作需要进行一次哈希计算加上额外的映射查询,假设虚拟结点的数量为M,则一次查询的时间复杂度为O(log2(M))。
采用虚拟结点的方式无法保证在物理结点增加时得到一个绝对平均的弧度划分,所以实现时采用数量级较大的虚拟结点来减小误差,为得到完全平均的划分,本申请提出一种基于线性探测的划分算法来实现物理结点增加时绝对平均的弧度划分,设计一种多叉树结构来得到数据结点储存位置的探测序列,这棵树的根结点包含两个孩子,其后每一层的孩子数量都比其父层的孩子个数多一,从根结点到每条叶子的路径上都有相应的数字标示,结合计算得到的哈希值得到相应的探测序列,采用多叉树的形式进行结点划分包括两部分,一是树构造过程,二是探测序列获取过程,其中,树构造过程只在当前集群中有新结点加入时才进行,会动态增长,构造完成后变化不大;探测序列的获取过程在每次查询时都会进行,其具体的计算过程为:
过程一,对数据Key值采用哈希函数计算得到哈希值,得到结果t=r(Key);
过程二,从多叉树Tree的根结点开始进行查询,取a=2,计算c=t MOD a,其中MOD为取余计算,按照得到的结果c选取匹配对应的路径,同时更新t的值使得t=t/a;
过程三,每向下一层,令a的值加1,重复过程二的过程直到到达树的叶子结点,得到最终的探测序列;
过程四,数据的查询顺序会按照得到的探测序列,如得到的序列为[X、Y、Z],则会先到结点X中查询数据,如果未命中再找去Y,Z结点中查询。
多叉树的具体形式如图8所示,其中左边部分是一棵包含两个结点X、Y的树,右边部分相对比左边多出了一个结点Z,以右边这个包含3个结点的集群为例,首先根据哈希函数计算得到哈希值w,计算可以得到6种不同的探测序列,根据探测序列,本申请依次按照顺序去相应的结点中查找结果数据。采用这种方式来维护映射关系,一个最大的好处就是当需要增加新的物理结点是,只需要在原有的树形结构中动态增加一层叶子结点,就可以得到一个全新的平均划分。当删除结点时,需要将原先树缩减一层即可。
(三)基于锁体系的并发控制生成
多个用户同时访问统一块数据,可能会造成数据的不一致,为解决这个问题,现有技术通常的做法是对数据加锁,在修改或读取数据时,先要获取到相应的锁,再访问数据,最后释放锁,在多线程环境下实现共享内存访问。相比较而言,Redis则提供一种更简单的乐观锁,一旦发现在操作期间这块内存区域被其它的客户端修改,就会导致整个操作全部失效。这种方式存在两方面的问题:一是没有提供任何机制来限制数据在同一时刻内只能被一个对象访问,二是这种限制访问方式必然导致在大并发情况下,一次成功的操作伴随多次尝试,导致整体执行效率低下。
在分布式消息收发调度中间件模型中,集群中每个结点中都保存一部分消息队列,每个队列内部都包含一个互斥锁,一个进程如果希望读取或修改队列中的消息,必须先获取到相应的锁。为强化消息队列在大并发情况下的请求响应效率,减少操作的重复尝试次数,本申请设计一种分布式锁体系实现对数据的同步访问。
在实现分布式锁体系时,考虑到可能存在某个客户端会有宕机或失效的情况,为防止由于这种情况导致的死锁问题,加入一个超时时间TTL,一旦某个锁被获取的时间超过这个限定,锁就会被自动释放。除此以外,实现分布式锁还有许多额外情况需要考虑包括:一是一个进程获取到了锁,但是由于其运行处理的时间超出了超时时间,其获取的锁已被自动释放,该进程在不知情的情况下释放了无效的超时锁,或该锁此时已被分配给了其它进程;二是有多个进程在同一个时间点请求了同一个锁,导致多个进程能获取到同一个锁,而这多个进程又认为自己是该锁的唯一拥有者;三是进程在获取锁后崩溃导致无法继续运行并释放锁,其它进程在请求这个锁时无法得知崩溃的情况而浪费很多时间来等待。
基于以上分析,本申请采用一种中心化的方式组织和管理在分布式环境下各个结点的锁分配情况,采用Redis的SETNX命令,设置一个键值对<key,value>,当且仅当key值不存在时,命令才能成功,在一个实例的全局范围内统一管理所有被请求的锁对象,对请求加锁的对象采用一套统一的命名规范,随机生成一个序列串作为解锁的密钥,一个锁对象在形式上表现为<锁名称,密钥>的键值对,方便的判断某个对象的加锁情况。
以上已给出了在单实例的情况下,中心化的分布式锁的管理方案。但在分布式环境下,任何结点都有可能出现失效,一旦持有锁对象的主结点失效,在其从结点完成失效转移之前,锁的管理就会出现混乱,锁安全性就会被破坏。具体表现为:假设存在两个客户端X和Y请求一个分布式锁,X已经获得这个分布式的锁,但此时锁管理服务器主结点出现故障,Redis哨兵会自动对当前主结点进行故障转移,一个从结点会进行写同步,并被上升为主结点,此时,如果写同步操作还未完毕,Y已向这个新的结点请求了与X相同的锁,从结点会在不知情的情况下将锁对象分配给Y,最终导致的结果就是X和Y得到同一个锁。
所以需要将这个算法扩展到分布式环境中,现假设集群中存在M个主结点,彼此间相互独立,在真正实现锁分配之前需要做一些额外的预处理工作,包括对集群中的结点进行统一编号和对结点进行唯一性分组,假设M的值为5,集群中的主结点就会被组织成如图9的形式。在进行锁申请时,根据图中的分组情况,从树形结构的叶子结点开始向上,找到支配分组结点,根据当前分组中下属的锁申请情况来决定最终的锁分配。例如1号结点和2号结点在一层中被分配到一个支配组中,在锁申请的过程中,如果客户端向1号结点申请锁,在1号结点中完成setnx操作后,会优先去同支配组的2号结点中执行setnx操作,当在2号结点成功申请时,才会将结果传播上升到一层支配分组。同理,需要对3,4,5号结点进行同样的操作。除去叶子结点的操作后,更上一层的支配分组中的分配情况取决于当前层中的多数意见,循环判定直到树根,找到最终唯一的一个锁分配方案,客户端才能真正获取到这个分布式锁。图中每一个支配分组中都有一个数字编号,表示的意义是当前支配分组的决策结果所存储在的集群中的哪个结点,该值动态计算,一旦集群中出现失效的结点,值就顺延,当值操作当前集群结点数时表示这个支配分组下的所有集群都已失效,此时默认其总是服从同层的其它支配的决策情况。
通过对键值对设置相应的过期时间来控制每个锁对象的被获取的最大时间,以此实现锁对象的自动释放,实现一个带超时的分布式锁来限制对数据并发访问。
三、实验结果分析
实验基于分布式网络消息中间件实现的消息队列与现有的成熟消息队列中间件产品进行对比,展现本申请性能和稳定性方面的优势。
(一)消息收发性能对比
先进行性能对比试验,设计的消息收发数量是每次收发14万条,每条消息的大小固定分成三个等级,分别为:2KB、5KB和15KB,统计各个消息队列在完成一次14万条消息收发操作所消耗的时间。
性能对比结果:其中Zero MQ作为一个非正规消息队列中间件,并不负责暂存消息,所以没有明确区分其接收、发送消息的时间,其消息收发的时间基本相同。N/A表示消息收发时间过大,或消息队列阻塞导致的无法完成收发任务的情况。对于实验中规定的每一种消息等级,本申请分别进行了三组实验,保证三组实验连续进行,用于展现消息队列的稳定性。实验结果表明,Active MQ在开启后,随着运行时间的增长,其性能会逐渐下降。其它算法总体上比较稳定。
四种消息中间件系统在进行消息收发时随着消息体的增长,消息收发性能的变化情况分析结果:本申请分布式网络消息中间件在消息收发过程中的性能是最好的,而且随着消息体的增长,其收发时间的变化情况变化率也在一个较小的范围内,相对于两个成熟的商业化消息队列中间件,性能有相当程度的提升。Active MQ的收发性能随着消息体的增长会急剧的下降,Rabbit MQ尽管性能最差,但消息收发的速度基本不会随着消息体的变化而产生显著的改变。在稳定性方面,Rabbit MQ表现得更好。综上,本申请分布式网络消息中间件模型在性能上最优,稳定性上又仅次于Rabbit MQ,本申请在用于作为消息队列中间件实现轻量级的快速消息收发时,有着显著的优势,同时也能够保持良好的稳定性。
(二)测定失效判定准确率
除消息的收发性能,收发准确率也是一个重要指标,实验表明,ActiveMQ和RabbitMQ能够保证消息收发的准确率接近98%,但在网络延迟较高的情况下,Zero MQ消息丢失的情况比较严重,本申请消息收发调度中间件模型由于具备确认重传体系,消息丢失率被控制在很小的范围内。
在结点的失效判定实验中,本申请模拟一个包含600个结点的集群,每次都随机设点每个结点的失效情况和结点间的网络状态。分别采用传统的基于法定人数的失效判定算法和本申请提出的算法进行失效判定,总共进行了5组实验,每组都包含3个数字,分别代表了:集群中真实的失效结点数,采用传统算法得出的失效结点数和新算法计算得到的失效结点数,原有算法判定得到的失效结点数量比真实情况多出较多的数量,相对的改进算法得到的结果非常接近真实值。实验结果证明了改进算法的准确度更高,更好得过滤掉了由网络延迟导致的结点失效情况。同时通过分析实验结果,本申请保证算法中找到的失效候选结点对真实失效结点的覆盖率为100%。
四、发明点总结
本申请在对现有技术的消息队列中间件系统和基于内存的非关系型数据库的基础上,结合Redis自身的特征和不足,提出基于Redis实现的高效消息收发调度中间件模型,有效解决了传统消息中间件系统所遇到的效率、可扩展性和易用性低下的问题,同时针对Redis在实现集群部署遇到失效判定、负载均衡和同步访问等一系列问题,提出了优化解决算法。主要包括:
第一,提出基于Redis实现的高效消息收发调度中间件模型,融合PUSH方式和PULL方式优化实现消息传递,改进消息的收发操作,为提高消息中间件的吞吐量,根据消息传输过程中的等待和处理的时间设计实现更优化的调度方法,同时给出延迟消息收发的解决方案,按照高效消息收发调度中间件模型中各个组成部分数据结构的特征进行类型划分,对不同的类型制定相应的持久化策略,提高消息队列的可靠性,完成对消息的备份和恢复;
第二,针对在分布式部署时可能出现的结点失效问题,需要自动判定失效结点,进行相应的故障转移操作,为解决传统的基于法定人数的结点失效算法中存在的问题,本申请提出全新的基于主观结论的结点失效判定算法,大幅提升失效结点判定的准确率,减少整体的故障转移的次数;
第三,提出基于多叉树的一致性哈希算法,在现有技术的一致性哈希算法中,如果出现新结点的添加或删除操作,原有结点的负载均衡情况就必定被打破,无法保证各个结点的平均承担负载,本申请的基于多叉树维护的结点探测序列有效解决了该问题。本申请实现轻量级的快速消息收发时,有着显著的优势,是一种更为高效、轻量化、易用的分布式网络消息队列中间件。
Claims (10)
1.高效轻量易用的分布式网络消息中间件,其特征在于,包括高效消息收发调度中间件模型和分布式网络消息队列并发控制方法,设计融合PUSH和PULL方式的消息快速收发和多优先级分发引擎、消息队列持久化优化策略、定时备份和容错处理机制,提出基于主观结论的结点失效判定算法,改进多叉树对一致性哈希算法实施进一步优化,克服传统方法结点负载不均匀问题,并改进原有基于单结点的分布式锁,提高分布式锁在集群中的安全性;
高效消息收发调度中间件模型基于Redis构建三个方面的内容特征,分别为:消息收发、优先级分发和持久化,具体包括:
第1步,对消息收发进行统一管理,首先定义消息的结构,然后基于Redis设计PUSH-PULL模型的消息收发体系,并采用Redis的SET数据结构设计消息接收确认机制;
第2步,提出一种静态优先级调度方法与一种动态优先级调度方法来满足不同的应用场景,在原有的实时消息队列的基础上,改进存储数据结构,构建具备延迟的队列模型;
第3步,优化Redis的数据持久化能力,通过存储设计和定时备份使得在故障发生后消息丢失的损失尽量降到最低,提高消息队列的整体可用性;
第4步,改进Redis在实现层面的部分细节,结合自身特征对消息收发调度中间件模型进行深度优化;
分布式网络消息队列并发控制方法包括:一是针对消息队列系统在分布式环境中的结点失效问题,结合Redis提供的哨兵机制给出的主观结论,基于观点一致性理论改进原有的基于法定人数的结点失效判定算法,减少不必要的故障转移次数,提高集群整体的稳定性;二是采用虚拟结点改进一致性哈希算法,对于不论是传统算法还是改进后的算法都存在的负载均匀问题,基于多叉树实现一种绝对均衡的划分算法;三是对集群中可能出现的同步互斥问题,设计基于分布式的Redis加锁算法,限制数据的访问,保证数据的安全性和有效性。
2.根据权利要求1所述的高效轻量易用的分布式网络消息中间件,其特征在于,本申请综合两者的优点提出一种全新的PUSH-PULL消息推送模型,首先同时采用PUSH方式和PULL方式来实现一次探测性消息的收发操作,根据服务器端和客户端在收发消息的时间点因子来计算消息模型的推送变化率TsC,计算式为:
首先由服务器端发送一条PUSH探测消息,记录发送的时间X(t),客户端在收到消息之后记录接收时间X’(t),在发送完成PUSH消息一定时间延迟后,在服务器端采用PULL方式生成一条探测消息,存入队列中,记录时间S(t),当客户端收到PULL消息时就记录对应的时间点S’(t),在PUSH-PULL模型中消息传输方式融合PUSH方式和PULL方式,在服务器端和客户端同时调用PUSH-PULL*PUSH算法和PUSH-PULL*PULL算法;
在消息队列开启之后,记录每次PUSH操作和PULL操作的传输时间,定期更新计算相应的传输时延,根据计算得到的传输时延,结合变化率因子来动态决定每次消息传输所采用的传输方式,当前传输时延表示为Delay,其计算式为:
其中,Yci表示的是在第i次传输成功后计算得到的时延,Ri表示在第i次传输过程中所花费的时间。
3.根据权利要求1所述的高效轻量易用的分布式网络消息中间件,其特征在于,基于令牌环的接收确认设计:采用Sets容器来控制各个接收端的确认情况,用SETQr-L表示对名为L的消息队列的确认,假设存在M个接收端,第i个接收端记录用Ti表示,对名为L的消息队列中的广播消息收发情况确认包含了以下步骤:
步骤一:发送端产生一条新的消息,为当前消息生成一个全局唯一的编号NID,并采用LPUSH指令将其存入消息队列LISTL中;
步骤二:保存形式为{<NID,[<T1,0>,...,<Tm,0>]}的数据到SETQr-L中,其中0表示接收方还未确认;
步骤三:当编号为Ti的接收端发现列表数据不为空时,将消息取出,并更新SETQr-L中的值,将键为Ti的值更新为1,表示已经接收到消息;
步骤四:每次对Sets中的值完成更新,都会检测当前消息的所有接收标识,如果存在值为0的标识,需要将消息重新存入队列中,等待另一个接收端发现并取出;否则表明本次消息发送已全部完成,清除SETQr-L中键值为NID的记录,表示已完成所有消息的发送任务;
在PUSH-PULL消息收发模型实现中,本申请采用一个Lists作为消息队列暂存消息,设计确认机制来保证消息接收的确认,设置一个Lists来保存消息的订阅情况,每次执行步骤二时都会从这个订阅情况集合中读取当前需要发送的目标接收端编号,用LISTJl-L表示所有订阅消息队列L的接收端记录情况,其数据结构形如[T1,T2,…,Ti,…,Tm],其中Ti表示第i个订阅队列中消息的接收端记录;
消息接收过程中,保证在某一时刻只有一个接收端T,在其完成接收确认后再允许其它接收端进行确认,对于接收端Ti(1≤i≤m),本申请保证其上运行一个监控进程,将所有的接收端进行编号后组成环形结构,环上有m个结点表示有m个接收端,环内部存在且仅存在一个令牌标识,且保证令牌时刻在接收端进程之间相互传递。
4.根据权利要求1所述的高效轻量易用的分布式网络消息中间件,其特征在于,构建多优先级消息队列:采用Redis的一组命令BLPOP/BRPOP,同时操作多个LIST,在一组LIST中找到第一个存在数据项的LIST,并弹出该队列中的最左/右的元素并返回,多优先级的队列对应的是多个LIST,实现一个多优先级的消息队列,在保证效率的同时最大化简化设计;
设定三个优先级:上级、中级、下级,其中上级优先级队列中的任务必须优先被执行,只有当上级优先级队列中没有任务时,中级优先级队列中的任务才能被执行,下级优先级队列只有在前两个队列中都不存在任务时才会被采用,分别将三个队列命名为up、centre和down,在静态优先级情况下,本申请消息队列转变为(LISTup,LISTcentre,LISTdown)的形式。
5.根据权利要求1所述的高效轻量易用的分布式网络消息中间件,其特征在于,基于最先截止期的优先级调度方法:同时设计一种动态的消息分发调度方法,解决低优先级的消息可能出现的饿死问题;
每条消息的处理时间不完全相同,但同类型的消息的处理时间处于一个范围区间内,将消息进行分类,记录统计每种类型消息的处理时间,计算平均值将其作为当前消息处理时间的参考,实时得到每条新入队消息的到达时间和消息处理时间,以此计算出消息的优先级,在消息队列中,一次消息收发的操作过程中包括了以下属性:
属性一,消息的产生时间R:消息队列一条消息从服务器端被发送的时间点;
属性二,消息的等待时间A:消息从R时刻到最终到达一个客户端所经历的时间;
属性三,消息的处理时间X:消息从被客户端接收到最终处理完成消耗的时间;
采用一个Hashes记录不同类型消息的处理时间,HashinT格式为:(<typeID,{time,count}>),typeID是消息类型,根据消息的不同用途划分,time为当前类型消息执行的总时间消耗,count为该类型消息被执行的总次数,计算得到的类型为typeID的消息处理时间inTT公式为:
在消息队列刚启动时,每个类型的消息的被执行的次数和时间都为0,消息处理时间不通过公式得到,而是采用一个默认值,每次当一个消息被处理完成,需要更新HashinT中的记录,增加执行次数和总执行时间,用一个Hashes来记录当前的消息队列内部的消息时间信息,记为Hashtime,每当有一条新的消息被加入时,更新Hashtime中的数据,重新计算得到优先级最高的消息,Hashtime的结构为:<NID,{reach,inT}>,其中NID为消息编号,reach表示为消息的到达时间,inT是消息的处理时间,消息分发的优先级划分根据消息的截止时间A,消息的截止时间越近,消息的优先级就越高,消息的截止时间越远,优先级越低,消息编号为NID的截止时间的计算式为:
ANID=Hashtime[NID].inT+Hashtime[NID].reach 式4
为充分利用已知条件使得系统整体吞吐量达到最优,综合考虑R、X和A的值,动态计算每条消息在队列中的优先级,其计算公式定义为:
YxNID为消息在队列中的优先级,YcNID为传输时延。
6.根据权利要求1所述的高效轻量易用的分布式网络消息中间件,其特征在于,构建具备延迟的队列模型:另一种数据结构记录额外的延迟时间,并找到最近的延迟请求进行分发,对于一个名为L带延迟的消息队列,本申请用YYsL来表示,YYsL中的成员唯一,但score可重复,基于有序集结构特征,本申请设计一种延迟队列的实现方法,具体包括:
第一,有序集根据记录的score自动排序,将延迟消息需要被执行的时间戳作为YYsL的score值,而消息体作为成员储存到一个YYsL的项中,解决延迟消息存储问题;
第二,消息的分发需要一个工作进程进行轮询,每隔100毫秒进行一次判断,取出YYsL中当前score最小的项,与当前时间戳进行比较,如果小于当前时间戳,则将当前项从YYsL中删除,并将消息加入执行队列;
第三,对于带优先级的延迟消息,在将消息加入执行队列时采用RPUSH命令直接将待处理的消息加入到队列的最右端,确保消息处理的响应时间的最小化;
采用YYsL保存延迟消息,采用一个工作进程轮询实现延迟消息的分发,每当到达延迟时间时,工作进程都会将消息从延迟队列中移出添加到实时的执行队列中,所有消息信息不论是否延迟最终都会进入执行队列,再根据其优先级进行分发,确保消息数据的一致性和可控性。
7.根据权利要求1所述的高效轻量易用的分布式网络消息中间件,其特征在于,基于主观结论的结点失效鉴别:采用以下定义来描述一个包含m个结点的集群:
定义1,结点主观结论:集群中每个结点内部都存在一个哨兵,用于监控其它结点的状态,状态结论的集合可以用一个m位的数字来表示,则对于集群中第i个结点的哨兵,其主观结论ODi表示为式6:
ODi=[g1,g2,…,gi,…,gm] 式6
其中,gi是当前哨兵对于第i个结点失效状态的结论,0表示为失效状态,1表示为运行正常状态;
定义2,观点一致性:对于集群中的任意两个结点i和j,定义其拥有统一的观点,当且仅当i和j的主观结论满足式7:
ODigj&ODjgi==1 式7
其中,ODigj为第i个结点对第j个结点失效状态的主观判定结论,&符号表示对两个值做位与操作;
定义3,失效支持率:对于持有统一观点的结点集合V,集合内部包含w个结点,定义当前集合对于结点i的失效支持率Vsupt-i计算式为:
如果集群中出现失效现象,按照半数通过的原则找到可能的失效结点集合,本申请进一步利用上述定义筛选得到更为精确的失效结点候选集合;
通过对失效结点的筛选,确保每次都只是在一个有限的范围内对可控数量的结点进行有效的故障转移,在完成一轮故障转移之后,再循环调用候选失效节点获取算法,继续检测集群的状态。
8.根据权利要求1所述的高效轻量易用的分布式网络消息中间件,其特征在于,基于多叉树改进的一致性哈希算法:将原先的一致性哈希算法中环上的真实物理结点都替换成并不真实存在的服务器虚拟结点,多个虚拟结点对应为同一个物理结点,这样即使在集群中服务器较少的情况下,也能保证环上有足够多的结点保证平均的弧度划分;
采用虚拟结点的方式无法保证在物理结点增加时得到一个绝对平均的弧度划分,实现时采用数量级较大的虚拟结点来减小误差,为得到完全平均的划分,本申请提出一种基于线性探测的划分算法来实现物理结点增加时绝对平均的弧度划分,设计一种多叉树结构来得到数据结点储存位置的探测序列,这棵树的根结点包含两个孩子,其后每一层的孩子数量都比其父层的孩子个数多一,从根结点到每条叶子的路径上都有相应的数字标示,结合计算得到的哈希值得到相应的探测序列,采用多叉树的形式进行结点划分包括两部分,一是树构造过程,二是探测序列获取过程,其中,树构造过程只在当前集群中有新结点加入时才进行,会动态增长,构造完成后变化不大;探测序列的获取过程在每次查询时都会进行,其具体的计算过程为:
过程一,对数据Key值采用哈希函数计算得到哈希值,得到结果t=r(Key);
过程二,从多叉树Tree的根结点开始进行查询,取a=2,计算c=t MOD a,其中MOD为取余计算,按照得到的结果c选取匹配对应的路径,同时更新t的值使得t=t/a;
过程三,每向下一层,令a的值加1,重复过程二的过程直到到达树的叶子结点,得到最终的探测序列;
过程四,数据的查询顺序会按照得到的探测序列;
根据探测序列,依次按照顺序去相应的结点中查找结果数据,当需要增加新的物理结点是,只需要在原有的树形结构中动态增加一层叶子结点,得到一个全新的平均划分;当删除结点时,需要将原先树缩减一层即可。
9.根据权利要求1所述的高效轻量易用的分布式网络消息中间件,其特征在于,基于锁体系的并发控制生成:本申请设计一种分布式锁体系实现对数据的同步访问,采用一种中心化的方式组织和管理在分布式环境下各个结点的锁分配情况,采用Redis的SETNX命令,设置一个键值对<key,value>,当且仅当key值不存在时,命令才能成功,在一个实例的全局范围内统一管理所有被请求的锁对象,对请求加锁的对象采用一套统一的命名规范,随机生成一个序列串作为解锁的密钥,一个锁对象在形式上表现为<锁名称,密钥>的键值对,方便的判断某个对象的加锁情况。
10.根据权利要求9所述的高效轻量易用的分布式网络消息中间件,其特征在于,基于单实例的情况,中心化的分布式锁的管理方案为:现假设集群中存在M个主结点,彼此间相互独立,在真正实现锁分配之前需要做一些额外的预处理工作,包括对集群中的结点进行统一编号和对结点进行唯一性分组,除去叶子结点的操作后,更上一层的支配分组中的分配情况取决于当前层中的多数意见,循环判定直到树根,找到最终唯一的一个锁分配方案,客户端才能真正获取到这个分布式锁,每一个支配分组中都有一个数字编号,表示的意义是当前支配分组的决策结果所存储在的集群中的哪个结点,该值动态计算,一旦集群中出现失效的结点,值就顺延,当值操作当前集群结点数时表示这个支配分组下的所有集群都已失效,此时默认其总是服从同层的其它支配的决策情况;
通过对键值对设置相应的过期时间来控制每个锁对象的被获取的最大时间,以此实现锁对象的自动释放,实现一个带超时的分布式锁来限制对数据并发访问。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202111124609.6A CN113722127A (zh) | 2021-09-24 | 2021-09-24 | 高效轻量易用的分布式网络消息中间件 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202111124609.6A CN113722127A (zh) | 2021-09-24 | 2021-09-24 | 高效轻量易用的分布式网络消息中间件 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN113722127A true CN113722127A (zh) | 2021-11-30 |
Family
ID=78684829
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202111124609.6A Withdrawn CN113722127A (zh) | 2021-09-24 | 2021-09-24 | 高效轻量易用的分布式网络消息中间件 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN113722127A (zh) |
Cited By (7)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN114579669A (zh) * | 2022-05-06 | 2022-06-03 | 天津南大通用数据技术股份有限公司 | 基于探测消息传递的分布式数据库事务死锁检测解锁方法 |
CN115146217A (zh) * | 2022-09-01 | 2022-10-04 | 国网信息通信产业集团有限公司 | 一种解决综合能源系统数据循环计算的方法、系统及设备 |
CN115238005A (zh) * | 2022-07-25 | 2022-10-25 | 中电金信软件有限公司 | 一种基于消息中间件集群的数据同步方法及系统 |
CN115269725A (zh) * | 2022-07-25 | 2022-11-01 | 中电金信软件有限公司 | 一种基于消息中间件集群的数据同步方法及系统 |
CN115396387A (zh) * | 2022-08-30 | 2022-11-25 | 上海航天电子通讯设备研究所 | 基于VxWorks消息队列的数据记录方法、装置、设备及存储介质 |
CN117114559A (zh) * | 2023-10-24 | 2023-11-24 | 广州一链通互联网科技有限公司 | 内贸集装航线动态规划中的天气因素优化算法 |
CN117956014A (zh) * | 2024-03-27 | 2024-04-30 | 四川省建筑设计研究院有限公司 | 一种提高物联网设备控制与反馈实时性的方法及系统 |
-
2021
- 2021-09-24 CN CN202111124609.6A patent/CN113722127A/zh not_active Withdrawn
Cited By (13)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN114579669B (zh) * | 2022-05-06 | 2022-08-30 | 天津南大通用数据技术股份有限公司 | 基于探测消息传递的分布式数据库事务死锁检测解锁方法 |
CN114579669A (zh) * | 2022-05-06 | 2022-06-03 | 天津南大通用数据技术股份有限公司 | 基于探测消息传递的分布式数据库事务死锁检测解锁方法 |
CN115269725B (zh) * | 2022-07-25 | 2023-07-28 | 中电金信软件有限公司 | 一种基于消息中间件集群的数据同步方法及系统 |
CN115238005A (zh) * | 2022-07-25 | 2022-10-25 | 中电金信软件有限公司 | 一种基于消息中间件集群的数据同步方法及系统 |
CN115269725A (zh) * | 2022-07-25 | 2022-11-01 | 中电金信软件有限公司 | 一种基于消息中间件集群的数据同步方法及系统 |
CN115238005B (zh) * | 2022-07-25 | 2023-04-28 | 中电金信软件有限公司 | 一种基于消息中间件集群的数据同步方法及系统 |
CN115396387B (zh) * | 2022-08-30 | 2024-04-12 | 上海航天电子通讯设备研究所 | 基于VxWorks消息队列的数据记录方法、装置、设备及存储介质 |
CN115396387A (zh) * | 2022-08-30 | 2022-11-25 | 上海航天电子通讯设备研究所 | 基于VxWorks消息队列的数据记录方法、装置、设备及存储介质 |
CN115146217B (zh) * | 2022-09-01 | 2022-12-13 | 国网信息通信产业集团有限公司 | 一种解决综合能源系统数据循环计算的方法、系统及设备 |
CN115146217A (zh) * | 2022-09-01 | 2022-10-04 | 国网信息通信产业集团有限公司 | 一种解决综合能源系统数据循环计算的方法、系统及设备 |
CN117114559A (zh) * | 2023-10-24 | 2023-11-24 | 广州一链通互联网科技有限公司 | 内贸集装航线动态规划中的天气因素优化算法 |
CN117114559B (zh) * | 2023-10-24 | 2024-01-23 | 广州一链通互联网科技有限公司 | 内贸集装航线动态规划中的天气因素优化算法 |
CN117956014A (zh) * | 2024-03-27 | 2024-04-30 | 四川省建筑设计研究院有限公司 | 一种提高物联网设备控制与反馈实时性的方法及系统 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN113722127A (zh) | 高效轻量易用的分布式网络消息中间件 | |
CN109977171B (zh) | 一种保证事务一致性和线性一致性的分布式系统和方法 | |
US8161244B2 (en) | Multiple cache directories | |
CN105959151B (zh) | 一种高可用的流式处理系统及方法 | |
US8224860B2 (en) | Database management system | |
CN102244685B (zh) | 一种支持负载均衡的分布式缓存动态伸缩方法及系统 | |
US7457835B2 (en) | Movement of data in a distributed database system to a storage location closest to a center of activity for the data | |
Van Renesse et al. | Willow: DHT, aggregation, and publish/subscribe in one protocol | |
US5819083A (en) | Minimal sufficient buffer space for data redistribution in a parallel database system | |
US20100138540A1 (en) | Method of managing organization of a computer system, computer system, and program for managing organization | |
US20080052322A1 (en) | Conflict resolution in database replication through autonomous node qualified folding | |
US8775622B2 (en) | Computer-based cluster management system and method | |
CN106484713A (zh) | 一种基于面向服务的分布式请求处理系统 | |
EP3019974B1 (en) | Control of a distributed data grid layer in a federated database system | |
CN116777182B (zh) | 半导体晶圆制造执行任务派工方法 | |
CN109639773A (zh) | 一种动态构建的分布式数据集群控制系统及其方法 | |
Choi et al. | Dynamic hybrid replication effectively combining tree and grid topology | |
JPH0887473A (ja) | データ処理装置 | |
CN107180034A (zh) | MySQL数据库的集群系统 | |
US11061719B2 (en) | High availability cluster management of computing nodes | |
CN106657333B (zh) | 一种基于云服务模式的集中式目录数据交换系统及方法 | |
CN110597809B (zh) | 一种支持树状数据结构的一致性算法系统及其实现方法 | |
CN113518126A (zh) | 一种面向联盟链的交叉容错方法 | |
CN108958967A (zh) | 一种数据处理的方法以及服务器 | |
CN116468124B (zh) | 一种量子任务的调度方法及相关装置 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
WW01 | Invention patent application withdrawn after publication | ||
WW01 | Invention patent application withdrawn after publication |
Application publication date: 20211130 |