【发布时间】:2021-07-06 13:04:32
【问题描述】:
前提条件:
- 编程语言:PHP。
- 序列化系统:Apache avro
- PHP 库:https://github.com/wikimedia/avro-php
我通过 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