Flink_Flink 的分布式缓存

Flink 的分布式缓存

在这里插入图片描述
操作步骤

  1. 将 distribute_cache_student 文件上传到 HDFS / 目录下
  2. 获取批处理运行环境
  3. 创建成绩数据集
  4. 对 成绩 数据集进行 map 转换,将(学生 ID, 学科, 分数)转换为(学生姓名,学科, 分数)
    a. RichMapFunction 的 open 方法中,获取分布式缓存数据
    b. 在 map 方法中进行转换
  5. 实现 open 方法
    a. 使用 getRuntimeContext.getDistributedCache.getFile 获取分布式缓存文件
    b. 使用 Scala.fromFile 读取文件,并获取行
    c. 将文本转换为元组(学生 ID,学生姓名),再转换为 List
  6. 实现 map 方法
    a. 从分布式缓存中根据学生 ID 过滤出来学生
    b. 获取学生姓名
    c. 构建最终结果元组
  7. 打印测试

代码实现

package com.czxy.flink.batch

import java.io.File
import org.apache.flink.api.common.functions.RichMapFunction
import org.apache.flink.api.scala.ExecutionEnvironment
import org.apache.flink.configuration.Configuration
import scala.io.Source

/**
 * 需求:
 * 创建一个 成绩 数据集
 * List( (1, "语文", 50),(2, "数学", 70), (3, "英文", 86))
 * 请通过分布式缓存获取到学生姓名, 将数据转换为
 * List( ("张三", "语文", 50),("李四", "数学", 70), ("王五", "英文", 86))
 * 注: distribute_cache_student 测试文件保存了学生 ID 以及学生姓名
 */
object BatchDisCachedFile {
  def main(args: Array[String]): Unit = {
    /**
     * 实现步骤:
     * 1) 将 distribute_cache_student 文件上传到 HDFS / 目录下
     * 2) 获取批处理运行环境
     * 3) 创建成绩数据集
     * 4) 对 成绩 数据集进行 map 转换, 将( 学生 ID, 学科, 分数) 转换为( 学生姓名, 学科,
     * 分数)
     *  a. RichMapFunction 的 open 方法中, 获取分布式缓存数据
     *  b. 在 map 方法中进行转换
     * 5) 实现 open 方法
     *  a. 使用 getRuntimeContext.getDistributedCache.getFile 获取分布式缓存文件
     *  b. 使用 Scala.fromFile 读取文件, 并获取行
     *  c. 将文本转换为元组( 学生 ID, 学生姓名) , 再转换为 List
     * 6) 实现 map 方法
     *  a. 从分布式缓存中根据学生 ID 过滤出来学生b. 获取学生姓名
     *  c. 构建最终结果元组
     * 7) 打印测试
     */

    // 获取批处理运行环境
    val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment

    //注册分布式缓存文件
    env.registerCachedFile("hdfs://node01:8020/test/input/distribute_cache_student", "student")
    //创建成绩数据集
    import org.apache.flink.api.scala._
    val scoreDataSet: DataSet[(Int, String, Int)] = env.fromCollection(List((1, "语文", 50), (2, "数学", 70), (3, "英文", 86)))
    val resultDataSet: DataSet[(String, String, Int)] = scoreDataSet.map(new RichMapFunction[(Int, String, Int), (String, String, Int)] {
      var stuMap: Map[Int, String] = null

      //初始化的时候只被执行一次
      override def open(parameters: Configuration): Unit = {
        //获取分布式缓存的文件
        val studentFile: File = getRuntimeContext.getDistributedCache.getFile("student")
        val linesIter: Iterator[String] = Source.fromFile(studentFile).getLines()
        stuMap = linesIter.map(item => {
          val itemArr: Array[String] = item.split(",")
          (itemArr(0).toInt, itemArr(1))
        }).toMap
      }

      //每条数据都会执行一次
      override def map(value: (Int, String, Int)): (String, String, Int) = {
        val name: String = stuMap.getOrElse(value._1, "")
        (name, value._2, value._3)
      }
    })
    //输出打印测试
    resultDataSet.print()
  }
}

Flink Accumulators & Counters(了解)

在这里插入图片描述
在这里插入图片描述
代码实现

package com.czxy.flink.batch

import org.apache.flink.api.common.JobExecutionResult
import org.apache.flink.api.common.accumulators.IntCounter
import org.apache.flink.api.common.functions.RichMapFunction
import org.apache.flink.api.scala.ExecutionEnvironment
import org.apache.flink.configuration.Configuration

/**
 * 需求:
 * 给定一个数据源
 * "a","b","c","d"
 * 通过累加器打印出多少个元素
 */
object BatchCounterDemo {
  def main(args: Array[String]): Unit = {
    //1.创建执行环境
    val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
    //2.构建数据集
    import org.apache.flink.api.scala._
    val sourceDataSet: DataSet[String] = env.fromElements("a", "b", "c", "d")
    //3.数据处理
    val counterDataSet: DataSet[String] = sourceDataSet.map(new RichMapFunction[String, String] {
      //1) 创建累加器
      val counter: IntCounter = new IntCounter()

      override def open(parameters: Configuration): Unit = {
        //2) 注册累加器
        getRuntimeContext.addAccumulator("myAccumulator", counter)
      }

      //每条数据都会执行一次
      override def map(value: String): String = {
        //3) 使用累加器
        counter.add(1)
        value
      }
    })
//    counterDataSet.print()
    counterDataSet.writeAsText("day02/data/output/Accumulator").setParallelism(1)
    val result: JobExecutionResult = env.execute("BatchCounterDemo")
    val myAccumulatorValue: Int = result.getAccumulatorResult[Int]("myAccumulator")
    println(myAccumulatorValue)
  }
}
  • Flink Broadcast 和 Accumulators 的区别:
    Broadcast(广播变量)允许程序员将一个只读的变量缓存在每台机器上,而不用在任务之间 传递变量。
    广播变量可以进行共享,但是不可以进行修改 Accumulators(累加器)是可以在不同任务中对同一个变量进行累加操作。

猜你喜欢

转载自blog.csdn.net/qq_44509920/article/details/107436422