基于apache paimon实时数仓全增量一体实时入湖

news2024/12/28 5:38:17

用例简介

Apache Paimon(以下简称 Paimon)作为支持实时更新的高性能湖存储,本用例展示了在千万数据规模下使用全量 + 增量一体化同步 MySQL 订单表到 Paimon明细表、下游计算聚合及持续消费更新的能力。整体流程如下图所示,其中  MySQL 需要提前准备 ,本机需要下载 Flink 包及 Paimon相关依赖,TPC-H 数据生成器。

数据源由 TPC-H toolkit 生成并导入 MySQL,在写入 Paimon时以 l_shipdate 字段作为业务时间定义分区 l_yearl_month,时间跨度从 1992.1-1998.12,动态写入 84 个分区,详细配置如下表所示。

ConfigurationValueDescription
记录数59,986,052全量阶段同步数据量
动态写入分区数84`l_year` 为一级分区,`l_month` 为二级分区
Checkpoint Interval1m数据更新频率
Parallelism2单机 2 个并发
FTS Bucket Number2每个分区下生成 2 个 bucket

经测试,在单机并发为 2,checkpoint interval 为 1 min 的配置下(每分钟更新可见)66 min 内写入 59.9 million 全量数据,每 10 min 的写入性能如下表所示,平均写入性能在 1 million/min。

Duration(min)Records In (million)
1010
2020
3031
4042
5050
6057

从作业运行图中可以观测到每 10 min 作业写入的数据量,在 66 min 时全量同步完成,开始持续监听增量数据。

关于数据生成

TPC-H 作为一个经典的 Ad-hoc query 性能测试 benchmark,其包含的数据模型与真实的商业场景十分类似。本用例选取其中订单明细表 lineitem 和针对它的单表查询 Q1(下文会有详细说明)

lineitem schema 如下表所示,每行记录在 128 bytes 左右

字段类型描述
l_orderkeyINT NOT NULL主订单 key,即主订单 id,联合主键第一位
l_partkeyINT NOT NULL配件 key,即商品 id
l_suppkeyINT NOT NULL供应商 key,即卖家 id
l_linenumberINT NOT NULL子订单 key,即子订单 id,联合主键第二位
l_quantityDECIMAL(15, 2) NOT NULL商品数量
l_extendedpriceDECIMAL(15, 2) NOT NULL商品价格
l_discountDECIMAL(15, 2) NOT NULL商品折扣
l_taxDECIMAL(15, 2) NOT NULL商品税
l_returnflagCHAR(1) NOT NULL订单签收标志,A 代表 accepted 签收,R 代表 returned 拒收,N 代表 none 未知
l_linestatusCHAR(1) NOT NULL子订单状态,发货日期晚于 1995-06-17 之前的订单标记为 O,否则标记为 F
l_shipdateDATE NOT NULL订单发货日期
l_commitdateDATE NOT NULL订单提交日期
l_receiptdateDATE NOT NULL收货日期
l_shipinstructCHAR(25) NOT NULL收货信息,比如 DELIVER IN PERSON 本人签收,TAKE BACK RETURN 退货,COLLECT COD 货到付款
l_shipmodeCHAR(10) NOT NULL快递模式,有 SHIP 海运,AIR 空运,TRUCK 陆运,MAIL 邮递等类型
l_commentVARCHAR(44) NOT NULL订单注释

业务需求(TPC-H Q1)

对发货日期在一定范围内的订单,根据订单状态和收货状态统计订单数、商品数、总营业额、总利润、平均出厂价、平均折扣价、平均折扣含税价等指标。

快速开始

步骤简介

mysql环境准备:

DROP DATABASE IF EXISTS flink;
CREATE DATABASE IF NOT EXISTS flink;
USE flink;
CREATE USER 'flink' IDENTIFIED WITH mysql_native_password BY 'flink';
GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'flink';
FLUSH PRIVILEGES;
-- Create Base Table
CREATE TABLE lineitem ( 
        l_orderkey    INTEGER NOT NULL,
        l_partkey     INTEGER NOT NULL,
        l_suppkey     INTEGER NOT NULL,
        l_linenumber  INTEGER NOT NULL,
        l_quantity    DECIMAL(15,2) NOT NULL,
        l_extendedprice  DECIMAL(15,2) NOT NULL,
        l_discount    DECIMAL(15,2) NOT NULL,
        l_tax         DECIMAL(15,2) NOT NULL,
        l_returnflag  CHAR(1) NOT NULL,
        l_linestatus  CHAR(1) NOT NULL,
        l_shipdate    DATE NOT NULL,
        l_commitdate  DATE NOT NULL,
        l_receiptdate DATE NOT NULL,
        l_shipinstruct CHAR(25) NOT NULL,
        l_shipmode     CHAR(10) NOT NULL,
        l_comment      VARCHAR(44) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    -- Add PK Constraint
    ALTER TABLE lineitem ADD PRIMARY KEY (l_orderkey, l_linenumber);
    -- Create Delta Table
CREATE TABLE update_lineitem LIKE lineitem; 
    
CREATE TABLE delete_lineitem (
        l_orderkey    INTEGER NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE delete_lineitem ADD PRIMARY KEY (l_orderkey);

准备TPC-H 生产文件 :添加tpch_dbgen_linux64-2.14.0.zip到服务器,解压执行命令,生产10G数据,其中lineitem大约7.3G

./dbgen -q -s 10 -T L

 

 加载数据到mysql

添加mycreds.cnf文件,内容包含mysql的基本信息

mysql --defaults-extra-file=mycreds.cnf -D flink --local-infile=1  -e "
  LOAD DATA LOCAL INFILE 'lineitem.tbl' INTO TABLE lineitem FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';"

本用例会在第一步中将全量订单数据(约 59.9 million)导入 MySQL container,预计耗时 15 min,在此期间您可以准备好 Flink 及 Paimon 等环境,等待数据导入完毕,然后启动 Flink 作业。然后使用脚本开始持续触发 TPC-H 产生 RF1(新增订单)和 RF2(删除已有订单)来模拟增量更新(每组新增和删除之间间隔 20s)。以 10 组更新为例,将会产生 6 million 新增订单和 1.5 million 删除订单(注:TPC-H 产生的删除订单为主订单 ID,由于 lineitem 存在联合主键,故实际删除数据量稍大于 1.5 million)。

第二步:下载 Flink、Paimon 及其他所需依赖

Demo 运行使用 Flink 1.17.0 版本( flink-1.17.0 ),需要的其它依赖如下

  • Flink MySQL CDC connector
  • 基于 Flink 1.15 编译的 FTS(Paimon Jar File)
  • Hadoop Bundle Jar

为方便操作,您可以直接在本项目的 flink-table-store-101/flink/lib 目录下载所有依赖,并放置于本地 flink-1.14.5/lib 目录下,也可以自行下载及编译

  • flink-sql-connector-mysql-cdc-2.2.1.jar
  • Hadoop Bundle Jar

上述步骤完成后,lib 目录结构如图所示

lib
-rw-r--r-- 1 hadoop hadoop    196487 3月  17 20:07 flink-cep-1.17.0.jar
-rw-r--r-- 1 hadoop hadoop    542616 3月  17 20:10 flink-connector-files-1.17.0.jar
-rw-r--r-- 1 hadoop hadoop    102468 3月  17 20:14 flink-csv-1.17.0.jar
-rw-r--r-- 1 hadoop hadoop 135969953 3月  17 20:22 flink-dist-1.17.0.jar
-rw-r--r-- 1 hadoop hadoop    180243 3月  17 20:13 flink-json-1.17.0.jar
-rw-r--r-- 1 hadoop hadoop  21043313 3月  17 20:20 flink-scala_2.12-1.17.0.jar
-rw-rw-r-- 1 hadoop hadoop  36327707 5月  19 15:12 flink-shaded-hadoop-2-uber-2.6.5-7.0.jar
-rw-rw-r-- 1 hadoop hadoop  22096298 5月  22 10:30 flink-sql-connector-mysql-cdc-2.2.1.jar
-rw-r--r-- 1 hadoop hadoop  15407474 3月  17 20:21 flink-table-api-java-uber-1.17.0.jar
-rw-r--r-- 1 hadoop hadoop  37975208 3月  17 20:15 flink-table-planner-loader-1.17.0.jar
-rw-r--r-- 1 hadoop hadoop   3146205 3月  17 20:07 flink-table-runtime-1.17.0.jar
-rw-r--r-- 1 hadoop hadoop    208006 3月  17 17:31 log4j-1.2-api-2.17.1.jar
-rw-r--r-- 1 hadoop hadoop    301872 3月  17 17:31 log4j-api-2.17.1.jar
-rw-r--r-- 1 hadoop hadoop   1790452 3月  17 17:31 log4j-core-2.17.1.jar
-rw-r--r-- 1 hadoop hadoop     24279 3月  17 17:31 log4j-slf4j-impl-2.17.1.jar
-rw-rw-r-- 1 hadoop hadoop  26745559 5月  19 15:14 paimon-flink-1.17-0.5-20230512.001824-7.jar

第三步:修改 flink-conf 配置文件并启动集群

vim flink-1.17.0/conf/flink-conf.yaml 文件,按如下配置修改

jobmanager.memory.process.size: 4096m
taskmanager.memory.process.size: 4096m
taskmanager.numberOfTaskSlots: 8
parallelism.default: 2
execution.checkpointing.interval: 1min
state.backend: rocksdb
state.backend.incremental: true
execution.checkpointing.checkpoints-after-tasks-finish.enabled: true

若想观察 Paimon的异步合并、Snapshot 提交及流读等信息,可以在 flink-1.14.5/conf 目录下修改 log4j.properties 文件,按需增加如下配置

# Log FTS
logger.commit.name = org.apache.flink.table.store.file.operation.FileStoreCommitImpl
logger.commit.level = DEBUG

logger.compaction.name = org.apache.flink.table.store.file.mergetree.compact
logger.compaction.level = DEBUG

logger.enumerator.name = org.apache.flink.table.store.connector.source.ContinuousFileSplitEnumerator
logger.enumerator.level = DEBUG

这里我们只开启提交的 DEBUG,然后在 flink-1.17.0 目录下执行 ./bin/start-cluster.sh

第四步:初始化表 schema 并启动 Flink SQL CLI

./bin/sql-client.sh
执行SQL
-- 设置使用流模式
SET 'execution.runtime-mode' = 'streaming';

-- 创建并使用 FTS Catalog
CREATE CATALOG `table_store` WITH (
    'type' = 'table-store',
    'warehouse' = 'hdfs://tmp/table-store-101'
);

USE CATALOG `table_store`;

-- ODS table schema

-- 注意在 FTS Catalog 下,创建使用其它连接器的表时,需要将表声明为临时表
CREATE TEMPORARY TABLE `ods_lineitem` (
  `l_orderkey` INT NOT NULL,
  `l_partkey` INT NOT NULL,
  `l_suppkey` INT NOT NULL,
  `l_linenumber` INT NOT NULL,
  `l_quantity` DECIMAL(15, 2) NOT NULL,
  `l_extendedprice` DECIMAL(15, 2) NOT NULL,
  `l_discount` DECIMAL(15, 2) NOT NULL,
  `l_tax` DECIMAL(15, 2) NOT NULL,
  `l_returnflag` CHAR(1) NOT NULL,
  `l_linestatus` CHAR(1) NOT NULL,
  `l_shipdate` DATE NOT NULL,
  `l_commitdate` DATE NOT NULL,
  `l_receiptdate` DATE NOT NULL,
  `l_shipinstruct` CHAR(25) NOT NULL,
  `l_shipmode` CHAR(10) NOT NULL,
  `l_comment` VARCHAR(44) NOT NULL,
  PRIMARY KEY (`l_orderkey`, `l_linenumber`) NOT ENFORCED
) WITH (
  'connector' = 'mysql-cdc',
  'hostname' = '127.0.0.1', -- 如果想使用 host,可以修改宿主机 /etc/hosts 加入 127.0.0.1 mysql.docker.internal
  'port' = '3306',
  'username' = 'flink',
  'password' = 'flink',
  'database-name' = 'flink',
  'table-name' = 'lineitem'
);


-- DWD table schema
-- 以 `l_shipdate` 为业务日期,创建以 `l_year` + `l_month` 的二级分区表,注意所有 partition key 都需要声明在 primary key 中
CREATE TABLE IF NOT EXISTS `dwd_lineitem` (
  `l_orderkey` INT NOT NULL,
  `l_partkey` INT NOT NULL,
  `l_suppkey` INT NOT NULL,
  `l_linenumber` INT NOT NULL,
  `l_quantity` DECIMAL(15, 2) NOT NULL,
  `l_extendedprice` DECIMAL(15, 2) NOT NULL,
  `l_discount` DECIMAL(15, 2) NOT NULL,
  `l_tax` DECIMAL(15, 2) NOT NULL,
  `l_returnflag` CHAR(1) NOT NULL,
  `l_linestatus` CHAR(1) NOT NULL,
  `l_shipdate` DATE NOT NULL,
  `l_commitdate` DATE NOT NULL,
  `l_receiptdate` DATE NOT NULL,
  `l_shipinstruct` CHAR(25) NOT NULL,
  `l_shipmode` CHAR(10) NOT NULL,
  `l_comment` VARCHAR(44) NOT NULL,
  `l_year` BIGINT NOT NULL,
  `l_month` BIGINT NOT NULL,
  PRIMARY KEY (`l_orderkey`, `l_linenumber`, `l_year`, `l_month`) NOT ENFORCED
) PARTITIONED BY (`l_year`, `l_month`) WITH (
  -- 每个 partition 下设置 2 个 bucket
  'bucket' = '2',
  -- 设置 changelog-producer 为 'input',这会使得上游 CDC Source 不丢弃 update_before,并且下游消费 dwd_lineitem 时没有 changelog-normalize 节点
  'changelog-producer' = 'input'
);

-- ADS table schema
-- 基于 TPC-H Q1,对已发货的订单,根据订单状态和收货状态统计订单数、商品数、总营业额、总利润、平均出厂价、平均折扣价、平均折扣含税价等指标
CREATE TABLE IF NOT EXISTS `ads_pricing_summary` (
  `l_returnflag` CHAR(1) NOT NULL,
  `l_linestatus` CHAR(1) NOT NULL,
  `sum_quantity` DOUBLE NOT NULL,
  `sum_base_price` DOUBLE NOT NULL,
  `sum_discount_price` DOUBLE NOT NULL,
  `sum_charge_vat_inclusive` DOUBLE NOT NULL,
  `avg_quantity` DOUBLE NOT NULL,
  `avg_base_price` DOUBLE NOT NULL,
  `avg_discount` DOUBLE NOT NULL,
  `count_order` BIGINT NOT NULL,
   PRIMARY KEY (`l_returnflag`, `l_linestatus`) NOT ENFORCED
) WITH (
  'bucket' = '2',
  'merge-engine'='partial-update',
  'changelog-producer'='full-compaction'
);

第五步:提交同步任务

在全量数据导入到 MySQL lineitem 表后,我们启动全量同步作业,这里以结果表作为作业名,方便标识

任务1:通过 Flink MySQL CDC 同步 ods_lineitemdwd_lineitem

-- 设置作业名
SET 'pipeline.name' = 'dwd_lineitem';
INSERT INTO dwd_lineitem
SELECT
  `l_orderkey`,
  `l_partkey`,
  `l_suppkey`,
  `l_linenumber`,
  `l_quantity`,
  `l_extendedprice`,
  `l_discount`,
  `l_tax`,
  `l_returnflag`,
  `l_linestatus`,
  `l_shipdate`,
  `l_commitdate`,
  `l_receiptdate`,
  `l_shipinstruct`,
  `l_shipmode`,
  `l_comment`,
  YEAR(`l_shipdate`) AS `l_year`,
  MONTH(`l_shipdate`) AS `l_month`
FROM `ods_lineitem`;

可以在 Flink Web UI 观察全量同步阶段的 rps、checkpoint 等信息,也可以切换到hdfs的 /tmp/table-store-101/default.db/dwd_lineitem 目录下,查看生成的 snpashot、manifest 和 sst 文件。

第六步:计算聚合指标并查询结果

在全量同步完成后,我们启动聚合作业,实时写入 ads 表 (注:如有需要在历史全量数据不全的情况下也展示聚合结果,可以不用等待全量同步完成)

任务2:写入结果表 ads_pricing_summary

-- 设置作业名
SET 'pipeline.name' = 'ads_pricing_summary';
INSERT INTO `ads_pricing_summary`
SELECT 
  `l_returnflag`,
  `l_linestatus`,
  SUM(`l_quantity`) AS `sum_quantity`,
  SUM(`l_extendedprice`) AS `sum_base_price`,
  SUM(`l_extendedprice` * (1-`l_discount`)) AS `sum_discount_price`, -- aka revenue
  SUM(`l_extendedprice` * (1-`l_discount`) * (1+`l_tax`)) AS `sum_charge_vat_inclusive`,
  AVG(`l_quantity`) AS `avg_quantity`,
  AVG(`l_extendedprice`) AS `avg_base_price`,
  AVG(`l_discount`) AS `avg_discount`,
  COUNT(*) AS `count_order`
FROM `dwd_lineitem`
WHERE (`l_year` < 1998 OR (`l_year` = 1998 AND `l_month`<= 9))
AND `l_shipdate` <= DATE '1998-12-01' - INTERVAL '90' DAY
GROUP BY  
  `l_returnflag`,
  `l_linestatus`;

我们切换到 batch 模式并且将结果展示切换为 tableau 模式

SET 'execution.runtime-mode' = 'batch';

SET 'sql-client.execution.result-mode' = 'tableau';

然后查询刚才聚合的结果,可以多运行几次来观测指标的变化 (查询间隔应大于所查上游表的 checkpoint 间隔)

SET 'pipeline.name' = 'Pricing Summary';

SELECT * FROM ads_pricing_summary;

除了查询聚合指标外,FTS 同时支持查询明细数据。假设我们发现 1998 年 12 月发生退货的子订单指标有问题,想通过订单明细进一步排查,可在 batch 模式下进行如下查询

SELECT `l_orderkey`, `l_returnflag`, `l_linestatus`, `l_shipdate` FROM `dwd_lineitem` WHERE `l_year` = 1998 AND `l_month` = 12 AND `l_linenumber` = 2 AND `l_shipinstruct` = 'TAKE BACK RETURN';

使用spark查询数据

下载spark-3.1.2-bin-hadoop2.7

在jars里面放入paimon-spark-3.1-0.5-SNAPSHOT.jar

spark-sql --conf spark.sql.catalog.paimon=org.apache.paimon.spark.SparkCatalog --conf spark.sql.catalog.paimon.warehouse=hdfs://tmp/table-store-101
USE paimon.default;
select count(*) from dwd_lineitem;
 SELECT `l_orderkey`, `l_returnflag`, `l_linestatus`, `l_shipdate` FROM `dwd_lineitem` WHERE `l_year` = 1998 AND `l_month` = 12 AND `l_linenumber` = 2 AND `l_shipinstruct` = 'TAKE BACK RETURN';

 

第七步:观测更新数据

生成更新数据

编写脚本

start_pair=1
total_pair=10
MYSQL_DATABASE=gmall
for i in `seq ${start_pair} ${total_pair}`; do

if [[ `expr ${i} % 10` -eq 0 ]]; then
      echo "$(date +"%Y-%m-%d %H:%M:%S") Start to apply Old Sales Refresh Function (RF2) for pair ${i}"
    fi
    # This refresh function removes old sales information from the database.
    mysql --defaults-extra-file=mycreds.cnf -D ${MYSQL_DATABASE} -e "TRUNCATE delete_lineitem"
    mysql --defaults-extra-file=mycreds.cnf -D ${MYSQL_DATABASE} --local-infile=1 -e "SET UNIQUE_CHECKS = 0;" -e "
    LOAD DATA LOCAL INFILE 'delete.${i}' INTO TABLE delete_lineitem FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';"
    mysql --defaults-extra-file=mycreds.cnf -D ${MYSQL_DATABASE} -e "
        BEGIN;
        DELETE FROM lineitem WHERE l_orderkey IN (SELECT l_orderkey FROM delete_lineitem);
        COMMIT;"

 sleep 20s
    if [[ `expr ${i} % 10` -eq 0 ]]; then
      echo "$(date +"%Y-%m-%d %H:%M:%S") Start to apply New Sales Refresh Function (RF1) for pair ${i}"
    fi
    # This refresh function adds new sales information to the database.
    mysql --defaults-extra-file=mycreds.cnf -D ${MYSQL_DATABASE} -e "TRUNCATE update_lineitem"
    mysql --defaults-extra-file=mycreds.cnf -D ${MYSQL_DATABASE} --local-infile=1 -e "SET UNIQUE_CHECKS = 0;" -e "
    LOAD DATA LOCAL INFILE 'lineitem.tbl.u${i}' INTO TABLE update_lineitem FIELDS TERMINATED BY '|' LINES TERMINATED BY '|\n';"
    mysql --defaults-extra-file=mycreds.cnf -D ${MYSQL_DATABASE} -e "
        BEGIN;
        INSERT INTO lineitem
        SELECT * FROM update_lineitem;
        COMMIT;"
    
    done
    start_pair=`expr ${total_pair} + 1`
    total_pair=`expr ${total_pair} \* 2`

    sleep 2m

参考

基于 Apache Flink Table Store 的全增量一体实时入湖 - 简书

Apache Flink Table Store 全增量一体 CDC 实时入湖

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/563536.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R语言实践——rWCVP:世界维管植物名录的R包

rWCVP&#xff1a;世界维管植物名录的R包 介绍1. 参照github安装与简单例子1.1 安装rWCVP1.2 安装rWCVPdata1.3 github的例子 2. rWCVP原始文献阅读2.1 前言&#xff08;背景&#xff09;2.2 功能概要2.2.1 名称匹配&#xff08;wcvp_match_names(), wcvp_match_exact(), wcvp …

ChatGPT:你真的了解网络安全吗?浅谈攻击防御进行时之网络安全新定义

ChatGPT&#xff1a;你真的了解网络安全吗&#xff1f;浅谈网络安全攻击防御进行时 网络安全新定义总结 ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;美国OpenAI 研发的聊天机器人程序&#xff0c;是人工智能技术驱动…

在字节跳动做了6年测试,5月无情被辞,想给划水的兄弟提个醒

先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入字节&#xff0c;以“人员优化”的名义无情被裁员&#xff0c;之后跳槽到了有赞&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是6年的工作经验吧。 这6年之间完成了一次…

API接口测试—详情版(拼多多根据ID取商品详情)

一、为什么要做接口测试 做接口测试的原因主要有以下几个方面&#xff1a; 1. 确保接口功能正确性&#xff1a;接口是不同软件系统或者不同模块之间的数据传输和交互的通道&#xff0c;通过接口测试能够确保不同系统或者模块之间传递的信息准确无误&#xff0c;从而保证了整个…

微信小程序点击icon实现分享功能

1.小程序分享功能实现方式 小程序分享功能有两种方式&#xff0c;监听用户点击页面内转发按钮&#xff08; 组件 open-type“share”&#xff09;或右上角菜单“转发”按钮的行为&#xff0c;并自定义转发内容。 使用微信小程序的分享功能需要定义onShareAppMessage(Object obj…

Java基础 变量与数据类型

变量 为什么需要变量 一花一世界&#xff0c;如果把一个程序看做一个世界或一个社会的话&#xff0c;那么变量就是程 序世界的花花草草、万事万物。即&#xff0c;变量是程序中不可或缺的组成单位&#xff0c;最基 本的存储单元。 初识变量 变量的概念 内存中的一个存储区域…

工作几年,涨薪4K遭拒,后一天我就裸辞走了···

19年7月大学毕业&#xff0c;当时学的计算机科学专业。因为考研之后&#xff0c;秋招结束了。也没什么更多的岗位选择&#xff0c;就想着找个工作先干着&#xff0c;刚好有个亲戚在一家大厂公司上班说要招测试&#xff0c;所以就来做测试了。 虽然都是属于计算机大类&#xff0…

chatgpt赋能Python-python_nor

了解Python NOR 在Python编程语言中&#xff0c;NOR运算是一种逻辑运算符&#xff0c;用于反转两个变量的逻辑值。它是布尔运算中的一种&#xff0c;通常用于检查两个条件是否都不成立。 NOR运算有两个输入和一个输出&#xff0c;当输入为空或两个输入都为False时&#xff0c…

nuxt视频播放(踩坑)

展示效果&#xff1a; nuxt样例视频 1.安装vue-video-player插件 ①执行命令 npm i vue-video-player 或者 npm i vue-video-player5.0.2 后者直接安装对应版本号的插件 ②安装完之后 执行npm i ③安装不对应的版本会报错 ④注意安装版本 不是vue3.0的 请安装&#xff08;“v…

【nginx】同一接口有时返回500(client_body_temp)

问题描述&#xff1a; 同一个接口&#xff0c;有能正常访问并返回的&#xff0c;有的访问未到服务器直接返回500。 查看nginx日志&#xff08;error.log&#xff09;&#xff0c;发现open() "/nginx/client_body_temp/0000476534" failed (13: Permission denied)报…

java的URL类

文章目录 1. 简介2. 创建URL3. 从URL获取数据4. 分解URL5. 相等性和比较 1. 简介 java.net.URL类是对统一资源定位符的抽象。它扩展了Object类&#xff0c;是一个final类&#xff0c;不能对其派生子类。它不依赖于继承来配置不同的URL实例&#xff0c;而使用了策略设计模式&am…

VivadoIO约束

VivadoIO约束 FPGA开发离不开IO约束和时序约束&#xff0c;IO约束用于确定输入/输出端口的物理端口和电气特性&#xff0c;与芯片和电路设计有关。而时序约束则用于设定FPGA设计中的时序特性&#xff0c;以确保系统能够在预期时钟频率下正常运行。本文将介绍vivado中常见的设置…

编码踩坑——Redis Pipeline中调用Lua脚本报错JedisMoveDataException的问题 / Lua脚本常遇到的问题

本篇记录使用Redis Pipeline时&#xff0c;调用redis.clients.jedis.PipelineBase#eval时&#xff0c;报错JedisMoveDataException的问题&#xff1b;通过查看源码发现问题的原因&#xff0c;通过jedis在Github的issue了解了解决方案&#xff1b;涉及知识&#xff1a;Redis slo…

FP独立站支付问题你还没解决?out了!

目前FP独立站是很多跨境卖家的变现方式&#xff0c;但是这类外贸电商会遇到一些收款问题&#xff0c;这些问题很容易就让卖家的资金被冻结、账号被风控、关联账号被限制&#xff0c;损失真是不小。那FP卖家的收款问题该怎么解决呢&#xff1f;往下看。 一、FP独立站常见收款方式…

抖音账号运营技巧,让你的短视频更火爆

抖音是目前最火爆的短视频平台之一&#xff0c;拥有着庞大的用户群体和广阔的市场前景。在这个平台上&#xff0c;每天都有大量的用户在发布自己的短视频内容&#xff0c;让自己的账号脱颖而出并吸引更多的粉丝&#xff0c;成为每个用户所追求的目标。下面就来介绍一些抖音账号…

新用户如何选择WMS仓储管理系统解决方案

引言&#xff1a;随着现代化物流技术的不断发展&#xff0c;WMS仓储管理系统已成为企业管理的重要工具。一款合适的WMS系统可以帮助企业提高库存管理效率、减少库存成本、提升物流服务质量。对于初学者来说&#xff0c;如何选择适合自己的WMS系统&#xff0c;往往是一项挑战。本…

如何做好app的测试工作?一文6个步骤到你秒变APP测试高手

先说结论: 想要做好 APP 的测试工作, 离不开相对完整的测试要点! 本篇文章不仅有完整的App测试介绍&#xff0c;还有相对完整的App测试视频分享。 闲话少叙, 咱们直奔主题, APP 应用测试应该主要包含以下几个方面的测试要点: 需要注意的是: APP 应用测试是个相对繁杂的测试类…

电脑远程连接软件推荐

您可以考虑使用多种可靠的计算机远程连接软件选项来远程连接和控制计算机。 以下是一些流行的选项&#xff1a; TeamViewer TeamViewer 是一种广泛使用的远程访问软件&#xff0c;以其易用性和跨平台兼容性而闻名。 它提供远程控制、文件传输和桌面共享等功能。 TeamViewer 通…

解密JavaScript混淆加密技术:揭秘隐藏的代码之谜

让我们通过一个案例来更好地理解JavaScript混淆加密的工作原理。假设我们有以下原始的JavaScript代码&#xff1a; function addNumbers(a, b) {return a b; }上述代码非常简单易懂&#xff0c;但对于一些恶意攻击者来说&#xff0c;他们可能会试图窃取您的代码或者修改其中的…

终身学习(LifeLong Learning)/ 增量学习(Incremental Learning)、在线学习(Online Learning)

1、在线学习 实时获得一个新样本就进行一次模型更新。显然&#xff0c;在线学习时增量学习的特例&#xff0c;而增量学习可视为“批模式”的在线/离线学习。 online主要相对于offline或者说batch&#xff0c;强调的是每次只进入一个或者很少的几个样本&#xff0c;多见于推荐…