beanstalkds文档

Beanstalkd学习

1、beanstalkd介绍

Beanstalkd,一个高性能、轻量级的分布式内存队列系统,最初设计的目的是想通过后台异步执行耗时的任务来降低高容量Web应用系统的页面访问延迟,支持过有9.5 million用户的Facebook Causes应用。后来开源,现在有PostRank大规模部署和使用,每天处理百万级任务。Beanstalkd是典型的类Memcached设计,协议和使用方式都是同样的风格,所以使用过memcached的用户会觉得Beanstalkd似曾相识。

beanstalkd 是一个高性能、轻量级分布式的内存队列

2、安装

安装和启动:
yum -y install beanstalkd
配置文件默认在 /etc/sysconfig/beanstalkd
nohup /usr/local/bin/beanstalkd -l 0.0.0.0 -b /mnt/beanstalkd &

3、特点

拉模式:消费者需要主动从服务器拉取消息数据;
tube:类似于消息主题 topic,一个 beanstalkd 中可以支持多个 tube,每个 tube 都有自己的 producer 和 consumer;多个生产者可以往同一个 tube 生产 job,多个消费者也能监听同一个 tube 获取 job;
job:代替了传统的 message,与消息最大的区别是,job 有多种状态;
conn:代表一个客户端链接;
优先级:job 可以有 0~2^32 个优先级,0 代表最高优先级,beanstalkd 使用堆处理 job 的优先级排序,因此 reserve 命令的时间复杂度是 O(logN);
延时:生产者发布任务时可以指定延时,到达延迟时间后,job 才能被消费者消费;
超时机制:消费者从 beanstalkd 获取一个 job 后,必须在预设的 TTR (time-to-run) 时间内处理完任务,并发送 delete / release/ bury 命令改变任务状态;否则 Beanstalkd 会认为消息消费失败,重置 job 状态,使其可以被其他消费者消费。如果消费者预计在 TTR (time-to-run) 时间内无法完成任务, 也可以发送 touch 命令, 它的作用是让 Beanstalkd 从重新计时 TTR;
暂停:pause 命令可以暂停当前 tube,暂停时期内所有 job 都不能够被消费者消费;

----------------------------

4、状态

READY:需要立即处理的任务,当延时 (DELAYED) 任务到期后会自动成为当前任务;
DELAYED:延迟执行的任务,;
RESERVED:已经被消费者获取, 正在执行的任务,Beanstalkd 负责检查任务是否在 TTR(time-to-run) 内完成;
BURIED:保留的任务: 任务不会被执行,也不会消失,除非有人将他修改为其他状态;
DELETED:消息被彻底删除。Beanstalkd 不再维持这些消息;

5、常用方法

<?php
require "vendor/autoload.php";
use Pheanstalk\Pheanstalk;
$ph = new Pheanstalk('127.0.0.1',11301);

//----------------------------------------维护类----------------------------------
//1.查看目前pheanStalkd状态信息
//print_r($ph->stats()); 

//2.显示目前存在的管道
//print_r($ph->listTubes()); 

//3.查看NewUsers管道的信息
//$ph->useTube('NewUsers')->put('test'); 
//$ph->useTube('NewUsers')->put('up'); //4.向NewUsers管道添加一个up任务
//print_r($ph->statsTube('NewUsers'));//3.查看NewUsers管道的信息

//6.查看指定管道中某一个任务的情况
//$job = $ph->watch('NewUsers')->reserve(); //5.从管道中取出任务(消费)
//print_r($ph->statsJob($job)); //6.查看指定管道中某一个任务的情况

//7.查看任务id为1的任务详情
//$job = $ph->peek(1);7.直接取出任务id为1的任务 [注:beanstalkd中所有任务的id都具有唯一性] 
//print_r($ph->statsJob($job));//查看任务id为1的任务详情
//----------------------------------------生产类--------------------------------------

第一种 put()

//$tube = $ph->useTube('NewUsers');//连接NewUsers管道
//print_r($tube->put('four'));//向NewUsers管道添加任务four,并返回结果
//注: put()方法还有3个可选参数(依次为: 优先级priority,延迟时间delay,任务超时重发ttr)

第二种 putInTube() [注: putInTube()就是对useTube()和put()的封装]
//$res = $ph->putInTube('NewUsers','three');//向NewUsers管道添加任务three
注: putInTube()方法还有3个可选参数(依次为: 优先级priority,延迟时间delay,任务超时重发ttr)
//print_r($res);//返回任务id

//print_r($ph->statsTube('NewUsers'));//查看NewUsers管道的详细情况
//---------------------------------------消费类--------------------------------------

// 1.watch 监听NewUsers管道 [ 注: watch()同样可以监听多个管道 ]
//$tube = $ph->watch('NewUsers');
//print_r($ph->listTubesWatched());//打印已经监听的管道


// 2.watch 监听多个管道
//$tube = $ph->watch('NewUsers')
//           ->watch('default');
//print_r($ph->listTubesWatched());//打印已经监听的管道


// 3.ignore 监听NewUsers管道,忽略default管道
//$tube = $ph->watch('NewUsers')
//            ->ignore('default');
//print_r($ph->listTubesWatched());//打印已经监听的管道


// 4.reserve 监听NewUsers管道,并且取出任务
//$job = $ph->watch('NewUsers')
//          ->reserve();
//
注reserve()有1个参数,阻塞的时间,过了阻塞时间,不管有没有东西,直接返回
//
//var_dump($job);//打印已经取出的任务
//$ph->delete($job);//删除已经取出的任务


// 5.putInTube/put 向NewUsers管道写入任务 [ 注:此为生产者方法,放到此处是为了方便理解 ]
//$ph->putInTube('NewUsers','number_1',5);
//$ph->putInTube('NewUsers','number_2',3);
//$ph->putInTube('NewUsers','number_3',0);
//$ph->putInTube('NewUsers','number_4',4);
//print_r($ph->statsTube('NewUsers'));//5.查看NewUsers管道详细信息


// 6.release 将取出的任务放回ready状态,还有2个参数(优先级和延迟)
//$job = $ph->watch('NewUsers')->reserve();//6.监听NewUsers管道,并取出任务

//if (true) {
//    sleep(30);
//    $ph->release($job);//6.将任务取出之后,停留30秒,然后将任务状态重新变为ready
//} else {
//    $ph->delete($job);
//}


// 7.bury (预留) 将任务取出之后,发现后面执行的逻辑不成熟(比如发邮件,突然发现邮件服务器挂掉了),
//或者说还不能执行后面的逻辑,需要把任务先封存起来,等待时机成熟了,再拿出这个任务进行消费

//$job = $ph->watch('NewUsers')->reserve();//取出任务
//$ph->bury($job);//取出任务后,将任务放到一边(预留)

// 8.peekBuried() 将处在bury状态的任务读取出来
//$job = $ph->peekBuried('NewUsers');//将NewUsers管道中处在bury状态的任务读取出来
//var_dump($ph->statsJob($job));//打印任务状态(此时任务状态应该是bury)

// 9.kickJob() 将处在bury任务状态的任务转化为ready状态
//$job = $ph->peekBuried('NewUsers');//将NewUsers管道中处在bury状态的任务读取出来
//$ph->kickJob($job);

// 10.kick()  将处在bury任务状态的任务转化为ready状态,有第二个参数int, 批量将任务id小于此数值的任务转化为ready
//$ph->useTube('NewUsers')->kick(65);//把NewUsers管道中任务id小于65,并且任务状态处于bury的任务全部转化为ready

// 11.peekReady() 将管道中处于ready状态的任务读出来
//$job = $ph->peekReady('NewUser');//将NewUser管道中处于ready状态的任务读取出来
//var_dump($job);
//$ph->delete($job);

// 12.peekDelay() 将管道中所有处于delay状态的任务读取出来
//$job = $ph->peekDelayed('NewUser');
//var_dump($job);
//$ph->delete($job);


// 13.pauseTube() 对整个管道进行延迟设置,让管道处于延迟状态
//$ph->pauseTube('NewUser',10);//设置管道NewUser延迟时间为10s
//$job = $ph->watch('NewUser')->reserve();//监听NewUser管道,并取出任务
//var_dump($job);

// 14.resumeTube() 恢复管道,让管道处于不延迟状态,立即被消费
//$ph->resumeTube('NewUser');//取消管道NewUser的延迟状态,变为立即读取
//$job = $ph->watch('NewUser')->reserve();//监听NewUser管道,并取出任务
//var_dump($job);

// 15.touch() 让任务重新计算任务超时重发ttr时间,相当于给任务延长寿命

6、细节

细节:
beanstalkd 如何维护 job 的状态:tube 有 3 个集合 delay、ready 和 buried 分别存放对应状态的 job,conn 的 reserved_jobs 集合存储状态为 reserved 的 job(消费者获取一个 job 后,job 的状态才会改变为 reserved,因此这个集合由 conn 维护)
delay 状态的 job 怎么修改为 ready:delay 集合是一个按照时间排序的最小堆,beanstalkd 不定时循环从堆根节点获取 job,校验是否需要改变其状态未 ready
如何实现优先级:只有 ready 状态的 job 才能被消费者获取消费,ready 集合是一个按照优先级排序的最小堆,根节点始终是优先级最高得 job
消费者持续拉模式实现:消费者使用 reserve 命令获取 job,beanstalkd 检查消费者监听的所有 tube,查找到 ready 的 job 即返回,否则阻塞消费者知道有 ready 状态的 job 产生为止

telnet 127.0.0.1 11300
命令:
use :使用指定 tube
watch :监听指定 tube
ignore :取消监听指定 tube
list-tubes:列出所有的 tube
list-tube-used:列出当前客户端使用的 tube
list-tubes-watched:列出当前客户端监听的所有 tube
pause-tube :暂停指定 tube,暂停期间所有 job 都不能再被消费者消费
put :生产者发布 job
reserve  :获得堆顶的 job,如果客户端监视的所有 tube 都没有 ready 状态的 tube,阻塞客户端;否则返回 job
reserve-with-timeout :同 reserve,只是设置最大阻塞时间
peek :返回 id 对应的 job
peek-ready:返回下一个 ready 的 job
peek-delay:返回剩余时间最短的 delay 状态的 job
peek-buried:返回下一个 buried 列表中的 job
release   :将一个 reserved 状态的 job 重置为 ready 状态
bury  :将 job 的状态设置为 buried
kick:将 buried 状态的 job 迁移为 ready,或将 delay 状态的 job 迁移为 ready
kick-job :将一个 job 的状态迁移为 ready
delete :删除一个 job
touch :客户端 reserve 获取 job 后,发现没有足够时间处理此 job,发送 touch 命令,放服务器重新开始计时 TTR
stats-job :查询 job 状态
stats-tube :查询 tube 状态
stats:查询服务器统计信息
quit:退出

7、什么是队列

什么是队列?  ==>   应用一种数据结构实现先进先出的排队功能
定义: 
只允许在一端进行插入操作 ,而在另一端进行删除操作的线性表FIFO 允许插入的一端称做队尾,允许删除的一端称作队头。(顺序队列、循环队列、链队列)

队头                 队尾
出队列      a1  a2  a3  ...   aN    入队列
轻量级 对比rabbit MQ Kafka
支持 生产者和消费者模式 (什么是生产者消费者模式?)

8、核心概念

Beanstalkd设计里面的核心概念:
job
一个需要异步处理的任务,是Beanstalkd中的基本单元,需要放在一个tube中。
tube
一个有名称的任务队列,用来存储统一类型的job,是producer和consumer操作的对象。
producer
Job的生产者,通过put命令来将一个job放到一个tube中。
consumer
Job的消费者,通过reserve/release/bury/delete命令来获取job或改变job的状态。
生产者  ->  管道(tube)-> 任务(job)

image-20210617102721364

9、任务状态

Beanstalkd中一个job的生命周期如图所示。一个job有READY, RESERVED, DELAYED, BURIED四种状态。当producer直接put一个job时,job就处于READY状态,等待consumer来处理,如果选择延迟put,job就先到DELAYED状态,等待时间过后才迁移到READY状态。consumer获取了当前READY的job后,该job的状态就迁移到RESERVED,这样其他的consumer就不能再操作该job。当consumer完成该job后,可以选择delete, release或者bury操作;delete之后,job从系统消亡,之后不能再获取;release操作可以重新把该job状态迁移回READY(也可以延迟该状态迁移操作),使其他的consumer可以继续获取和执行该job;有意思的是bury操作,可以把该job休眠,等到需要的时候,再将休眠的job kick回READY状态,也可以delete BURIED状态的job。正是有这些有趣的操作和状态,才可以基于此做出很多意思的应用,比如要实现一个循环队列,就可以将RESERVED状态的job休眠掉,等没有READY状态的job时再将BURIED状态的job一次性kick回READY状态。

image-20210617131903431

10、特性

特性:
优先级 (priority)  相当于插队的概念
延迟   (delay)   
持久化  (persistent data)   因为是内存队列 所以一旦服务器宕机,数据消失,beanstalk_log 定时写入
预留   (buried) 
任务超时重发 (time-to-run)

优先级
支持02**32的优先级,值越小,优先级越高,默认优先级为1024。

持久化
可以通过binlog将job及其状态记录到文件里面,在Beanstalkd下次启动时可以通过读取binlog来恢复之前的job及状态。

分布式容错
分布式设计和Memcached类似,beanstalkd各个server之间并不知道彼此的存在,都是通过client来实现分布式以及根据tube名称去特定server获取job。

超时控制
为了防止某个consumer长时间占用任务但不能处理的情况,Beanstalkd为reserve操作设置了timeout时间,如果该consumer不能在指定时间内完成job,job将被迁移回READY状态,供其他consumer执行。

Pheanstalk 类
方法:生产者  消费者  维护

状态。

分布式容错
分布式设计和Memcached类似,beanstalkd各个server之间并不知道彼此的存在,都是通过client来实现分布式以及根据tube名称去特定server获取job。

超时控制
为了防止某个consumer长时间占用任务但不能处理的情况,Beanstalkd为reserve操作设置了timeout时间,如果该consumer不能在指定时间内完成job,job将被迁移回READY状态,供其他consumer执行。

Pheanstalk 类
方法:生产者 消费者 维护




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值