流批一体的近实时数仓的思考与设计

news2024/11/19 20:41:42

摘要:基于对数据时间旅行的思考,引出了对目前三种数仓形态和两种数仓架构的思考。结合数据湖在 Flink 的应用和数据湖元数据类型的思考,探索了基于数据湖的 Flink SQL 流批一体的实践,在流批一体 SQL 表达一致、结果一致性、流批任务分离、混合调度依赖等进行了设计和探索。同时,欢迎大家多分享具体实践,一起共筑新的数据实践方式。

Tips:点击「阅读原文」查看更多技术内容


01

数据的时间旅行和业务对数据的本质要求

大规模的数据处理兴起于 Hadoop 生态的发展,关键在于分布式储存和分布式计算的发展,造就了如今近百种有关大数据的生态技术。数仓理论和建模理论基于大数据技术体系得以快速发展,其中离线数仓的标准化建设得到了广泛应用。数据的本质是一种行为的具象,业务在对数据的需求,核心在于对行为的可探索和可观察。基于此,我们需要明确一点,大数据技术是否完全满足了业务对数据需求在时间维度上的确定性了呢,这点是值得思考的。那么我们先来看一下数据的时间旅行。

7862fc4e6973a8e7f3bd5063d3f5276d.png

业务期望的数据:用户空间下的时间数据,t1时间数据,用户自然时间点或自然时间段的明细或者统计数据。

传输延迟:App 用户,数据发送到网关或者日志服务系统,或者 Server 日志落文件系统所产生的延迟。Event 进入到存储空间,可以代表数据已经是确定的,基本可观察,一般情况下,这个延迟很小。但是,在某些情况,比如 APP 的日志产生之后,但是因为网络等问题一直没有发送,或者 Server 宕机,导致延迟发送或者最终丢失。总体而言,传输延迟属于不可控延迟,暂时没有什么好的技术方案来解决。

存储空间:数据承载于实际的存储中,离线数仓承载于具体的分布式文件系统,实时数仓基于 Kafka 的消息队列系统,近实时数仓承载于数据湖存储中。这里可以抽象来看离线数仓,Event 承载于分布式文件系统,以小时分区为例,某个小时的分区本质是自然时间产生的文件的集合,时间精度退化为小时级别。

计算延迟:数据进入存储之后,与进入计算空间的时间差,t3-t2。实时数仓中,计算延迟是数据的 ProcessTime-IngestTime。离线数仓中,计算延迟是调度产生实例运行时间-数据进入存储空间的时间差。本质离线数仓和实时数仓的计算延迟在抽象上看是一致的。计算延迟在不同的数仓体系下,产生的时效不同,我们会划分为三种主流的数仓体系,秒级的实时数仓,分钟级的近实时数仓,小时级的离线数仓。可以看出,数仓的时效性差异,因为传输延迟的不可控,退化为计算延迟的差异。

02

离线、近实时、实时三种数仓

在时间维度下的成因

在离线数仓和实时数仓,常常会提到数据的有界和无界,认为离线数仓的数据是有界的,实时数仓的消息流是无界的。准确与否在于数据的确定性考量。

离线数仓的确定性,在于文件自然生成时间的确定性和不可更改性,某个小时的自然文件生成,近似等于事件时间在自然时间的确定性,反例就是我们能看到数据漂移的情况,事件时间会或多或少落入上个小时或者下个小时的自然文件生成时间。那么离线数仓的确定性,实质是数据的 IngestTime 的确定性,具有天然的文件属性,易于分割。当我们说离线数仓计算的数据是准确的时候,默认了传输延迟带来的影响很小或者默认了当前小时的数据指标的标准是文件的自然形成时间。

aaf3a0f1099263e32a74c4ad22142ee6.png

实时数仓,常常会提及不确定性或者说 Lambda 架构实际是对实时数仓的不确定性的替代方案。这种不确定性的原因是什么呢?这里分为四类情况说明,一是 ETL 的处理,从窗口上来说,是单条数据即为一个窗口,窗口的产生和销毁在一个 Event 中完成,y=window(data)。二是基于 EventTime 的时间窗口,如果再定义延迟时间,y=window(datas, datas.EventTime, delay),第三种和第四种分别就是 IngestTime 和 ProcessTime 的时间窗口函数。对比离线数仓,可以看出,基于 IngestTime 的时间窗口和离线数仓的时间语义最为一致。离线数仓在时间窗口上,可以看做为数据进入文件的自然时间所对应的小时窗口,数据所承载的文件的确定性,保证了小时窗口的数据确定性,y=window(files)。

e019a151b0c8988349eacdf6ad10fc7c.png

近实时数仓,比如基于 Iceberg 的数据湖建立的近实时数仓,在于离线数仓对比中,实际是将基于小时文件细分到分钟级别的快照文件上来,y=window(snapshots)。对比实时数仓,因为 Kafka 的 IngestTime 目前在精确性上是不精确的,基于快照的文件划分,在精确性上有一定的保证,同时在降低时效程度,从秒退化为分钟,很多场景是可以容忍的。

39cb5498d954214088513db1710247bd.png

三种在时间维度对比上看,一是在某个时间,统计的本质对业务的需求都是近似的,这个本质是传输延迟所带来的,但是这个在实践中,不影响数据的可用性和统计学意义。二是不同数仓的划分,是存储和计算技术发展所带来的。三是离线数仓的确定性模糊了传输延迟,实时数仓的不确定性,是对传输延迟的一种取舍,人为的限定了 EventTime 的最大延迟时间,从而保证了指标的时效性,都是具有实践的意义所在。

03

Lambda 和 Kappa 架构

在时间维度下的取舍

当离线数仓刚刚发展的时候,只有一种数仓架构,也是基于大数据分布式处理刚刚发展的原因。随着实时技术的发展,大家在时效性上有了更多要求,但是同离线数仓对比的时候,在数据的准确性上,因为统计的窗口不同,必然会导致某个时刻的指标结果的不严格一致。

为了解决这种不严格一致的情况,Lambda 架构(由 Storm 的作者 Nathan Marz 提出的)产生的,实时确保时效,离线确保准确。最终会以确保离线三个时间窗口的统计一个事件时间窗口的结果,来回补实时数仓以为 EventTime 窗口,因为时效性丢弃的延迟数据的结果,从而保证业务上对 EventTime 窗口的要求,或者默认为离线的 IngestTime 所产生的文件分区近似认为 EventTime 的时间窗口。这种带来的弊端,维护两套数据路线,而大家总在想办法解决。

Kappa 架构的提出,得益于实时计算的效率提升,但是因为在批处理技术短板,生产实践推广受限。Kappa 架构是基于实时 EventTime 的一种数据窗口处理,因为 Kafka 的 IngestTime 不精确和为了同离线数仓对比而权衡考虑,EventTime 在传输延迟上的不可控,导致 Kappa 架构的准确性就会出现折扣。虽然是业务上最准确的时间范围,可行性上确不佳。

近些年来,不断发展的 MPP 架构的 OLAP 查询引擎,并不会涉及到时间窗口的计算取舍,OLAP 引擎本质是基于 ProcessTime 来加速查询的一种技术手段,是数仓不可分割的一部分,但是传输延迟的不可控没有解决,但是将计算延迟下推到了查询时,通过快速查询来解决尽可能减少计算延迟,同时保证了查询的灵活性,自助分析探索上有着广泛的应用。

从数仓架构的发展上看,不断在围绕结果的确定性,技术的可行性,数据的时效性,查询的灵活性上,不断的权衡,各个组件也是依据实际需求而发展起来的。

04

数仓一体的可行性思考

基于三种数仓体系和两种架构的思考,每个设计都是兼顾一种或多种考量,那么能不能实现一种机制,能够较好的满足数仓需求体系建设呢?从目前的技术发展上看,是有一定的可能性的。架构体系的发展一是基于技术基础,二是不断吸收组件的优点,做加法。

除去实时、近实时、离线数仓的划分,从技术的视角去看数仓建设的可行性。那么我们就要选取一些重要的点,取舍掉一些不可能的实现。

第一点是结果的确定性,这点是基于离线数仓发展的思考。不确定性带来的问题是信息的不对称,确定性的结果是可以模糊一定的指标含义的。

第二点是数据的时效性,高时效必然能够满足低时效,反之不然。另外数据的时效性,本身是基础组件的技术发展所限制的。

第三点是开发的便利性,排在时效性后面的考虑是,便利性是基于应用层面建设的,难度一般是弱于基础组件的,可以通过不断实践优化,达到一个良好的使用体验。

第四点是查询的灵活性和高响应,OLAP 的基础设计保证了查询速度,那么 OLAP 的技术架构体现是可以复用或者拓展的。

那么基于上面四点考虑,可以在实时数仓的基础上,优先解决掉确定性问题。这个是很重要的一个命题,要保证计算结果同离线数仓的一致性。这一点的实现方面,可以参考离线数仓,模糊 EventTime 和 IngestTime,用文件的 start 和 end 作为确定性的依据,文件的中间实时计算,确保时效性。那么基于Flink,就需要实现一种基于文件自然分割的 Watermark 机制,作为计算窗口划分的依据。

在确定性问题之后,需要解决计算的成本和使用的成本,这里比较重要的是存储层,实时数仓依赖 Kafka,Kafka 发展不具备数仓一些重要的点,成本是一个方面,查询是一个方面,Kafka 无法架构在各种 OLAP 引擎或者计算引擎上面。这里,近实时数仓的依赖,比如数据湖或者 Paimon,数据湖分钟级的时效。不过,从发展的角度上看,是一种可行的解决方案。数据湖兼顾了流计算和批计算,同时,如果未来 OLAP 引擎如果能够在数据湖上实现类似 MPP 架构的查询效率,这也是有可能的,比如短期可以用数据冗余,将数据湖格式的数据转换一份到 OLAP 对应的引擎上实现加速查询。

第三个方面,流式计算的管理和依赖机制,借鉴于离线数仓的管理方式,需要一套完备的数据依赖管理,任务容错回跑机制。实时数仓一般是基于单个任务式的管理,离线数仓是基于任务流的管理,那么实时数仓的发展,也必然要实现任务流的管理方式,覆盖整个开发链路。

为了实现一种统计的数仓架构,那么需要的发展工作如下:一是着重发展存储层,比如数据湖,既要比较好的适应流和批引擎,又要能够高度适应 OLAP 查询引擎。二是在实时数仓或者近实时数仓,引入类似离线数仓的调度依赖管理和补数和容错回跑机制,或者在离线调度上兼容流任务依赖调度,实现任务流级别的管理和流批一体的数仓实现。三是在引擎层着重发展Flink批处理能力。

1019f05db88b000b0a733a4772014c6a.png

最终的任务运行方式同时包含三种:实时模式、离线模式、业务模式,分别对应着不同的数据准确性级别。也可以任选其一或者其二作为运行方式。

05

基于 Flink 和数据湖

的流批一体近实时数仓设计示例

数仓任务在离线调度和实时任务的简单抽象示例:

数据源=>同步任务/实时任务 =>

stg_table(partition=hour) =>计算任务(insert overwrite partition=hour)=>

dwd_table(partition=hour)=>计算任务(insert overwrite partition=hour)=>

dws_table(partition=hour)=>同步任务=>OLAP 加速=>数据服务

如果存储层是基于数据湖(以 Paimon 为例):

离线调度产生的表的版本信息,commit_kind: insert overwrite 类型的。同时离线任务的驱动,是基于调度依赖的驱动,one by one 的调度。

如果是基于流式计算,比如分钟级生成snapshot那么会演变为:

数据源=>同步任务/实时任务 =>

stg_table(version=snapshot_id) =>计算任务(insert into version=snapshot_id)=>

dwd_table(version=snapshot_id)=>计算任务(insert into version=snapshot_id)=>

dws_table(version=snapshot_id)=>同步任务=>OLAP 加速=>数据服务

那么启动多个任务,任务是持续的运行。commit_kind: insert into类型的。

那么要想实现流批一体的近实时数仓,需要解决如下问题:

1. Flink 任务支持批量计算能力要持续不断的加强

从 Flink 1.16/1.17 的版本发布情况,在批处理能力上有比较大的提升,同时,社区也在持续不断的加强批处理能力以及同 hive 的兼容能力。

2. 如何使用同一份 Flink SQL,既可以用于批任务调度,又可以用于流任务运行呢

两张表:dwd_partition_word_count,dws_partition_word_count,计算 word count

 
 
CREATE TABLE tablestore.tablestore_test.dwd_partition_word_count (
  logdate String,
    user_id bigint
) PARTITIONED BY (logdate)
WITH (
    'bucket' = '3'
);


CREATE TABLE tablestore.tablestore_test.dws_partition_word_count (
  logdate String,
    user_id bigint,
    cnt BIGINT,
    PRIMARY KEY (logdate,user_id) NOT ENFORCED
) PARTITIONED BY (logdate)
WITH (
    'bucket' = '3'
);

批任务的 Flink SQL:

insert overwrite tablestore.tablestore_test.dws_partition_word_count PARTITION(logdate=${start_date}) 
select user_id,count(1) as cnt from tablestore.tablestore_test.dwd_partition_word_count where logdate=${start_date} group by user_id;
-- 或者
insert overwrite tablestore.tablestore_test.dws_partition_word_count
select logdate, user_id,count(1) as cnt from tablestore.tablestore_test.dwd_partition_word_count where logdate=${start_date} group by logdate,user_id;

流任务的 Flink SQL:

insert into tablestore.tablestore_test.dws_partition_word_count 
select logdate,user_id,count(1) as cnt from tablestore.tablestore_test.dwd_partition_word_count group by logdate,user_id;

如何用一个 Flink SQL 来实现流批模型下的不同呢?

不同点:Insert into 和 Insert overwrite 的问题,这个通过在提交运行模式的时候,如果是批任务,则是 Insert Overwrite,如果是流任务,则转为 Insert into,这个在技术上没有什么难点。

不同点:Where 条件的数据范围问题。抽象来看,流任务和批任务的时间范围在表达上是可以统一的

insert overwrite tablestore.tablestore_test.dws_partition_word_count
select logdate, user_id,count(1) as cnt from tablestore.tablestore_test.dwd_partition_word_count where logdate>=${start_date} and logdate<=${end_date} group by logdate,user_id;

比如跑 4 月 22 号一天的数据,执行的批 SQL 为:

insert overwrite tablestore.tablestore_test.dws_partition_word_count
select logdate, user_id,count(1) as cnt from tablestore.tablestore_test.dwd_partition_word_count where logdate>='20230422' and logdate<='20230422' group by logdate,user_id;

如果用流模式跑,执行的 SQL 可以为:

select logdate, user_id,count(1) as cnt from tablestore.tablestore_test.dwd_partition_word_count where logdate>='19700101' and logdate<='99990101' group by logdate,user_id;

insert overwrite/into 和时间范围,可以由平台执行的时候自动转换和参数输入。

3. 批任务的调度和流任务的计算如何分离

任务完成开发,在批模式下,用调度任务验证了逻辑无误,那么之后可以用流模式,一直持续不断的运行。一是计算逻辑变更或者历史数据修复怎么办,二是可不可以支持流批双跑。其实本质是一个问题。如果计算逻辑变更,那么可以修改流批一体的 SQL 逻辑,然后流任务重启应用新的计算逻辑。同时,流批一体的 SQL,在调度上回跑历史数据,重新刷写数据。

重刷历史数据的时候,流任务会不会读取到重刷的历史数据进行计算。

这个问题主要是通过上述说的数据湖版本 commit kind 解决。批任务只应用 insert overwrite,流任务应用 insert into.如果流任务检测到 insert overwrite 的版本提交,直接跳过,不做实际的数据读取和处理。只处理 insert into  的数据。实际批任务的执行,对流任务不会产生影响。

目前在数据湖流式读取上,只需要加个开关选项就可以实现。

4. 流任务的 Insert into 如何实现主键写入

如果流任务的 Insert into 不能实现主键写入,那么分区数据的重复性无法解决,那么就只能流批双跑来解决数据的重复性问题。也就是,下游如果是主键幂等写入,insert into 和 insert overwrite 语义等同。

这个可以通过数据湖主键表(比如 Paimon 的主键表)实现。Paimon 的主键表已初步具备生产可用性。

5. 流批任务的调度依赖

如果一个流任务,下游接的是批任务调度,如果实现调度依赖呢?

比较优雅的实现可以是,在流任务写入下游表的时候,假如数据的 Watermark 写入到下游表的属性中,如果最晚的数据已经是当前小时的 05 分,那么当前小时的下游调度任务,通过检查表的属性时间,就可以判断批任务的调度实例是否应该拉起。或者也可以基于流任务的运行延迟做检查依赖。

基于上述的实现和解决,我们基本就可以实现流批一体的 Flink SQL 在批模式和流模式下运行,如果调度依赖做的比较完善的情况下,可以实现流批混跑。同时补数或者双跑对流任务的稳定性不会产生影响。

实际开发,就可以用批任务先开发验证,然后用流模式拉起,数据产出基本是分钟级别的。出问题可以用批任务修正。

往期精选

177c5ffe6a765d33ba61973468761633.png

bbdfeec26918da7ed0a758bc022b6cd8.jpeg

36157cd305e5a4ef5424b511dac67014.jpeg

79b928b7cb55e4023313618a7ba6af3e.jpeg

907ab14930d224729008d7cae544616e.jpeg


▼ 活动推荐▼

a36987359bfb8f34b70b3e19ed55ecfd.png

▼ 关注「Apache Flink」,获取更多技术干货 ▼

a9ef019ef3666ba47bd2cfe261bfa590.png

 c565a11c2f3e5c762e08c9e38e3e8bbc.gif  点击「阅读原文」,查看更多技术内容

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

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

相关文章

【JS】1686- 重学 JavaScript API - Clipboard API

&#x1f3dd; 1. 什么是 Clipboard API 1.1 概念介绍 Clipboard API[1] 是一组 JavaScript API&#xff0c;用于在浏览器中操作剪贴板。通过 Clipboard API&#xff0c;开发者可以将文本、图片和其他数据复制到剪贴板&#xff0c;也可以从剪贴板中读取数据&#xff0c;实现复制…

OPPO解散芯片团队的真相,真的不缺钱?

OPPO解散芯片研发团队&#xff0c;各方都喜欢说OPPO不缺钱&#xff0c;解散芯片研发团队应该不是因为资金问题&#xff0c;然而仔细看看当下全球智能手机市场的表现&#xff0c;就未必会如此想了。 全球手机市场的出货量在2022年下跌了12%&#xff0c;跌穿了12亿部&#xff1b;…

【JVM】4. 虚拟机栈

文章目录 4.1. 虚拟机栈概述4.1.2. 初步印象4.1.3. 内存中的栈与堆4.1.4. 虚拟机栈基本内容Java虚拟机栈是什么&#xff1f;生命周期作用栈的特点面试题&#xff1a;开发中遇到哪些异常&#xff1f; 4.2. 栈的存储单位4.2.1. 栈中存储什么&#xff1f;4.2.2. 栈运行原理4.2.3. …

GPT理解的CV:基于Yolov5的半监督目标检测

关注并星标 从此不迷路 计算机视觉研究院 公众号ID&#xff5c;ComputerVisionGzq 学习群&#xff5c;扫码在主页获取加入方式 计算机视觉研究院专栏 作者&#xff1a;Edison_G 主要贡献是提出了一种名为“Efficient Teacher”的半监督目标检测算法。与传统的监督学习算法不同&…

10人面试9个答错?鹅厂T12详解MySQL加锁机制

&#x1f449;腾小云导读 鹅厂有一道关于「数据库锁」的面试题。我们发现其实很多 DBA &#xff08;数据库管理员&#xff0c;Database administrator&#xff09;包括工作好几年的 DBA 都答得不太好。这说明 MySQL 锁的机制其实还是比较复杂&#xff0c;值得深入研究。本文对3…

探索Vue的组件世界-实现Vue插件

一个好的框架满足几大设计原则&#xff1a; 开闭原则&#xff1a;对修改源码关闭&#xff0c;对功能扩展开放 vue作为一个优秀的组件框架&#xff1a;满足开闭原则&#xff0c;提供良好的插件机制&#xff0c;以提供三方来扩展功能 Mixin模式 Vue.mixin(mixin) 全局注册的m…

嵌入式 QT 定时器与计时器

目录 1、定时器 2、计时器 2.1 QTime 时间转换成字符串函数 3、QT 获取日期&#xff0c;时间&#xff0c;星期 4、综合应用 定时器是用来处理周期性事件的一种对象&#xff0c;类似于硬件定时器。例如设置一个定时器的定时周期为 1000 毫 秒&#xff0c;那么每 1000 毫秒就会…

现在的00后,真是卷死了呀,辞职信准备好了·····

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。这不&#xff0c;三月份春招我们公司来了个00后&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪23K&#xff0c;都快接近我了。 后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了…

Kali-linux使用社会工程学工具包(SET)

社会工程学工具包&#xff08;SET&#xff09;是一个开源的、Python驱动的社会工程学渗透测试工具。这套工具包由David Kenned设计&#xff0c;而且已经成为业界部署实施社会工程学攻击的标准。SET利用人们的好奇心、信任、贪婪及一些愚蠢的错误&#xff0c;攻击人们自身存在的…

python使用海龟turtle实现绘制汉字、中文

一、实现要求 使用python中的turtle库绘制指定汉字、中文 二、实现思路 1、要想实现汉字的绘制&#xff0c;首先需要知道汉字的笔画坐标&#xff0c;汉字的笔画坐标在网上有&#xff0c;需要使用爬虫技术抓取到指定汉字的笔画坐标信息 2、根据汉字的笔画坐标信息&#xff0c;使…

基于Kubernetes的电商平台部署:实现高可用、弹性伸缩与容器化管理

▲ 点击上方"DevOps和k8s全栈技术"关注公众号 背景&#xff1a;电商平台的高可用性和可伸缩性是保证用户体验和业务发展的重要因素。Kubernetes&#xff08;K8s&#xff09;作为一个容器编排平台&#xff0c;可以提供强大的容器管理和自动化部署能力&#xff0c;使得…

人手一个 Midjourney,StableStudio 重磅开源!

公众号关注 “GitHubDaily” 设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01; 上个月 19 号&#xff0c;Stability AI 开源大语言模型 StableLM&#xff0c;模型的 Alpha 版本有 30 亿和 70 亿参数&#xff0c;并支持商用。 过去仅一个月&#xff0c;Stability AI 再次…

鉴权管理系统(JWT技术架构)——SpringBoot2+Vue2(一定惊喜满满,万字长文)

初衷&#xff1a; 一直不太理解整个前后端的鉴权&#xff0c;跨域等问题&#xff0c;抽空两个晚上整理出万字文章&#xff0c;也是对于自己的一个交代&#xff0c;现在共享出来&#xff0c;希望大家也能受益&#xff0c;将使用过程在这里一一详述&#xff0c;还是多说一句&…

简述 JavaScript 中 prototype

简述 JavaScript 中 prototype 这篇笔记主要捋一下这么几个概念&#xff1a; JS 的继承构造函数new 的作用及简易实现__proto__ & prototype同样的方法&#xff0c;class 和 prototype 中分别是怎么实现的 基础概念 JS 是通过 prototype chaining 实现继承的语言&#…

linux(缓冲区学习)

目录&#xff1a; 1.对进程是如何和这个进程打开文件进行关联的总结 2.标准输出和标准错误都是往显示器上打印--有何区别 3.缓冲区 --------------------------------------------------------------------------------------------------------------------------- 1.对进程是…

双模齐下,提质增效:知微携手CODING共创BizDevOps体系新篇章

为了提升工作和管理效率&#xff0c;工具建设是许多企业不得不面对的现实&#xff0c;然而在工具建设落地过程中&#xff0c;往往存在一系列的问题。如不同组织、部门之间互不相通&#xff0c;各自为政&#xff0c;工具流程与实际工作所需不符&#xff0c;导致工具建设的结果是…

做实大模型的产业价值,度小满深耕“NLP+金融”

2023年的五月&#xff0c;称得上一句AI之夏。 大模型层出不穷、扎堆发布。 这一轮由大模型推动的AI热潮中&#xff0c; NLP&#xff08;自然语言处理&#xff09;技术与金融落地场景的结合备受期待。金融行业是数字化、智能化的先行者&#xff0c;也是大模型技术落地的最佳领域…

chatgpt赋能Python-python3h怎么操作

Python3 SEO操作指南 Python3语言已成为计算机编程领域的标准和主要工具之一。SEO&#xff08;Search Engine Optimization&#xff09;是一种促进网站在搜索引擎结果中排名的技术。Python3也可以用来执行SEO操作&#xff0c;本文将介绍如何使用Python3进行SEO操作&#xff0c…

替换字符串的关键字KeywordProcessor

【小白从小学Python、C、Java】 【等级考试500强双证书考研】 【Python-数据分析】 替换字符串的关键字 KeywordProcessor [太阳]选择题 以下说法错误的一项是&#xff1a; from flashtext import KeywordProcessor myKP KeywordProcessor() myKP.add_keyword(English, Math) …

别在碳排放问题上大搞双重标准!

* * * 原创&#xff1a;刘教链 * * * 隔夜比特币从26.5k一线奋力跃升&#xff0c;回升至27.5k一线。 最近美国有些人又要对比特币的碳排放搞双重标准了。说的是比特币挖矿烧掉了多少多少电力&#xff0c;折合多少多少碳排放&#xff0c;因此应当加征多少多少排放税&#xff0c…