distribuído cache
Flink fornece um cache distribuído, Hadoop semelhante, o usuário pode facilmente ler função no arquivo local paralelo, e colocá-lo nó taskmanager, para evitar a tarefa de puxar repetido. Este mecanismo de cache é a seguinte: para registrar um arquivo ou diretório (sistemas de arquivos locais ou remotos, tais como hdfs ou S3), arquivos de cache e registrado pelo ExecutionEnvironment-se um nome para ele.
Quando o programa é executado, Flink automaticamente copiar arquivos ou diretórios para o sistema de arquivos local taskmanager todos os nós só será executada uma vez. Os usuários podem encontrar o arquivo ou diretório especificado pelo nome e, em seguida, acessá-lo a partir do nó taskmanager sistema de arquivos local.
Na verdade, o cache distribuído é equivalente a transmitir a centelha, para uma transmissão variável para todo o executor, ele também pode ser visto no fluxo de transmissão Flink, mas aqui é um arquivo de transmissão.
Exemplos
Passo 1: Registrar um arquivo, o arquivo pode ser usado em hdfs também podem ser arquivos locais para testes
Passo 2: Use Arquivo
Nota:
Acesse o arquivo de cache ou diretório na função de usuário (aqui é uma função de mapa). Esta função deve herdar RichFunction, porque requer o uso RuntimeContext para ler os dados:
Distribuído código java Cache é a seguinte:
/**
* <p/> DataSet 分布式缓存 </li>
* <li>@author: li.pan</li>
* <li>Date: 2019/12/29 16:10 下午</li>
* <li>Version: V1.0</li>
* <li>Description: </li>
*/
public class JavaDataSetDistributedCacheApp {
public static void main(String[] args) throws Exception {
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
String filePath = "file:///Users/lipan/workspace/flink_demo/flink-local-train/src/main/resources/sink/java/cache.txt";
// step1: 注册一个本地/HDFS文件
env.registerCachedFile(filePath, "lp-java-dc");
DataSource<String> data = env.fromElements("hadoop","spark","flink","pyspark","storm");
data.map(new RichMapFunction<String, String>() {
List<String> list = new ArrayList<String>();
// step2:在open方法中获取到分布式缓存的内容即可
@Override
public void open(Configuration parameters) throws Exception {
File file = getRuntimeContext().getDistributedCache().getFile("lp-java-dc");
List<String> lines = FileUtils.readLines(file);
for(String line : lines) {
list.add(line);
System.out.println("line = [" + line + "]");
}
}
@Override
public String map(String value) throws Exception {
return value;
}
}).print();
}
}
Distribuído código scala Cache é a seguinte:
/**
* <p/>
* <li>title: DataSet 分布式缓存</li>
* <li>@author: li.pan</li>
* <li>Date: 2019/11/23 2:15 下午</li>
* <li>Version: V1.0</li>
* <li>Description:
* step1: 注册一个本地/HDFS文件
* step2:在open方法中获取到分布式缓存的内容即可
* </li>
*/
object DistributedCacheApp {
def main(args: Array[String]): Unit = {
val env = ExecutionEnvironment.getExecutionEnvironment
val filePath = "file:///Users/lipan/workspace/flink_demo/flink-local-train/src/main/resources/sink/scala/cache.txt"
// step1: 注册一个本地/HDFS文件
env.registerCachedFile(filePath, "pk-scala-dc")
import org.apache.flink.api.scala._
val data = env.fromElements("hadoop", "spark", "flink", "pyspark", "storm")
data.map(new RichMapFunction[String, String] {
// step2:在open方法中获取到分布式缓存的内容即可
override def open(parameters: Configuration): Unit = {
val dcFile = getRuntimeContext.getDistributedCache().getFile("pk-scala-dc")
val lines = FileUtils.readLines(dcFile) // java
/**
* 此时会出现一个异常:java集合和scala集合不兼容的问题
*/
import scala.collection.JavaConverters._
for (ele <- lines.asScala) {
println(ele)
}
}
override def map(value: String): String = value
}).print()
}
}
Acumulador (acumuladores)
Acumuladores (acumulador) é muito simples, o resultado acumulação final em uma operação de adição, o resultado final pode ser adquirida na execução do trabalho.
O mais simples é o contador de acumulador (contador): Pode ser incrementado por Accumulator.add (valor V), este método. Mesclando todos os resultados no final da tarefa, flink, então, enviar os resultados finais para o cliente. Acumulador na depuração ou se você quiser entender rapidamente quando os seus dados é muito útil.
Há built-bit acumulador Flink, cada um acumulador de ter alcançado interface do acumulador. IntCounter, LongCounter e DoubleCounter: O que se segue é um exemplo de um contador utilizado. Por exemplo: distribuído programa de contagem de palavras.
exemplo:
Passo 1: Criar uma transformação personalizada onde você quer usar operadores para criar objetos em um operador acumulador.
val counter = new LongCounter()
Passo 2: o acumulador registar o objecto, que é geralmente uma função do método aberto rico. Aqui você também pode definir um nome
getRuntimeContext.addAccumulator("ele-counts-scala", counter)
Passo 3: Utilizar este acumulador operação
counter.add(1)
Passo 4: O resultado final global irá ser armazenada no objecto devolvido a partir JobExecutionResult executar () na. (Esta operação tem de aguardar a conclusão da execução da tarefa)
val num = jobResult.getAccumulatorResult[Long]("ele-counts-scala")
código acumulador Java é a seguinte:
/**
* <p/>
* <li>title: flink 计数器</li>
* <li>@author: li.pan</li>
* <li>Date: 2019/12/29 2:59 下午</li>
* <li>Version: V1.0</li>
* <li>Description:
* Java实现通过一个add操作累加最终的结果,在job执行后可以获取最终结果
* </li>
*/
public class JavaCounterApp {
public static void main(String[] args) throws Exception {
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
DataSource<String> data = env.fromElements("hadoop","spark","flink","pyspark","storm");
DataSet<String> info = data.map(new RichMapFunction<String, String>() {
LongCounter counter = new LongCounter();
@Override
public void open(Configuration parameters) throws Exception {
super.open(parameters);
getRuntimeContext().addAccumulator("ele-counts-java", counter);
}
@Override
public String map(String value) throws Exception {
counter.add(1);
return value;
}
});
String filePath = "file:///Users/lipan/workspace/flink_demo/flink-local-train/src/main/resources/sink/java/";
info.writeAsText(filePath, FileSystem.WriteMode.OVERWRITE).setParallelism(2);
JobExecutionResult jobResult = env.execute("CounterApp");
// step3: 获取计数器
long num = jobResult.getAccumulatorResult("ele-counts-java");
System.out.println("num = [" + num + "]");
}
}
código acumulador Scala é a seguinte:
/**
* <p/>
* <li>Description: flink 计数器</li>
* <li>@author: panli@[email protected]</li>
* <li>Date: 2019-04-14 21:53</li>
* Scala实现通过一个add操作累加最终的结果,在job执行后可以获取最终结果
*/
object CountApp {
def main(args: Array[String]): Unit = {
val env = ExecutionEnvironment.getExecutionEnvironment
val data = env.fromElements("hadoop", "spark", "flink", "pyspark", "storm")
val info = data.map(new RichMapFunction[String, String]() {
// step1:定义计数器
val counter = new LongCounter()
override def open(parameters: Configuration): Unit = {
// step2: 注册计数器
getRuntimeContext.addAccumulator("ele-counts-scala", counter)
}
override def map(in: String): String = {
counter.add(1)
in
}
})
val filePath = "file:///Users/lipan/workspace/flink_demo/flink-local-train/src/main/resources/sink/scala/"
info.writeAsText(filePath, WriteMode.OVERWRITE).setParallelism(2)
val jobResult = env.execute("CounterApp")
// step3: 获取计数器
val num = jobResult.getAccumulatorResult[Long]("ele-counts-scala")
println("num: " + num)
}
}