flink+es实战优化

Flink应用场景:社交应用中同步用户信息到ES 目前公司社交应用“暖聊”中的首页推荐等用户匹配功能,都是基于 es 算法实现,那么就需要将用户数据实时同步到 es。项目中操作 es 的方式是基于 jpa 框架直连操作 es,当用户信息变更时,通过 jpa 的 save 方法实时同步用户数据到 es。这样做的后果就是,es 更新频繁,在用户活跃高峰期,es 服务器 IO、CPU 都面临巨大的压力,甚至会直接影响线上功能的正常使用,同步 es 的方式调整优化迫在眉睫。 阅读详情
package com.juege.business;

import org.apache.flink.api.common.state.ListState;
import org.apache.flink.api.common.state.ListStateDescriptor;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.runtime.state.FunctionInitializationContext;
import org.apache.flink.runtime.state.FunctionSnapshotContext;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.JsonNode;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.flink.streaming.api.checkpoint.CheckpointedFunction;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.http.HttpHost;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class ElasticsearchScrollSourceFunction<T> implements SourceFunction<T>, CheckpointedFunction {

    private final String host;
    private final int port;
    private final String index;
    private final String type;
    private final String query;

    private volatile boolean isRunning = true;
    private volatile String scrollId;

    // 缓存列表和计数器
    private transient List<T> cacheList;
    private transient int count = 0;

    // 保存当前 Scroll ID 的状态后端
    private transient ListState<String> checkpointedState;

    public ElasticsearchScrollSourceFunction(String host, int port, String index, String type, String query) {
        this.host = host;
        this.port = port;
        this.index = index;
        this.type = type;
        this.query = query;
    }

    @Override
    public void run(SourceContext<T> ctx) throws Exception {
        // 创建 Elasticsearch 客户端
        RestClient client = RestClient.builder(new HttpHost(host, port)).build();

        Map<String, String> params = new HashMap<>();
        params.put("scroll", "1m");

        // 第一次查询,获取 Scroll ID
        Request request = new Request("POST", "/" + index + "/" + type + "/_search");
        request.setJsonEntity(query);
        Response response = client.performRequest(request);
        String responseBody = EntityUtils.toString(response.getEntity());
        JsonNode jsonNode = new ObjectMapper().readTree(responseBody);
        scrollId = jsonNode.get("_scroll_id").asText();

        while (isRunning) {
            // 使用 Scroll API 进行分页查询
            request = new Request("POST", "/_search/scroll");
            request.addParameter("scroll", "1m");
            request.setJsonEntity(scrollId);
            response = client.performRequest(request);
            responseBody = EntityUtils.toString(response.getEntity());

            // 解析查询结果并将数据添加到缓存列表中
            List<T> dataList = parseData(responseBody);
            if (dataList != null && !dataList.isEmpty()) {
                cacheList.addAll(dataList);
                count += dataList.size();
            }

            // 如果达到缓存阈值或者到达 Checkpoint,则将缓存中的数据发送出去
            if (count >= 10000) {
                for (T data : cacheList) {
                    ctx.collect(data);
                }
                cacheList.clear();
                count = 0;

                // 将当前的 Scroll ID 保存到状态后端中
                if (checkpointedState != null) {
                    checkpointedState.clear();
                    checkpointedState.add(scrollId);
                }
            }

            // 更新 Scroll ID,准备下一次查询
            jsonNode = new ObjectMapper().readTree(responseBody);
            scrollId = jsonNode.get("_scroll_id").asText();
        }
    }

    @Override
    public void cancel() {
        isRunning = false;
    }

    @Override
    public void snapshotState(FunctionSnapshotContext context) throws Exception {
        // Snapshot 时不需要进行任何操作,因为 Scroll ID 已经保存在 ListState 中

    }

    @Override
    public void initializeState(FunctionInitializationContext context) throws Exception {
        // 从状态后端中获取已保存的 Scroll ID
        checkpointedState = context.getOperatorStateStore()
                .getListState(new ListStateDescriptor<>("scroll-id-list", Types.STRING));
        if (context.isRestored()) {
            for (String scrollId : checkpointedState.get()) {
                this.scrollId = scrollId;
            }
        }

        // 初始化缓存列表
        cacheList = new LinkedList<>();
    }

    private List<T> parseData(String responseBody) {
        // 解析查询结果,并将数据转换成对应的对象列表
        // ...
        return null;
    }

}

所需依赖

implementation "org.apache.flink:flink-core_2.12:1.13.2"
implementation "org.apache.flink:flink-connector-elasticsearch7_2.12:1.13.2"
implementation "org.elasticsearch.client:elasticsearch-rest-high-level-client:7.14.0"
implementation "com.fasterxml.jackson.core:jackson-databind:2.12.5"
implementation "org.apache.flink:flink-json_2.12:1.13.2"

ES 数据写入方式:直连 VS Flink 集成系统 ES 作为一个分布式搜索引擎,从扩展能力和搜索特性上而言无出其右,然而它有自身的弱势存在,其作为近实时存储系统,由于其分片和复制的设计原理,也使其在数据延迟和一致性方面都是无法和 OLTP(Online Transaction Processing)系统相媲美的。也正因如此,通常它的数据都来源于其他存储系统同步而来,做二次过滤和分析的。这就引入了一个关键节点,即 ES 数据的同步写入方式,本文介绍的则是 MySQL 同步 ES 方式。将 MySQL 数据写入 ES,首先想到的一定是消费 Binlog 直连 阅读详情

相关推荐

用Flink CDC实现MySQL到Elasticsearch的实时数据同步:手把手教你处理Schema变更难题

本文详细介绍了如何利用Flink CDC Connector实现MySQL到Elasticsearch的实时数据同步,重点解决Schema动态演化这一技术难题。通过实战案例和优化策略,帮助开发者构建高可靠的实时数据管道,提升数据处理效率和系统稳定性。

weixin_30275415的博客 414

flink源码分析_Flink 全链路端到端延迟的测量方法

点击上方“zhisheng”,选择“设为星标”后台回复”ffa“可以查看Flink 资料一、背景FLink Job端到端延迟是一个重要的指标,用来衡量Flink任务的整体性能和响应延迟(大部分流式应用,要求低延迟特性)。通过流处理引擎竞品对比,我们发现大部分流计算引擎产品,都在告警监控页面,集成了全链路时延指标展示。一些低延时的处理场景,例如用于登陆、用户下单规则检测,实时预测场景,需...

weixin_39571749的博客 428

Kafka在大数据领域的实时数据可视化应用

数据可靠性Kafka生产者开启acks=all(确保数据写入所有副本);Flink开启Checkpoint(→每1秒做一次 checkpoint);Elasticsearch使用_id字段避免重复数据(比如数据序列化用Avro或Protobuf代替JSON(减少数据大小50%以上);Kafka生产者/消费者使用对应的序列化器(比如监控与告警用Prometheus监控Kafka的(消费者延迟,超过1000触发告警);用Grafana监控Flink的(作业重启次数,超过0触发告警);

AI智能探索者的博客 841

Flink2ES写入性能调优

这里写自定义目录标题背景说明测试环境rally压测集群性能合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 背景说明 测试环境 ...

dtzly的博客 3350

Dataflow Model总结

一.简介 The Dataflow Model 是 Google Research 于2015年发表的一篇流式处理领域的有指导性意义的论文,它对数据集特征和相应的计算方式进行了归纳总结,并针对大规模/无边界/乱序数据集,提出一种可以平衡准确性/延迟/处理成本的数据模型。这篇论文的目的不在于解决目前流计算引擎无法解决的问题,而是提供一个灵活的通用数据模型,可以无缝地切合不同的应用场景。 二.CLC与CAP CAP In a distributed system (a collection of inter

独立开发,substack顶级编辑 1341

Java多模型数据库优化:3种策略让查询速度翻倍?揭秘多数据库的“加速秘籍”!

你有没有遇到过这些“尴尬”:这就是 Java在多模型数据库中的优化难题!它像“瑞士军刀”一样灵活,但也像“俄罗斯方块”一样复杂。本文将带你从 “数据库小白” 到 “多模型大师”,手把手教你用Java玩转混合数据库!传统数据库的“三大阵营”:而 多模型数据库 是:问题:如何让Java根据数据类型自动选择数据库?解决方案:用 策略模式 + 动态代理! 接口:定义路由规则,Java根据数据类型自动选择数据库。 类:动态代理实现查询路由,像“快递分拣站”一样精准! 适用场景:用户信息用MySQL,日志用Mo

java专栏 1646

Flink+Elasticsearch实时写入:6大性能优化实战指南

你是否还在为实时数据写入Elasticsearch(ES)时的延迟飙升、吞吐量不足而头疼?当数据量从日均百万级跃升到亿级,普通配置的Flink写入任务往往会出现ES集群过载、Flink Checkpoint超时等问题。本文将通过6个实战优化点,帮你把写入性能提升3-10倍,同时降低70%的资源消耗。读完你将掌握: - 批量写入配置的黄金参数组合 - 并行度与ES集群容量的匹配公式 - 内存缓冲区的...

gitblog_01168的博客 421

电子书 Flink原理与实战(java版)- 目录结构

本专栏系统的介绍了大数据的简史、Flink的发展历程、Flink的实现原理与应用场景和具体的示例,对初入门或有一定基础的读者是大有裨益的,当然阅读本专栏需要一定的语言和大数据方面的基础知识。

alanchanchn的专栏 1万+

Java量化交易面试:深入Spark、Flink、MyBatis与Elasticsearch的实战与优化

本文以互联网大厂Java开发面试为背景,通过面试官与“小润龙”的对话,深入探讨Spark、Flink、Elasticsearch、MyBatis、HikariCP和Spring Data JDBC在量化交易场景中的应用、优化与架构设计。文章提供详细技术解析、代码示例及学习建议,助你应对高并发、大数据挑战。

2303_76177839的博客 488

基于Flink的实时非结构化数据处理

本文将从“理论→技术→实战”三层递进,系统讲解如何基于Flink构建实时非结构化数据处理管道。非结构化数据的特点与处理挑战;Flink处理非结构化数据的核心能力与技术栈;三大实战案例(实时日志解析、文本情感分析、图像元数据提取),从环境搭建到代码落地全流程;进阶优化(性能调优、状态管理、混合数据处理)与最佳实践。非结构化数据指没有固定格式、缺乏预定义schema数据类型特点示例处理难点结构化数据固定schema、行列清晰MySQL表、CSV文件扩展性差(schema变更成本高)

软件工程实践的博客 743

利用Flink在大数据领域构建实时数据分析平台

本文旨在为大数据工程师和架构师提供使用Apache Flink构建实时数据分析平台的全面指南。Flink的核心架构和编程模型实时数据处理流水线设计状态管理和容错机制性能调优和扩展策略实际应用案例和最佳实践文章首先介绍Flink的核心概念,然后深入其架构和编程模型。接着我们会探讨关键算法和实现细节,并通过实际案例展示完整解决方案。最后讨论应用场景、工具资源和未来发展趋势。流处理(Stream Processing):对无界数据流进行连续处理的计算模式事件时间(Event Time)

AGI×大数据,开启智能时代的认知跃迁;解码AGI,赋能数据驱动的智能革命。 351

阿里巴巴主推的 Flink 为什么火?

不知道你是否有过和我类似的经历?我是 2018 年 6 月加入公司,一直负责监控平台的告警系统。之后,我们的整个监控平台架构中途换过两次,其中一次架构发生了巨大的变化。我...

优快云资讯 1234

U24时钟信号上升下降沿出现非单调性--简单分析

交换机U24时钟信号上升下降沿出现非单调性--简单分析

qq_45185504的博客 1131

从零开始学Flink:数据输出的终极指南

本文详细介绍了Flink数据输出(Sink)的核心概念、各种连接器的使用方法、配置选项及可靠性保证机制。基于Flink 1.20.1的DataStream API,通过丰富的代码示例展示了如何将处理后的数据输出到Kafka、Elasticsearch、文件系统等不同目标,并构建了一个完整的实时数据处理流水线。

专注大数据与 Java 全栈技术栈。深耕 Flink 实时计算、Spring Boot 源码解析与高并发系统架构设计。拒绝浅尝辄止,坚持源码级剖析与生产环境实战复盘,致力于为开发者提供有深度的技术干货与架构思维。代码不止,匠心不息。 1128

别再只用GPS了!用Android手机传感器实现室内步行轨迹记录(避坑指南)

本文详细介绍了如何利用Android手机传感器(如加速度计、陀螺仪和磁力计)实现室内步行轨迹记录,克服GPS在室内的局限性。通过传感器数据采集、步态检测、航向估计和轨迹绘制等步骤,结合避坑指南和优化技巧,帮助开发者高效构建室内定位应用。

weixin_26821003的博客 274

PCB工艺-SI9000使用教程

本文介绍了阻抗计算工具SI9000的使用方法,重点讲解了微带线与带状线的区别、共面阻抗概念及参考面选择。通过USB差分走线实例,详细说明了如何选择计算模型、填写参数并确定线宽线距。文章还提供了层叠设计资料和工厂常规阻抗表格作为参考,建议制板时标注需控阻抗的线路供板厂调整。最后简单提及了嘉立创阻抗计算工具作为备选方案。

weixin_50120208的博客 2023

大数据计算引擎,你 pick 哪个?

不知道你是否有过和我类似的经历?我是 2018 年 6 月加入公司,一直负责监控平台的告警系统。之后,我们的整个监控平台架构中途换过两次,其中一次架构发生了巨大的变化。我...

优快云人工智能头条 2844

拯救你的备份数据!STM32F407 RTC Tamper功能防篡改设计指南

本文详细介绍了STM32F407 RTC Tamper功能在物联网数据安全中的应用,包括硬件触发、数据清除和时间戳记录等核心机制。通过实战案例和代码示例,展示了如何构建多层次的防御体系,确保敏感数据在物理入侵时自动擦除并记录精确时间戳,适用于智能门锁、工业传感器等高安全需求场景。

weixin_28278377的博客 278

Flink并行度与任务链优化:提升数据交换性能的深度解析

并行度(Parallelism)在 Flink 中指的是一个算子(Operator)或作业(Job)被划分成多少个并行任务(Task)来执行。每个任务运行在独立的线程中,处理数据流的一个子集。例如,如果一个 Map 算子的并行度设置为 4,那么 Flink 会创建 4 个相同的 Map 任务实例,每个实例处理一部分输入数据。这种设计使得 Flink 能够充分利用多核 CPU 和分布式集群的计算能力,实现高吞吐和低延迟的数据处理。

zuiyuelong的博客 838

VS2022+Qt6保姆级环境配置指南:从插件安装到项目互通全流程

本文提供VS2022与Qt6深度整合的全流程指南,涵盖环境配置、插件安装、项目互通等关键步骤。详细解析编译器版本匹配、跨IDE协作方案及效能优化技巧,帮助开发者高效搭建C++界面设计开发环境,实现软件项目无缝互通。

zero1的博客 731

040、未来展望:MLIR与编译技术的演进方向

MLIR不是又一个编译框架,它更像是一套“元框架”——提供构建专用编译工具的能力。未来几年,我们会看到更多垂直领域(自动驾驶、射频信号处理、生物计算)出现基于MLIR的专用编译器,它们可能不会挂“MLIR”的名字,但内核都是这套可扩展的IR基础设施。不要等MLIR“成熟”再用,现在就该把它当成一把瑞士军刀,先挑刀口最锋利的那个功能(比如图优化、循环变换)用起来。编译技术的演进不再是学术界的独角戏,而是越来越贴近实际生产中的异构、动态、领域专用需求。

m0_50546716的博客 174

智能营销系统的日志系统架构:AI应用架构师的实战解析

本文将以"智能营销系统的日志系统架构"为核心,从AI应用架构师的视角,完整拆解日志系统从需求分析到落地的全流程。我们将结合实战案例,详细讲解如何设计一个支持"数据采集-实时处理-AI分析-业务赋能"的日志架构,解决智能营销场景下的日志痛点。AI模型服务(如推荐模型)的日志包含特征向量、推理结果、模型版本等特殊字段,需通过自定义SDK采集,避免侵入业务代码。Step 1:定义AI模型日志Schematrace_id: str # 全链路追踪ID(与用户行为日志关联)

AI算力网络与通信的博客 1075

网络速度的极致:800G & 1.6T 以太网的突破!

你好,这里是网络技术联盟站。在我们进入数据驱动的世界时,以太网的重要性日益突出。从根本上说,以太网是一种连接计算机的技术,旨在形成一个本地网,通过它,设备可以与其他设备进行通信。然而,随着时间的推移,以太网已经发展成为一种全球的数据通信系统,其速度从初始的10Mbit/s发展到现在的800G,甚至1.6T。这种巨大的进步并不是没有挑战的,但每一次的突破都代表了技术的巨大飞跃。本文将探讨800G和1.6T以太网的创新与挑战。

网络技术联盟站 1769
上一篇: 云原生(docker+jenkins+k8s)
下一篇: 云原生时代最推荐RPC技术 ——gRPC
我才是真的封不觉
博客等级 码龄8年 871粉丝 436原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我才是真的封不觉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值