当前位置: 首页 > article >正文

基于 Flink CDC YAML 的 MySQL 到 Kafka 流式数据集成

本教程的演示都将在 Flink CDC CLI 中进行,无需一行 Java/Scala 代码,也无需安装 IDE。

 

这篇教程将展示如何基于 Flink CDC YAML 快速构建 MySQL 到 Kafka 的 Streaming ELT 作业,包含整库同步、表结构变更同步演示和关键参数介绍。

准备阶段

准备 Flink Standalone 集群

  1. 1. 下载 Flink 1.19.2[1]压缩包,解压后并跳转至 Flink 目录下,设置 FLINK_HOME 为 flink-1.19.2 所在目录。

tar -zxvf  flink-1.19.2-bin-scala_2.12.tgz
export FLINK_HOME=$(pwd)/flink-1.19.2
  1. 2. 在 conf/config.yaml 文件追加下列参数开启 checkpoint,每隔 3 秒做一次 checkpoint。

execution:checkpointing:interval: 3000
  1. 3. 使用下面的命令启动 Flink 集群。

./bin/start-cluster.sh

启动成功后可以在 http://localhost:8081/访问到 Flink Web UI,如下图所示:

图片

重复执行 start-cluster.sh 可以拉起多个 TaskManager

注意:如果是在云服务器上运行,需要将 conf/config.yaml 里面 rest.bind-address 和 rest.address 的 localhost 改成0.0.0.0,然后使用 公网IP:8081 即可访问。

准备 Docker 环境

使用下面的内容新建一个 docker-compose.yml 文件:

services:Zookeeper:image: zookeeper:3.7.1ports:- "2181:2181"environment:- ALLOW_ANONYMOUS_LOGIN=yesKafka:image: bitnami/kafka:2.8.1ports:- "9092:9092"- "9093:9093"environment:- ALLOW_PLAINTEXT_LISTENER=yes- KAFKA_LISTENERS=PLAINTEXT://:9092- KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://192.168.67.2:9092- KAFKA_ZOOKEEPER_CONNECT=192.168.67.2:2181MySQL:image: debezium/example-mysql:1.1ports:- "3306:3306"environment:- MYSQL_ROOT_PASSWORD=123456- MYSQL_USER=mysqluser- MYSQL_PASSWORD=mysqlpw

注意:文件里面的 192.168.67.2 为内网 IP,可通过 ifconfig 查找。

该 Docker Compose 中包含的组件有:
● MySQL: 包含商品信息的数据库app_db
● Kafka: 存储从 MySQL 中根据规则映射过来的结果表
● Zookeeper:主要用于进行Kafka集群管理和协调
在 docker-compose.yml 所在目录下执行下面的命令来启动上述组件:

docker-compose up -d

该命令以 detached 模式启动 Docker Compose 配置中定义的所有组件。可以通过 docker ps 来观察上述的组件是否正常启动。

图片

在 MySQL 数据库中准备数据

通过执行如下命令可以进入 MySQL 容器:

docker-compose exec MySQL mysql -uroot -p123456

创建数据库 app_db和表 orders,products,shipments 并插入数据:

-- 创建数据库CREATE DATABASE app_db;USE app_db;-- 创建 orders 表CREATE TABLE `orders` (`id` INT NOT NULL,`price` DECIMAL(10,2) NOT NULL,PRIMARY KEY (`id`));-- 插入数据INSERT INTO `orders` (`id`, `price`) VALUES (1, 4.00);INSERT INTO `orders` (`id`, `price`) VALUES (2, 100.00);-- 创建 shipments 表CREATE TABLE `shipments` (`id` INT NOT NULL,`city` VARCHAR(255) NOT NULL,PRIMARY KEY (`id`));-- 插入数据INSERT INTO `shipments` (`id`, `city`) VALUES (1, 'beijing');INSERT INTO `shipments` (`id`, `city`) VALUES (2, 'xian');-- 创建 products 表CREATE TABLE `products` (`id` INT NOT NULL,`product` VARCHAR(255) NOT NULL,PRIMARY KEY (`id`));-- 插入数据INSERT INTO `products` (`id`, `product`) VALUES (1, 'Beer');INSERT INTO `products` (`id`, `product`) VALUES (2, 'Cap');INSERT INTO `products` (`id`, `product`) VALUES (3, 'Peanut');

通过 Flink CDC CLI 提交任务

  1. 1. 下载压缩包并解压得到目录 flink-cdc-3.3.0;
    flink-cdc-3.3.0-bin.tar.gz[2]中包含 bin、lib、log、conf 四个目录。

  2. 2. 下载下面列出的 connector 包,并且移动到 lib 目录下:
    ■ MySQL pipeline connector 3.3.0[3]
    ■ Kafka pipeline connector 3.3.0[4]

您还需要将下面的 Driver 包放在 Flink lib 目录下,或通过 --jar 参数将其传入 Flink CDC CLI,因为 CDC Connectors 不再打包这个依赖:
■ MySQL Connector Java[5]
3. 编写任务配置 yaml 文件
下面给出了一个整库同步的示例文件 mysql-to-kafka.yaml:

################################################################################
# Description: Sync MySQL all tables to Kafka
################################################################################
source:type: mysqlhostname: 0.0.0.0port: 3306username: rootpassword: 123456tables: app_db.\.*server-id: 5400-5404server-time-zone: UTCsink:type: kafkaname: Kafka Sinkproperties.bootstrap.servers: 0.0.0.0:9092topic: yaml-mysql-kafkapipeline:name: MySQL to Kafka Pipelineparallelism: 1

其中 source 中的 tables: app_db..* 通过正则匹配同步 app_db 下的所有表。
4. 最后,通过命令行提交任务到 Flink Standalone cluster

bash bin/flink-cdc.sh mysql-to-kafka.yaml
# 参考,一些自定义路径的示例  主要用于多版本flink,mysql驱动不一致等情况 如,
# bash /root/flink-cdc-3.3.0/bin/flink-cdc.sh /root/flink-cdc-3.3.0/bin/mysql-to-kafka.yaml --flink-home /root/flink-1.19. --jar /root/flink-cdc-3.3.0/lib/mysql-connector-java-8.0.27.jar

提交成功后,返回信息如:

Pipeline has been submitted to cluster.
Job ID: ba2afd0697524bd4857183936507b0bf
Job Description: MySQL to Kafka Pipeline

在 Flink Web UI,可以看到名为 MySQL to Kafka Pipeline 的任务正在运行。

通过 Kafka 客户端查看 Topic 数据,可得到debezium-json格式的内容:

docker-compose exec Kafka kafka-console-consumer.sh --bootstrap-server 192.168.31.229:9092 --topic yaml-mysql-kafka --from-beginning

debezium-json 格式包含了 before/after/op/source 几个元素,示例如下:

{"before": null,"after": {"id": 1,"price": 4},"op": "c","source": {"db": "app_db","table": "orders"}
}
...
{"before": null,"after": {"id": 1,"product": "Beer"},"op": "c","source": {"db": "app_db","table": "products"}
}
...
{"before": null,"after": {"id": 2,"city": "xian"},"op": "c","source": {"db": "app_db","table": "shipments"}
}

同步变更

进入 MySQL 容器:

docker-compose exec MySQL mysql -uroot -p123456

接下来,修改 MySQL 数据库中表的数据,StarRocks 中显示的订单数据也将实时更新:

  1. 1. 在 MySQL 的 orders 表中插入一条数据

INSERT INTO app_db.orders (id, price) VALUES (3, 100.00);
  1. 2. 在 MySQL 的 orders 表中增加一个字段

ALTER TABLE app_db.orders ADD amount varchar(100) NULL;
  1. 3. 在 MySQL 的 orders 表中更新一条数据

UPDATE app_db.orders SET price=100.00, amount=100.00 WHERE id=1;
  1. 4. 在 MySQL 的 orders 表中删除一条数据

DELETE FROM app_db.orders WHERE id=2;

通过 Kafka 消费者监控 Topic,可以看到 Kafka 上也在实时接收到这些变更:

{"before": {"id": 1,"price": 4,"amount": null},"after": {"id": 1,"price": 100,"amount": "100.00"},"op": "u","source": {"db": "app_db","table": "orders"}
}

同样地,去修改 shipments, products 表,也能在 Kafka对应的 Topic 中实时看到同步变更的结果。

特色功能

路由变更

Flink CDC 提供了将源表的表结构/数据路由到其他表名的配置,借助这种能力,我们能够实现表名库名替换,整库同步等功能。下面提供一个配置文件说明:

################################################################################
# Description: Sync MySQL all tables to Kafka
################################################################################
source:type: mysqlhostname: 0.0.0.0port: 3306username: rootpassword: 123456tables: app_db.\.*server-id: 5400-5404server-time-zone: UTCsink:type: kafkaname: Kafka Sinkproperties.bootstrap.servers: 0.0.0.0:9092
pipeline:name: MySQL to Kafka Pipelineparallelism: 1
route:- source-table: app_db.orderssink-table: kafka_ods_orders- source-table: app_db.shipmentssink-table: kafka_ods_shipments- source-table: app_db.productssink-table: kafka_ods_products

通过上面的 route 配置,会将 app_db.orders 表的结构和数据同步到 kafka_ods_orders 中。从而实现数据库迁移的功能。特别地,source-table 支持正则表达式匹配多表,从而实现分库分表同步的功能,例如下面的配置:

route:- source-table: app_db.order\.*sink-table: kafka_ods_orders

这样,就可以将诸如 app_db.order01、app_db.order02、app_db.order03 的表汇总到 kafka_ods_orders 中。利用 Kafka 自带的工具,可查看对应 Topic 的建立,详情可使用 kafka-console-consumer.sh 进行查询。

docker-compose exec Kafka kafka-topics.sh --bootstrap-server 192.168.67.2:9092 --list

Kafka 中新建的 Topic 信息如下:

__consumer_offsets
kafka_ods_orders
kafka_ods_products
kafka_ods_shipments
yaml-mysql-kafka

选取 kafka_ods_orders 这个 Topic 进行查询,返回数据示例如下:

{"before": null,"after": {"id": 1,"price": 100,"amount": "100.00"},"op": "c","source": {"db": null,"table": "kafka_ods_orders"}
}

写入多个分区

使用 partition.strategy 参数可以定义发送数据到 Kafka 分区的策略, 可以设置的选项有:
● all-to-zero(将所有数据发送到 0 号分区),默认值
● hash-by-key(所有数据根据主键的哈希值分发)
我们基于 mysql-to-kafka.yaml 在sink下增加一行配置: partition.strategy: hash-by-key

source:...
sink:...topic: yaml-mysql-kafka-hash-by-keypartition.strategy: hash-by-key
pipeline:...

同时我们利用 Kafka 的脚本新建一个 12 分区的 Kafka Topic:

docker-compose exec Kafka kafka-topics.sh --create --topic yaml-mysql-kafka-hash-by-key --bootstrap-server 192.168.67.2:9092  --partitions 12

提交 YAML 作业后,查看一下各个分区里面所存储的数据。

docker-compose exec Kafka kafka-console-consumer.sh --bootstrap-server=192.168.67.2:9092  --topic yaml-mysql-kafka-hash-by-key  --partition 0  --from-beginning

部分分区数据详情如下:

  • • 分区0

{"before": null,"after": {"id": 1,"price": 100,"amount": "100.00"},"op": "c","source": {"db": "app_db","table": "orders"}
}
  • • 分区4

{"before": null,"after": {"id": 2,"product": "Cap"},"op": "c","source": {"db": "app_db","table": "products"}
}
{"before": null,"after": {"id": 1,"city": "beijing"},"op": "c","source": {"db": "app_db","table": "shipments"}
}

输出格式

value.format 参数用于序列化 Kafka 消息的值部分数据的格式。可选的填写值包括 debezium-json和 canal-json,默认值为 debezium-json,目前还不支持用户自定义输出格式。
debezium-json  [6]格式会包含 before(变更前的数据)/after(变更后的数据)/op(变更类型)/source(元数据) 几个元素,ts_ms 字段并不会默认包含在输出结构中(需要在 Source 中指定 metadata.list 配合)。canal-json  [7]格式会包含 old/data/type/database/table/pkNames 几个元素,但是 ts 并不会默认包含在其中(原因同上)。
可以在 YAML 文件的 sink 中定义 value.format: canal-json 来指定输出格式为 canal-json 类型:

source:...sink:...topic: yaml-mysql-kafka-canalvalue.format: canal-json
pipeline:...
查询对应 topic 的数据,返回示例如下:
{"old": null,"data": [{"id": 1,"price": 100,"amount": "100.00"}],"type": "INSERT","database": "app_db","table": "orders","pkNames": ["id"]
}

自定义上下游映射关系

使用 sink.tableId-to-topic.mapping 参数可以指定上游表名到下游 Kafka Topic 名的映射关系。无需使用 route 配置。与之前介绍的通过 route 实现的不同点在于,配置该参数可以在保留源表的表名信息的情况下设置写入的 Topic 名称。
在前面的 YAML 文件中增加 sink.tableId-to-topic.mapping 配置指定映射关系,每个映射关系由 ; 分割,上游表的 TableId 和下游 Kafka 的 Topic 名由 : 分割:

source:...sink:...sink.tableId-to-topic.mapping: app_db.orders:yaml-mysql-kafka-orders;app_db.shipments:yaml-mysql-kafka-shipments;app_db.products:yaml-mysql-kafka-products
pipeline:...

运行后,Kafka 中将会生成如下的 Topic:

...
yaml-mysql-kafka-orders
yaml-mysql-kafka-products
yaml-mysql-kafka-shipments

上述 3 个 Topic 中的部分数据详情:

{"before": null,"after": {"id": 1,"price": 100,"amount": "100.00"},"op": "c","source": {"db": "app_db","table": "orders"}
}
{"before": null,"after": {"id": 2,"product": "Cap"},"op": "c","source": {"db": "app_db","table": "products"}
}
{"before": null,"after": {"id": 2,"city": "xian"},"op": "c","source": {"db": "app_db","table": "shipments"}
}

环境清理

本教程结束后,在 docker-compose.yml 文件所在的目录下执行如下命令停止所有容器:

docker-compose down

在 Flink 所在目录 flink-1.19.2 下执行如下命令停止 Flink 集群:

./bin/stop-cluster.sh

参考资料

[1]

Flink 1.19.2: https://archive.apache.org/dist/flink/flink-1.19.2/flink-1.19.2-bin-scala_2.12.tgz

[2]

flink-cdc-3.3.0-bin.tar.gz: https://www.apache.org/dyn/closer.lua/flink/flink-cdc-3.3.0/flink-cdc-3.3.0-bin.tar.gz

[3]

MySQL pipeline connector 3.3.0: https://repo1.maven.org/maven2/org/apache/flink/flink-cdc-pipeline-connector-mysql/3.3.0/flink-cdc-pipeline-connector-mysql-3.3.0.jar

[4]

Kafka pipeline connector 3.3.0: https://repo1.maven.org/maven2/org/apache/flink/flink-cdc-pipeline-connector-kafka/3.3.0/flink-cdc-pipeline-connector-kafka-3.3.0.jar

[5]

MySQL Connector Java: https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.27/mysql-connector-java-8.0.27.jar

[6]

debezium-json: https://debezium.io/documentation/reference/stable/integrations/serdes.html

[7]

canal-json: https://github.com/alibaba/canal/wiki


基于 Flink CDC 打造企业级实时数据同步方案


相比于传统数据集成流水线,Flink CDC 提供了全量和增量一体化同步的解决方案。对于一个同步任务,只需使用一个 Flink 作业即可将上游的全量数据和增量数据一致地同步到下游系统。此外, Flink CDC 使用了增量快照算法,无需任何额外配置即可实现全量和增量数据的无缝切换。

现推出“Flink CDC 挑战任务”参与挑战不仅可快速体验《基于 Flink CDC 打造企业级实时数据同步方案》,限时上传任务截图还可获得精美礼品。

 点击即可跳转:Flink CDC 挑战任务

图片

相关文章:

基于 Flink CDC YAML 的 MySQL 到 Kafka 流式数据集成

本教程的演示都将在 Flink CDC CLI 中进行,无需一行 Java/Scala 代码,也无需安装 IDE。 这篇教程将展示如何基于 Flink CDC YAML 快速构建 MySQL 到 Kafka 的 Streaming ELT 作业,包含整库同步、表结构变更同步演示和关键参数介绍。 准备阶段…...

ubuntu下r8125网卡重启丢失修复案例一则

刚装的一台服务器,ubuntu24.04,主板网卡是r8125,安装服务后会莫名其妙丢失驱动 按照官网的方法下载最新8125驱动包: Realtek 然后卸载驱动 rmmod r8125 然后在驱动包里安装(幸好我之前装了build-essential&#x…...

解决 ERROR 1130 (HY000): Host is not allowed to connect to this MySQL server

当使用 MySQL 时,您可能会遇到错误信息“ERROR 1130 (HY000): Host ‘hostname’is not allowed to connect to this MySQL server”这是 MySQL 用于防止未经授权的访问的标准安全特性。实际上,服务器还没有配置为接受来自相关主机的连接。 Common Caus…...

科普|无人机专业术语

文章目录 前言一、飞控二、电调三、通道四、2S、3S、4S电池五、电池后面C是什么意思?六、电机的型号七、什么是电机的KV值?八、螺旋桨的型号九、电机与螺旋桨的搭配 前言 无人机飞控系统控制飞行姿态,电调控制电机转速,遥控器通道控制飞行动作。电池C…...

Qt:窗口

目录 菜单栏 QMenuBar 菜单添加快捷键 添加子菜单 添加分割线和添加图标 QMenuBar创建方式 工具栏 QToolBar 和菜单栏搭配 创建多个工具栏 状态栏 QStatusBar 状态栏中添加其他控件 浮动窗口 QDockWidget 对话框 对话框的内存释放问题 自定义对话框界面 模态对话…...

深入浅出 Go 语言:协程(Goroutine)详解

深入浅出 Go 语言:协程(Goroutine)详解 引言 Go 语言的协程(goroutine)是其并发模型的核心特性之一。协程允许你轻松地编写并发代码,而不需要复杂的线程管理和锁机制。通过协程,你可以同时执行多个任务,并…...

Python从0到100(八十九):Resnet、LSTM、Shufflenet、CNN四种网络分析及对比

前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…...

实验:k8s+keepalived+nginx+iptables

1、创建两个nginx的pod,app都是nginx nginx1 nginx2 2、创建两个的pod的service 3、配置两台keepalived的调度器和nginx七层反向代理,VIP设置192.168.254.110 keepalived调度器master keepalived调度器backup 两台调度器都配置nginx七层反向代理&#…...

elpis全栈课程学习之elpis-core学习总结

elpis全栈课程学习之elpis-core学习总结 核心原理 elpis-core是全栈框架elpis的服务端内核,主要应用于服务端接口的开发以及页面的SSR渲染,elpis-core基于约定优于配置的原理,通过一系列的loader来加载对应的文件,大大节约用户的…...

LlamaFactory-webui:训练大语言模型的入门级教程

LlamaFactory是一个开源框架,支持多种流行的语言模型,及多种微调技术,同时,以友好的交互式界面,简化了大语言模型的学习。 本章内容,从如何拉取,我已经搭建好的Llamafactory镜像开始&#xff0…...

手机打电话时如何识别对方按下的DTMF按键的字符-安卓AI电话机器人

手机打电话时如何识别对方按下的DTMF按键的字符 --安卓AI电话机器人 一、前言 前面的篇章中,使用蓝牙电话拦截手机通话的声音,并对数据加工,这个功能出来也有一段时间了。前段时间有试用的用户咨询说:有没有办法在手机上&#xff…...

Spring Cloud LoadBalancer详解

一、介绍 Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器,抽象和实现,用来替代Ribbon(已经停更), 二、Ribbon和Loadbalance 对比 组件组件提供的负载策略支持负载的客户端Ribbon随机 RandomRule轮询 RoundRobinRule 重试 RetryRule最低并发 Bes…...

使用Spring Boot与达梦数据库(DM)进行多数据源配置及MyBatis Plus集成

使用Spring Boot与达梦数据库(DM)进行多数据源配置及MyBatis Plus集成 在现代企业级应用开发中,处理多个数据源是一个常见的需求。本文将详细介绍如何使用Spring Boot结合达梦数据库(DM),并通过MyBatis Plus来简化数据库操作&…...

基于SpringBoot和PostGIS的省域“地理难抵点(最纵深处)”检索及可视化实践

目录 前言 1、研究背景 2、研究意义 一、研究目标 1、“地理难抵点”的概念 二、“难抵点”空间检索实现 1、数据获取与处理 2、计算流程 3、难抵点计算 4、WebGIS可视化 三、成果展示 1、华东地区 2、华南地区 3、华中地区 4、华北地区 5、西北地区 6、西南地…...

【Qt】详细介绍如何在Visual Studio Code中编译、运行Qt项目

Visual Studio Code一只用的顺手,写Qt的时候也能用VS Code开发就方便多了。 理论上也不算困难,毕竟Qt项目其实就是CMake(QMake的情况这里就暂不考虑了)项目,VS Code在编译、运行CMake项目还是比较成熟的。 这里笔者打…...

【Linux】修改 core 文件大小和路径

在 Linux 系统中,默认情况下,核心转储文件(core dump)会生成在当前工作目录下。为了将核心转储文件生成在指定路径下,可以通过以下方法进行配置。 1. 设置核心转储文件路径 Linux 系统提供了两种方式来指定核心转储文…...

本地部署大语言模型-DeepSeek

DeepSeek 是国内顶尖 AI 团队「深度求索」开发的多模态大模型,具备数学推理、代码生成等深度能力,堪称"AI界的六边形战士"。 Hostease AMD 9950X/96G/3.84T NVMe/1G/5IP/RTX4090 GPU服务器提供多种计费模式。 DeepSeek-R1-32B配置 配置项 规…...

【03】STM32F407 HAL 库框架设计学习

【03】STM32F407 HAL 库框架设计学习 摘要 本文旨在为初学者提供一个关于STM32F407微控制器HAL(Hardware Abstraction Layer)库框架设计的详细学习教程。通过本文,读者将从零开始,逐步掌握STM32F407的基本知识、HAL库的配置步骤…...

鸿蒙HarmonyOS NEXT开发:组件-样式-基础 2

// 1 // 2 ArkUI 基本语法 // 方舟开发框架(简称:ArkUI),是一套 构建HarmonyOS应用 界面 的框架。 // 构建页面的最小单位就是 "组件"。 // 组件名(参数) { // 内容 // } // .属性1() // .属性2() // .属性N() import text from @ohos.graphics.text // @En…...

SQLAlchemy系列教程:SQLAlchemy快速入门示例项目

SQLAlchemy是与数据库交互的Python开发人员不可或缺的库。这个强大的ORM允许使用python结构进行简单的数据库操作。设置过程很简单,并且允许可扩展的数据库应用程序开发。本文通过入门项目完整介绍SQLAlchemy的应用过程,包括安装依赖包,创建连…...

【Linux网络#10】:Https协议原理

📃个人主页:island1314 🔥个人专栏:Linux—登神长阶 ⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 生活总是不会一帆风顺&#xf…...

蓝桥杯备考:记忆化搜索之function

这道题是有重复的问题的&#xff0c;所以我们可以选择记忆化搜索 #include <iostream> using namespace std; typedef long long LL; const int N 25; LL ret[N][N][N]; LL dfs(LL a,LL b, LL c) {if(a<0 || b<0 || c<0) return 1;if(a>20 || b>20 || c…...

在Nginx上配置并开启WebDAV服务的完整指南

在Nginx上配置并开启WebDAV服务的完整指南 如何在 Nginx 上开启 WebDAV 服务 要在 Nginx 上开启 WebDAV 服务&#xff0c;你需要配置 Nginx 以支持 WebDAV 请求。以下是详细的步骤&#xff1a; 1. 确保 Nginx 安装了 WebDAV 模块 Nginx 的 WebDAV 功能由 http_dav_module 模…...

mysql 全方位安装教程

下载 MySQL 【官网下载地址】 注意要选择较大的哪个安装包&#xff0c;小的安装包是一个安装器。 我们不用登录&#xff0c;直接下载 直接运行下载好的安装包 MySQL如果是 安装包安装, 可以图形化界面自主配置 如果是压缩包解压, 可以配置 配置文件, 可以解压安装到指定的…...

设计模式Python版 观察者模式

文章目录 前言一、观察者模式二、观察者模式示例 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&#xff1a;关注类和对象之间的组…...

如何在Python用Plot画出一个简单的机器人模型

如何在Python中使用 Plot 画出一个简单的模型 在下面的程序中&#xff0c;首先要知道机器人的DH参数&#xff0c;然后计算出每一个关节的位置&#xff0c;最后利用 plot 函数画出关节之间的连杆就可以了&#xff0c;最后利用 animation 库来实现一个动画效果。 import matplo…...

如何使用ArcGIS Pro制作横向图例:详细步骤与实践指南

ArcGIS Pro&#xff0c;作为Esri公司推出的新一代地理信息系统&#xff08;GIS&#xff09;平台&#xff0c;以其强大的功能和灵活的操作界面&#xff0c;在地理数据处理、地图制作和空间分析等领域发挥着重要作用。 在地图制作过程中&#xff0c;图例作为地图的重要组成部分&…...

MySQL 创建指定IP用户并赋予全部权限(兼容8.0以下及8.0以上版本)

在MySQL中,为用户指定访问IP并授予权限是常见的运维操作。但由于MySQL 8.0对用户创建和权限管理机制进行了升级,不同版本的操作存在差异。以下是针对MySQL 8.0以下版本和8.0及以上版本的具体实现方法。 一、MySQL 8.0以下版本(如5.7、5.6) 在MySQL 8.0之前,可以通过一条G…...

每日十个计算机专有名词 (7)

Metasploit 词源&#xff1a;Meta&#xff08;超越&#xff0c;超出&#xff09; exploit&#xff08;漏洞利用&#xff09; Metasploit 是一个安全测试框架&#xff0c;用来帮助安全专家&#xff08;也叫渗透测试人员&#xff09;发现和利用计算机系统中的漏洞。你可以把它想…...

【Python 数据结构 3.顺序表】

目录 一、顺序表基本概念 1.顺序表的概念 2.顺序表的元素插入 元素插入的步骤 3.顺序表的元素删除 元素删除的步骤 4.顺序表的元素查找 元素查找的步骤 5.顺序表的元素索引 元素索引的步骤 6.顺序表的元素修改 元素修改的步骤 二、Python中的顺序表 1.顺序表的定义 2.顺序表的插…...