state backends

状态后端
数据流API的程序中通常以如下几种形式保存状态:
窗口算子收集数据元素或聚合直到他们被发射出去
转换函数会使用key/value状态接口存储数据
转换函数会实现CheckpointedFunction接口,来保证局部变量的故障恢复

当检查点机制被激活,这种状态在检查点上保持,以防止数据丢失和一致地恢复。
状态是如何在内部表示,并且它如何在检查点上保持依赖于选择的状态后端。

可用的状态后端
开箱即用,flink直接提供了如下的状态后端:
MemoryStateBackend
FsStateBackend
RocksDBStateBackend
在没有任何配置时,系统使用MemoryStateBackend

MemoryStateBackend
MemoryStateBackend将数据以对象的方式保存在java虚拟机的堆中。key/value状态和窗口算子保持hash表存储值和触发器,等等。
检查点时,状态后端会快照状态并将快照作为ack消息发送给jobmanager(主),通过将数据保存在堆上。
MemoryStateBackend能够配置使用异步快照。虽然强烈鼓励使用异步快照来避免阻塞管道,但需要注意,当前默认情况下就启动了此功能。
可以在构造MemoryStateBackend实例时指定false标志来关闭这个特性,例如:
new MemoryStateBackend(MAX_MEM_STATE_SIZE, false);

MemoryStateBackend的局限性:
每个独立的状态默认限制大小为5m。可以在构造MemoryStateBackend时增加限制大小。
不考虑配置的最大状态尺寸,状态不能超过akka框架的尺寸。
聚合状态必须写入JobManager内存。

MemoryStateBackend适用的场景:
本地部署和调试
作业保持小规模的状态,例如作业由每次处理一条记录的算子组成(map,flatmap,filter,…).
kafka消费需要非常小的状态。

FsStateBackend
FsStateBackend配置文件系统URL路径(type,address,path),例如:“hdfs://namenode:40010/flink/checkpoints”或者“file:///data/flink/checkpoints”
FsStateBackend保存in-flight数据在TaskManager内存中.生成checkpoint时,它将状态快照写入配置的文件系统目录。
极小的元数据存储在JobManager内存中(或者在高可靠性模式下存储在元数据检查点)
FsStateBackend默认使用异步快照来避免写入状态检查点会阻塞数据流处理。
取消这个默认特性,可以在构造FsStateBackend时指定false标志,例如:
new FsStateBackend(path, false);
FsStateBackend适用的场景:
任务使用大的状态,大的窗口,大的key/value状态
需要高可靠性

RocksDBStateBackend
RocksDBStateBackend配置文件系统URl路径,例如:“hdfs://namenode:40010/flink/checkpoints”或“file:///data/flink/checkpoints”
RocksDBStateBackend保存in-flight数据在TaskManager数据目录下的RocksDB数据库中。
生成检查点时,完整的RocksDB数据库会被作为检查点保存在配置的文件系统目录下。
极少的元数据存储在JobManager内存中(或者在高可靠性模式下存储在元数据检查点)
RocksDBStateBackend总是执行异步快照。
RocksDBStateBackend的限制:
由于RocksDB的JNI API基于byte[],单个key和value最大支持的尺寸为2^31 bytes。
重要:带有合并操作的状态(例如:liststate)在RocksDB可能会悄然累计超过2^31 bytes,这会导致取回状态时发生失败。
这时目前RocksDB JNI的限制。
RocksDBStateBackend适用的场景:
任务使用非常大的状态,大的窗口,大的key/value状态
需要高可靠性
注意状态的规模限制取决于可用的硬盘大小。相对FsStateBackend将状态保存在内存,RocksDBStateBackend允许保存非常大的状态。
但这也意味着,它实现的最大吞吐量更低。对后端的读取/写入操作必须经过序列化/反序列化才能检索/存储这些状态对象,相对与基于堆
实现的后端耗费了更多的性能。

RocksDBStateBackend是当前唯一提供增量检查点的后端。
某些RocksDB提供可用的原生度量但没有默认打开,可以查阅完整的文档。

配置一个状态后端
默认的状态后端,没有任何配置下就是jobmanager。如果希望在集群上为所有任务设置特殊的默认配置,可以在flink-conf.yaml设置默认状态后端。
默认的状态后端可以被具体任务的配置覆盖。

设置单个任务的状态后端
单个任务的状态后端需要设置到任务对应的StreamExecutionEnvironment对象上,参考下面的例子:
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStateBackend(new FsStateBackend(“hdfs://namenode:40010/flink/checkpoints”));

设置默认的状态后端
默认的状态后端设置在flink-conf.yaml,关键字为state.backend
可用的配置项为jobmanager(MemoryStateBackend),filesystem (FsStateBackend), rocksdb (RocksDBStateBackend),
或者实现了状态后端工厂FsStateBackendFactory的类的全名,例如RocksDBStateBackend的全名org.apache.flink.contrib.streaming.state.RocksDBStateBackendFactory

state.checkpoints.dir选项定义所有后端写入检查点数据和元数据文件的路径。可以查看更多关于检查点目录结构的细节。

配置文件的一段节选:
#The backend that will be used to store operator state checkpoints

state.backend: filesystem

#Directory for storing checkpoints

state.checkpoints.dir: hdfs://namenode:40010/flink/checkpoints

RocksDB状态后端的配置选项
key 默认值 描述
state.backend.rocksdb.localdir none 保存RocksDB文件的本地路径(TaskManager上)
state.backend.rocksdb.timer-service.factory HEAP 这决定了定时器服务状态实现的工厂。可选堆(基于堆,默认值)或者ROCKSDB基于ROCKSDB的实现。

import tkinter as tk import csv import pandas as pd import matplotlib.pyplot as plt from tkinter import filedialog from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg root = tk.Tk() root.title("数据科学基础") root.geometry("800x600") font = ("楷体", 16) root.option_add("*Font", font) root.configure(bg="pink") def import_csv_data(): global file_path, df, txt_data file_path = filedialog.askopenfilename() df = pd.read_csv(file_path) top_5 = df.head() txt_data.delete('1.0', tk.END) txt_data.insert(tk.END, top_5) label2 = tk.Label(root, text="请选择要显示的图像:") label2.pack(side="left") button1 = tk.Button(root, text="散点图") button1.pack(side="left") button2 = tk.Button(root, text="折线图") button2.pack(side="left") button3 = tk.Button(root, text="柱状图") button3.pack(side="left") fig_container = tk.Frame(root) fig_container.pack() def show_figure(): x = df.iloc[:, 0] y = df.iloc[:, 1] if plt.fignum_exists(1): plt.clf() # 清空画布 if button1["state"] == "normal": plt.scatter(x, y) elif button2["state"] == "normal": plt.plot(x, y) elif button3["state"] == "normal": plt.bar(x, y) canvas = FigureCanvasTkAgg(plt.gcf(), master=fig_container) canvas.draw() canvas.get_tk_widget().pack() button1.config(command=lambda: (button1.config(state="disabled"), button2.config(state="normal"), button3.config(state="normal"), show_figure())) button2.config(command=lambda: (button2.config(state="disabled"), button1.config(state="normal"), button3.config(state="normal"), show_figure())) button3.config(command=lambda: (button3.config(state="disabled"), button1.config(state="normal"), button2.config(state="normal"), show_figure())) btn_import = tk.Button(root,text="导入CSV文件",command=import_csv_data) btn_import.pack() txt_data = tk.Text(root) txt_data.pack() btn_show_figure = tk.Button(root, text="显示图像", command=lambda: (button1.config(state="normal"), button2.config(state="normal"), button3.config(state="normal"))) btn_show_figure.pack() root.mainloop()如何修改代码实现对界面右侧实现滑动上下拉动界面的功能
05-31
要实现界面右侧实现滑动上下拉动界面的功能,可以将图像框架 fig_container 放在一个滚动框架中,并将滚动框架的大小和位置与图像框架相同。可以使用 tkinter 中的 Scrollbar 和 Canvas 实现滚动框架。以下是修改后的代码: ``` import tkinter as tk import csv import pandas as pd import matplotlib.pyplot as plt from tkinter import filedialog from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg root = tk.Tk() root.title("数据科学基础") root.geometry("800x600") font = ("楷体", 16) root.option_add("*Font", font) root.configure(bg="pink") def import_csv_data(): global file_path, df, txt_data file_path = filedialog.askopenfilename() df = pd.read_csv(file_path) top_5 = df.head() txt_data.delete('1.0', tk.END) txt_data.insert(tk.END, top_5) label2 = tk.Label(root, text="请选择要显示的图像:") label2.pack(side="left") button1 = tk.Button(root, text="散点图") button1.pack(side="left") button2 = tk.Button(root, text="折线图") button2.pack(side="left") button3 = tk.Button(root, text="柱状图") button3.pack(side="left") fig_container = tk.Frame(root) fig_container.pack(side="right", fill="both", expand=True) # 添加滚动框架 canvas = tk.Canvas(fig_container) canvas.pack(side="left", fill="both", expand=True) scrollbar = tk.Scrollbar(fig_container, orient="vertical", command=canvas.yview) scrollbar.pack(side="right", fill="y") canvas.configure(yscrollcommand=scrollbar.set) canvas.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all"))) # 将图像框架放入滚动框架中 frame = tk.Frame(canvas) canvas.create_window((0, 0), window=frame, anchor="nw") def show_figure(): x = df.iloc[:, 0] y = df.iloc[:, 1] if plt.fignum_exists(1): plt.clf() # 清空画布 if button1["state"] == "normal": plt.scatter(x, y) elif button2["state"] == "normal": plt.plot(x, y) elif button3["state"] == "normal": plt.bar(x, y) # 将图像框架放在滚动框架中 canvas = FigureCanvasTkAgg(plt.gcf(), master=frame) canvas.draw() canvas.get_tk_widget().pack() button1.config(command=lambda: (button1.config(state="disabled"), button2.config(state="normal"), button3.config(state="normal"), show_figure())) button2.config(command=lambda: (button2.config(state="disabled"), button1.config(state="normal"), button3.config(state="normal"), show_figure())) button3.config(command=lambda: (button3.config(state="disabled"), button1.config(state="normal"), button2.config(state="normal"), show_figure())) btn_import = tk.Button(root,text="导入CSV文件",command=import_csv_data) btn_import.pack() txt_data = tk.Text(root) txt_data.pack() btn_show_figure = tk.Button(root, text="显示图像", command=lambda: (button1.config(state="normal"), button2.config(state="normal"), button3.config(state="normal"))) btn_show_figure.pack() root.mainloop() ``` 其中,滚动框架的大小和位置由以下代码控制: ``` fig_container = tk.Frame(root) fig_container.pack(side="right", fill="both", expand=True) # 添加滚动框架 canvas = tk.Canvas(fig_container) canvas.pack(side="left", fill="both", expand=True) scrollbar = tk.Scrollbar(fig_container, orient="vertical", command=canvas.yview) scrollbar.pack(side="right", fill="y") canvas.configure(yscrollcommand=scrollbar.set) canvas.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all"))) # 将图像框架放入滚动框架中 frame = tk.Frame(canvas) canvas.create_window((0, 0), window=frame, anchor="nw") ``` 其中,fig_container 是图像框架所在的框架,canvas 是滚动框架,scrollbar 是滚动条。在 canvas 上添加滚动条和图像框架。通过 canvas.create_window() 将图像框架放入滚动框架中。通过 lambda 函数绑定 canvas 的 <Configure> 事件,使滚动框架可以根据图像框架的大小自动调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值