项目pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.jike.flink</groupId>
<artifactId>flink-demo</artifactId>
<version>1.0-SNAPSHOT</version> <properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<encoding>UTF-8</encoding>
<flink.version>1.10.0</flink.version>
</properties> <dependencies>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>${flink.version}</version>
</dependency> <dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_2.11</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency> <!-- flink 11中需要手动添加
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients_2.11</artifactId>
<version>1.11.2</version>
</dependency>
--> <dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-redis_2.11</artifactId>
<version>1.1.5</version>
<scope>system</scope>
<systemPath>${basedir}/lib/flink-connector-redis_2.11-1.1.5.jar</systemPath>
</dependency> <dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
<scope>compile</scope>
</dependency> </dependencies> </project>

实现flink写入redis

实现wordcount功能,并将结果实时写入redis,这里使用了第三方依赖flink-connector-redis_2.11,该依赖提供了RedisSink可以直接使用,具体代码如下:

代码

首先定义数据源处理实现类LineSplitter,该类将一行数据分词,输出<单词,1>元祖

package com.jike.flink.examples.redis;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.util.Collector; public class LineSplitter implements FlatMapFunction<String, Tuple2<String,Integer>> {
public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) throws Exception {
String[] tokens = s.toLowerCase().split("\\W+");
for(String token : tokens){
if(token.length() > 0){
collector.collect(new Tuple2<String,Integer>(token,1));
}
}
}
}

然后定义数据写入Redis的配置类,这里面将统计后的所有信息词频写入一个哈希表,哈希表的key为"flink",作为测试使用,哈希表中每个元素key为单词,value为词频

package com.jike.flink.examples.redis;

import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.connectors.redis.common.mapper.RedisCommand;
import org.apache.flink.streaming.connectors.redis.common.mapper.RedisCommandDescription;
import org.apache.flink.streaming.connectors.redis.common.mapper.RedisMapper; public class SinkRedisMapper implements RedisMapper<Tuple2<String,Integer>> {
@Override
public RedisCommandDescription getCommandDescription() {
//hset
return new RedisCommandDescription(RedisCommand.HSET,"flink");
} @Override
public String getKeyFromData(Tuple2<String, Integer> stringIntegerTuple2) {
return stringIntegerTuple2.f0;
} @Override
public String getValueFromData(Tuple2<String, Integer> stringIntegerTuple2) {
return stringIntegerTuple2.f1.toString();
}
}

最后编写主程序类,该类中使用了socketTextStream数据源,通过前面定义LineSplitter完成解析,然后根据单词进行分组统计,最后写入redis


package com.jike.flink.examples.redis; import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.api.java.tuple.Tuple2;
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.connectors.redis.RedisSink;
import org.apache.flink.streaming.connectors.redis.common.config.FlinkJedisPoolConfig; public class Sink2Redis {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment executionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment();
DataStreamSource<String> dataStreamSource = executionEnvironment.socketTextStream("实际IP",12345);
DataStream<Tuple2<String,Integer>> counts = dataStreamSource.flatMap(new LineSplitter()).keyBy(new KeySelector<Tuple2<String, Integer>, String>() {
public String getKey(Tuple2<String, Integer> stringIntegerTuple2) throws Exception {
return stringIntegerTuple2.f0;
}
}).sum(1);
//控制台打印
counts.print().setParallelism(1);
//定义redis服务器信息
FlinkJedisPoolConfig conf = new FlinkJedisPoolConfig.Builder().setHost("redis服务器ip").setPort(redis服务端口).setPassword("redis服务密码").build();
counts.addSink(new RedisSink<>(conf,new SinkRedisMapper()));
executionEnvironment.execute();
}
}

运行效果

通过nc -l 12345,命令模拟数据源,并输入一些数据

IDEA中查看打印记录

查看redis

可以发现数据已写入redis

总结

flink-connector-redis_2.11中提供了RedisSink类,该类实现了RichSinkFunction,可以直接使用,如果有特殊需求,可以自定义Sink类,继承RichSinkFunction,实现特殊处理。flink-connector-redis_2.11的源码比较简洁,下一篇打算分析学习下。

Flink读写Redis(一)-写入Redis的更多相关文章

  1. Flink读写Redis(三)-读取redis数据

    自定义flink的RedisSource,实现从redis中读取数据,这里借鉴了flink-connector-redis_2.11的实现逻辑,实现对redis读取的逻辑封装,flink-connec ...

  2. Flink读写Redis(二)-flink-redis-connector代码学习

    源码结构 RedisSink package org.apache.flink.streaming.connectors.redis; import org.apache.flink.configur ...

  3. Redis学习笔记~Redis主从服务器,读写分离

    回到目录 Redis这个Nosql的存储系统一般会被部署到linux系统中,我们可以把它当成是一个数据服务器,对于并发理大时,我们会使用多台服务器充当Redis服务器,这时,各个Redis之间也是分布 ...

  4. redis作为缓存场景使用,内存耗尽时,突然出现大量的逐出,在这个逐出的过程中阻塞正常的读写请求,导致 redis 短时间不可用

    redis 突然大量逐出导致读写请求block   内容目录: 现象 背景 原因 解决方案 ref 现象 redis作为缓存场景使用,内存耗尽时,突然出现大量的逐出,在这个逐出的过程中阻塞正常的读写请 ...

  5. flink04 -----1 kafkaSource 2. kafkaSource的偏移量的存储位置 3 将kafka中的数据写入redis中去 4 将kafka中的数据写入mysql中去

    1. kafkaSource 见官方文档 2. kafkaSource的偏移量的存储位置 默认存在kafka的特殊topic中,但也可以设置参数让其不存在kafka的特殊topic中   3   将k ...

  6. 批量写入redis

    批量写入redis key := GetSeriesKey(series.Id) idNames = append(idNames, key, series.Name) == { err = Mset ...

  7. ELKStack入门篇(三)之logstash收集日志写入redis

    1.部署Redis 1.1.下载redis [root@linux-node2 ~]# wget http://download.redis.io/releases/redis-4.0.6.tar.g ...

  8. ELK之logstash收集日志写入redis及读取redis

    logstash->redis->logstash->elasticsearch 1.安装部署redis cd /usr/local/src wget http://download ...

  9. Redis原子性写入HASH结构数据并设置过期时间

    Redis中提供了原子性命令SETEX或SET来写入STRING类型数据并设置Key的过期时间: > SET key value EX NX ok > SETEX key value ok ...

随机推荐

  1. 金九银十已到!Cookie 和 Session的这些知识你必须知道,面试必问!

    前言 会话:一次会话中包含多次请求和响应 注:一次会话表示浏览器第一次给服务器发送请求,会话建立,直到有一方断开为止 功能:在一次会话的多次请求间共享数据 方式: (1) 客户端会话技术:Cookie ...

  2. .Net orm 开源项目 FreeSql 2.0.0(满意的答卷)

    写在开头 2018年11月头脑发热到今天,一晃已经两年,当初从舒服区走向一个巨大的坑,回头一看后背一凉. 两年时间从无到有,经历数不清的日夜奋斗(有人问花了多长时间投入,答案:全职x2 + 两年无休息 ...

  3. Folx使用教程:怎么通过设置标签分类下载内容

    很多Mac OS下载软件从网上下载各种各样的文件,一般默认都会存放在"下载"文件夹中.如果不是经常整理"下载"文件夹,久而久之,该文件夹会变得庞大而杂乱. 如果 ...

  4. Cypress系列(93)- Cypress.dom 命令详解

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 作用 与 DOM 元素相关的 helpe ...

  5. 「LOJ 537」「LibreOJ NOIP Round #1」DNA 序列

    description NOIP 复赛之前,HSD 桑进行了一项研究,发现人某条染色体上的一段 DNA 序列中连续的\(k\)个碱基组成的碱基序列与做题的 AC 率有关!于是他想研究一下这种关系. 现 ...

  6. Luogu P43916 图的遍历

    我们把"u点能够到达的最大点"转化为反向图中能到达u点的所有点里的最大值,可知缩点后满足无后效性.val[i]的初值设为连通分量i中的最大点.反向存图,tarjan缩点,拓扑序dp ...

  7. Django 的F查询与Q查询,事物

           F查询 Django 提供 F() 来做这样的比较.F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值 示例1: 查询出卖出数大于库存数的商品 from ...

  8. javascript开发后端程序的神器nodejs

    目录 简介 nodejs的历史 nodejs简介 nodejs的运行环境 process 终止进程 env argv CLI交互 exports模块 nodejs API nodejs的框架 简介 j ...

  9. PyQt(Python+Qt)学习随笔:Qt Designer中spacer部件的sizeHint属性

    在两种Spacer部件中都有sizeHint属性,在<PyQt(Python+Qt)学习随笔:Qt Designer中部件的三个属性sizeHint缺省尺寸.minimumSizeHint建议最 ...

  10. Python实现自动整理文件

    前言 工作上的文档和资料好几个月没整理了,因为平常太忙都是随手往桌面丢.整个桌面杂乱无章全是文档和资料.几乎快占满整个屏幕了,所有我必须要整理一下了.但是手动整理太费时间了,于是我想到了python. ...