PostgreSQL中vacuum 物理文件truncate发生的条件

前言

前段时间,有些同学说到vacuum截断的行为时,认为,只要末尾是空页,无论多少,都会被截断,真是这样的吗?

PostgreSQL当中,由于vacuum的操作并不总能将死元组的空间进行”物理截断”,虽然说是回收了(表示空间可重用),但是真正的物理文件的大小依然不会收缩。那么什么时候这个空间会被真正截断呢?

我们不妨看看源代码:

摘自: src/backend/access/heap/vacuumlazy.c/** Space/time tradeoff parameters: do these need to be user-tunable?** To consider truncating the relation, we want there to be at least* REL_TRUNCATE_MINIMUM or (relsize / REL_TRUNCATE_FRACTION) (whichever* is less) potentially-freeable pages.*/
#define REL_TRUNCATE_MINIMUM    1000
#define REL_TRUNCATE_FRACTION    16/** should_attempt_truncation - should we attempt to truncate the heap?** Don't even think about it unless we have a shot at releasing a goodly* number of pages.  Otherwise, the time taken isn't worth it, mainly because* an AccessExclusive lock must be replayed on any hot standby, where it can* be particularly disruptive.** Also don't attempt it if wraparound failsafe is in effect.  The entire* system might be refusing to allocate new XIDs at this point.  The system* definitely won't return to normal unless and until VACUUM actually advances* the oldest relfrozenxid -- which hasn't happened for target rel just yet.* If lazy_truncate_heap attempted to acquire an AccessExclusiveLock to* truncate the table under these circumstances, an XID exhaustion error might* make it impossible for VACUUM to fix the underlying XID exhaustion problem.* There is very little chance of truncation working out when the failsafe is* in effect in any case.  lazy_scan_prune makes the optimistic assumption* that any LP_DEAD items it encounters will always be LP_UNUSED by the time* we're called.*/
static bool
should_attempt_truncation(LVRelState *vacrel)
{BlockNumber possibly_freeable;if (!vacrel->do_rel_truncate || VacuumFailsafeActive)return false;possibly_freeable = vacrel->rel_pages - vacrel->nonempty_pages;if (possibly_freeable > 0 &&(possibly_freeable >= REL_TRUNCATE_MINIMUM ||possibly_freeable >= vacrel->rel_pages / REL_TRUNCATE_FRACTION))return true;return false;
}

从代码里头可以看出,只有不少于1000个空页或者空页比例不低于总页数/16的情况下,才会真正发生truncate。两者必须满足其中之一。

这方面的原理分析,在cc老师的文章里都有谈及 (https://mp.weixin.qq.com/s/ymFYOAGin2kqo96gfNYDnQ),为加深印象,我们可以通过实验来进一步验证。

实验验证

-- 安装几个内置的插件:
create extension pg_buffercache;
create extension pg_freespacemap;
create extension pageinspect;
create extension pg_visibility;
create extension pgstattuple

准备表及数据

CREATE OR REPLACE FUNCTION random_string( int ) RETURNS TEXT as $$
SELECT string_agg(substring('abcdefghijklmnopqrstuvwxyz', round(random() * 25 + 0.5)::integer, 1), '') FROM generate_series(1, $1); 
$$ language sql;postgres=# create table t(id int primary key, col2 varchar(4000));
CREATE TABLE
postgres=# insert into t select n, random_string(2000) from generate_series(1, 4000) as n;
INSERT 0 4000

相当于是建一个表t, 往里边插入4000条数据。里边使用随机串,主要是为了避免字符串压缩。我们看看相关表大小。

select pg_total_relation_size('t') total, pg_table_size('t') table, pg_indexes_size('t') indexes, pg_table_size('t')+pg_indexes_size('t') as sum, pg_relation_size('t') relation, pg_table_size('t')-pg_relation_size('t') as toast;total  |  table  | indexes |   sum   | relation | toast
---------+---------+---------+---------+----------+-------8331264 | 8224768 |  106496 | 8331264 |  8192000 | 32768
(1 row)

我们看到,上边的空间大小主要集中在表本身。因为实际插入长度2000左右,还不会进入到Toast空间。

postgres=# select min(blkno), max(blkno) from pg_freespace('t');min | max
-----+-----0 | 999
(1 row)postgres=# select pg_relpages('t');pg_relpages
-------------1000
(1 row)postgres=# select * from pgstattuple('t') \gx
-[ RECORD 1 ]------+--------
table_len          | 8192000
tuple_count        | 4000
tuple_len          | 8128000
tuple_percent      | 99.22
dead_tuple_count   | 0
dead_tuple_len     | 0
dead_tuple_percent | 0
free_space         | 20000
free_percent       | 0.24

可以看出,这个表实际占用了1000个页面(每4条记录占用一页,符合预期)。

删除末尾的4条记录

我们就只删除末尾的4条记录,看下情况,相当于是最后一页。

postgres=# delete from t where id >= 3997;
DELETE 4
postgres=# select * from pgstattuple('t') \gx
-[ RECORD 1 ]------+--------
table_len          | 8192000
tuple_count        | 3996
tuple_len          | 8119872
tuple_percent      | 99.12
dead_tuple_count   | 0
dead_tuple_len     | 0
dead_tuple_percent | 0
free_space         | 28128
free_percent       | 0.34postgres=# vacuum verbose t;
INFO:  vacuuming "public.t"
INFO:  table "t": index scan bypassed: 1 pages from table (0.10% of total) have 4 dead item identifiers
INFO:  table "t": found 0 removable, 0 nonremovable row versions in 1 out of 1000 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223185
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  vacuuming "pg_toast.pg_toast_29708"
INFO:  table "pg_toast_29708": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223186
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
postgres=# select * from pgstattuple('t') \gx
-[ RECORD 1 ]------+--------
table_len          | 8192000
tuple_count        | 3996
tuple_len          | 8119872
tuple_percent      | 99.12
dead_tuple_count   | 0
dead_tuple_len     | 0
dead_tuple_percent | 0
free_space         | 28128
free_percent       | 0.34

上边的信息也可以看到,并没有什么截断发生。统计一下物理空间:

select pg_total_relation_size('t') total, pg_table_size('t') table, pg_indexes_size('t') indexes, pg_table_size('t')+pg_indexes_size('t') as sum, pg_relation_size('t') relation, pg_table_size('t')-pg_relation_size('t') as toast;total  |  table  | indexes |   sum   | relation | toast
---------+---------+---------+---------+----------+-------8339456 | 8232960 |  106496 | 8339456 |  8192000 | 40960
(1 row)

表的物理大小,仍然为:8192000

postgres=# select pg_relation_filepath('t');pg_relation_filepath
----------------------base/13236/29708\! stat postgres/data/base/13236/29708
16777234 104752459 -rw------- 1 ***** ***** 0 8192000 "Feb  4 06:40:12 2024" "Feb  4 06:44:03 2024" "Feb  4 06:44:03 2024" "Feb  4 06:40:12 2024" 4096 16512 0 postgres/data/base/13236/29708

继续删除12条记录:

postgres=# delete from t where id >= 4000 - 16 + 1;
DELETE 12
INFO:  vacuuming "public.t"
INFO:  table "t": index scan bypassed: 4 pages from table (0.40% of total) have 16 dead item identifiers
INFO:  table "t": found 16 removable, 3984 nonremovable row versions in 1000 out of 1000 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223205
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  vacuuming "pg_toast.pg_toast_29729"
INFO:  table "pg_toast_29729": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223205
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
postgres=# select pg_total_relation_size('t') total, pg_table_size('t') table, pg_indexes_size('t') indexes, pg_table_size('t')+pg_indexes_size('t') as sum, pg_relation_size('t') relation, pg_table_size('t')-pg_relation_size('t') as toast;total  |  table  | indexes |   sum   | relation | toast
---------+---------+---------+---------+----------+-------8339456 | 8232960 |  106496 | 8339456 |  8192000 | 40960
(1 row)

累计16个页面:

postgres=# delete from t where id >= 4000 - 64 + 1;
DELETE 32
postgres=# vacuum verbose t;
INFO:  vacuuming "public.t"
INFO:  table "t": index scan bypassed: 16 pages from table (1.60% of total) have 64 dead item identifiers
INFO:  table "t": found 32 removable, 0 nonremovable row versions in 16 out of 1000 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223209
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  vacuuming "pg_toast.pg_toast_29729"
INFO:  table "pg_toast_29729": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223210
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM

还是一点动静都没有。

那么要多少个空页,才有效:1000/16 = 62页? 

我们不妨逐步推进这个实验,累计16一直往上,看到底多少次以后,开始有截断?

。。。。。。

发现,删除80条记录(20个页面),结果不变

删除84条记录时,结果仍不变。

删除88条记录的时候(22个页面),这个时候会截断20个页面。(INFO:  table "t": truncated 1000 to 980 pages)

postgres=# delete from t where id >= 4000 - 88 + 1;
DELETE 8
postgres=# vacuum verbose t;
INFO:  vacuuming "public.t"
INFO:  table "t": index scan bypassed: 2 pages from table (0.20% of total) have 8 dead item identifiers
INFO:  table "t": found 8 removable, 0 nonremovable row versions in 22 out of 1000 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223218
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  table "t": truncated 1000 to 980 pages
DETAIL:  CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
INFO:  vacuuming "pg_toast.pg_toast_29736"
INFO:  table "pg_toast_29736": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223219
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUMpostgres=# select pg_relpages('t');pg_relpages
-------------980
(1 row)

事实上,我们发现,在删除87条记录的时候,仍然不会发生截断:

postgres=# delete from t where id >= 4000 - 87+1; vacuum verbose t;
DELETE 1
INFO:  vacuuming "public.t"
INFO:  table "t": index scan bypassed: 1 pages from table (0.10% of total) have 3 dead item identifiers
INFO:  table "t": found 1 removable, 1 nonremovable row versions in 22 out of 1000 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223228
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  vacuuming "pg_toast.pg_toast_29743"
INFO:  table "pg_toast_29743": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223228
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM

autovacuum禁掉,去除影响

我们禁掉autovacuum, 并进行连续操作

drop table t;create table t(id int, col2 varchar(4000)); alter table t SET (autovacuum_enabled = off); insert into t select n, random_string(2000) from generate_series(1, 4000) as n;postgres=# insert into t select n, random_string(2000) from generate_series(1, 4000) as n;
INSERT 0 4000
postgres=# delete from t where id >= 4000 - 88+1; vacuum verbose t;
DELETE 88
INFO:  vacuuming "public.t"
INFO:  table "t": removed 88 dead item identifiers in 22 pages
INFO:  table "t": found 88 removable, 3912 nonremovable row versions in 1000 out of 1000 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223240
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  vacuuming "pg_toast.pg_toast_29756"
INFO:  table "pg_toast_29756": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223240
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
postgres=# select pg_relpages('t');pg_relpages
-------------1000
(1 row)

如果我们快速进行处理:

postgres=# drop table t;create table t(id int, col2 varchar(4000)); alter table t SET (autovacuum_enabled = off); insert into t select n, random_string(2000) from generate_series(1, 4000) as n;
DROP TABLE
CREATE TABLE
ALTER TABLE
INSERT 0 4000
postgres=# delete from t where id >= 4000 - 247+1; vacuum verbose t; select pg_relpages('t');
DELETE 247
INFO:  vacuuming "public.t"
INFO:  table "t": removed 247 dead item identifiers in 62 pages
INFO:  table "t": found 247 removable, 3753 nonremovable row versions in 1000 out of 1000 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223267
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  vacuuming "pg_toast.pg_toast_29776"
INFO:  table "pg_toast_29776": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223267
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUMpg_relpages
-------------1000
(1 row)-- 再执行一次
postgres=# delete from t where id >= 4000 - 247+1; vacuum verbose t; select pg_relpages('t');
DELETE 0
INFO:  vacuuming "public.t"
INFO:  table "t": found 0 removable, 0 nonremovable row versions in 1 out of 1000 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223267
Skipped 0 pages due to buffer pins, 60 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  table "t": truncated 1000 to 939 pages
DETAIL:  CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
INFO:  vacuuming "pg_toast.pg_toast_29776"
INFO:  table "pg_toast_29776": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223268
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUMpg_relpages
-------------939
(1 row)

这里会因为:  Skipped 0 pages due to buffer pins, 60 frozen pages.,  最后还是触发truncate. 但是从实验结果来看,在没有到达62个页面之前,第一次插,确实没有被trunate.

删除62个页面对应的记录:

postgres=# drop table t;create table t(id int primary key, col2 varchar(4000)); alter table t SET (autovacuum_enabled = off); insert into t select n, random_string(2000) from generate_series(1, 4000) as n;
DROP TABLE
CREATE TABLE
ALTER TABLE
INSERT 0 4000
postgres=# delete from t where id >= 4000 - 248+1; vacuum verbose t; select pg_relpages('t');
DELETE 248
INFO:  vacuuming "public.t"
INFO:  scanned index "t_pkey" to remove 248 row versions
DETAIL:  CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
INFO:  table "t": removed 248 dead item identifiers in 62 pages
DETAIL:  CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
INFO:  index "t_pkey" now contains 3752 row versions in 13 pages
DETAIL:  248 index row versions were removed.
0 index pages were newly deleted.
0 index pages are currently deleted, of which 0 are currently reusable.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  table "t": found 248 removable, 3752 nonremovable row versions in 1000 out of 1000 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223284
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  table "t": truncated 1000 to 938 pages
DETAIL:  CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
INFO:  vacuuming "pg_toast.pg_toast_29795"
INFO:  table "pg_toast_29795": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 223285
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUMpg_relpages
-------------938postgres=# select pg_total_relation_size('t') total, pg_table_size('t') table, pg_indexes_size('t') indexes, pg_table_size('t')+pg_indexes_size('t') as sum, pg_relation_size('t') relation, pg_table_size('t')-pg_relation_size('t') as toast;total  |  table  | indexes |   sum   | relation | toast
---------+---------+---------+---------+----------+-------7831552 | 7725056 |  106496 | 7831552 |  7684096 | 40960
(1 row)         

小结

vacuum一个表,产生物理截断,默认情况下,需要空页达到一定条件。上边的实验表明,在空页没达到1000个页同时也没达到总页数/16的情况下,第一次尝试截断,并不会真正发生。(autovacuum关闭,是为了屏蔽自动vacuum的影响)因为autovacuum还会触发freeze等其它动作,会间接产生影响。

上边的实验,禁掉auto vacuum, 在删除最后62个页面的情况下,会发生截断。

如果不禁掉auto vacuum, 你会发现在20个页面被删除的情况下,会发生截断,那刚好是autovacuum默认触发的条件(20%)。而它本身又会触发与freeze action相关的操作,最终会引发截断。

一个小实验,结合代码,可以引发很多思考。希望这个实验对vacuum原理感兴趣的人有所帮助。

与我联系:

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

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

相关文章

React——关于JSX

JSX的概述 为什么要学习jsx? ​ 我们在初建react项目的时候,需要使用到react.creatElement去写虚拟dom,在编写过程中太繁琐不直观,不利于开发,而jsx就是解决这个问题,可以直接写一段类似HTML的代码去代替…

【设计模式】Java 设计模式之桥接模式(Bridge)

桥接模式(Bridge Pattern)深入解析 一、桥接模式概述 桥接模式是一种结构型设计模式,它将抽象部分与它的实现部分分离,使它们都可以独立地变化。桥接模式是一种非常有用的设计模式,在软件系统中,某些类型…

HNU-计算机系统-实验1-原型机vspm1.0-(二周目玩家视角)

前言 二周目玩家,浅试一下这次的原型机实验。总体感觉跟上一年的很相似,但还是有所不同。 可以比较明显地感觉到,这个界面越来越好看了,可操作与可探索的功能也越来越多了。 我们HNU的SYSTEM真的越来越好了!&#x…

流程引擎接入设计

流程引擎接入设计 文章目录 流程引擎接入设计流程基础信息接入通用流程模型HDFS path删除工单类型工单流程图工单流程表与工单类型详细表关联关系流程基础信息 接入通用流程模型 交互过程 #mermaid-svg-UqP5icyFfibTMWRb {font-family:"trebuchet ms",verdana,aria…

JMeter 查看 TPS 数据,详细指南

TPS 是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。在 JMeter 中,我们可以使用以下方法查看 T…

量子遗传算法优化VMD参数,五种适应度函数任意切换,最小包络熵、样本熵、信息熵、排列熵、排列熵/互信息熵...

关于量子遗传算法,在众多文献均有应用。下面简述一下原理。 (1)量子比特编码 子遗传算法通过引入量子比特来完成基因的存储和表达。量子比特是量子信息中的概念,它与经典比特不同,是因为它可以在同一时刻处于两个状态的…

centos防火墙firewall-cmd限定特定的ip访问

文章目录 firewall-cmd是什么?启动firewalld服务查看默认区域关闭端口访问添加富规则firewall-cmd的区域概念firewall-cmd的常用选项通用选项:状态选项:永久选项:区域选项: firewall-cmd是什么? firewall-…

Kubernetes基础(二十八)-K8S调度之拓扑分布TopologySpreadConstraints

1 引言 Kubernetes(K8s)是一款开源的容器编排平台,其调度系统能够智能地将容器化应用程序部署到集群中的节点。在分布式系统中,节点的负载均衡是至关重要的,而TopologySpreadConstraints(拓扑分散约束&…

Unreal发布Android App如何面对混乱的Android SDK开发环境

Unreal发布Android App如何面对混乱的Android SDK开发环境 混乱的Android SDK开发环境Unreal 4可以借用Unity3D安装的Android环境Unreal 5需要安装Android Studio开发环境Android Studio的DK版本目录处理gradle和java版本gradle提示错误总结 混乱的Android SDK开发环境 Unreal…

2024年能源、自动化与电气工程国际会议(ICEAEE 2024)

2024年能源、自动化与电气工程国际会议(ICEAEE 2024) 2024 International Conference on Energy, Automation and Electrical Engineering 会议简介: 电气工程与自动化技术是能源自动化的重要组成部分,主要涉及电能的生成、传输…

流式数据湖平台实战 | 在Flink DataStream API中集成和使用Hudi

1.Flink Datastream API中使用Hudi 添加相应版本的maven依赖 <!-- Flink 1.13 --> <dependency><groupId>org.apache.hudi</groupId><artifactId>hudi-flink1.13-bundle</artifactId><version>0.14.0</version> </depend…

SpringMVC基础之简单程序应用

文章目录 SpringMVC 简单应用程序1. 配置2. 创建 Controller 类3. 配置控制器映射信息4. 创建视图 SpringMVC 简单应用程序 Spring MVC 是 Spring 提供的一个实现了 Web MVC 设计模式的轻量级 Web 框架。它与 Struts 2 框架一样&#xff0c;都属于 MVC 框架&#xff0c;但其使…

Python爬虫 Day1

要注意看网页的请求方式是request还是get 一、小型爬虫 &#xff08;爬百度首页&#xff09; from urllib.request import urlopen url "https://www.baidu.com" resp urlopen(url) print(resp.read().decode(utf-8)) print("over!") //&#xff01;&am…

【Hadoop】Hadoop概述与核心组件

目录 Hadoop概述Hadoop 发展历史Hadoop 三大发行版本1.Apache Hadoop&#xff08;常用&#xff09;2.Cloudera Hadoop3.Hortonworks Hadoop优势优势总结——4高&#xff08;高可靠、高扩展、高效、高容错&#xff09; Hadoop组成1.HDFS管理者&#xff1a;NameNode&#xff08;n…

css3 实现html样式蛇形布局

文章目录 1. 实现效果2. 实现代码 1. 实现效果 2. 实现代码 <template><div class"body"><div class"title">CSS3实现蛇形布局</div><div class"list"><div class"item" v-for"(item, index) …

pyflink1.18.0 报错 TypeError: cannot pickle ‘_thread.lock‘ object

完整报错 Traceback (most recent call last):File "/Users//1.py", line 851, in <module>ds1 = my_datastream.key_by(lambda x: x[0]).process(MyProcessFunction()) # 返回元组即: f0 f1 f2 三列File "/Users/thomas990p/bigdataSoft/minicondaarm/…

【测试知识】业务面试问答突击版2-----测试计划、上线、性能测试、web端移动端

文章目录 灰度发布&#xff0c;作用是&#xff1f;测试计划中测试开始条件一般包括哪些内容测试计划中的测试结束条件一般包含哪些内容测试人员是否需要代码能力&#xff0c;应用在哪些方面测试人员参与代码审核&#xff0c;重点关注什么产品上线后发现问题&#xff0c;如何产品…

音视频如何快速转二维码?在线生成音视频活码的教程

音频文件的二维码制作步骤是什么样的呢&#xff1f;扫描二维码来展现内容是很流行的一种方式&#xff0c;基本上日常生活中经常会用的图片、音频、视频等都可以使用生成二维码的方式。现在很多的幼儿园或者学校会录制孩子的音频或者视频内容用来展示&#xff0c;那么二维码制作…

鸿蒙开发实战:【音频组件】

简介 音频组件用于实现音频相关的功能&#xff0c;包括音频播放&#xff0c;录制&#xff0c;音量管理和设备管理。 图 1 音频组件架构图 基本概念 采样 采样是指将连续时域上的模拟信号按照一定的时间间隔采样&#xff0c;获取到离散时域上离散信号的过程。 采样率 采样…

Hystrix的原理及应用:构建微服务容错体系的利器(二)

本系列文章简介&#xff1a; 本系列文章旨在深入剖析Hystrix的原理及应用&#xff0c;帮助大家理解其如何在微服务容错体系中发挥关键作用。我们将从Hystrix的核心原理出发&#xff0c;探讨其隔离、熔断、降级等机制的实现原理&#xff1b;接着&#xff0c;我们将结合实际应用场…