通过Avro反序列化C#中的Flume事件

时间:2013-11-13 10:43:03

标签: c# flume avro

我已经设置了一个Flume服务,它可以监视Netcat或者用Exec作为Source来记录日志,就像那样。我使用Memory作为通道,Avro作为接收器(Thrift在文档中指定,但似乎不适用于Flume 1.3或1.4)

我已经设置了一个C#套接字服务器来接收消息,我得到了一个字节流。如果我使用Encoding.UTF8.GetString(buffer)读取它们,那么我可以看到类似的东西:

"\0\0\0\0\0\0\0\0\00�����Tt������5\ne\0�����Tt������5\ne\0\0appendBatch\0\0�\0�127.0.0.1 - - [12/Nov/2013:22:42:50 +0000] \"GET /docs/appdev/index.html HTTP/1.1\" 200 7645\0�127.0.0.1 - - [12/Nov/2013:22:44:07 +0000] \"GET /docs/appdev/introduction.html HTTP/1.1\" 200 8619\0�127.0.0.1 - - [12/Nov/2013:22:44:09 +0000] \"GET /docs/appdev/installation.html HTTP/1.1\" 200 9045\0�127.0.0.1 - - [12/Nov/2013:22:44:12 +0000] \"GET /docs/appdev/deployment.html HTTP/1.1\" 200 18800\0�127.0.0.1 - - [12/Nov/2013:22:49:07 +0000] \"GET /docs/appdev/source.html HTTP/1.1\" 200 24554\0�127.0.0.1 - - [12/Nov/2013:22:50:38 +0000] \"GET /docs/appdev/processes.html HTTP/1.1\" 200 30743\0�127.0.0.1 - - [12/Nov/2013:22:51:39 +0000] \"GET /docs/appdev/sample/ HTTP/1.1\" 200 1852\0�0:0:0:0:0:0:0:1 - - [12/Nov/2013:22:51:48 +0000] \"GET /sample HTTP/1.1\" 404 963\0�0:0:0:0:0:0:0:1 - - [12/Nov/2013:22:51:48 +0000] \"GET /favicon.ico HTTP/1.1\" 200 21630\0�0:0:0:0:0:0:0:1 - - [12/Nov/2013:23:02:13 +0000] \"GET /sample HTTP/1.1\" 404 963\0"

显然,我正在获取数据,但我想正确地反序列化而不是进行某种正则表达式提取。我可以看到有一个官方的Avro C#库,并且有一个具有反序列化库的Microsoft Hadoop库。我创建了一个反序列化的本地对象:

[DataContract]
public class AvroEvent
{
    [DataMember]
    public byte[] Body { get; set; }
}

并尝试反序列化:

  client = serverSocket.EndAccept(result);
  var myNetworkStream = new NetworkStream(client);
  myNetworkStream.Read(buffer, 0, size);
  var avro = new AvroSerializer(typeof(AvroEvent));
  var deser = avro.Deserialize(myNetworkStream);

然后我收到了这个错误:

  System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Unexpected number of bytes.
  Source=Microsoft.Hadoop.Avro

我几乎肯定会以错误的方式解决所有这些问题,而且我相信人们会告诉我不要使用C#,但我几乎没有使用Google上的消息来源,所以如果有人其他人已经做到了这一点并指出了我正确的方向,我将非常感激

托比

1 个答案:

答案 0 :(得分:1)

Flume使用RPC mechanism来传达事件。如果选择Avro,则Flume依赖于Avro RPC not supported by Microsoft's Avro Library (如新增内容中所述),因为它仅用于序列化框架。

从技术上讲,Deserialize()方法期望流具有以下数据(以位为单位):

11[size of byte array encoded in variable-length zig zag][actual byte](*)

您收到的错误可能是因为收到的数据有不同的wire-format


*起始1是必要的,因为库的版本0.8.4951.5418将每个类型封装在null(0)和类型(1)的联合中,因此第一个1是用于记录AvroEvent,第二个1用于字段Body。此行为可在最新版本1.1.0.5中配置。