Flink流式计算从入门到实战五

Flink流式计算实战专题五

==楼兰

八、Flink项目实战

​ 这一个章节,我们来找一个常见的流式计算场景,将Flink真正用起来。

1、需求背景

​ 现在网络直播平台非常火爆,在斗鱼这样的网络直播间,经常可以看到这样的总榜排名,体现了主播的活跃度。我们就以这个贡献日榜为例,来设计一个Flink的计算程序。

在这里插入图片描述

​ 大家可以思考下这样的业务场景应该要如何实现?

​ 对于贡献日榜 这样的功能,可以理解为是一个典型的流式计算的场景,强调的是数据的实时处理。因为在这个场景下,必须要及时的累计用户的送礼物数据,才能形成你追我赶的实时效果,提升用户的参与体验。这个场景下的实时性,虽然不要求每一条数据都及时响应,但是整体的数据延迟还是要尽量缩短的。例如有一个狂热粉丝想要争抢日榜榜首的位置,虽然不要求送了礼物之后就立即刷新到榜首,但是最长也需要在几分钟内能够看到榜单的刷新效果。这在大数据场景下,也是非常有挑战的。

​ 这种场景下,使用Flink进行流批统一的计算,感觉就非常合适。

2、数据流程设计

​ 在确定了使用Flink进行计算后,首先就需要设计出数据的上下游流程,进行简单的方案可行性评估。

​ 对于数据上游,我们这个贡献榜统计的业务场景,数据来源自然就是粉丝们的打赏行为。一方面整个平台的打赏行为的数据量是非常大的,另一方面这些打赏行为涉及到账户操作,所以他的作用,更大的是体现在贡献榜功能以外的其他业务过程中。基于这两方面考虑,自然就会想到使用kafka来进行削峰以及解耦。而Flink在DataStream/DataSet API和 Table API&SQL 两个部分都对kafka提供了连接器实现,所以用kafka作为数据接入是可行的。

​ 而对于数据下游,其实可以想象,最终计算出来的数据,最为重要的是要强调查询的灵活性以及时效性,这样才能支持页面的快速查询。如果考虑查询的时效性,HBase和ElasticSearch都是比较理想的大数据存储引擎。但是如果考虑到查询的灵活性,就会想到ElasticSearch会相比HBase更适合。因为我们统计出来的这些粉丝贡献度的结果,不光可以作为每个直播间贡献榜的排名,也应该可以作为以后平台主播年度排名等其他业务场景的数据来源。如果想要兼顾这些查询场景,使用HBase就会对Rowkey产生大量的侵入,而Elasticsearch可以根据任意字段快速查询,就比较有优势。 另外,从官方文档中可以查到,对于HBase,Flink只提供了Table API&SQL 模块的connector支持,而DataStream/DataSet API中没有提供支持,而ElasticSearch则支持更为全面。当然,这跟HBase的具体场景是有关联的,但是也可以从另一个角度认为,使用ElasticSearch的可行性更高。

​ 这样,就初步确定了 kafka-> Flink -> ElasticSearch 这样的大致数据流程。这也是在实际开发中非常典型的一个组合方式。后续就可以着手搭建kafka集群以及ElasticSearch+Kibana的集群了。在这次示例中,我们还是会以hadoop01,hadoop02,hadoop03这三台机器来搭建集群。搭建的过程就略过了。

然后确定数据的基础结构

​ 这一步主要是确定入口数据和出口数据的结构。只要这两个数据结构确定了,那么应用程序模块和大数据计算模块就可以分开进行开发了。是双方主要的解耦方式。

​ 在数据入口处,可以定义这样的简化的数据结构:

public static class GiftRecord{
    private String hostId; //主播ID
    private String fansId; //粉丝ID
    private long giftCount; //礼物数量
    private String giftTime; //送礼物时间。时间格式 yyyy-MM-DD HH:mm:SS
    .....
}

​ 在kafka中,确定使用gift作为Topic,MQ的消息格式为 #{hostId},#{fansId},#{giftCount},#{giftTime} 这样的字符串。

​ 在数据出口处,可以定义ES中这样简化的索引结构:

-- 贡献日榜索引
PUT daygiftanalyze
{
  "mappings":{
    "properties": {
      "windowEnd":{
        "type": "long"
      },
      "hostId": {
        "type": "keyword"
      },
      "fansId": {
        "type": "keyword"
      },
      "giftCount":{
        "type": "long"
      }
    }
  }
}

​ 这样,一个简单的设计方案就形成了。应用程序只需要在粉丝发送礼物时往kafka中同步一条消息记录,然后从ES中查询主播的贡献日榜和贡献周榜数据即可。而我们也可以模拟数据格式进行开发了。

3、应用实现

贡献日榜

基础数据结构:

public static class GiftRecord{
    private String hostId; //主播ID
    private String fansId; //粉丝ID
    private long giftCount; //礼物数量
    private String giftTime; //送礼物时间。时间格式 yyyy-MM-DD HH:mm:SS
    .....
}

在kafka中,确定使用gift作为Topic,MQ的消息格式为 #{hostId},#{fansId},#{giftCount},#{giftTime} 这样的字符串。

ES索引:

PUT daygiftanalyze
{
  "mappings":{
    "properties": {
      "windowEnd":{
        "type": "long"
      },
      "hostId": {
        "type": "keyword"
      },
      "fansId": {
        "type": "keyword"
      },
      "giftCount":{
        "type": "long"
      }
    }
  }
}

​ 然后运行Flink程序,com.roy.flink.project.flink.DayGiftAna,从kafka中读取数据。测试数据见giftrecord.txt。计算程序会及时将十分钟内的粉丝礼物统计都存入到ES当中。

ES查询语句:

GET daygiftanalyze/_search
{
  "query": {
    "bool": {
      "must": [
        {"range": {
          "windowEnd": {
            "gte": 1631635200000,
            "lte": 1631721600000
          }
        }},
        {"match": {
          "hostId": "1001"
        }}
      ]
    }
  },
  "aggs": {
    "groupByFans": {
      "terms": {
        "field": "fansId",
        "size": 3,
        "order": {
          "giftCount": "desc"
        }
      },
      "aggs": {
        "giftCount": {
          "sum": {
            "field": "giftCount"
          }
        }
      }
    }
  }
}

ES中的查询结果:

在这里插入图片描述

直播应用就可以根据这个查询结果组织客户端查询代码,最终实现日榜排名的功能。

4、实现效果分析

​ 具体的计算方案参见示例代码,这里就不多做分析了。这里只分析一下在实现过程中需要注意的几个重要的问题:

1、时间语义分析:

​ 对于网络直播这样的场景,从下午六点到第二天早上六点才是一天的高峰期,所以,在进行统计时,将每一天的统计时间定义为从早上六点到第二天早上六点,这样就能尽量保持高峰期的完整性。很多跟娱乐相关的场景,比如网络游戏,也大都是以这样的范围来定义一天,而不是传统意义上的从0点到24点。

2、并行度优化:

​ 可以直接使用Flink的开窗机制,待一周的数据收集完整了之后,一次性向ES中输出统计结果,这种场景下要注意累计器的持久化,以及计算程序出错后的重启恢复机制。

3、后续的改进方式:

​ 状态后端、

而对于贡献日榜的计算,就不能等一天的数据收集齐了再计算了。这时是有两种解决方案,一种是完全的流处理方式。也就是每来一条数据就往ES中更新结果。另一中方式是采用小批量的流处理方式。以五分钟为单位,将数据拆分成一个一个小窗口来进行处理。显然后一种方式对数据处理的压力会比较小一点。虽然数据量会更多,但是ES的存储以及快速查询能力可以比较好的弥补数据量的问题。也因此,在设计ES数据机构时,将贡献日榜的文档结构设计成了一个一个的小范围。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

roykingw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值