阿里天池中间比赛总结,即消息队列引擎设计
2017-07-03 17:56
405 查看
阿里天池中间比赛总结,即消息队列引擎设计
题目传送门:
https://code.aliyun.com/middlewarerace2017/open-messaging-demo?spm=5176.100068.555.1.76d97540zXrIuM
这次比赛的任务就是:根据阿里的《Open-Messaging规范》实现消息队列引擎该规范也是阿里开源消息队列racketMq的接口规范。要求,多线程写入,把消息竟可能多的罗盘。杀掉消息生产者后,启动消息消费者,多线程尽可能多地消费消息。然后计算tps.
由于消息body是设定为无限大的,导致一个消息的大小是不固定的,为此我们对消息建立索引块MessageIndex,这个MessageIndex规定了一个消息的边界和位置。一个消息索引的大小是固定的。
topic和queue的功能一样的,唯一的却别是topic是多个消费者线程共享的,而且是而且消息是广播的(每个消费者有且只能消费一次)。抽象了一个队列父类bucket.
为了提高写入速度,充分利用硬盘空间和内存空间采用顺序写入。消息引擎顺序写入硬盘会导致各个队列高度离散(各个队列的数据参差在一起),使得读取数据时候耗费大量CPU资源。为了减低队列的离散程度,队列申请消息存放空间是队列块BucketBlock的形式申请的,一个块的大小可以通过一个全局参数去调优。这样一个队列就是由多个离散的BucketBlock组成,而BucketBlock内的消息都属于同一队列的连续消息,有了BucketBlock同一队列的消息离散程度变得可调节了。
为了硬盘的吞吐量,采用直接内存映射技术。这个技术利用的是虚拟内存技术,充分利用内存大大提高的文件的读写性能。
我们将一个消息顺序的写入一个文件中,直到消息文件的大小超过阀值才另起门户。同时将该消息的索引messageIndex写入该队列最新的bucketBlock中,存放bucketBlock的文件也是顺序写入的,所以存放bucketBlock的文件也是有一个阀值。
我们发现对于上亿的数据量bucketBlock的文件很多,这会给消息引起解析队列长度和bucketBlock的寻址造成很大的负担。由此我们队bucketBlock建立了索引,也就是说一个bucketBlock对应一个所以bucketBlockIndex,那么一个队列由多个bucketBlockIndex组成,一个bucketBlockIndex对象索引一个队列块,一个队列块有多个消息索引messageIndex ,一个消息索引对应一个消息message。
至此,我们设计完了队列的数据结构。
通过调优文件的阀值,和bucketBlock中存放消息索引的个数就可以实现很好的性能调优了。
读取的消息我们采用随机访问机制,通过解析队列中的索引,我们可以轻易的访问到硬盘中的消息。
比赛中还有一个比较有意思的考点:设计高效的序列化算法。由于消息的头部的数据类型只有字符串,Integer,Double,long,所以我们可以最大程度的提高数据的紧凑程度,比如一个Integer默认就是4个Byte,long用8个Byte,这样提高紧凑程度。当然还可以更高效的采用无损压缩算法,对数据进行压缩。
题目传送门:
https://code.aliyun.com/middlewarerace2017/open-messaging-demo?spm=5176.100068.555.1.76d97540zXrIuM
这次比赛的任务就是:根据阿里的《Open-Messaging规范》实现消息队列引擎该规范也是阿里开源消息队列racketMq的接口规范。要求,多线程写入,把消息竟可能多的罗盘。杀掉消息生产者后,启动消息消费者,多线程尽可能多地消费消息。然后计算tps.
由于消息body是设定为无限大的,导致一个消息的大小是不固定的,为此我们对消息建立索引块MessageIndex,这个MessageIndex规定了一个消息的边界和位置。一个消息索引的大小是固定的。
topic和queue的功能一样的,唯一的却别是topic是多个消费者线程共享的,而且是而且消息是广播的(每个消费者有且只能消费一次)。抽象了一个队列父类bucket.
为了提高写入速度,充分利用硬盘空间和内存空间采用顺序写入。消息引擎顺序写入硬盘会导致各个队列高度离散(各个队列的数据参差在一起),使得读取数据时候耗费大量CPU资源。为了减低队列的离散程度,队列申请消息存放空间是队列块BucketBlock的形式申请的,一个块的大小可以通过一个全局参数去调优。这样一个队列就是由多个离散的BucketBlock组成,而BucketBlock内的消息都属于同一队列的连续消息,有了BucketBlock同一队列的消息离散程度变得可调节了。
为了硬盘的吞吐量,采用直接内存映射技术。这个技术利用的是虚拟内存技术,充分利用内存大大提高的文件的读写性能。
我们将一个消息顺序的写入一个文件中,直到消息文件的大小超过阀值才另起门户。同时将该消息的索引messageIndex写入该队列最新的bucketBlock中,存放bucketBlock的文件也是顺序写入的,所以存放bucketBlock的文件也是有一个阀值。
我们发现对于上亿的数据量bucketBlock的文件很多,这会给消息引起解析队列长度和bucketBlock的寻址造成很大的负担。由此我们队bucketBlock建立了索引,也就是说一个bucketBlock对应一个所以bucketBlockIndex,那么一个队列由多个bucketBlockIndex组成,一个bucketBlockIndex对象索引一个队列块,一个队列块有多个消息索引messageIndex ,一个消息索引对应一个消息message。
至此,我们设计完了队列的数据结构。
通过调优文件的阀值,和bucketBlock中存放消息索引的个数就可以实现很好的性能调优了。
读取的消息我们采用随机访问机制,通过解析队列中的索引,我们可以轻易的访问到硬盘中的消息。
比赛中还有一个比较有意思的考点:设计高效的序列化算法。由于消息的头部的数据类型只有字符串,Integer,Double,long,所以我们可以最大程度的提高数据的紧凑程度,比如一个Integer默认就是4个Byte,long用8个Byte,这样提高紧凑程度。当然还可以更高效的采用无损压缩算法,对数据进行压缩。
相关文章推荐
- ActiveMQ学习总结(8)——消息队列设计精要
- ActiveMQ学习总结(8)——消息队列设计精要
- ActiveMQ学习总结(8)——消息队列设计精要
- ActiveMQ学习总结(8)——消息队列设计精要
- ActiveMQ学习总结(8)——消息队列设计精要
- 服务器设计笔记(3)-----消息队列
- Windows消息队列,UI线程,窗口以及消息处理方式总结
- /LGC设计模式/消息队列的设计与实现
- Windows消息队列 UI线程,窗口以及消息处理方式总结
- 消息队列的设计
- 深入浅出Win32多线程设计之MFC的多线程-线程与消息队列(经典)
- 消息队列的设计与实现
- discuz 论坛 消息队列问题的总结!
- 因为一个空格,就注定了结果——第五届山东省ACM程序设计比赛总结
- ENode 1.0 - 消息队列的设计思路
- enode框架step by step之消息队列的设计思路
- [C++]合理的设计和使用消息队列
- 深入浅出Win32多线程设计之MFC的多线程-线程与消息队列(经典)
- 关于消息队列这种设计模式的利弊
- Linux 进程间通讯(IPC)详细总结 4消息队列。