分布式队列

来源:互联网 发布:淘宝嘉年华到什么时候 编辑:程序博客网 时间:2024/06/05 06:05

转载请注明出处:http://jameswxx.iteye.com/blog/2034111

  

本来只是想看下metaq的文档,结果发现好乱,现在metaq其实有两个大分支了,一个是庄晓丹维护的已开源的,另外一个是淘宝内部的,本质结构原理没太大区别,只不过开源的已经去掉了对淘系相关的依赖。然后淘系的metaq已经到3.*版本了,但是文档比较乱,深入到细节时,发现好乱,一个点有好几种说法,火大,干脆自己看metaq的源码,有点意思,做个笔记记录下,怕我以后忘记了。有少量的章节和图片从内网拿来的,大部分是自己写的,记录下几个主要的点。

 

一:metaq是什么

metaq是一个分布式消息中间件,消息中间件是典型的生产者-消费者模型,核心作用是解耦,生产者和消费者彼此没有直接依赖,同步化解成了异步。metaq并没有遵循jms规范,jms规范体现在系统层面和api层面。

 

消费模型

例如jms定义了两种消息传递方式:

 1 基于队列的点对点消费模型

 2 基于发布/订阅的消费模型

 Metaq只有发布订阅的消费方式。

消息类型

JMS定义的消息类型有TextMessage、MapMessage、BytesMessage、StreamMessage、ObjectMessage。Metaq只有一种类型:Message。

消息持久性

JMS定义两种持久性类型:

 PERSISTENT   指示JMS provider持久保存消息,以保证消息不会因为JMS provider的失败而丢失。 
NON_PERSISTENT 不要求JMS provider持久保存消息。

 Metaq的消息都是持久性的

API

JMS定义了消息中间件的生产端api和消费端api,这些api都是约定的接口,都都被metaq无视了。

 

二:一些概念

消息生产者
负责产生消息并发送消息到meta服务器
消息消费者
负责消息的消费,meta采用pull模型,由消费者主动从meta服务器拉取数据并解析成消息并消费
Topic
消息的主题,由用户定义并在服务端配置。producer发送消息到某个topic下,consumer从某个topic下消费消息
分区
同一个topic下面还分为多个分区,如meta-test这个topic我们可以分为10个分区,分别有两台服务器提供,那么可能每台服务器提供5个分 区,假设服务器分别为0和1,则所有分区为0-0、0-1、0-2、0-3、0-4、1-0、1-1、1-2、1-3、1-4
Message
消息,负载用户数据并在生产者、服务端和消费者之间传输
Broker
就是meta的服务端或者说服务器,在消息中间件中也通常称为broker。
消费者分组(Group)
消费者可以是多个消费者共同消费一个topic下的消息,每个消费者消费部分消息。这些消费者就组成一个分组,拥有同一个分组名称,通常也称为消费者集群
Offset
消息在broker上的每个分区都是组织成一个文件列表,消费者拉取数据需要知道数据在文件中的偏移量,这个偏移量就是所谓offset。Offset是绝对偏移量,服务器会将offset转化为具体文件的相对偏移量

 

 

 

三:总体结构图

 

 

 

 

 

四:消息存储

       消息中间件中消息堆积是很常见,这要求broker具有消息存储的能力,消息存储结构决定了消息的读写性能,对整体性能有很大影响,metaq是分布式的,多个borker可以为一个topic提供服务,一个topic下的消息分散存储在多个broker,它们是多对多关系。

如下图



为什么要用分布式的消息队列:

1. 消息的堆积需要分布存储在内存或者硬盘

2. 异步解耦:

举个例子:http://simple-is-better.com/news/466

 比如SNS网站的“新鲜事儿”系统,我发帖之后,会给所有关注我的人推送一条通知。乍一看没什么难的,发帖之后找出关注我的人, 然后生成相应的消息记录就行了。但问题是,100个人关注我,就要执行100条INSERT查询,更要命的是,Web服务器是同步的, 这100条查询执行完成之前,用户是看不到结果的。

怎么办呢,这时就轮到消息队列上场了。发帖之后只需给队列发送一条消息, 告诉队列“我发帖子了”,然后把发帖的结果返回给用户。 这时另一个叫做worker的进程会取出这条消息并执行那100条INSERT查询。这样,推送通知的操作在后台异步执行, 用户就能立即看到发帖结果。更精彩的是,可以运行多个worker实现分布式,多繁重的任务都不在话下了。



0 0
原创粉丝点击