大数据技术-flink-利用RichMapFunction和AggregateFunction计算系统访问量PV\UV

flink某一个算子,不同分区水印不一致

在研发过程红碰到一个问题,实时计算的flink某一个算子的不同分区水印不一致,很明显,由于上游在keyby处理后,导致下游不同分区数据分配不均衡,导致不同分区到达的水印不一致,这种情况下可以考虑收缩分区数量;

如下是统计PV\UV的核心计算代码;

 		int parallelism = 2;
        int dbParallelism = 1;
        int days = 7;
        DataStream<PVModel> dataStream = dataStream
                .keyBy(item -> item.getName())
                .map(new MyRepeatMapFunction(days)).setParallelism(parallelism)
                .keyBy(item -> item.getName())
                .timeWindow(Time.days(days), Time.seconds(10))
                .aggregate(new MyPVStatisticFunction()).setParallelism(parallelism)
                .name(this.days + "Day");
        dataStream.addSink(sink).setParallelism(dbParallelism).name("ToDbSink");

这里采用map的RichMapFunction对数据进行预处理,将PV的访问数据加工成PVModel模型,如下

datenameuvpv
2022-05-30 13:00:00ikong11
2022-05-30 14:00:00ikong01
2022-05-30 15:00:00ikong01
2022-05-30 14:00:00lilei11
2022-05-30 15:00:00lilei01

思路:通过state记录当天的用户是否已经存在,不存在则uv=1,否则uv=0,pv会一直为1;

MyRepeatMapFunction.java

 public static class MyRepeatMapFunction extends RichMapFunction<UVModel, PVModel> {

        private int days;

        public MyRepeatMapFunction(int days) {
            this.days = days;
        }


        MapState<String, Integer> uvState;
        MapState<String, Integer> pvState;

        @Override
        public void open(Configuration parameters) throws Exception {

            uvState = this.getRuntimeContext()
                    .getMapState(new MapStateDescriptor<>("uv-state" + days
                            , BasicTypeInfo.STRING_TYPE_INFO
                            , BasicTypeInfo.INT_TYPE_INFO)
                    );

            pvState = this.getRuntimeContext()
                    .getMapState(new MapStateDescriptor<>("pv-state" + days
                            , BasicTypeInfo.STRING_TYPE_INFO
                            , BasicTypeInfo.INT_TYPE_INFO)
                    );
        }


        @Override
        public PVModel map(UVModel uvm) throws Exception {
            String uvKey = uvm.getName() + new DateTime(uvm.getViewTime()).toString("yyyyMMdd");
            String pvKey = uvm.getName();
            int uv = 0;
            if (!uvState.contains(uvKey)) {
                uv = 1;
                uvState.put(uvKey, uv);
            }

            int pv = 1;
            pvState.put(pvKey, pv);
            PVModel vm = new PVModel();
            vm.setDays(uv);
            vm.setCount(pv);
            vm.setName(uvm.getName());

            return vm;
        }

    }

通过聚合函数AggregateFunction,对用户的uv、pv数据进行累加,最终得到用户最近x天的uv和pv总数

public static class MyPVStatisticFunction implements AggregateFunction<PVModel, PVModel, PVModel> {


        @Override
        public MyPVStatisticFunction createAccumulator() {
            return new PVModel();
        }

        @Override
        public PVModel add(PVModel uvm, PVModel acc) {

            acc.setCount(acc.getCount() + 1);

            acc.setName(uvm.getName());

            acc.setDays(acc.getDays() + uvm.getDays());

            return acc;
        }

        @Override
        public PVModel getResult(PVModel tp) {
            return tp;
        }

        @Override
        public PVModel merge(PVModel tp1, PVModel tp2) {
            PVModel uvm = new PVModel();
            uvm.setCount(tp1.getCount() + tp2.getCount());
            uvm.setDays(tp1.getDays() + tp2.getDays());
            uvm.setName(tp1.getName());
            return uvm;
        }
    }

对PVModel进行累加后的结果如下

datenameuvpv
2022-05-30 ikong13
2022-05-30 14:00:00lilei12

其他辅助代码

UVModel.java

public class UVModel {

    private String name = "";

    private String url = "";

    private Long viewTime = 0L;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Long getViewTime() {
        return viewTime;
    }

    public void setViewTime(Long viewTime) {
        this.viewTime = viewTime;
    }

    @Override
    public String toString() {
        return "UVModel{" +
                "name='" + name + '\'' +
                ", url='" + url + '\'' +
                ", viewTime=" + viewTime +
                '}';
    }
}

PVModel.java

public class PVModel implements Serializable {
    private String name = "";

    private int days = 0;

    private int count = 0;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getDays() {
        return days;
    }

    public void setDays(int days) {
        this.days = days;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }


    @Override
    public String toString() {
        return "UserViewStatisticModel{" +
                "name='" + name + '\'' +
                ", days=" + days +
                ", count=" + count +
                '}';
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Hadoop是一个开源的分布式计算框架,主要用于处理大规模数据集。它的核心是HDFS(Hadoop分布式文件系统)和MapReduce计算模型。 Spark是一个快速、通用的大数据处理引擎,可以在内存中进行数据处理,比Hadoop MapReduce更快。它支持多种数据源,包括HDFS、HBase、Cassandra等。 Storm是一个分布式实时计算系统,可以处理实时数据流。它的核心是Storm集群,可以在多个节点上运行,实现高可用性和可扩展性。 Flink是一个分布式流处理框架,可以处理实时数据流和批处理数据。它的核心是DataStream API,可以进行流式计算和窗口计算。 Samza是一个分布式流处理框架,可以处理实时数据流。它的核心是Kafka和YARN,可以实现高可用性和可扩展性。 ### 回答2: 大数据框架是指一组用于处理大规模数据的软件工具。随着大数据及其分析应用的不断增长,数十个大数据框架已经随着时间而推出,其中包括hadoop、spark、storm、flink、samza等。下面将对这几种大数据框架进行详细介绍。 1. Hadoop Hadoop是一个在大数据应用领域最流行的框架。它是以Java语言开发的,是一个分布式的计算平台。通过它,用户能够处理超过普通计算机可以承受的数据量。Hadoop集群由多个计算机组成,在不同的计算机上存储和计算数据。Hadoop的主要组件包括HDFS(分布式文件系统),MapReduce计算模型(可以实现大规模数据的并行处理)。 2. Spark Spark是一个基于内存的计算框架,可以实现大数据的快速处理。与Hadoop相比,Spark运行速度更快,因为它可以在内存中执行计算任务。Spark可以通过Java、Scala和Python编写,还支持Spark SQL(基于SQL的查询),Spark Streaming(处理实时数据流)、MLlib(机器学习库)等功能模块。 3. Storm Storm也是一个实时数据处理框架。它能够实现一种“实时数据流”的处理模式,这在需要对流式数据进行实时处理和计算的场景中非常有用。Storm是一个分布式的框架,包括多个节点,支持高可靠性、水平扩展、非常灵活的拓扑连接等功能。 4. Flink Flink是一个高度可扩展、分布式的计算框架。它支持流式处理和批处理。通过内存进行数据计算,速度更快,同时也支持实时流式数据处理。Flink将传统的批量处理和流式处理集成到了一个框架中,将批量计算看成一种特殊形式的流式计算。 5. Samza Samza是一个其他不同大数据框架的组件,它是一个分布式流处理器,可以处理大量的流数据。它可以作为批处理系统的组件来使用,提供可靠的消息传递、基于字符串的状态存储、多维度流处理和都市需求等功能。Samza主要用于大规模流式数据的分析和处理,通常和其他的大数据处理框架一起使用。 总体来说,以上这几种大数据框架适用于不同的场景和需求。在实际应用时,需要根据具体情况进行选择和使用,以达到最佳的效果和效率。 ### 回答3: 大数据框架是当今大数据技术领域中越来越重要的一部分。在众多大数据框架中,Hadoop、Spark、Storm、Flink和Samza是其中最常用的框架。 Hadoop是由Apache基金会开发的开源框架,主要用于存储和处理大数据。它的核心组件包括HDFS和MapReduce。HDFS是一个分布式文件系统,通常用于存储大数据,而MapReduce是一种分布式数据处理模型,用于对大数据进行批处理。 Spark是另一个Apache开源项目,也是用于大数据处理的框架。与Hadoop不同的是,Spark使用内存计算,这意味着它可以比Hadoop更快地处理大量数据。Spark支持多种编程语言,包括Java、Scala和Python,也支持SQL查询和图形计算。 Storm是另一个Apache开源项目,主要用于流式数据处理。与Hadoop和Spark不同的是,Storm能够实时处理流数据,而不需要等待离线批处理。Storm支持容错和高可用性,并支持多种编程语言,包括Java、Scala和Clojure。 Flink是由Apache开发的开源流处理框架。与Storm类似,Flink也可以进行实时数据处理,并支持批处理模式。Flink的主要特点是低延迟和高吞吐量,同时支持复杂事件处理和机器学习。 最后,Samza也是另一个Apache开源框架,主要用于流式数据处理。与Storm和Flink不同的是,Samza的焦点是可扩展性和容错性。Samza的主要优点之一是它与Kafka集成良好,Kafka是一个分布式消息队列。 总之,Hadoop、Spark、Storm、Flink和Samza都是在大数据领域中广泛应用的重要框架。每个框架都有自己的特点和优劣,应根据具体的大数据需求和场景进行选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码者人生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值