Transcript Document

高性能队列Fqueue的设计和使用实践
孙立@qunar.com
weibo.com@sunli1223
2011.11
提纲
•
•
•
•
FQueue简介
Fqueue的存储设计
Fqueue的使用实践
Q&A
Fqueue简介
Fqueue(Fast Queue)
提供跟Memcached一样的客户端分布式和高可用机制
单实例多队列功能
每个队列可设置安全认证密码
可动态增加队列或者更改密码
纯JAVA实现,可以内置到JAVA进程内使用
simple,真的simple
开源
http://code.google.com/p/fqueue/
Fqueue有多快
• 进程内
每次写入10字节,909万qps 86MB/s
每次写入1024字节,19万qps 185MB/s
• 跨服务器
多个client每次写入10字节,32万qps
Fqueue使用有多简单
• 下载->解压->启动
• 直接使用
无需繁杂的参数优化,你总是能获得高性能的Queue队列服务器
Fqueue的存储设计
Fqueue的整体设计结构
架构在Memcached协议之上
Producer
add
get
FSQueue持久化
队列存储
Memcached
接口
Comsumer
FSQueue持久化
队列存储
FSQueue持久化
队列存储
Fqueue协议实现
管理、监控
Fqueue的存储结构设计
初始想法
1
2
3
18
3
4
5
6
7
8
9
存储出队和入队的位置
问题:出队数据不好删除
单文件顺序
存储数据
Fqueue的存储结构设计
最终的结构
1 2 3 4 5 6 7 8
File1
1 2 3 4 5 6 7 8
File2
1 2 3 4 5 6 7 8
File3
Read
offset
Write
offset
Read
FileNo
1.
2.
3.
4.
Write
FileNo
数据顺序写
数据顺序读
IndexFile记录读写位置和文件编号
Index File标记删除,不删除物理数据
FileNo全部消费后,再删除FileNo文件。
Index File
选择读写实现方式-内存映射
JAVA的读写文件方式有很多,性能、特点都不一样,所以需要选择一个合适的。
测试方式:循环顺序写入10字节数据1000万次
写方式
结果耗时(ms)
备注
BufferedOutputStream
414
速度最快(与设置的cache大小
有关),数据cache在JVM内。
RandomAccessFile
29499
速度最慢,数据直接刷盘。
FileChannel
1868
速度比较快。OS级别cache
MappedByteBuffer
1456
速度快。OS级别内存映射
BufferedOutputStream虽然最快,但是易丢失数据,权衡之下,我们选择
了MappedByteBuffer作为我们的文件操作实现
Fqueue一些优化
1. FileNo文件全部消费后,交给后台线程异步删除
2. 在新创建一个FileNo时,会让后台线程预创建
下一编号的存储文件
3. 每10ms让OS强制刷盘
4. 每个Queue的读写都有自己的Queue级别writeLock
1、2在FileRunner.java中实现
Fqueue的使用实践
队列服务器的常见使用场景-缓解数据库写压力
• 直接写数据库
app
直接Insert into
应用的性能直接依赖于数
据库的响应时间和性能
数据库
队列服务器的常见使用场景-缓解数据库写压力
• 用队列服务器应付高峰写入
queue
处理job
批量insert
用户
数据库
queue
高速队列,降低了应用
写库的时间,能提高系
统的写入吞吐量,应付
高峰值
合并写。(批量插入可提升性能)
队列服务器的常见使用场景-缓解数据库写压力
• 用队列服务器应付高峰写入
queue
处理job
用户
queue
数据库宕机,队列部分宕机
不影响应用的正常服务
数据库
队列服务器的常见使用场景-缓解数据库写压力
• 用了队列服务器,如何实现实时性?
queue
处理job
用户
queue
数据库
复制
实时缓冲区
数据库
用户
merge
队列服务器的常见使用场景-任务处理
• 比如发送邮件
[email protected] maila
[email protected] maila
[email protected]
maila mailb
[email protected]
[email protected] mailb
Queue.get()
发送进程
Queue.get()
发送进程
Queue.get()
发送进程
[email protected] mailb
……
[email protected] maila
[email protected] maila
Queue.get()
发送进程
Queue.get()
发送进程
Queue.get()
发送进程
[email protected] mailb
[email protected] mailb
[email protected] mailb
[email protected]
maila
分组发送
队列服务器的常见使用场景-任务处理
• 自描述任务
//存储逻辑到队列
memcachedClient.add("job_pass", 0, "#!/bin/sh\r\nsome code");
memcachedClient.add("job_pass", 0, "<?php sone code?>");
//执行代码
String code = memcachedClient.get("job_pass");
String result=RunJob.runCode(code);
队列服务器的常见使用场景-数据收集
• 日志收集
统计系统
app
queue
日志监控报警系统
app
app
低延迟,速度稳定
queue
系统性能分析系统
延迟比较高,速度不稳定,
可能跨机房
日处理1亿日志的队列服务资源占用截图,高峰期不超过20%
队列服务器的常见使用场景-解耦程序
• 视频网站的用户视频上传流程
视频上传
视频上传
视频上传
转换处理
Queue
转换处理
存储用户上传
的信息,文件
实体分开存储
转换处理
Queue
存储转换
成功的数
据
文件分发
文件分发
文件分发
视频传
db
Queue
成功的后续处
理
转换成功
用队列异步解耦程序,可以更好的进行扩展,这与actor模型类似。
存储分发
成功的数
据
Fqueue的使用
PHP使用
Java使用
(Xmemcached)
Fqueue的使用-分布式与key的设计
Fqueue1
Fqueue2
Fqueue3
•
•
•
client
Hash(key_pass)始终 只会hash到一台。(HA)
Hash(key_pass_固定字符串),固定hash到3三
台,可用于负载均衡。
Hash(Key_pass_变化字符串),随机hash到三台,
可用于负载均衡。
Fqueue实践-Qunar.com的火车票余票抓取
Memcached
火
车
票
系
统
Fqueue
处理程序
处理程序
余票抓取任务
Fqueue
后台定时任务
处理程序
清除堆积数据
Fqueue实践-监控
Q&A
谢谢
加入我们吧
各种技术人员,简历投递到 [email protected]
微博联系:http://weibo.com/sunli1223