消息队列

 应用场景

有很多业务, 客户端和内网都要进行数据传输和交换, 现有架构中, 客户端不能直接访问内网, 

那么客户端只能: 先把数据保存到外网服务器, 然后内网服务器再拉回来处理. 这种方式可以保证数据

都能被处理, 但实效性不够.

 

通常, 外网服务器只起到一个暂时保存数据的作用, 保存客户端报上来的数据, 然后等待内网来拉走,

把客户端看做producer, 内网看做consumer, 这正是消息队列的用武之地.

客户端先把数据写入外网服务器的消息队列, 然后内网服务器再从消息队列取走数据, 消息队列须满足:

(1) 支持高并发的入队和出队操作, 允许很多客户端同时插入数据, 而且允许内网服务器高频率地取走

      数据

(2) 支持数据的持久化, 为保证速度, 消息队列缓存在内存中, 如果内存不够用了, 则写入磁盘.

(3) 支持一次性插入多条记录, 以及一次性取走多条数据, 这样可以提高传输效率

 

二 技术选型

1 存储方案: Tokyo Cabinet

Tokyo Cabinet数据库是日本最大的社交网站mixi开发的一款Key-Value数据库,之所以选择Tokyo Cabinet,

而不是MySQL, Redis或者Memcached, 这是因为:

 

(1) Tokyo Cabinet的读写速度非常快, 比MySQL快很多, 和Memcached差不多, 比Redis当然慢一截,

      有测试数据为证:

写入100万条:tcbtest write test.tcb 1000000

时间: 0.994秒 速度:100,6036条/秒

写入200万条:tcbtest write test.tcb 2000000

时间: 2.028秒 速度: 98,6193条/秒

写入500万条:tcbtest write test.tcb 5000000

时间: 5.276秒 速度: 94,7687条/

 

(2) Tokyo Cabinet占用内存不大, 而且支持数据的持久化, 用户可以设定内存缓存的大小, 缓存不够用

     的时候, 就把数据持久化到磁盘

 

2 网络接口: Libevent

Tokyo Cabinet只是一个数据存储层面的东西, 它没有提供网络接口, 所以得写一个http服务器为用户

提供服务.对于高并发的服务器来说, 基于事件驱动的libevent网络库是非常好的选择. 事实上, libevent

自带了一个简单高效的http服务器实现, 对于消息队列服务器来说足够使用了. 代码不足400行.

 

 

三 如何使用

用户使用http的get请求来操作消息队列. 参数如下

o: 操作参数, 取值为{get|set|status}, set表示入队,get表示出队, status查看队列的状态

m: 消息数据.

p: 密码参数或者校验参数

n: 一次入队n条消息, 或者出队n条消息

 

1 入队

http://localhost:3333/dsr?o=set&d=foobar|hello|world

把foobar, hello, world三条消息插入队列,消息之间用"|"号隔开,若成功入队, 服务端返回0#0

 

 

2 出队

http://localhost:3333/dsr?o=get&n=10

从队列中取出10条消息, 每条消息以换行符隔开.

 

 

3 状态

http://localhost:3333/dsr?o=status

查看队列的状态,显示队列的容量, 当前消息数量, 队列头指针, 队列尾指针:

 

 

四 压力测试

测试环境 : 8核CPU

1 入队操作

1000并发量, 插入10万条消息, 每条消息512字节

* 使用keep-alive

测试结果:21246 qps, 占用磁盘空间: 51M

* 不使用keep-alive

测试结果:12768 qps, 占用磁盘空间: 51M

 

2 出队操作

1000并发量, 每次取走一条消息, 取10万次

* 使用keep-alive

测试结果: 27709 qps

* 不使用keep-alive

测试结果: 11461 qps

 

从测试结果来看, 消息队列的读写性能都非常不错, 应该能够满足很多应用的需求

posted @ 2015-11-23 21:47  if_only  阅读(309)  评论(0编辑  收藏  举报
回到顶部