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