【问题标题】:Avro encoder/decoder on PHP - how to send encoded binary data without the schema itself?PHP 上的 Avro 编码器/解码器 - 如何在没有架构本身的情况下发送编码的二进制数据?
【发布时间】:2021-07-06 13:04:32
【问题描述】:

前提条件

我通过 Apache kafka 发送各种消息,每条消息都有自己的结构(具有特定键集的数组)并发送到严格定义的主题,数据本身使用 Apache avro 进行编码和解码。

问题是模式本身与数据一起传输,这在我的情况下是多余的(高负载),因为客户端(来自 Kafka 的消息的消费者) 拥有每个消息结构的模式(一个结构 - 一个 Kafka 主题)。

显然,当前的包https://github.com/wikimedia/avro-php不适合。

我正在寻找一个现成的解决方案 - PHP 上的 Avro 编码器/解码器,它不会每次都将模式本身与数据一起发送,而是在客户端替换它(它将被存储为文件并根据主题进行替换)。它将节省磁盘空间和网络流量。

当前解决方案的使用示例:

<?php

require_once('../lib/avro.php');

$schemaJson = <<<_JSON
{"name":"member",
 "type":"record",
 "fields":[{"name":"foo", "type":"int"},
           {"name":"bar", "type":"string"}]}
_JSON;

$item1               = ['foo' => 123, 'bar' => 'ktwop'];
$itemsForSerializing = [$item1];

$avroSchemaForWriter = \AvroSchema::parse($schemaJson);
$writeAvroStringIO   = new \AvroStringIO();
$avroIODatumWriter   = new \AvroIODatumWriter($avroSchemaForWriter);
$avroDataIOWriter    = new \AvroDataIOWriter($writeAvroStringIO, $avroIODatumWriter, $avroSchemaForWriter);

foreach ($itemsForSerializing as $itemForSerializing) {
    $avroDataIOWriter->append($itemForSerializing);
}

$avroDataIOWriter->close();

$encodedString = $writeAvroStringIO->string();
echo $encodedString . PHP_EOL . PHP_EOL;

// ACTUAL OUTPUT:
/* 
    Objavro.codenullavro.schema�{"type":"record","name":"member","fields":[{"name":"foo","type":"int"},{"name":"bar","type":"string"}]} �k����N�*��1�V��ktwop�k����N�*��1�V�
*/

// EXPECTED OUTPUT: ktwop�k����N�*��1�V�

$readAvroStringIO = new \AvroStringIO($encodedString);
$avroDataIOReader = new \AvroDataIOReader(
    $readAvroStringIO, new \AvroIODatumReader($avroSchemaForWriter, $avroSchemaForWriter) // HERE I WANT TO USE SCHEMA FROM FILE ON CLIENT SIDE
);
echo "from binary string:" . PHP_EOL;

foreach ($avroDataIOReader->data() as $dataItem) {
    echo var_export($dataItem, true) . PHP_EOL;
}

//OUTPUT:
/*
    from binary string:
    array (
      'foo' => 123,
      'bar' => 'ktwop',
    )
*/

【问题讨论】:

    标签: php apache-kafka avro


    【解决方案1】:

    应该这样做。

    $io = new AvroStringIO();
    $writer = new AvroIODatumWriter($schema);
    $encoder = new AvroIOBinaryEncoder($io);
    $writer->write($data, $encoder);
    $io->string();
    

    【讨论】:

      猜你喜欢
      • 2012-01-08
      • 1970-01-01
      • 2014-09-11
      • 2022-07-22
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      • 2014-12-29
      • 1970-01-01
      相关资源
      最近更新 更多