getting start with storm 翻译 第七章 part-2

本文介绍Apache Storm中Spout与Bolt的基本实现原理及PHP脚本示例,包括如何通过Spout发送元组,Bolt接收并处理元组等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处:http://blog.youkuaiyun.com/lonelytrooper/article/details/9988951

启动循环并读写元组

这是最重要的步骤,所有的工作在这里完成。本步骤的实现取决于是否你正在开发一个spout或bolt。

如果是spout,你应该启动发送元组。如果是bolt,循环并读取元组,处理并发射,ack或fail。

我们看一下发射数字的spout的实现:

$from =intval($argv[1]);

$to =intval($argv[2]);

 

while(true) {

$msg =read_msg();

$cmd =json_decode($msg,true);

if ($cmd['command']=='next') {

if ($from<$to) {

storm_emit(array("$from"));

$task_ids =read_msg();

$from++;

} else{

sleep(1);

}

}

storm_sync();

}

从命令行参数获取from和to并且开始迭代。每次你从storm获取一条next消息都意味着你准备发射一个新的元组。

一旦你发射了所有的数字并且没有更多的元组要发射,就休眠一段时间。

为了确保脚本为下一个元组准备好了,Storm在发送下一个之前等待行sync\n。为读取命令,只需调用read_msg()并用JSON解码它。

如果是bolts,有一些小不同。                                                                                                  

while(true) {

$msg =read_msg();

$tuple =json_decode($msg,true, 512, JSON_BIGINT_AS_STRING);

if (!empty($tuple["id"])) {

if (isPrime($tuple["tuple"][0])) {

storm_emit(array($tuple["tuple"][0]));

}

storm_ack($tuple["id"]);

}

}

循环,从标准输入读取元     组。一旦获取消息,就用JSON解码它。如果是一个元组,处理,检查是否是质数。

如果是质数,发射该数;否则忽略它。在任何情况下,ack元组。

json_decode函数内JSON_BIGINT_AS_STRING的使用是Java和PHP转换的变通方案。Java发送非常大的数字,它们被以较低的精度编码成PHP,这会导致问题。为解决这个问题,当在JSON消息中打印数字时,告诉PHP解码大数字为字符串并避免使用双引号。该参数工作需要PHP5.4.0或更高的版本。

类似emit,ack,fail和log的消息有如下结构:

Emit

{

"command": "emit",

"tuple": ["foo","bar"]

}

这里的数组包含你要为元组发送的值。

Ack

{

"command": "ack",

"id": 123456789

}

这里的id是你正在处理的元组的ID。

Fail

{

"command": "fail",

"id": 123456789

}

同emit,id是你正在处理的元组的ID。

Log

{

"command": "log",

"msg": "somemessage to be logged by storm."

}

把它放到一起使得你有了下边的PHP脚本。

对于你的spout:

<?php

function read_msg() {

$msg ="";

while(true) {

$l =fgets(STDIN);

$line =substr($l,0,-1);

if ($line=="end") {

break;

}

$msg ="$msg$line\n";

}

return substr($msg,0, -1);

}

function write_line($line) {

echo("$line\n");

}

function storm_emit($tuple) {

$msg =array("command"=> "emit","tuple"=> $tuple);

storm_send($msg);

}

function storm_send($json) {

write_line(json_encode($json));

write_line("end");

}

function storm_sync() {

storm_send(array("command"=> "sync"));

}

function storm_log($msg) {

$msg =array("command"=> "log","msg"=> $msg);

storm_send($msg);

flush();

}

$config =json_decode(read_msg(),true);

$heartbeatdir =$config['pidDir'];

$pid =getmypid();

fclose(fopen("$heartbeatdir/$pid","w"));

storm_send(["pid"=>$pid]);

flush();

$from =intval($argv[1]);

$to =intval($argv[2]);

while(true) {

$msg =read_msg();

$cmd =json_decode($msg,true);

if ($cmd['command']=='next') {

if ($from<$to) {

storm_emit(array("$from"));

$task_ids =read_msg();

$from++;

} else{

sleep(1);

}

}

storm_sync();

}

?>

对于你的bolt:

<?php

function isPrime($number) {

if ($number<2) {

return false;

}

if ($number==2) {

return true;

}

for ($i=2;$i<=$number-1;$i++) {

if ($number% $i == 0) {

return false;

}

}

return true;

}

function read_msg() {

$msg ="";

while(true) {

$l =fgets(STDIN);

$line =substr($l,0,-1);

if ($line=="end") {

break;

}

$msg ="$msg$line\n";

}

return substr($msg,0, -1);

}

function write_line($line) {

echo("$line\n");

}

function storm_emit($tuple) {

$msg =array("command"=> "emit","tuple"=> $tuple);

storm_send($msg);

}

function storm_send($json) {

write_line(json_encode($json));

write_line("end");

}

function storm_ack($id) {

storm_send(["command"=>"ack","id"=>"$id"]);

}

function storm_log($msg) {

$msg =array("command"=> "log","msg"=> "$msg");

storm_send($msg);

}

$config =json_decode(read_msg(),true);

$heartbeatdir =$config['pidDir'];

$pid =getmypid();

fclose(fopen("$heartbeatdir/$pid","w"));

storm_send(["pid"=>$pid]);

flush();

while(true) {

$msg =read_msg();

$tuple =json_decode($msg,true, 512, JSON_BIGINT_AS_STRING);

if (!empty($tuple["id"])) {

if (isPrime($tuple["tuple"][0])) {

storm_emit(array($tuple["tuple"][0]));

}

storm_ack($tuple["id"]);

}

}

?>

把所有的这些脚本放在工程路径下一个特殊的叫做mutilang/resources的文件夹下是重要的。该文件夹被包含在发送的worker的jar文件中。如果你没有将脚本放置在那个文件夹下,Storm没法运行它们并且会报告一个错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值