Beanstalkd 是一个轻量级高性能的分布式内存队列系统,主要的作用是想通过后台异步执行一些耗时的任务,以解决 Web 应用系统的页面访问延迟和降低系统间各个模块的强耦合关联问题。
Beanstalkd 的安装
git clone https://github.com/kr/beanstalkd.git
cd beanstalkd && make && make install
/usr/bin/beanstalkd -l 0.0.0.0 -p 11300 -b /var/lib/beanstalkd/binlog -F &
#-b 参数开启 binlog 模式方便意外情况消息队列数据的恢复
/etc/sysconfig/beanstalkd # beanstalk 的配置文件位置
/usr/bin/beanstalkd -h
Use: /usr/bin/beanstalkd [OPTIONS]
Options:
-b 开启 binlog,重启会自动恢复任务。
-f MS fsync 最多每 MS 毫秒
-F 从不 fsync(默认)
-l ADDR 侦听地址(默认为 0.0.0.0)
-p 端口侦听端口(默认为 11300)
-u USER 成为用户和组
-z BYTES 设置最大作业大小(以字节为单位)(默认值为 65535)
-s BYTES 设置每个 wal 文件的大小(默认为 10485760) (将被舍入到 512 字节的倍数)
-c 压缩 binlog(默认)
- n 不要压缩 binlog
-v 显示版本信息
-V 增加冗长度
-h 显示这个帮助
Beanstalkd 的一些核心概念
job:一个需要异步处理的任务,是 Beanstalkd 中的基本单元,需要放在一个 tube 中。
tube:一个有名的任务队列,用来存储统一类型的 job,是 producer 和 consumer 操作的对象。
producer:Job 的生产者,通过 put 命令来将一个 job 放到一个 tube 中。
consumer:Job 的消费者,通过 reserve/release/bury/delete 命令来获取 job 或改变 job 的状态。
job 的生命周期介绍
当生产者直接 put 一个 job 时,job 就处于 READY 状态,等待消费者来处理,如果选择延迟 put,job 就先到 DELAYED 状态,等待时间过后才迁移到 READY 状态。consumer 获取了当前 READY 的 job 后,该 job 的状态就迁移到 RESERVED,这样其他的 consumer 就不能再操作该 job。当 consumer 完成该 job 后,可以选择 delete,release 或者 · 操作;delete 之后,job 从系统消亡,之后不能再获取;release 操作可以重新把该 job 状态迁移回 READY(也可以延迟该状态迁移操作),使其他的消费者可以继续获取和执行该 job;bury 操作,可以把该 job 休眠,等到需要的时候,再将休眠的 job kick 回 READY 状态,也可以 delete BURIED 状态的 job。正是有这些有趣的操作和状态,才可以基于此做出很多意思的应用,比如要实现一个循环队列,就可以将 RESERVED 状态的 job 休眠掉,等没有 READY 状态的 job 时再将 BURIED 状态的 job 一次性 kick 回 READY 状态。
READY - 需要立即处理的任务,当延时 (DELAYED) 任务到期后会自动成为当前任务;
DELAYED - 延迟执行的任务, 当消费者处理任务后, 可以用将消息再次放回 DELAYED 队列延迟执行;
RESERVED - 已经被消费者获取, 正在执行的任务。Beanstalkd 负责检查任务是否在 TTR(time-to-run) 内完成;
BURIED - 保留的任务: 任务不会被执行,也不会消失,除非有人把它 "踢" 回队列;
DELETED - 消息被彻底删除。Beanstalkd 不再维持这些消息。
beanstalkd 的一些特性
优先级
任务 (job) 可以有 0~2^32 个优先级, 0 代表最高优先级,默认优先级为 1024。
持久化
可以通过 binlog 将 job 及其状态记录到文件里面,在 Beanstalkd 下次启动时可以通过读取 binlog 来恢复之前的 job 及状态。
分布式容错
分布式设计和 Memcached 类似,beanstalkd 各个 server 之间并不知道彼此的存在,都是通过 client 来实现分布式以及根据 tube 名称去特定 server 获取 job。
超时控制
为了防止某个消费者长时间占用任务但不能处理的情况,Beanstalkd 为 reserve 操作设置了 timeout 时间,如果该消费者不能在指定时间内完成 job,job 将被迁移回 READY 状态,供其他 consumer 执行。