Flink  内存

Flink基本转换算子map/filter/flatmap map是大家非常熟悉的大数据操作算子,主要用于将数据流中的数据进行转换,形成新的数据流。简单来说,就是一个“一一映射”,消费一个元素就产出一个元素。我们只需要基于DataStream调用map()方法就可以进行转换处理。方法需要传入的参数是接口MapFunction的实现;返回值类型还是DataStream,不过泛型(流中的元素类型)可能改变。面代码中,MapFunction实现类的泛型类型,与输入数据类型和输出数据的类型有关。 阅读详情

 Flink 

map:做一些清洗转换;

flatMap:输入一个元素,返回一个或者多个元素;

filter:符合条件的数据留下;

keyBy:key相同的数据进入同一个分区;

reduce:当前元素与上一次reduce返回值进行聚合操作;

Union:合并多个流,但是所有的流类型必须一致;

Connect:合并两个流,两个流的类型可以不同;

CoMap、CoFlatMap:对于ConnectedStream使用这俩函数,对两个流进行不同的处理;

split:根据规则吧一个数据流切分为多个流;

Select:配合split,选择切分后的流;

3. Flink On Yarn

Flink on yarn上的好处:

  • 提高集群机器的利用率;
  • 一套集群,可以同时执行MR任务,Spark任务,Flink任务。

Flink on yarn的两种方式:

  • 一开始在Yarn上初始化一个集群;yarn-session.sh【开辟资源】+flink run【提交任务】
  • 每个Flink job都申请一个集群,互不影响,任务执行之后资源会被释放掉。flink run -m yarn-cluster【开辟资源+提交任务】 

4. FlinkKafkaConnector(FlinkKafkaConsumer+FlinkKafkaProducer)

阅读过FlinkKafkaConnector源码后对Kafka偏移量的存储机制有了一个全新的认识,这里有两个坑,简单记下:

  • FlinkKafkaComsumer08用的Kafka老版本Consumer,偏移量提交Zookeeper,由Zookeeper保管,而FlinkKafkaComsumer09以后,偏移量默认存在Kafka内部的Topic中,不再向Zookeeper提交;
  • 使用FlinkKafkaProducer08写Kafka1.10(其他高版本没试过)存在超时。

5. DataStream API之partition

  • 随机分区
1 dataStream.shuffle();
  • 重分区,消除数据倾斜
1 dataStream.rebalance();
  • 自定义分区
1 dataStream.partitionCustom(partiitoner,"somekey");
  • 广播分区:把元素广播所有分区,会被重复消费
1 DataStream.broadcast();

6. Flink Distributed Cache(分布式缓存)

  • 原理

类似Hadoop,可以在并行函数比如map中读取本地文件或则HDFS文件,Flink自动将文件复制到所有taskmanager节点的本地文件系统。

  • 用法

用法一:注册一个文件

1 env.registerCachedFile(“hdfs:///path/to/yout/file","hdfsfile");

用法二:访问数据

1 File myFile = getRuntimeContext().getDistributedCache().getFile("hdfsFile");

7. State

为了实现at least once和exactly once,flink引入了state和checkpoint;state一般将数据保存在堆内存中,而checkpoint是每隔一段时把state数据持久化存储了,当失败时可以恢复。

8. Checkpoint

依赖checkpoint机制,只能保证Flink系统内的exactly once。

checkpoint默认是disabled的,开启之后默认是exactly once,这种模式对大多数应用合适,而at least once在某些低延迟的场景中比较合适(例如几毫秒)。例如,

复制代码

1 env.enableCheckpointing(1000);                                            //每隔1000ms设置一个检查点【检查点周期】             
2 env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);//设置模式为exactly once(默认值)                 
3 env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);//检查点之间至少有500ms的间隔【检查点最小间隔】        
4 env.getCheckpointConfig().setCheckpointTimeout(60000); //检查点必须在一分钟之内完成,否则丢弃【检查点的超时时间】
5 env.getCheckpointConfig().setMaxConcurrentCheckpoints(1); //同一时间点只允许一个检查点                        
6 env.getCheckpointConfig().enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
7 //Flink程序被取消后,会保留检查点数据                

复制代码

9. Flink重启策略

Flink中常用重启策略:

固定时间(Fixed delay);

失败率(Failure rate)【checkpoint机制默认策略】;

无重启(No start)【默认】

10. Window(窗口)

Window将一个stream拆分成有限大小的"桶(buckets)",在这些桶上做计算。Flink中的窗口与可以分为时间驱动【Time Window】和数据驱动【Count Window】,每一个可以细分为:

  • 滚动窗口【没有重叠】tumbling windows
1 .timeWindow(Time.minutes(1));
2 .countWindow(100);
  • 滑动窗口【有重叠】sliding windows
1 .timeWindow(Time.minutes(1),Time.seconds(30))//每隔30秒,统计一分钟的数据
2 .countWindow(100,10)//每隔10条数据,统计100条的数据
  • 会话窗口 session windows

定义了窗口之后,会存在不同的聚合:

  • 增量聚合(窗口中每进入一条数据,就进行一次计算),例如reduce、aggregate、sum、min、max;
  • 全量聚合(等窗口所有数据到齐,才开始计算,可以进行排序等)例如apply、process等

当然也可以分为keyed window和non-keyed window,分组的stream调用keyBy(...)和window(...),非分组的stream中window(...)换成了windowAll(...)

11. Time

针对Stream数据流中的时间,可以分为以下三种:

  • Event Time:日志产生的时间;
  • Ingestion Time:事件从kafka等取出来,进入Flink的时间;
  • Processing Time:事件被处理的时间,例如达到窗口处理的时间等。【默认】 

12. Flink并行度

  • Flink中每个TaskManager为集群提供slot,slot数量与每个节点的可用CPU核数成比例,slot上启动进程,进程内有多个线程。如果任务管理器有n个槽,它会为每个槽分配 1/n 的内存,这里没有对 CPU 进行隔离;目前任务槽仅仅用于划分任务的内存。

配置一个TaskManager有多少个并发的slot数有两种配置方式:

  • taskmanager.numberOfTaskSlots。在conf/flink-conf.yaml中更改,默认值为1,表示默认一个TaskManager只有1个task slot.
  • 提交作业时通过参数配置。--yarnslots 1,表示TaskManager的slot数为1.

⚠️注意:slot不能搞太多,几十个就行,你想啊假如你机器不多,TaskManager不多,搞那么多slot,每个slot分到的内存小的可怜,容易OOM啊

  • 并行度的设置有多个地方:操作算子层面、执行环境层面、客户端层面、系统层面,具体可以参考:FLINK并行度;

算子层面具体情况具体分析,例如KafkaSource的并行度最好跟Kafka Topic的分区数成比例,比如:

1 val wordCounts = text
2    .flatMap{ _.split(" ") map { (_, 1) } }
3    .keyBy(0)
4    .timeWindow(Time.seconds(5))
5    .sum(1).setParallelism(5)

执行环境层面比如:

1 env.setParallelism(5)

提交任务的时候,在客户端侧flink可以通过-p参数来设置并行度。例如:

1 ./bin/flink run -p 5 ../examples/*WordCount-java*.jar

13. TaskManager数量

TaskManager的数量是在提交作业时根据并行度动态计算。先根据设定的operator的最大并行度计算,例如,如果作业中operator的最大并行度为10,则 Parallelism/numberOfTaskSlots为向YARN申请的TaskManager数。

14. Flink传递参数给函数

参数可以使用构造函数或withParameters(Configuration)方法传递,参数将会作为函数对象的一部分被序列化并传递到task实例中。

  • 使用构造函数方式

复制代码

 1 DataSet toFilter = env.fromElements(1, 2, 3);
 2 toFilter.filter(new MyFilter(2));
 3 private static class MyFilter implements FilterFunction {
 4   private final int limit;
 5   public MyFilter(int limit) {
 6     this.limit = limit;
 7   }
 8   @Override
 9   public boolean filter(Integer value) throws Exception {
10     return value > limit;
11   }
12 }

复制代码

(2)withParameters(Configuration)方式

这个方法将携带一个Configuration对象作为参数,参数将会传递给Rich Function的open方法(关于Rich Function参见:rich function)。Configuration对象是一个Map,存储Key/Value键值对.

复制代码

 1 DataSet toFilter = env.fromElements(1, 2, 3);
 2 Configuration config = new Configuration();
 3 config.setInteger("limit", 2);
 4 toFilter.filter(new RichFilterFunction() {
 5     private int limit;
 6     @Override
 7     public void open(Configuration parameters) throws Exception {
 8       limit = parameters.getInteger("limit", 0);
 9     }
10     @Override
11     public boolean filter(Integer value) throws Exception {
12       return value > limit;
13     }
14 }).withParameters(config);

复制代码

(3)使用全局的the ExecutionConfig方式

参数可以被所有的rich function获得

复制代码

 1 Configuration conf = new Configuration();
 2 conf.setString("mykey","myvalue");
 3 final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
 4 env.getConfig().setGlobalJobParameters(conf);
 5 public static final class Tokenizer extends RichFlatMapFunction> {
 6     private String mykey;
 7     @Override
 8     public void open(Configuration parameters) throws Exception {
 9       super.open(parameters);
10       ExecutionConfig.GlobalJobParameters globalParams = getRuntimeContext().getExecutionConfig().getGlobalJobParameters();
11       Configuration globConf = (Configuration) globalParams;
12       mykey = globConf.getString("mykey", null);
13     }
14     // ... more here ...

复制代码

15. Flink中的Metrics

Flink中有丰富的Metrics指标,当然我们也可以使用它的Reporter自定义,具体参见官网,示例如下:

复制代码

 1 import org.apache.flink.api.common.accumulators.LongCounter;
 2 import org.apache.flink.api.common.functions.RichMapFunction;
 3 import org.apache.flink.api.java.utils.ParameterTool;
 4 import org.apache.flink.configuration.Configuration;
 5 import org.apache.flink.dropwizard.metrics.DropwizardMeterWrapper;
 6 import org.apache.flink.metrics.Counter;
 7 import org.apache.flink.metrics.Meter;
 8 import org.apache.flink.metrics.MetricGroup;
 9 
10 
11 public class Map extends RichMapFunction<String, String> {
12   private transient Meter logTotalMeter;
13   private transient Counter logTotalConter;
14   private LongCounter logAcc = new LongCounter();
15 
16   @Override
17   public void open(Configuration parameters) throws Exception {
18     MetricGroup metricGroup = getRuntimeContext().getMetricGroup();
19     logTotalMeter = metricGroup.meter("logTotalMeter",
20         new DropwizardMeterWrapper(new com.codahale.metrics.Meter()));
21     logTotalConter = metricGroup.counter("logTotalConter");
22     getRuntimeContext().addAccumulator("logAcc", this.logAcc);
23   }
24 
25 
26   @Override
27   public String map(String log) throws Exception {
28     logTotalConter.inc();
29     logTotalMeter.markEvent();
30     logAcc.add(NumberUtil.LONG_ONE);
31     logMeter.mark();
32     return log;
33   }
34 }

复制代码

16. Flink中的table API

听了阿里军长的讲解后有所了解,简单做下笔记,以免忘记。table API和SQL有很多相同的优良特性,比如:

声明式-用户只关心做什么,不用关心怎么做;

高性能-支持查询优化,可以获取更好的执行性能;

流批统一-相同的统计逻辑,既可以流模式也可以批模式;

标准稳定-语义遵循SQL标准,不易变动

易理解-所见即所得

比如:

复制代码

1 // table API
2 tab.groupBy("word").select("word,count(1) as cnt")
3 
4 // SQL
5 SELECT COUNT(1) AS cnt
6 FROM tab
7 GROUP BY word

复制代码

总的来说,SQL有的功能table API都有,如下图所示

 

 环境配置如下

 

三种注册表的方式

三种发射表的方式

 

table API对列操作比较方便,比如

再比如有一张100列的表,选择1到10列怎么操作?

另外,table API的map函数扩展起来也很方便

 

 也可参考:Table API & SQL、Flink SQL-Client。

17. Flink中的内存管理

写这个也是有点心累的,搞了好久,也算对Flink Web UI上的几个内存指标大致了解了,老规矩记录下。所有程序都是绝对受人控制的,在提交任务那一刻,我们可以指定程序中使用的内存,例如:

1 ./bin/flink run -m yarn-cluster -yn 2 -yjm 1024 -ytm 1024 ./examples/batch/WordCount.jar

红色参数的具体含义是(参见Flink官网):

-yjm,--yarnjobManagerMemory <arg>    Memory for JobManager Container
                                          with optional unit (default: MB)
-ytm,--yarntaskManagerMemory <arg>   Memory per TaskManager Container
                                          with optional unit (default: MB)

 先上两个小图(这俩图我没找到原版出处,一直觉得这玩意坑爹,大概率上这里的JVM Heap包括了on-heap和off-heap,on-heap和off-heap下边有介绍)

 看图说话,TaskManager 的堆内存主要被分成了三个部分:

  • Network Buffers: 一定数量的32KB大小的 buffer,主要用于数据的网络传输。在 TaskManager 启动的时候就会分配。默认数量是 2048 个,可以通过 taskmanager.network.numberOfBuffers来配置。
  • Memory Manager Pool: 这是一个由 MemoryManager 管理的,由众多MemorySegment组成的超大集合。Flink 中的算法(如 sort/shuffle/join)会向这个内存池申请 MemorySegment,将序列化后的数据存于其中,使用完后释放回内存池。默认情况下,池子占了堆内存的 70% 的大小。
  • Remaining (Free) Heap: 这部分的内存是留给用户代码以及 TaskManager 的数据结构使用的。因为这些数据结构一般都很小,所以基本上这些内存都是给用户代码使用的。从GC的角度来看,可以把这里看成的新生代,也就是说这里主要都是由用户代码生成的短期对象。

⚠️注意:Memory Manager Pool 主要在Batch模式下使用。在Steaming模式下,该池子不会预分配内存,也不会向该池子请求内存块。也就是说该部分的内存都是可以给用户代码使用的。不过社区是打算在 Streaming 模式下也能将该池子利用起来。

从堆的角度来说,Flink当前的内存支持堆内(on-heap)和堆外(off-heap)管理,用户想去申请什么类型的内存,有相关的参数去配置。Flink off-heap的内存管理相对于on-heap的优点主要在于:

  • 启动分配了大内存(例如100G)的JVM很耗费时间,垃圾回收也很慢。如果采用off-heap,剩下的Network buffer和Remaining heap都会很小,垃圾回收也不用考虑MemorySegment中的Java对象了,节省了GC时间;
  • 有效防止OOM,MemorySegment大小固定,操作高效。如果MemorySegment不足写到磁盘,内存中的数据不多,一般不会发生OOM;
  • 更有效率的IO操作。在off-heap下,将MemorySegment写到磁盘或是网络可以支持zeor-copy技术,而on-heap的话则至少需要一次内存拷贝;
  • off-heap上的数据可以和其他程序共享。

好了概念讲了一通,看下任务TaskManager日志

复制代码

 1 2019-07-23 07:27:50,035 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -  Starting YARN TaskExecutor runner (Version: 1.7.1, Rev:<unknown>, Date:<unknown>)
 2 2019-07-23 07:27:50,035 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -  OS current user: yarn
 3 2019-07-23 07:27:50,436 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -  Current Hadoop/Kerberos user: worker
 4 2019-07-23 07:27:50,436 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -  JVM: Java HotSpot(TM) 64-Bit Server VM - Oracle Corporation - 1.8/25.112-b15
 5 2019-07-23 07:27:50,436 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -  Maximum heap size: 345 MiBytes
 6 2019-07-23 07:27:50,437 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -  JAVA_HOME: /usr/local/jdk/
 7 2019-07-23 07:27:50,438 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -  Hadoop version: 2.6.0-cdh5.5.0
 8 2019-07-23 07:27:50,438 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -  JVM Options:
 9 2019-07-23 07:27:50,438 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -     -Xms360m
10 2019-07-23 07:27:50,439 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -     -Xmx360m
11 2019-07-23 07:27:50,439 INFO  org.apache.flink.yarn.YarnTaskExecutorRunner                  -     -XX:MaxDirectMemorySize=664m

复制代码

红色的地方有几个值,Flink源码中这几个值的计算在TaskManagerServices.calculateHeapSizeMB(计算堆内内存大小)和calculateNetworkBufferMemory(计算堆外内存大小),下边我们来看默认情况下这些值怎么计算的(仅限Flink 1.7.1版本,其他版本系数可能有变化)。

1. JVM预留内存,总内存的25%,最小预留,600M:

1024MB - (1024 * 0.25 < 600MB) -> 600MB = 424MB (cutoff)

2. 剩下的内存的10%作为networkBuffer的内存,最小64M:

424MB - (424MB * 0.1 < 64MB) -> 64MB(networkbuffer) = 360MB 

3. 批作业的话剩下内存30%设为堆内内存,总内存减去堆内内存设为directMemory,流作业全部都是堆内内存了,用于netty和rocksDB和networkBuffer以及JVM自身内存。

这样360M和664M都明了了,那为啥一开始日志打印“Maximum heap size: 345 MiBytes”呢,这里还有一个小坑,先看Flink怎么计算的,

复制代码

 1     /**
 2      * The maximum JVM heap size, in bytes.
 3      * 
 4      * <p>This method uses the <i>-Xmx</i> value of the JVM, if set. If not set, it returns (as
 5      * a heuristic) 1/4th of the physical memory size.
 6      * 
 7      * @return The maximum JVM heap size, in bytes.
 8      */
 9     public static long getMaxJvmHeapMemory() {
10         final long maxMemory = Runtime.getRuntime().maxMemory();
11         if (maxMemory != Long.MAX_VALUE) {
12             // we have the proper max memory
13             return maxMemory;
14         } else {
15             // max JVM heap size is not set - use the heuristic to use 1/4th of the physical memory
16             final long physicalMemory = Hardware.getSizeOfPhysicalMemory();
17             if (physicalMemory != -1) {
18                 // got proper value for physical memory
19                 return physicalMemory / 4;
20             } else {
21                 throw new RuntimeException("Could not determine the amount of free memory.\n" +
22                         "Please set the maximum memory for the JVM, e.g. -Xmx512M for 512 megabytes.");
23             }
24         }
25     }

复制代码

它用了Java lang的方法,这就有问题了,问题在于JVM使用的GC算法都会有一些内存丢失,比如Survivor有两个,但只有1个会用到,另一个一直闲置,总有一块Survivor区是不被计算到可用内存中的。

到底是不是呢,我在Flink程序的Map函数中加了这么一段代码:

复制代码

1 logger.info("Runtime max: " + mb(Runtime.getRuntime().maxMemory()));
2 MemoryMXBean m = ManagementFactory.getMemoryMXBean();
3 
4 logger.info("Non-heap: " + mb(m.getNonHeapMemoryUsage().getMax()));
5 logger.info("Heap: " + mb(m.getHeapMemoryUsage().getMax()));
6 
7 for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) {
8   logger.info("Pool: " + mp.getName() + " (type " + mp.getType() + ")" + " = " + mb(mp.getUsage().getMax()));
9 }

复制代码

打印日志出来

复制代码

 1 2019-07-20 09:03:16,344 INFO  data.demo.core.example                             - Heap: 361758720 (345.00 M)
 2 2019-07-20 09:03:16,344 INFO  data.demo.core.example                             - Pool: PS Survivor Space (type Heap memory) = 15728640 (15.00 M)
 3 2019-07-20 09:03:16,344 INFO  data.demo.core.example                             - Pool: Code Cache (type Non-heap memory) = 251658240 (240.00 M)
 4 2019-07-20 09:03:16,344 INFO  data.demo.core.example                             - Pool: PS Old Gen (type Heap memory) = 251658240 (240.00 M)
 5 2019-07-20 09:03:16,344 INFO  data.demo.core.example                             - Pool: Metaspace (type Non-heap memory) = -1 (-0.00 M)
 6 2019-07-20 09:03:16,344 INFO  data.demo.core.example                             - Pool: Compressed Class Space (type Non-heap memory) = 1073741824 (1024.00 M)
 7 2019-07-20 09:03:16,344 INFO  data.demo.core.example                             - Pool: PS Eden Space (type Heap memory) = 94371840 (90.00 M)
 8 2019-07-20 09:03:16,344 INFO  data.demo.core.example                             - Pool: PS Survivor Space (type Heap memory) = 15728640 (15.00 M)
 9 2019-07-20 09:03:16,345 INFO  data.demo.core.example                             - Pool: PS Old Gen (type Heap memory) = 251658240 (240.00 M)
10 2019-07-20 09:03:16,345 INFO  data.demo.core.example                             - Runtime max: 361758720 (345.00 M)

复制代码

眼见为实,实锤了。

再看Flink TaskManager WebUI

有一些概念还要说下,比如JVM管理两种类型的内存:堆(heap)和非堆(Nonheap),堆就是Java代码可及的内存,所有类实例和数组的内存都是在堆上分配。非堆就是JVM留给自己用的,方法区、栈、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。

再比如Direct和Mapped,这俩是JVM缓冲池,主要是JNI使用。

 UI上的这些参数我们都可以通过Flink的Rest API拿到下面这些指标值,比如通过访问本地localhost:23799/taskmanagers/container_e37_1563420494990_0370_01_000009(具体参见Flink官网):

ScopeInfixMetricsDescription
Job-/TaskManagerStatus.JVM.MemoryMemory.Heap.Used当前使用的堆内存大小.
Heap.Committed保证JVM可用的堆内存大小.
Heap.Max可用于内存管理的堆内存最大值.
NonHeap.Used当前使用的非堆内存大小.
NonHeap.Committed保证JVM可用的非堆内存大小.
NonHeap.Max可用于内存管理的非堆内存最大值.
Direct.Count直接缓冲池中的缓冲区数量.
Direct.MemoryUsedJVM中用于直接缓冲池的内存大小.
Direct.TotalCapacity直接缓冲池中所有缓冲区的总容量.
Mapped.Count映射缓冲池中缓冲区的数量.
Mapped.MemoryUsedJVM中用于映射缓冲池的内存大小.
Mapped.TotalCapacity映射缓冲池中缓冲区的数量.

 

18. Flink中依赖配置

    每个Flink应用程序都依赖一组Flink库,至少应用程序依赖于Flink API。许多应用程序还依赖于某些连接器库(如Kafka,Cassandra等)。所以阅读了下官网依赖配置这一节的内容,简单记一下,Flink中有两大类依赖项和库:

  • Flink核心依赖:Flink本身由运行系统所需的一组类和依赖项组成,例如协调,网络,检查点,故障转移,API,操作(如窗口),资源管理等。所有这些这些类和依赖项构成了Flink运行时的核心,在启动Flink应用程序时必须存在。这些核心类和依赖项打包在flink-dist.jar中。它们是Flink lib文件夹的一部分。这部分不包含任何连接器或库(CEP,SQL,ML等),以避免默认情况下在类路径中具有过多的依赖项和类,保持默认的类路径较小并避免依赖性冲突。Maven(和其他构建工具)将依赖项打包时一般将核心依赖设为provided,如果它们未设置为provided,可能使生成的JAR包过大,还可能出现添加到应用程序的jar文件的Flink核心依赖项与用户自己的一些依赖版本冲突(可以通过反向类加载来避免);如果在IntelliJ IDEA中调试,则将scope设置为comiple,否则失败报NoClassDefFountError错;
  • 用户应用程序依赖: connectors, formats, or libraries(CEP, SQL, ML),用户应用程序通常打包到应用程序jar中。

     另外,当Flink程序读写HDFS时需要添加Hadoop依赖,不要把Hadoop依赖直接添加到Flink application,而是: export HADOOP_CLASSPATH=`hadoop classpath`,Flink组件启动时会使用该环境变量,这样做是因为:

  • 一些Hadoop交互发生在Flink的核心,可能在用户应用程序启动之前,例如为检查点设置HDFS,通过Hadoop的Kerberos令牌进行身份验证或在YARN上部署。
  • Flink的反向类加载方法隐藏了核心依赖关系中的许多传递依赖关系,应用程序可以使用相同依赖项的不同版本,而不会遇到依赖项冲突。

19. Flink单元测试指南

    参考:指南文档翻译

20. Flink读HDFS

    简单点说,读数据

1 DataSet<String> hdfslines=env.readTextFile("your hdfs path")

写数据

1 hdfslines.writeAsText("your hdfs path")

以上会根据你的默认的线程数来生成多少个分区文件,如果你想最后生成一个文件的话,可以在后面使用setParallelism(1),这样最后就只会生成一个文件了。具体可以这么整

复制代码

 1    try {
 2       String topic = args[0];
 3       String path = args[1];
 4       //读取配置文件
 5       Configuration conf = new Configuration();
 6       //获取文件系统
 7       FileSystem fs = FileSystem.get(URI.create("/"), conf);
 8 
 9       System.out.println(fs.getUri());
10       if (!fs.getUri().toString().contains("hdfs")) {
11         path = "hdfs://localhost:8020" + path;
12       }
13 
14       ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
15       DataSet<String> union = env.readTextFile(fs.getUri() + path + "/").setParallelism(20);
16 
17       union.rebalance().setParallelism(15).map(new MapFunction<String, String>() {
18         private static final long serialVersionUID = 1033071381217373267L;
19 
20         @Override
21         public String map(String rawLog) throws Exception {
22           return rawLog;
23         }
24       }).output(new DiscardingOutputFormat<>())
25           .setParallelism(20);
26       try {
27         env.execute();
28       } catch (Exception e) {
29         e.printStackTrace();
30       }
31 
32       //关闭文件系统
33       fs.close();
34     } catch (Exception e) {
35       logger.error("task submit process error, due to {}.", e.getMessage());
36       e.printStackTrace();
37     }

复制代码

 path是传入的目录,比如/user/rawlog/hourly/2019-09-15/09

【Flink】Flink内存调优 基于 JVM 内存存在一些问题,并且在大数据场景下,无法在内存中存储海量数据,计算效率无法提高。Flink 社区采用自主内存管理设计,设计了两种内存模型 JobManager 内存模型和 TaskManager 内存模型。 阅读详情

相关推荐

Flink学习笔记(二):Flink内存模型

Flink JVM 进程的进程总内存(Total Process Memory)包含了由 Flink 应用使用的内存(Flink 总内存)以及由运行 Flink 的 JVM 使用的内存。Flink 总内存(Total Flink Memory)包括 JVM 堆内存(Heap Memory)和堆外内存(Off-Heap Memory)。如配置总内存中所述,另一种配置 JobManager 内存的方式是明确指定 JVM 堆内存的大小(jobmanager.memory.heap.size)。

u011047968的专栏 3459

flink 常用算子之map、filter和flatMap

Transformation各算子可以对Flink数据流进行处理和转化,是Flink流处理非常核心的API。 map map算子对一个DataStream中的每个元素使用用户自定义的map函数进行处理,每个输入元素对应一个输出元素,最终整个数据流被转换成一个新的DataStream。输出的数据流DataStream[OUT]类型可能和输入的数据流DataStream[IN]不同。 如业务需求可以对一些数据进行拼接字符,倍数扩大等场景使用。 我们可以重写MapFunction或RichMapFun

dongxiexiaoadou的博客 4910

Flink部署——内存配置

Apache Flink 基于 JVM 的高效处理能力,依赖于其对各组件内存用量的细致掌控。 考虑到用户在 Flink 上运行的应用的多样性,尽管社区已经努力为所有配置项提供合理的默认值,仍无法满足所有情况下的需求。 为了给用户生产提供最大化的价值, Flink 允许用户在整体上以及细粒度上对集群的内存分配进行调整。为了优化内存需求,参考网络内存调优指南。本文接下来介绍的内存配置方法适用于 1.10 及以上版本的 TaskManager 进程和 1.11 及以上版本的 JobManager 进程。 Flin

京河小蚁的博客 9378

一图明白:flatMap和map的区别

一图明白:flatMap和map的区别 一map:对每一个元素进行操作 比如:(“a”,“b”,“c”,“d”) 需要对它加个”#“ ,就是每个元素都加在后面加个”#“ (“a#”,“b#”,“c#”,“d#”) 二flatMp:简单来说就是切分单词的,把一个单词分成两份 ...

weixin_42272887的博客 1806

flink任务内存调优,TaskManager、JobManager内存配置

Flink是基于java的JVM运行,拥有高效的数据处理能力,但是考虑到用户在 Flink 上运行的应用的多样性,尽管flink框架已经为所有配置项提供合理的默认值,仍无法满足所有情况下的需求。 flink进程总内存、taskmanager内存、jobmanager内存配置...

weixin_47019045的博客 7999

flink 内存配置(一):设置Flink进程内存

Apache Flink通过严格控制各个组件的内存使用,在JVM之上提供了高效的工作负载。虽然Flink社区努力为所有配置提供合理的默认值,但由于用户部署在Flink上的应用范围很广,这并不总是可行的。为了给用户提供最大的生产价值,Flink支持对集群内的内存分配进行高层和细粒度的调优。下面进一步描述的内存配置适用于1.10版本之后的TaskManager进程和1.11版本之后的JobManager进程。

chanyue123的博客 1516

map 和 flatMap 区别

区别 这两个在本质上是一样的,都是 map 操作,即对流形式的传入数据进行处理返回一个数据。但是区别方面从字面上就可以体现出来,flatMap 比 map 多了一个 flat 操作,也就是 “展平/扁平化” 处理的意思。 所以 flatMap 是一个 map 和一个 flat 操作的组合。其首先将一个函数应用于元素,然后将其展平,当你需要将 [[a,b,c],[d,e,f],[x,y,z]] 具有两个级别的数据结构转换为 [a,b,c,d,e,f,x,y,z] 这样单层的数据结构时,就选择使用 flatMa

小单的博客专栏 2万+

【Flink】Flink TaskManager 内存如何计算、TaskManager每个部分的内存怎么计算

距离上一次搞内存已经很久了,今天打算再次学一下。Flink 1.10对 Task Manager 内存模型做了较大改动Flink使用了堆上内存和堆外内存框架堆外内存、Task堆外内存、网络缓冲内存,都在堆外的直接内存里Flink使用内存=框架堆内和堆外内存+Task堆内和堆外内存 +网络缓冲内存+管理内存逃程内存=Flink内存+JVM特有内存首先要知道一点就是FLink是既能使用堆内存、又能使用堆外内存的。

九师兄 464

Flink从入门到放弃—Stream API—常用算子(map和flatMap)

flink map和flatmap算子源码解析

京河小蚁的博客 1870

sap销售发货的流程_SAP销售订单发货后如何实现发票的自动创建?

问SAP销售订单发货后如何实现发票的自动创建?答业务场景有些快消零售企业,SAP系统单据量大,单据金额少,一般在销售发货后即可确认收入。此时无需人工在系统内操作VF01或者VF04进行开票操作,可将该操作设置成后台作业进行自动批量开票,具体操作如下:1、定义任务:VF06输入完以上信息,点击保存进入以下界面:说明:当前日期的意思是“开票的日期”等于“系统电脑中的当前日期”当前日期+/-...

weixin_42358409的博客 3370

IPMItool 控制风扇转速

然后手动设置风扇,最后一位0x1e为设置30%的转速(16进制)。最后4位 0x0f 表示15%,0x0a,表示10%,不建议小于10%,因为10%已经很静音了 如果再小怕不能控温,烧毁硬件。首先停止服务器的自动风扇控制,最后一位0x00表示停止自动风扇控制,0x01为开启自动风扇控制。首先开启主板上的ipmi 设置好 用户名密码。此过程可以在网上搜索,有很多的资料可以参考。解压只有在目录里面有ipmltool。下面是一些常用的修改温度命令。

m0_37970303的博客 5063

Flink系统知识讲解之:Flink内存管理详解

Flink系统知识讲解之:Flink内存管理详解

大数据开发、JAVA开发、人工智能AI 2539

关于keil编译报.sct (7): error: L6236E: No section matches selector - no section to be FIRST/LAST.处理方法

使用keilUvision5向下兼容,选择S3C2440主款芯片编译运行汇编语言。 出现了一个错误: . \objectslex3-2.sct (7): error: L6236E: No section matches selector - no section to be FIRST/LAST. 我在网上搜了很多,没有找到适合修正我这里的错误的。故咨询陈老师,终于将这个错误解决。 错误如下: 修改过程: 打开小仙女棒 将linker的Use Memory Layout fromTarget Dial

weixin_45865666的博客 9526

【Flink实战】Flink网络内存和托管内存

【Flink实战】Flink网络内存和托管内存

hiliang521的博客 1323

Modelsim安装教程以及管理员身份运行patch_dll.bat时找不到文件mgls.dll的解决

Modesim安装教程 Modesim版本有很多,但是安装方式大都相同,我们以modesim.10.5为例,电脑使用的是win10 64位,讲一下安装过程中的步骤以及出现问题的解决方法 一 安装 1.首先解压安装包,在解压的安装包内选择应用程序,右键选择管理员运行。 2.稍等一会,有的电脑会弹出是否允许modesim进行更改,选择 是 即可,然后出现下面的界面,点击下一步。 3.弹出此界面选择安装路径,选择安装路径,我是在D盘新建的文件夹,直接把文件夹中的路径复制在框内。文件夹名称切记不要带中文 4.

weixin_48564372的博客 1万+

7、PPG信号处理与质量评估

本文详细介绍了PPG信号的处理与质量评估方法,包括信号滤波技术(如卷积和互相关)、滤波器选择、信号质量指标(SQI)的定义与应用,以及标注一致性的评估。同时,提供了MATLAB代码示例和操作步骤,并分析了不同指标的优势与适用场景,旨在提高PPG信号在诊断和监测中的准确性与可靠性。

salt的博客 256

【Flink 核心篇】Flink 内存管理(一):设置 Flink 进程内存

Apache Flink 通过严格控制各种组件的内存使用,在 JVM 上提供高效的工作负载。虽然社区努力为所有配置提供合理的默认值,但用户在 Flink 上部署的应用程序种类繁多,这意味着这并非总是可行。为了向用户提供最大的生产价值,Flink 允许对集群内的内存分配进行高级和精细调整。

Data · Model · Agent · Repeat 3919

Windows 下 Hermes Agent(爱马仕)安装全记录:从零到一的保姆级图文教程

本文主要介绍了Windows 下 Hermes Agent(爱马仕) 安装全记录:从零到一的保姆级图文教程,希望能对学习使用 Hermes Agent 的同学们有所帮助。 文章目录 1. 背景 2. 实战教程 2.1 步骤一 安装WSL环境 2.2 步骤二 安装Python环境 2.3 步骤三 安装Hermes Agent 2.4 步骤四 修正 API Key 错误 2.5 步骤五 配置多个模型 2.6 步骤六 启动Hermes Agent 3. 常见问题及解决方案 4. 总结

weixin_43178406的博客 14万+

Flink之Flink中内存模型全详解

Flink之Flink中内存模型全详解

luoyepiaoxue2014的博客 1681

【AI黑话日日新】什么是算力调度?

算力调度 = 在有限资源下,把任务智能分配到最合适的计算节点,实现效率、成本、稳定性最优。更完整的定义:算力调度是对 CPU、GPU、内存、网络、存储等异构资源进行统一抽象、感知、决策、分配、监控与自愈的全生命周期管理,是分布式系统的“智能管家”。算力调度不是玄学,它是资源管理 + 算法 + 工程实践的结合。先懂概念 → 再玩工具 → 再写策略 → 再优化算法从单机到集群,从CPU到GPU,从离线到在线,循序渐进未来AI与算力网络时代,算力调度是性价比最高、最稀缺、最长期吃香的技术方向之一。

专注:太空算力、AI infra、异构调度、大模型成本工程 268

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Flink是如何管理内存的

在讲Flink管理内存之前要了解下Flink为什么要自己实现内存管理 一、Flink为什么要自己实现内存管理 在大数据领域,大多数数据相关的开源框架(Hadoop、Spark、Storm)都是基于JVM运行的,但是JVM的内存管理机制往往存在着诸多类似OutOfMemoryError的问题,主要是因为创建过多的对象实例而超过JVM的最大堆内存限制,却没有被有效回收掉,这在很大程度上影响了系统的稳定性,尤其对于大数据应用,面对大量的数据对象产生,仅仅靠JVM所提供的各种垃圾回收机制很难解决内存溢出的问题。

星空的风fly 3232

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Flink内存优化

flink 分别提供了通用和细粒度的内存配置,来满足不同用户的需求。 一、Flink内存模型 Total Process Memory: 包括 flink 应用消耗的内存(Total Flink Memory) 和 JVM 消耗的内存 Total Flink Memory: 包括 JVM heap, managed memory 和 direct memory 如果用户只是使用了 local 模式运行 flink(比如通过idea),那么只有部分内存配置是生效的,具体配置后面有讲到。 对于集群上

lixinkuan的博客 2459

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【内存模型】Flink内存模型:从宏观(Flink内存模型)、微观(Flink内存结构)、数据传输等角度分析Flink的内存管理

我们首先先从Flink的不同角色看一下Flink的内存管理,然后在微观的看一下Flink的内存管理器和数据模型,最后再观察下数据传输时的内存管理。

hiliang521的博客 5245

flink的TaskManager 内存模型

Flink TaskManager 的内存模型是一个多层管理体系,从 JVM 进程到具体任务的内存分配均有明确的逻辑划分和配置策略。

jiedaodezhuti的博客 1389

Flink内存配置

通过本文可以解决以下3个问题。

初阳 1307
上一篇: Flink 容错机制与状态
下一篇: Elasticsearch-6.x 倒排索引,doc_values,Fielddata, store研究
王树民
博客等级 码龄10年 912粉丝 560原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值