实战:Flink 1.12 维表 Join Hive 最新分区功能体验
余东@哗啦啦 Flink 中文社区
我们生产常有将实时数据流与 Hive 维表 join 来丰富数据的需求,其中 Hive 表是分区表,业务上需要关联上 Hive 最新分区的数据。上周 Flink 1.12 发布了,刚好支撑了这种业务场景,我也将 1.12 版本部署后做了一个线上需求并上线。对比之前生产环境中实现方案,最新分区直接作为时态表提升了很多开发效率,在这里做一些小的分享。
Flink 1.12 前关联 Hive 最新分区方案
Flink 1.12 关联 Hive 最新分区表
关联Hive最新分区 Demo
Flink SQL 开发小技巧
Flink 1.12 前关联 Hive 最新分区方案
在分区时态表出来之前,为了定期关联出最新的分区数据,通常要写 DataStream 程序,在 map 算子中实现关联 Hive 最新分区表的逻辑,得到关联打宽后的 DataStream 对象,通过将该 DataStream 对象转换成 Table 对象后,再进行后续的 SQL 业务逻辑加工。
StreamTableEnvironment tblEnv = StreamTableEnvironment.create(env, streamSettings);
DataStream> indexBeanStream = masterDataStream.map(new IndexOrderJoin());
map 算子中的主要逻辑: 将 T+2 的维度数据与实时数据关联,返回 Tuple2 数据,因为离线数仓出数一般在凌晨 3 点,有时候由于集群资源不稳定导致数据产出慢,业务对实时性要求也不高,所以这里用的是 T+2 的数据。
public class IndexOrderJoin extends RichMapFunction> {
private Map> map = null;
Logger logger;
@Override
public void open(Configuration parameters) throws Exception {
logger = LoggerFactory.getLogger(Class.forName("com.hll.util.IndexOrderJoin"));
map = new HashMap<>();
}
public Tuple2 map(MasterBean masterBean) {
if (map.get(masterBean.getReportDate() - 2) == null) {
//如果map里没有T+2的维表数据则查询一次Hive,并将结果存入线程级别map,所以保证Task维表数据是全的
logger.info("initial hive data : {}", masterBean.getReportDate());
map.put(masterBean.getReportDate() - 2, getHiveDayIndex(masterBean.getReportDate() - 2));
}
//将的kafka数据与hive join后返回打宽数据
return new Tuple2<>(masterBean, map.get(masterBean.getReportDate() - 2).get(masterBean.getGroupID()));
}
基于关联打宽后的 DataStream 创建视图,然后再做后续的 SQL 业务逻辑查询。
tblEnv.createTemporaryView("index_ord