Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Flink程序设计之道

Flink程序设计之道

作者头像
Flink实战剖析
发布于 2022-04-18 05:43:57
发布于 2022-04-18 05:43:57
34200
代码可运行
举报
文章被收录于专栏:Flink实战剖析Flink实战剖析
运行总次数:0
代码可运行

01 - 前言

软件架构的复杂性通常并不是由功能性需求来决定,而是取决于非功能性需求,例如高性能、高可用、易扩展、易运维、低成本等要求,功能性需求通常是易于实现的,但是为了满足非功能性需求需要去做不同的技术方案选型对比、架构设计等,比喻说为了实现高性能,要去做缓存、分库分表、预计算、异步等方案,这些方案会提高系统的复杂程度。对于Flink程序开发同样会面临这些问题,在设计、实现之初除了需要考虑如何满足功能性需求外,还需要考虑性能、容错等非功能需求。本文将结合自己的实际开发经验从以下几个方面来介绍做一个实时Flink程序设计需要关注的一些问题:

适合性

当前的业务需求是否适合使用Flink去实现。

准确性

由Flink程序提供出去的数据是否正确。

延时

在流量高峰期或者是非高峰期,Flink任务是不是丝滑般处理,保证不延时。

容错能力

是否有一套完备的故障检测、恢复的能力,保证其可用性。

可维护性

在面对版本升级、程序升级时,是否可以方便的维护升级。

02 - 合适性

在做程序设计的时候经常会有一个误区,为了技术而技术,也就是一味的去追求技术的火热,某个技术很牛逼因而在项目中去使用它,比喻分析的数据量只有几万、几千级别,使用MySql 就可以轻松的处理,但是却为了追求Hadoop而去使用Hadoop做数据处理,很明显得不偿失。对于是否适合使用Flink去实现业务需求,从两个方面去考虑:业务、技术。

业务是否需要?对于数据业务开发来说,是需要通过数据技术手段解决业务问题或者是辅助业务决策,因此对于开发人员的要求就是需要熟悉业务,需要我们去辅助判断这个实时需求对于业务的增量情况,通常影响用户实时决策,例如实时效果指标、监控指标等,这个时候我们可以去考虑使用实时技术去解决。

技术是否合适?Flink在当下流计算很火热,并不是任何计算场景都使用Flink来完成,需要充分考虑其实现的成本,有没有更好的方案进行代替。

03 - 准确性

这里的准确性代表数据质量中数据准确性,也就是Flink程序提供出去的数据是否正确,保证我们交付出去的数据得到业务的认可。在不同的业务领域内对数据的正确性要求不一样,例如做实时监控,是允许存在数据丢失情况,但是在一些金融领域或者是跟钱相关统计计算的对数据正确性要求极高,应对不同的正确性要求会做出不同的设计,接下来列举几个常见会影响数据正确性的设计。

checkpoint, Flink checkpoint 是对状态数据周期性的全局快照,保证任务失败从快照恢复仍然能够保证数据的正确性。第一个考虑就是是否需要使用checkpoint, 如果可以忍受数据丢失,那么就没有必要开启checkpoint机制;第二个考虑是使用exactly-once语义还是at-least-once语义,这二者语义都是Flink内部数据的一种保证机制 , 使用at-least-once语义在任务重启的情况下,会存在重复状态计算,导致最终的数据结果有偏差。

事件时间语义,事件时间语义的支持处理是Flink区别于其他流式计算的重要特性,可以根据数据的时间执行相应的处理,比较常见的就是事件时间窗口,同时事件时间语义可以支持数据回放。如何决定可以触发一个事件时间操作(窗口计算), 在Flink中使用Watermark来衡量数据的处理进度,决定是否触发计算,但是这是一种理论情况,在实际中只能说是相对的减少数据丢失(可以监控numLateRecordsDropped指标),使用EventTime 语义并不能百分之百保证数据没有丢失,也就是计算指标可能会存在一定的误差。那么如何规避这种误差?常见的方式就是使用离线的语义去完成实时处理方式,以窗口计算为例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT user,
    TUMBLE_START(rowtime, INTERVAL '1' DAY) as wStart,  
    SUM(amount) FROM Orders 
  GROUP BY TUMBLE(rowtime, INTERVAL '1' DAY), user

可改写为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT user,userFunction(rowtime) as wStart,SUM(amount) 
  FROM Orders
    GROUP BY userFunction(rowtime), user

端到端一致性,这个是流式计算中比较难的一个话题,其涉及数据源端、Flink计算端、输出端,这三端的保证机制:数据源可回放、Flink checkpoint机制、输出端幂等或者事务的机制,通过这些机制保证数据的准确性。

除了上面提到的几点还与一些比较常见的技术实现相关,比喻使用BloomFilter、Hyperloglog 本身存在一定误差的数据结构等。

04 - 延时

延时大小代表了当前任务处理数据的进度,一般会通过监控消费Kafka的Lag或者是在数据源处数据时间与当前系统时间差值来判断任务是否延时,同时延时代表了Flink程序的处理数据的能力。如果程序的处理能力跟不上数据流量,最终的表现就是任务延时,得到的数据指标是滞后的,影响业务及时决策。因此我们在开发过程中需要考虑到可能会影响任务性能瓶颈的卡点,同时需要通过提前压测的方式,检测任务是否出现延时情况。简单列举几点常见影响性能的问题。

数据倾斜,大量的数据被分配给同一个task处理,也就是流量分配不均匀,常常出现在大商家流量统计或者是热门话题流量统计中,数据倾斜导致的直接问题就是出现"木桶效应",该task成为整个任务处理的性能瓶颈,最终触发反压,降低了消费速率。常出现在group by 、join 一些操作中,其优化手段与离线优化大体相同,预聚合、两阶段计算等方式。

大状态,flink 任务保留了大量的状态数据,例如全局group by 操作、regular-join 操作,这种保留数据时间比较长的计算,如果选用FsStateBackend那么可能会造成严重的gc问题,拖慢整个任务, 对于大状态一般会选用RocksDBStateBackend,使用rocksdb存储状态数据,即便如此可能会带来比较大的io消耗,最终导致io延时比较高,这时可以考虑:使用SSD作为存储、MiniBatch机制减少对状态的访问、或者是regular-join转变为interval-join等优化手段。

外部IO交互,常常发生维度扩充或者是结果数据输出需要与外部存储交互,这在个过程中出现与外部交互延时比较高通常是因为使用的姿势不正确或者是使用存储不合理,可以使用异步IO、LRU缓存机制、批量输出机制、使用写优化类型的存储等方式优化。

05 - 容错能力

在分布式系统中,可能会因为程序处理异常、网络故障、机器故障等原因导致系统失败,因此在设计之初会充分考虑其容错能力,也就是可用性。Flink本身设计了一套先进的容错能力,从故障检测到恢复,保证在各种不可预知的问题下可以自动恢复并且数据恢复到正确的状态。

故障检测分为两个方面:一、守护进程检测, JobManager、ResourceManager 、TaskManager 之间会通过心跳检测相互判断对方是否存活;二、task异常上报,某个task处理异常,TaskManager会将异常信息上报给JobManager。通过这两方面的检测最终触发恢复策略,任务恢复会依赖持久化的一致性状态数据,也就是会依赖checkpoint机制,保证失败重启可以从最近一次成功的checkpoint状态数据中恢复。

除了Flink程序本身容错机制的保证,在实际的开发中还需要考虑以下几点:

  • 缓存数据是否加入状态

通常为了减轻输出压力使用批量方式输出,那么批量缓存数据也需要加入到一致性状态中,保证失败恢复数据不会丢失

  • 双链路

双链通常应对保障等级比较高的任务,做计算、存储双链路保障机制,类似于同城双机房或者异地多活策略。

  • 平台层面支持

计算平台支持检测任务状态、自动拉起任务并从最近一次checkpoint中恢复。

06 - 可维护性

可维护性是指当面对Flink版本升级、修改程序bug、功能扩展等情况能够很方便的对程序做出修改。列举几种常见的处理手段:

  • 模块化处理,比较常见一点就是数仓里面分层、数据抽象化,将通用的部分提取出来单独处理
  • 尽量选择易懂的编程方式,对于分析类型程序来说,通俗易懂的就是sql, 使用sql化的方式完成程序开发
  • 编程质量保证,从表、字段、注释等制定开发规范
  • 当使用DataStream API时,给每一个算子设置一个唯一的uid, 当任务拓扑图发生改变时仍然能恢复对应的状态数据;当使用自定义状态时, 需要考虑并行度改变状态的伸缩变化以及使用的状态数据结构是否可支持变更与版本兼容性。

07 - 总结

本文主要从架构的视角去窥探如何比较全面考虑、设计一个Flink程序,包括适用性、数据质量、性能(延时)、容错能力、可维护性上的思考。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Flink实战剖析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
centos中KVM虚拟化
1.确认 CPU 已经支持虚拟化,intel 的 CPU 虚拟化技术叫 vmx,AMD 的 CPU 叫 svm
@凌晨
2020/05/28
7550
Cent os 7之KVM虚拟化基础管理
至此,命令行创建虚拟机就完成了,接下来使用手动更改配置文件的方式,克隆test1,生成新的虚拟机test2(在我博文前面的那个博文链接中有专用于克隆的命令工具的使用方法,这里只是为了来了解虚拟机的配置文件) 二、手动更改配置文件的方式,克隆web01,生成新的虚拟机web02
小手冰凉
2020/07/29
7380
Cent os 7之KVM虚拟化基础管理
KVM 简介
KVM(Kernel-based Virtual Machine) ,基于内核的虚拟机,配合QEMU(处理器虚拟软件),需要CPU支持虚拟化技术(并且在BIOS里打开虚拟化选项),效率可达到物理机的80%以上。此外,它对SMP的支持很好。
为为为什么
2022/08/06
1.7K0
统信服务器操作系统V20 1060e【KVM 虚拟化】
KVM(Kernel-based Virtual Machine)是一个基于Linux内核的开源虚拟化解决方案,它允许在单个物理服务器上运行多个虚拟机。每个虚拟机都可以运行自己的操作系统和应用程序。KVM利用了Linux内核的虚拟化功能,通过将物理主机的资源(如CPU、内存和网络接口)动态分配给虚拟机,实现了对虚拟机的隔离和资源管理。
Kevin song
2024/04/28
9350
统信服务器操作系统V20 1060e【KVM 虚拟化】
KVM虚拟化平台部署及管理
前言 KVM即Kernel Virtual Machine,最初是由以色列公司Qumranet开发。2007年2月被导入Linux 2.6.20核心中,成为内核源代码的一部分。2008年9月4日,Redhat收购了Qumranet,至此Redhat拥有了自己的虚拟化解决方案,之后便舍弃Xen开始全面扶持KVM,从RHEL6开始KVM便被默认内置于内核中。本文介绍KVM虚拟化平台部署及管理。 KVM简介 KVM特点 KVM必须在具备Intel VT或AMD-V功能的x86平台上运行。KVM包含一个为处理器提供
小小科
2018/05/04
2.6K0
KVM虚拟化平台部署及管理
麒麟系统V10 SP2 KVM virt-install 创建虚拟机
从ftp,http,nfs启动,如ftp://192.168.10.7/dvd;nfs:192.168.10.7:/dvd
Kevin song
2022/11/19
4.8K0
麒麟系统V10 SP2 KVM virt-install 创建虚拟机
ESXI 迁移至KVM (V2V迁移)
1.1.1 ESXI将虚拟机导出    导出ova模板    将导出的ova模板导入到KVM环境中。 1.1.2 配置KVM环境 详情参考:http://www.cnblogs.com/clsn/p/
惨绿少年
2018/04/19
1.2K0
ESXI 迁移至KVM (V2V迁移)
KVM简介,安装及常见使用详解
查看状态操作结果,如Active: active (running),说明运行情况良好
用户8851537
2021/07/21
3.4K0
KVM部署篇
KVM 介绍 KVM是以色列初创公司Qumranet开发,2008年9月RedHat公司收购了Qumranet KVM是Linux内核的一个模块,它把Linux内核变成了一个Hypervisor KVM是完全开源的,RedHat基于KVM的虚拟化解决方案叫做RHEV KVM在Linux操作系统里面以进程的形式出现,由标准的Linux调度程序进行调度,这使得KVM能够使用Linux内核的已有功能,只有一个KVM内核模块还不能实现虚拟化的全部功能,就好比操作系统只有内核还不能成为一个完整的操作系统一样 QEMU
老七Linux
2018/05/31
1.6K0
kvm 虚拟化安装 Ubuntu 18.04 server
首先要配置好 KVM 环境,上文已经详细说明,磁盘配置类似的使用 qemu-img create -f qcow2 ubuntu.qcow2 100G 命令创建虚拟磁盘,系统镜像可以去官网下载:
宋天伦
2020/07/16
2.5K0
kvm虚拟化进阶 原
前面学习了kvm虚拟化的一些基础操作,本节整理一下kvm快照、扩容等等相关的内容。
阿dai学长
2019/04/03
1K0
QEMU/KVM虚拟机安装配置
[root@KVM ~]# yum install qemu-img qemu-kvm qemu-kvm-tools virt-manager virt-viewer virt-v2v virt-top libvirt libvirt-Python libvirt-client python-virtinst bridge-utils tunctl
用户8704835
2021/06/08
1.7K0
Centos6.3安装KVM
一、安装kvm 1 在安装CentOS6.3时可以选择安装好kvm 2 如果未安装好kvm,请按照下列方式安装 [创建本地yum源] 挂载iso文件 mount -o loop -t iso9660 CentOS-6.3-x86_64-bin-DVD1.iso /mnt 设置本地yum源 在/etc/yum.repos.d/创建   “任意文件名.repo"    文件   vi 刚才新建的文件名编辑 【localyum】任意名称 ,不能有空格。 name= local yum  任意名称 baseurl=file:////mnt/Packages      这个路径是自定的。Server为光盘中的Server目录 ,Packages与Server放在同一目录下。即/software目录下 enabled=1   代表   生效     0为不生效 gpgcheck=1   检查gpgkey  1 生效   0不生效 gpgkey=file:///software    安装光盘里有这个文件        不指定  安装时,可能提示没有注册 保存退出 执行命令 yum clean all (1) kvm需要有 CPU 的支持(Intel VT 或 AMD SVM) [root@moniter ~]#egrep '^flags.*(vmx|svm)' /proc/cpuinfo 如果有返回值说明cpu支持虚拟化 (2) 安装kvm libvirted yum install kvm kmod-kvm qemu kvm-qemu-img virt-viewer virt-manager libvirt libvirt-python python-virtinst (3) 启动libvirted service messagebus start service haldaemon start service libvirtd start chkconfig messagebus on chkconfig haldaemon on chkconfig libvirtd on (4)检查kvm是否安装成功 [root@jiayuan ~]# virsh -c qemu:///system list  Id    名称                         状态 ----------------------------------------------------  1     redhat6.3                      running (5)kvm模块 [root@myKVM ~]# lsmod | grep kvm kvm_intel              52570  0 kvm                  314739  1 kvm_intel 二、配置网桥 vi /etc/sysconfig/network-scripts/ifcfg-br0 DEVICE=br0 TYPE=Bridge BOOTPROTO=static BROADCAST=10.207.20.255 IPADDR=10.207.20.200 NETMASK=255.255.255.0 NETWORK=10.207.20.0 ONBOOT=yes b、 vi /etc/sysconfig/network-scripts/ifcfg-eth0 # Broadcom Corporation NetXtreme II BCM5709 Gigabit Ethernet DEVICE=eth0 BOOTPROTO=none ONBOOT=yes BRIDGE=br0 c、 重起网络服务生效 service network restart d、 echo 1 > /proc/sys/net/ipv4/ip_forward  #虚拟机上网 e、 检查桥接网络 [root@moniter ~]# brctl show bridge name     bridge id               STP enabled     interfaces br0             8000.842b2b74e1b6       no              eth0 virbr0          8000.000000000000       yes br0是我们配置的桥接网卡,virbr0是系统脚本自动配置的NAT网卡 三、安装vnc 注意:CentOS6.3 VNC的命名rpm为tiggervnc-server (1) yum install tiggervnc-server (2) vi /etc/sysconfig/vncservers #加一行     VNCSERVERS="
DevinGeng
2019/04/09
1.2K0
裸金属服务器kvm虚拟化安装win10
和普通的 VPS 相比,裸金属服务器属于物理服务器,我的数据和其他用户数据做到了物理隔离,同时服务器本身是支持二次虚拟化的。
宋天伦
2020/07/16
7.4K0
kvm研究和实践
qemu-kvm 该软件包主要包含KVM内核模块和基于KVM重构后的QEMU模拟器。KVM模块作为整个虚拟化环境的核心工作在系统空间,负责CPU和内存的调度。QEMU作为模拟器工作在用户空间,负责虚拟机I/O模拟。 依赖包qemu-img 主要用来QEMU磁盘镜像的管理,如新建一块磁盘镜像给虚拟机。
初心不改
2020/01/23
1.8K0
OpenEuler 部署 KVM 虚拟化制作openstack镜像
内核模块导出了一个名为/dev/kvm的设备,该设备将虚拟机的的地址空间独立于内核或者任何应用程序的地址空间
Kevin song
2023/12/04
1.7K0
OpenEuler 部署 KVM 虚拟化制作openstack镜像
virsh查看虚拟网络信息_kvm创建虚拟机
1.virsh查看/管理虚拟机 问题 本案例要求熟悉KVM虚拟化的virsh管理工具的的基本使用,从命令行来操作虚拟机,完成以下基本任务: 1)查看KVM服务器信息 2)列出有哪些虚拟机、指定虚拟机的状态 3)基本的开关机操作 4)将虚拟机设置为自动运行 方案 virsh命令行管理的常见用法: 1)virsh:直接进交互模式 2)virsh nodeinfo:查看KVM节点(服务器)信息 3)virsh list:列出正在运行的虚拟机 4)virsh list –all:列出所有虚拟机(包括未启动的) 5)virsh dominfo 虚拟机名称:查看指定虚拟机的信息 6)virsh start 虚拟机名称:将指定的虚拟机开机 7)virsh reboot 虚拟机名称:将指定的虚拟机重启 8)virsh shutdown 虚拟机名称:将指定的虚拟机正常关机 9)virsh destroy 虚拟机名称:将指定的虚拟机强制关机(相当于拔电源) 10)virsh autostart 虚拟机名称:将指定的虚拟机设置随KVM自动开机 11)virsh autostart –disable 虚拟机名称:禁止自动开机 步骤 实现此案例需要按照如下步骤进行。 步骤一:直接使用virsh交互模式 执行不带任何参数的virsh命令,即可进入交互模式。在virsh交互模式下,可以快速、连续地执行多条虚拟机管理指令,不用每次都指定virsh,最后再exit退出;这种方式与在Shell命令行执行virsh时后面跟上虚拟机管理指令的作用是等效的。 [root@kvmsvr ~]# virsh //进入virsh交互模式 欢迎使用 virsh,虚拟化的交互式终端。
全栈程序员站长
2022/09/21
1.7K0
virsh查看虚拟网络信息_kvm创建虚拟机
kvm命令行安装
qemu-img创建磁盘文件 通过文件管理可以直接查看、修改、复制虚拟机的内部文件。例如,当系统因为配置文件无法启动 时,可以直接修改虚拟机的文件。虚拟机磁盘文件主要有raw和qcow2格式。raw格式性能最好,速度最 快,它的缺点就是不支持一些新的功能,如支持镜像,zlib磁盘压缩,AES加密等。要使用镜像功能,磁 盘格式必须为qcow2。 raw格式的话,速度稍微快点,在高版本的qemu-kvm中,几乎不比qcow2的格式快,而qcow2格式节 省空间,可动态增长,在
L宝宝聊IT
2018/06/27
3.4K0
KVM虚拟机静态迁移
KVM 全称是 基于内核的虚拟机(Kernel-based Virtual Machine),它是一个 Linux 的一个内核模块,该内核模块使得 Linux 变成了一个 Hypervisor,KVM 是基于虚拟化扩展(Intel VT 或者 AMD-V)的 X86 硬件的开源的 Linux 原生的全虚拟化解决方案。KVM 中,虚拟机被实现为常规的 Linux 进程,由标准 Linux 调度程序进行调度;虚机的每个虚拟 CPU 被实现为一个常规的 Linux 进程。这使得 KMV 能够使用 Linux 内核的已有功能。但是,KVM 本身不执行任何硬件模拟,需要客户空间程序通过 /dev/kvm 接口设置一个客户机虚拟服务器的地址空间,向它提供模拟的 I/O,并将它的视频显示映射回宿主的显示屏。
机械视角
2019/10/23
1.2K0
部署 KVM 虚拟化平台
KVM自Linux 2.6.20版本后就直接整合到Linux内核,它依托CPU虚拟化指令集实现高性能的虚拟化支持。它与Linux内核高度整合,因此在性能、安全性、兼容性、稳定性上都有很好的表现。 在KVM环境中运行的每个虚拟化操作系统都将表现为单个独立的系统进程。因此它可以很方便地与Linux系统中的安全模块进行整合(SELinux),可以灵活的实现硬件资源的管理和分配,KVM虚拟化的架构图如下:
小手冰凉
2019/09/10
1.3K0
部署 KVM 虚拟化平台
相关推荐
centos中KVM虚拟化
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档