Scala 如何使用Flink streaming处理复杂协议的数据流

Scala 如何使用Flink streaming处理复杂协议的数据流,scala,apache-flink,Scala,Apache Flink,我正在使用Flink Stream处理3G网络中的数据流量日志(GPRS隧道协议)。我在用户会话中的信息合成方面遇到了问题 例如:如何映射一个会话的开始和结束。我不知道Flink流媒体是否适合处理这样复杂的协议 附言: 我们捕获了3G网络中SGSN和GGSN之间的数据交换(使用GTP协议和GTP-C/U消息)。当SGSN发送CreateReq(TEID,Seq,IMSI,TEID_dl,TEID_data_dl)消息和GGSN响应CreateRsp(TEID_dl,Seq,TEID_ul,TEI

我正在使用Flink Stream处理3G网络中的数据流量日志(GPRS隧道协议)。我在用户会话中的信息合成方面遇到了问题

例如:如何映射一个会话的开始和结束。我不知道Flink流媒体是否适合处理这样复杂的协议

附言:
我们捕获了3G网络中SGSN和GGSN之间的数据交换(使用GTP协议和GTP-C/U消息)。当SGSN发送CreateReq(TEID,Seq,IMSI,TEID_dl,TEID_data_dl)消息和GGSN响应CreateRsp(TEID_dl,Seq,TEID_ul,TEID_data_ul)消息时,会话启动。 会话建立后,从SGSN发送到GGSN的其他GTP-C消息(例如:UpdateReq、DeleteReq)使用TEID_ul,响应消息使用TEID_dl,GTP-U消息使用TEID_data_ul(SGSN->GGSN)和TEID_data_dl(GGSN->SGSN)。GTP-U消息包含AppID(facebook、twitter、web)、url等信息,
最后,我想处理连续日志数据流,并映射同一个用户(IMSI)的GTP-C消息和GTP-U以生成报告

我试过这个:

val sessions = createReqs.connect(createRsps).flatMap(new CoFlatMapFunction[CreateReq, CreateRsp, Session] {
  // holds CreateReqs indexed by (tedid_dl,seq)
  private val createReqs = mutable.HashMap.empty[(String, String), CreateReq]
  // holds CreateRsps indexed by (tedid,seq)
  private val createRsps = mutable.HashMap.empty[(String, String), CreateRsp]


  override def flatMap1(req: CreateReq, out: Collector[Session]): Unit = {
    val key = (req.teid_dl, req.header.seqNum)
    val oRsp = createRsps.get(key)
    if (!oRsp.isEmpty) {
      val rsp = oRsp.get
      println("OK")
      out.collect(new Session(rsp.header.time, req.imsi, req.teid_dl, req.teid_ddl, rsp.teid_upl, rsp.teid_dupl, req.rat, req.apn))
      createRsps.remove(key)
    } else {
      createReqs.put(key, req)
    }
  }

  override def flatMap2(rsp: CreateRsp, out: Collector[Session]): Unit = {
    val key = (rsp.header.teid, rsp.header.seqNum)
    val oReq = createReqs.get(key)

    if (!oReq.isEmpty) {
      val req = oReq.get
      out.collect(new Session(rsp.header.time, req.imsi, req.teid_dl, req.teid_ddl, rsp.teid_upl, rsp.teid_dupl, req.rat, req.apn))
      createReqs.remove(key)
    } else {
      createRsps.put(key, rsp)
    }
  }
}).print()

此代码始终返回空结果。输入流包含同一会话的CreateRsp和CreateReq消息的事实。它们看起来非常接近(在1秒之内)。每次调试时,oReq.isEmpty==true。
我做错了什么?

老实说,要看穿这里的电信细节有点困难,但如果我理解正确,您至少有3个流,前两个是CreateReq和CreateRsp流

为了检测会话的建立,我将使用ConnectedDataStream抽象在前面提到的两个流之间共享状态。查看此文件了解用法或相关信息


这就是你想要达到的目标吗?

你所说的“如何绘制一个会话的开始和结束”是什么意思?请提供您尝试执行的更多详细信息。@MatthiasJ.Sax我刚刚添加了有关用户会话的更多详细信息。您使用的是哪个版本的Flink?最近,数据流API进行了重大重构(可在当前master中获得,并将成为Flink 0.10.0的一部分)。查看Flink To me中有关窗口处理的新文档,您似乎希望根据用户id对流进行分区,并使用自定义窗口(每个窗口对应于一个会话)。希望这有帮助…我正在使用Flink 0.10-SNAPSHOT。imsi(用户id)仅出现在CreateReq消息中。因此,我无法在其上对流进行分区。我建议使用一个小的测试数据集,并在
LocalStreamEnvironment
中进行调试,或者进行日志/printf调试以获得更多信息。我已尝试如上所述使用ConnectedDataStream。但有些事情正在发生!