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

时间:2015-10-10 03:25:25

标签: scala apache-flink

我使用Flink Stream处理3G网络中的数据流量日志(GPRS隧道协议)。而且我在用户的用户会话中合成信息时遇到了麻烦。

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

P / S:
我们捕获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 。 我做错了什么?

1 个答案:

答案 0 :(得分:0)

说实话,通过这里的电信公司细节来看有点困难,但如果我理解正确你至少有3个流,前两个是 CreateReq CreateRsp 流。

为了检测会话的建立,我将使用 ConnectedDataStream 抽象来共享上述两个流之间的状态。查看此example的使用情况或相关的Flink docs

这是你想要实现的目标吗?