[转]使用PHP处理Kafka消息

Kafka 是一种高吞吐的分布式消息系统,能够替代传统的消息队列用于解耦合数据处理,缓存未处理消息等,同时具有更高的吞吐率,支持分区、多副本、冗余,因此被广泛用于大规模消息数据处理应用。

Kafka的特点:

  • 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间复杂度的访问性能。
  • 高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条以上消息的传输。【据了解,Kafka每秒可以生产约25万消息(50 MB),每秒处理55万消息(110 MB)】
  • 支持Kafka Server间的消息分区,同时保证每个Partition内的消息顺序传输。
  • 分布式系统,易于向外扩展。所有的producer、broker和consumer都会有多个,均为分布式的。无需停机即可扩展机器。
  • 消息被处理的状态是在consumer端维护,而不是由server端维护。当失败时能自动平衡。
  • 同时支持离线数据处理和实时数据处理。

Kafka的架构:

kafka

Kafka的整体架构非常简单,producer、broker(kafka)和consumer都可以有多个。Producer,consumer实现Kafka注册的接口,数据从producer发送到broker,broker承担一个中间缓存和分发的作用。broker分发注册到系统中的consumer。broker的作用类似于缓存,即活跃的数据和离线处理系统之间的缓存。客户端和服务器端的通信,是基于简单,高性能,且与编程语言无关的TCP协议。

Kafka基本概念:

  • Topic:特指Kafka处理的消息源(feeds of messages)的不同分类。
  • Partition:Topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。
  • Message:消息,是通信的基本单位,每个producer可以向一个topic(主题)发布一些消息。
  • Producers:消息和数据生产者,向Kafka的一个topic发布消息的过程叫做producers。
  • Consumers:消息和数据消费者,订阅topics并处理其发布的消息的过程叫做consumers。
  • Broker:缓存代理,Kafa集群中的一台或多台服务器统称为broker。

Kafka消息发送的流程:

Kafka-Message

下面是PHP生产、消费Kafka消息的例子(假设已经配置好Kafka):

1.从zookeeper源码src/c/src安装zookeeper c client

 cd  zookeeper-3.4.8/src/c
   ./configure
   make  &&  make  install

2.编译php libzookper扩展

git clone  https://github.com/Timandes/libzookeeper.git
cd  libzookeeper
phpize
./configure  --with-libzookeeper=/usr/local/bin/cli_mt
make  &&  make  install

3.编译php zookeeper扩展

git clone  https://github.com/andreiz/php-zookeeper.git
cd  php-zookeeper
phpize
./configure
make  &&  make  install

4.修改php.ini配置,添加libzookeeper和php-zookeeper扩展

extension=libzookeeper.so
extension=zookeeper.so

PHP处理Kafka消息

1.启动zookeeper和kafka

 kafka_2.11-0.10.0.0/bin/zookeeper-server-start.sh  --daemon 
 kafka_2.11-0.10.0.0/config/zookeeper.properties
 kafka_2.11-0.10.0.0/bin/kafka-server-start.sh  kafka_2.11-0.10.0.0/config/server.properties

2.创建由2个partition组成的、名为testtopic的topic

kafka_2.11-0.10.0.0/bin/kafka-topics.sh  --create  --zookeeper localhost:2181  --replication-factor  1  --partitions  2  --topic testtopic

3.composer安装nmred/kafka-php

composer require  "nmred/kafka-php"

4.producer.php代码

<?php
 require_once('./vendor/autoload.php');
 $produce  =  \Kafka\Produce::getInstance('localhost:2181',  3000);
 $produce->setRequireAck(-1);
$topicName  =  'testtopic';
//获取到topic下可用的partitions
$partitions  =  $produce->getAvailablePartitions($topicName);
$partitionCount  =  count($partitions);
$count  =  1;
while(true){
    $message  =  json_encode(array('uid'  =>  $count,  'age'  =>  $count%100,  'datetime'  =>  date('Y-m-d H:i:s')));

    //发送消息到不同的partition

    $partitionId  =  $count%$partitionCount;

    $produce->setMessages('testtopic',  $partitionId,  array($message));

    $result  =  $produce->send();

    var_dump($result);

    $count++;

    echo  "producer sleeping\n";

    sleep(1);
}

5.consumer.php代码

<?php

require_once('./vendor/autoload.php');

//获取需要处理的partitionId

$partitionId  =  isset($argv[1])  ?  intval($argv[1])  :  0;

$consumer  =  \Kafka\Consumer::getInstance('localhost:2181');

$consumer->setGroup('test-consumer-group');

$consumer->setPartition('testtopic',  $partitionId);

$consumer->setFromOffset(true);

$consumer->setMaxBytes(102400);

while(true){

    $topic  =  $consumer->fetch();

foreach  ($topic  as  $topicName  =>  $partition)  {

    foreach  ($partition  as  $partId  =>  $messageSet)  {

        foreach  ($messageSet  as  $message)  {

            var_dump($message);

        }

    }

    }

echo  "consumer sleeping\n";

sleep(1);

}

6.运行php代码

在3个终端界面分别运行

php producer.php

php consumer.php  0

php consumer.php  1

7.结果

两个consumer脚本依次收到producer发送的消息


php-kafka-consumer-output

转自:https://aiddroid.com/kafka-introduction-and-php-kafka-usage/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容