大数据计算框架Flink入门

Flink概述

官网:http://flink.apache.org/

Apache Flink是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。Flink设计为在所有常见的集群环境中运行,以内存速度和任何规模执行计算。

Flink特点

与其它组件集成!
flink是分布式系统,需要计算资源才可执行程序。flink可以与常见的集群资源管理器进行集成(Hadoop Yarn,Apache Mesos..)。
可以单独作为独立集群运行。通过不同部署模式实现。这些模式允许flink以其惯有的方式进行交互。当我们部署flink应用程序时,Flink会根据应用程序配置的并行性自动识别所需资源。从资源管理器中请求它们。如果发生故障,flink会请求新的资源来替换发生故障的容器。提交或控制程序都通过REST调用进行,简化Flink在许多环境的集成。

以任何比例应用程序(小集群、无限集群)

Flink旨在以任何规模运行有状态流应用程序。应用程序可以并行化在集群中分布和同时执行程序。因此,我们的应用集群可以利用无限的cpu和磁盘与网络IO。Flink可以轻松的维护非常大的应用程序状态。用户可拓展性报告:

  • 应用程序每天可以处理万亿个事件
  • 应用程序每天可以维护多个TB的状态
  • 应用程序可以在数千个内核运行

利用内存中的性能

有状态Flink应用程序针对于对本地状态访问进行了优化。任务状态始终的保留在内存中,或者如果大小超过了可用内存,则保存在访问高效的磁盘数据结构中(SSD 机械/固态)。任务可以通过访问本地来执行所有计算。从来产生极小的延迟。Flink定期和异步检查本地状态持久存储来保持出现故障时一次状态的一致性。

  • 处理结果准确:无论是有序数据还是延迟到达的数据。
  • 容错机制:有状态:保持每次的结果往下传递,实现累加。DAG(有向无环图)。
  • 有很强大的吞吐量和低延迟:计算速度快,吞吐量处理的量级大。
  • 精准的维护一次的应用状态。
  • 支持大规模的计算:可以运行在数千台节点上。
  • 支持流处理和窗口化操作
  • 版本化处理
  • 检查点机制实现精准的一次性计算保证:checkpoint
  • 支持yarn与mesos资源管理器

Flink运行模型

流计算/无界
数据源源不断产生,我们的需求是源源不断的处理。程序需要一直保持在计算的状态。
批处理/有界
计算一段完整的数据集,计算成功后释放资源,那么此时工作结束。

安装部署

Local模式:直接解压启动即可
集群模式:
    解压并修改配置文件 conf/masters,slaves,flink-conf.yaml
        vi masters:bigdata111:8081
        vi slaves:bigdata112 换行 bigdata13
        vi flink-conf.yaml :
            taskmanager.numberOfTaskSlots:2
            jobmanager.rpc.address: bigdata111
    可选配置:
        每个JobManager(jobmanager.heap.mb)的可用内存量,
        每个TaskManager(taskmanager.heap.mb)的可用内存量,
        每台机器的可用CPU数量(taskmanager.numberOfTaskSlots),
        集群中的CPU总数(parallelism.default)和
        临时目录(taskmanager.tmp.dirs)
    节点分发:scp  -r flink-1.6.1/  root@bigdata112 ....
    启动flink: ./bin/start-cluster.sh 
    停止flink: ./bin/stop-cluster.sh
    WebUI查看: http://bigdata111:8081
集群HA模式:
    修改flink-conf.yaml
    #jobmanager.rpc.address: bigdata11  注释掉,不需要指定
    high-availability:zookeeper
    #指定高可用模式(必须)
    high-availability.zookeeper.quorum:bigdata111:2181,bigdata112:2181,bigdata113:2181
    #ZooKeeper仲裁是ZooKeeper服务器的复制组,它提供分布式协调服务(必须)
    high-availability.storageDir:hdfs:///flink/ha/
    #JobManager元数据保存在文件系统storageDir中,只有指向此状态的指针存储在ZooKeeper中(必须)
    high-availability.zookeeper.path.root:/flink 
    #根ZooKeeper节点,在该节点下放置所有集群节点(推荐) 
    high-availability.cluster-id:/flinkCluster
    #自定义集群(推荐)
    state.backend: filesystem
    state.checkpoints.dir: hdfs:///flink/checkpoints
    state.savepoints.dir: hdfs:///flink/checkpoints
    修改conf/zoo.cfg
    server.1=bigdata111:2888:3888
    server.2=bigdata112:2888:3888
    server.3=bigdata113:2888:3888
    修改conf/masters
    bigdata111:8081
    bigdata112:8081
    修改slaves
    bigdata112
    bigdata113
    同步配置文件conf到各节点
启动HA:先启动zk,dfs,再启动flink
    手动将JobManager / TaskManager实例添加到群集
    可以使用bin/jobmanager.sh和bin/taskmanager.sh脚本将JobManager和TaskManager实例添加到正在运行的集群中 jobmanager.sh start bigdata112

Flink开发

Wordcount案例  Scala代码

import org.apache.flink.api.java.utils.ParameterTool
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.streaming.api.windowing.time.Time

object SocketWindowWordCountScala {
  def main(args: Array[String]) : Unit = {
    // 定义一个数据类型保存单词出现的次数
    case class WordWithCount(word: String, count: Long)
    // port 表示需要连接的端口
    val port: Int = try {
      ParameterTool.fromArgs(args).getInt("port")
    } catch {
      case e: Exception => {
        System.err.println("No port specified. Please run 'SocketWindowWordCount --port '")
        return
      }
    }
    // 获取运行环境
    val env: StreamExecutionEnvironment =StreamExecutionEnvironment.getExecutionEnvironment
    // 连接此socket获取输入数据
    val text = env.socketTextStream("node21", port, '\n')
    //需要加上这一行隐式转换 否则在调用flatmap方法的时候会报错
    import org.apache.flink.api.scala._
    // 解析数据, 分组, 窗口化, 并且聚合求SUM
    val windowCounts = text
      .flatMap { w => w.split("\\s") }
      .map { w => WordWithCount(w, 1) }
      .keyBy("word")
      .timeWindow(Time.seconds(5), Time.seconds(1))
      .sum("count")
    // 打印输出并设置使用一个并行度
    windowCounts.print().setParallelism(1)
    env.execute("Socket Window WordCount")
  }
}

Wordcount案例  Java代码

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.utils.ParameterTool;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.util.Collector;

/**
 * Desc: 使用flink对指定窗口内的数据进行实时统计,最终把结果打印出来
 *       先在node21机器上执行nc -l 9000
 */
public class StreamingWindowWordCountJava {
    public static void main(String[] args) throws Exception {
    //定义socket的端口号
    int port;
    try{
        ParameterTool parameterTool = ParameterTool.fromArgs(args);
        port = parameterTool.getInt("port");
    }catch (Exception e){
        System.err.println("没有指定port参数,使用默认值9000");
        port = 9000;
    }
    //获取运行环境
    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    //连接socket获取输入的数据
    DataStreamSource text = env.socketTextStream("node21", port, "\n");
    //计算数据
    DataStream windowCount = text.flatMap(new FlatMapFunction() {
        //打平操作,把每行的单词转为类型的数据
        public void flatMap(String value, Collector out) throws Exception{
            String[] splits = value.split("\\s");
            for (String word:splits) {
                out.collect(new WordWithCount(word,1L));
            }
        }
    })
     //针对相同的word数据进行分组
     .keyBy("word")
     //指定计算数据的窗口大小和滑动窗口大小
     .timeWindow(Time.seconds(2),Time.seconds(1))
     .sum("count");
    //把数据打印到控制台,使用一个并行度
    windowCount.print().setParallelism(1);
    //注意:因为flink是懒加载的,所以必须调用execute方法,上面的代码才会执行
    env.execute("streaming word count");
}
/**
* 主要为了存储单词以及单词出现的次数
 */
static class WordWithCount{
    public String word;
    public long count;
    public WordWithCount(){}
    public WordWithCount(String word, long count) {
    this.word = word;
        this.count = count;
    }
    @Override
    public String toString() {
        return "WordWithCount{" +"word='" + word + '\'' +", count=" + count +'}';}
    }
}

运行测试

首先,使用nc命令启动一个本地监听,命令是:

 nc -l 9000

通过netstat命令观察9000端口。 netstat -anlp | grep 9000,启动监听如果报错:-bash: nc: command not found,请先安装nc,在线安装命令:yum -y install nc

你可能感兴趣的:(大数据)