Doris进阶介绍(三)

数据划分

        列定义

这里我们只以 AGGREGATE KEY 数据模型为例进行说明。

以AGGREGATE KEY数据模型为例进行说明。更多数据模型参阅Doris数据模型。

列的基本类型,可以通过在mysql-client中执行HELP CREATE TABLE; 查看。

AGGREGATE KEY数据模型中,所有没有指定聚合方式(SUM、REPLACE、MAX、MIN)的列视为Key列。而其余则为Value列。

定义列时,可参照如下建议:

  • Key 列必须在所有Value列之前。
  • 尽量选择整型类型。因为整型类型的计算和查找比较效率远高于字符串。
  • 对于不同长度的整型类型的选择原则,遵循够用即可。
  • 对于VARCHAR和STRING类型的长度,遵循够用即可。

所有列的总字节长度(包括 Key和Value)不能超过100KB

ENGINE(引擎)

Doris 支持的引擎有:olap|mysql|broker|hive

olap 是默认的引擎, 在 Doris 中,只有这个 ENGINE 类型是由 Doris 负责数据管理和存储的。其他 ENGINE 类型,如 mysql、broker、es、hive等等,本质上只是对外部其他数据库或系统中的表的映射,以保证 Doris 可以读取这些数据。而 Doris 本身并不创建、管理和存储任何非 olap ENGINE 类型的表和数据

​​​​​​​分区和分桶

Doris支持两层的数据划分。第一层是 Partition,支持 Range和List的划分方式。第二层是 Bucket(Tablet),仅支持Hash的划分方式。

也可以仅使用一层分区。使用一层分区时,只支持Bucket划分

​​​​​​​分区(partiton)

Partition列可以指定一列或多列。分区列必须为KEY列。多列分区的使用方式在后面介绍。

不论分区列是什么类型,在写分区值时,都需要加双引号

分区数量理论上没有上限

当不使用Partition建表时,系统会自动生成一个和表名同名的,全值范围的 Partition。

该Partition对用户不可见,并且不可删改。创建分区时不可添加范围重叠的分区。

Rang 分区(范围分区)

分区列通常为时间列( PARTITION BY RANGE(`date`) ),以方便的管理新旧数据

VALUES LESS THAN (...) 仅指定上界,系统会将前一个分区的上界作为该分区的下界,生成一个左闭右开的区间。

VALUES [...) 指定上下界,生成一个左闭右开的区间。

通过 VALUES [...) 同时指定上下界比较容易理解。这里举例说明,当使用VALUES LESS THAN (...) 语句进行分区的增删操作时,分区范围的变化情况:

  • 如上 example_range_tbl 示例,当建表完成后,会自动生成如下3个分区:

p201701: [MIN_VALUE,  2017-02-01)

p201702: [2017-02-01, 2017-03-01)

p201703: [2017-03-01, 2017-04-01)


查看一个表的所有分区信息

show partitions from example_range_tbl;


插入数据:

进入 p201701 分区

insert into test_db.example_range_tbl values (10000,'2017-01-01','北京',20,0,'2017-01-01 06:00:00',20,10,10);


没有对应的分区, 插入不成功,抛出异常

insert into test_db.example_range_tbl values (20000,'2017-11-01','北京',20,0,'2017-11-01 06:00:00',20,10,10);

  • 当我们增加一个分区 p201705 VALUES LESS THAN ("2017-06-01"),分区结果如下。

新增分区语法:

alter table example_range_tbl add partition p201705 values less than ('2017-06-01');


p201701: [MIN_VALUE,  2017-02-01)

p201702: [2017-02-01, 2017-03-01)

p201703: [2017-03-01, 2017-04-01)

p201705: [2017-04-01, 2017-06-01)

  • 此时我们删除分区 p201703,则分区结果如下:

删除分区语法:

alter table example_range_tbl drop partition p201703;


p201701: [MIN_VALUE,  2017-02-01)

p201702: [2017-02-01, 2017-03-01)

p201705: [2017-04-01, 2017-06-01)

需要注意的是,这时其他分区并不会发生变化, p201702和p201705之间就出现了一个空洞: [2017-03-01, 2017-04-01) 即如果导入的数据范围在这个空洞范围内,是无法导入的。

综上,分区的删除不会改变已存在分区的范围。删除分区可能出现空洞。通过 VALUES LESS THAN 语句增加分区时,分区的下界紧接上一个分区的上界

        List 分区(列表分区)

分区列支持 BOOLEAN, TINYINT, SMALLINT, INT, BIGINT, LARGEINT, DATE, DATETIME, CHAR, VARCHAR 数据类型,分区值为枚举值。只有当数据为目标分区枚举值其中之一时,才可以命中分区

Partition 支持通过 VALUES IN (...) 来指定每个分区包含的枚举值。

如上 example_list_tbl 示例,当建表完成后,会自动生成如下3个分区:

p_cn: ("Beijing", "Shanghai", "Hong Kong")

p_usa: ("New York", "San Francisco")

p_jp: ("Tokyo")

进入 p_cn 分区

insert into test_db.example_list_tbl values (10000,'2017-01-01','Beijing',20,0,'2017-01-01 06:00:00',20,10,10);

插入不成功, 不进入任何分区,且报错

insert into test_db.example_list_tbl values (20000,'2017-01-01','shenzhen',20,0,'2017-01-01 06:00:00',20,10,10);

当我们增加一个分区 p_uk VALUES IN ("London"),分区结果如下:

p_cn: ("Beijing", "Shanghai", "Hong Kong")

p_usa: ("New York", "San Francisco")

p_jp: ("Tokyo")

p_uk: ("London")

当我们删除分区 p_jp,分区结果如下:

p_cn: ("Beijing", "Shanghai", "Hong Kong")

p_usa: ("New York", "San Francisco")

p_uk: ("London")

​​​​​​​分桶(Bucket)

DISTRIBUTED BY HASH(`user_id`) BUCKETS 16

如果使用了 Partition,则 DISTRIBUTED ... 语句描述的是数据在各个分区内的划分规则。如果不使用 Partition,则描述的是对整个表的数据的划分规则。

分桶列可以是多列,但必须为 Key 列。分桶列可以和 Partition 列相同或不同。

分桶的数量理论上没有上限。

分桶列的选择,是在查询吞吐和查询并发之间的一种权衡:

如果选择多个分桶列,则数据分布更均匀。如果一个查询条件不包含所有分桶列的等值条件,那么该查询会触发所有分桶同时扫描,这样查询的吞吐会增加,单个查询的延迟随之降低。这个方式适合大吞吐低并发的查询场景。

如果仅选择一个或少数分桶列,则对应的点查询可以仅触发一个分桶扫描。此时,当多个点查询并发时,这些查询有较大的概率分别触发不同的分桶扫描,各个查询之间的IO影响较小(尤其当不同桶分布在不同磁盘上时),所以这种方式适合高并发的点查询场景。

​​​​​​​复合分区与单分区

复合分区:分区和分桶

单分区:只分桶(其实是所有数据在一个分区,数据只做 hash 分布)

以下场景推荐使用复合分区

有时间维度或类似带有有序值的维度,可以以这类维度列作为分区列。分区粒度可以根据导入频次、分区数据量等进行评估。

历史数据删除需求:如有删除历史数据的需求(比如仅保留最近N 天的数据)。使用复合分区,可以通过删除历史分区来达到目的。也可以通过在指定分区内发送 DELETE 语句进行数据删除。

解决数据倾斜问题:每个分区可以单独指定分桶数量。如按天分区,当每天的数据量差异很大时,可以通过指定分区的分桶数,合理划分不同分区的数据,分桶列建议选择区分度大的列。

​​​​​​​多列分区

Doris 支持指定多列作为分区列

  • Range 分区

PARTITION BY RANGE(`date`, `id`)

(

    PARTITION `p201701_1000` VALUES LESS THAN ("2017-02-01", "1000"),

    PARTITION `p201702_2000` VALUES LESS THAN ("2017-03-01", "2000"),

    PARTITION `p201703_all`  VALUES LESS THAN ("2017-04-01")

)

指定 `date`(DATE 类型) 和 `id`(INT 类型) 作为分区列。以上示例最终得到的分区如下:

p201701_1000: [(MIN_VALUE,  MIN_VALUE), ("2017-02-01", "1000")   )

p201702_2000: [("2017-02-01", "1000"),  ("2017-03-01", "2000")   )

p201703_all:  [("2017-03-01", "2000"),  ("2017-04-01", MIN_VALUE))

注意,最后一个分区用户缺省只指定了 `date` 列的分区值,所以 `id` 列的分区值会默认填充 `MIN_VALUE`。当用户插入数据时,分区列值会按照顺序依次比较,当第一列处于边界的时候, 由第二列决定,最终得到对应的分区。举例如下:

数据  -->  分区

2017-01-01, 200     --> p201701_1000

2017-01-01, 2000    --> p201701_1000

2017-02-01, 100     --> p201701_1000

2017-02-01, 2000    --> p201702_2000

2017-02-15, 5000    --> p201702_2000

2017-03-01, 2000    --> p201703_all

2017-03-10, 1       --> p201703_all

2017-04-01, 1000    --> 无法导入

2017-05-01, 1000    --> 无法导入

  • List 分区

PARTITION BY LIST(`id`, `city`)

(

    PARTITION `p1_city` VALUES IN (("1", "Beijing"), ("1", "Shanghai")),

    PARTITION `p2_city` VALUES IN (("2", "Beijing"), ("2", "Shanghai")),

    PARTITION `p3_city` VALUES IN (("3", "Beijing"), ("3", "Shanghai"))

)

指定 `id`(INT 类型) 和 `city`(VARCHAR 类型) 作为分区列。最终得到的分区如下:

p1_city: [("1", "Beijing"), ("1", "Shanghai")]

p2_city: [("2", "Beijing"), ("2", "Shanghai")]

p3_city: [("3", "Beijing"), ("3", "Shanghai")]

当用户插入数据时,分区列值会按照顺序依次比较,最终得到对应的分区。举例如下:

数据  --->  分区

1, Beijing     ---> p1_city

1, Shanghai    ---> p1_city

2, Shanghai    ---> p2_city

3, Beijing     ---> p3_city

1, Tianjin     ---> 无法导入

4, Beijing     ---> 无法导入

PROPERTIES
 

  • replication_num

副本数。默认副本数为3。如果 BE 节点数量小于3,则需指定副本数小于等于 BE 节点数量。

  • storage_medium/storage_cooldown_time

storage_medium 用于声明表数据的初始存储介质,而 storage_cooldown_time 用于设定到期时间。

"storage_medium" = "SSD",
"storage_cooldown_time" = "2020-11-20 00:00:00"

这个示例表示数据存放在 SSD 中,并且在 2020-11-20 00:00:00 到期后,会自动迁移到 HDD 存储上。

​​​​​​​动态分区

前面的分区, 必须在插入数据之前手动添加需要的分区, 使用颇多不变.

动态分区是在 Doris 0.12 版本中引入的新功能。旨在对表级别的分区实现生命周期管理(TTL),减少用户的使用负担。

目前实现了动态添加分区及动态删除分区的功能。

动态分区只支持 Range 分区

​​​​​​​原理

在某些使用场景下,用户会将表按照天进行分区划分,每天定时执行例行任务,这时需要使用方手动管理分区,否则可能由于使用方没有创建分区导致数据导入失败,这给使用方带来了额外的维护成本。

通过动态分区功能,用户可以在建表时设定动态分区的规则。FE 会启动一个后台线程,根据用户指定的规则创建或删除分区。用户也可以在运行时对现有规则进行变更

​​​​​​​使用方式

动态分区的规则可以在建表时指定,或者在运行时进行修改。当前仅支持对单分区列的分区表设定动态分区规则。

​​​​​​​建表时指定

CREATE TABLE tbl1

(...)

PROPERTIES

(

    "dynamic_partition.prop1" = "value1",

    "dynamic_partition.prop2" = "value2",

    ...

)

​​​​​​​运行时修改

ALTER TABLE tbl1 SET

(

    "dynamic_partition.prop1" = "value1",

    "dynamic_partition.prop2" = "value2",

    ...

)

​​​​​​​动态分区规则主要参数

动态分区的规则参数都以 dynamic_partition. 为前缀:

dynamic_partition.enable

是否开启动态分区特性,可指定true或false,默认为true

如果为 FALSE,则 Doris 会忽略该表的动态分区规则。

dynamic_partition.time_unit

动态分区调度的单位,可指定HOUR、DAY、WEEK、MONTH。

HOUR,后缀格式为 yyyyMMddHH,分区列数据类型不能为 DATE。

DAY,后缀格式为 yyyyMMdd。

WEEK,后缀格式为yyyy_ww。即当前日期属于这一年的第几周。

MONTH,后缀格式为 yyyyMM。

dynamic_partition.time_zone

动态分区的时区,如果不填写,则默认为当前机器的系统的时区

dynamic_partition.start

动态分区的起始偏移,为负数。根据 time_unit 属性的不同,以当天(星期/月)为基准,分区范围在此偏移之前的分区将会被删除。如果不填写默认值为Interger.Min_VALUE 即-2147483648,即不删除历史分区

dynamic_partition.end

动态分区的结束偏移,为正数。根据 time_unit 属性的不同,以当天(星期/月)为基准,提前创建对应范围的分区

dynamic_partition.prefix

动态创建的分区名前缀

dynamic_partition.buckets

动态创建的分区所对应分桶数量

dynamic_partition.replication_num

动态创建的分区所对应的副本数量,如果不填写,则默认为该表创建时指定的副本数量。

dynamic_partition.start_day_of_week

当 time_unit 为 WEEK 时,该参数用于指定每周的起始点。取值为 1 到 7。其中 1 表示周一,7 表示周日。默认为 1,即表示每周以周一为起始点

dynamic_partition.start_day_of_month

当 time_unit 为 MONTH 时,该参数用于指定每月的起始日期。取值为 1 到 28。其中 1 表示每月1号,28 表示每月28号。默认为 1,即表示每月以1号位起始点。暂不支持以29、30、31号为起始日,以避免因闰年或闰月带来的歧义

dynamic_partition.create_history_partition

默认为 false当置为 true 时,Doris 会自动创建所有分区,当期望创建的分区个数大于 max_dynamic_partition_num 值时,操作将被禁止。当不指定 start 属性时,该参数不生效。

dynamic_partition.hot_partition_num

指定最新的多少个分区为热分区。对于热分区,系统会自动设置其 storage_medium 参数为SSD,并且设置 storage_cooldown_time。

hot_partition_num 是往前 n 天和未来所有分区

我们举例说明。假设今天是 2021-05-20,按天分区,动态分区的属性设置为:hot_partition_num=2, end=3, start=-3。则系统会自动创建以下分区,并且设置 storage_medium 和 storage_cooldown_time 参数:

p20210517:["2021-05-17", "2021-05-18")

storage_medium=HDD

storage_cooldown_time=9999-12-31 23:59:59

p20210518:["2021-05-18", "2021-05-19")

storage_medium=HDD

storage_cooldown_time=9999-12-31 23:59:59

p20210519:["2021-05-19", "2021-05-20")

storage_medium=SSD

storage_cooldown_time=2021-05-21 00:00:00

p20210520:["2021-05-20", "2021-05-21")

storage_medium=SSD

storage_cooldown_time=2021-05-22 00:00:00

p20210521:["2021-05-21", "2021-05-22")

storage_medium=SSD

storage_cooldown_time=2021-05-23 00:00:00

p20210522:["2021-05-22", "2021-05-23")

storage_medium=SSD

storage_cooldown_time=2021-05-24 00:00:00

p20210523:["2021-05-23", "2021-05-24")

storage_medium=SSD

storage_cooldown_time=2021-05-25 00:00:00

dynamic_partition.reserved_history_periods

需要额外保留的历史分区的时间范围。当dynamic_partition.time_unit 设置为 "DAY/WEEK/MONTH" 时,需要以 [yyyy-MM-dd,yyyy-MM-dd],[...,...] 格式进行设置。当dynamic_partition.time_unit 设置为 "HOUR" 时,需要以 [yyyy-MM-dd HH:mm:ss,yyyy-MM-dd HH:mm:ss],[...,...] 的格式来进行设置。如果不设置,默认为 "NULL"。

我们举例说明。假设今天是 2021-09-06,按天分类,动态分区的属性设置为:

time_unit="DAY", \

end=3, \

start=-3, \

reserved_history_periods="[2020-06-01,2020-06-20],[2020-10-31,2020-11-15]"。

则系统会自动保留:

["2020-06-01","2020-06-20"],

["2020-10-31","2020-11-15"]

或者

time_unit="HOUR", \

end=3, \

start=-3, \

reserved_history_periods="[2020-06-01 00:00:00,2020-06-01 03:00:00]".

则系统会自动保留:

["2020-06-01 00:00:00","2020-06-01 03:00:00"]

这两个时间段的分区。其中,reserved_history_periods 的每一个 [...,...] 是一对设置项,两者需要同时被设置,且第一个时间不能大于第二个时间``。

        

​​​​​​​创建历史分区规则

        当 create_history_partition 为 true,即开启创建历史分区功能时,Doris 会根据 dynamic_partition.start 和 dynamic_partition.history_partition_num 来决定创建历史分区的个数。

        假设需要创建的历史分区数量为 expect_create_partition_num,根据不同的设置具体数量如下:

  • create_history_partition = true

① dynamic_partition.history_partition_num 未设置,即 -1。

则expect_create_partition_num = end - start + 1;

② dynamic_partition.history_partition_num 已设置

则expect_create_partition_num = end - max(start, -histoty_partition_num) + 1;

  • create_history_partition = false

不会创建历史分区,expect_create_partition_num = end - 0 + 1;

  • 当 expect_create_partition_num > max_dynamic_partition_num(默认500)时,禁止创建过多分区。

总结:今天的分区(1) +  end(未来的分区) + 过去的分区(start 和 history-num 谁少听谁的

假设今天是 2021-05-20,按天分区,动态分区的属性设置为:create_history_partition=true, end=3, start=-3, history_partition_num=1,则系统会自动创建以下分区:

p20210519

p20210520

p20210521

p20210522

p20210523

history_partition_num=5,其余属性与 1 中保持一直,则系统会自动创建以下分区:

p20210517

p20210518

p20210519

p20210520

p20210521

p20210522

p20210523

history_partition_num=-1 即不设置历史分区数量,其余属性与 1 中保持一直,则系统会自动创建以下分区:

p20210517

p20210518

p20210519

p20210520

p20210521

p20210522

p20210523

​​​​​​​注意事项

        动态分区使用过程中,如果因为一些意外情况导致dynamic_partition.start 和 dynamic_partition.end 之间的某些分区丢失,那么当前时间与 dynamic_partition.end 之间的丢失分区会被重新创建,dynamic_partition.start与当前时间之间的丢失分区不会重新创建

​​​​​​​动态分区创建示例

        ​​​​​​​创建动态分区表

create table student_dynamic_partition1

(

id int,

time date,

name varchar(50),

age int

)

duplicate key(id,time)

PARTITION BY RANGE(time)()

distributed by hash(`id`)

PROPERTIES(

"dynamic_partition.enable" = "true",

"dynamic_partition.time_unit" = "DAY",

"dynamic_partition.create_history_partition" = "true",

"dynamic_partition.history_partition_num" = "3",

"dynamic_partition.start" = "-7",

"dynamic_partition.end" = "3",

"dynamic_partition.prefix" = "p",

"dynamic_partition.buckets" = "10",

 "replication_num" = "1"

 );

​​​​​​​查看动态分区表调度情况

SHOW DYNAMIC PARTITION TABLES

LastUpdateTime: 最后一次修改动态分区属性的时间

LastSchedulerTime: 最后一次执行动态分区调度的时间

State: 最后一次执行动态分区调度的状态

LastCreatePartitionMsg: 最后一次执行动态添加分区调度的错误信息

LastDropPartitionMsg: 最后一次执行动态删除分区调度的错误信息

查看表的分区情况

SHOW PARTITIONS FROM student_dynamic_partition1\G

​​​​​​​插入测试数据(需要修改日期)

insert into student_dynamic_partition1 values(1,'2023-07-11 11:00:00','name1',18);

insert into student_dynamic_partition1 values(1,'2023-07-12 11:00:00','name1',18);

insert into student_dynamic_partition1 values(1,'2023-07-13 11:00:00','name1',18);

​​​​​​​动态分区表与手动分区表相互转换

对于一个表来说,动态分区和手动分区可以自由转换,但二者不能同时存在,有且只有一种状态。

手动分区转换为动态分区

如果一个表在创建时未指定动态分区,可以通过ALTER TABLE在运行时修改动态分区相关属性来转化为动态分区,具体示例可以通过HELP ALTER TABLE查看。

注意:如果已设定dynamic_partition.start,分区范围在动态分区起始偏移之前的历史分区将会被删除。

动态分区转换为手动分区

ALTER TABLE tbl_name SET ("dynamic_partition.enable" = "false")

关闭动态分区功能后,Doris将不再自动管理分区,需要用户手动通过ALTER TABLE 的方式创建或删除分区。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java面试-SpringAOP

1.SpringAOP的使用 你了解Spring AOP 吗? 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。 2.SpringAOP的原理 我们可以将ASM生成的类进行缓存,这样能解决生成的类比较低效的问题。 ASM是可以操作字节码的框架。 真实实现类和…

Windows 组策略编辑器怎么打开,这两种方法你必须知道

组策略编辑器(Group Policy Editor, 简称 GPEdit.msc)是 Windows 操作系统中一个强大的工具,主要用于管理和配置系统设置、安全选项、用户权限等,尤其适用于企业环境中批量部署和管理策略。 尽管家庭版 Windows(如 Win…

数字集群手持终端是什么_鼎跃安全

在当今快速发展的科技时代,通信技术的进步为各行各业带来了巨大的变革。尤其是在公共安全、应急救援和交通运输等领域,通信的及时性和可靠性变得尤为重要。数字集群手持终端作为一种专用于数字集群通信系统的便携式设备,数字集群手持终端是一…

ubuntu安装miniconda、jupyer、ros2

miniconda: 类似于虚拟机 ,可以安装不同版本的python jupyer: python执行、调试命令工具 1.下载安装文件 wget https://repo.anaconda.com/miniconda/Miniconda3-py310_23.5.2-0-Linux-x86_64.sh 2.安装minconda bash https://repo.anaconda.com/miniconda/Miniconda3-py…

Linux 防火墙开放端口

启动防火墙服务:systemctl start firewalld 查看防火墙开放端口 :firewall-cmd --list-ports 开放3306端口:firewall-cmd --zonepublic --add-port2375/tcp --permanent 防火墙重启:firewall-cmd --reload

第十二届信息系统与计算技术国际会议(ISCTech 2024)

随着信息技术的迅猛发展,信息系统与计算技术已成为推动社会进步和经济发展的重要力量。为了加强国内外专家学者在信息系统与计算技术领域的交流与合作,第十二届信息系统与计算技术国际会议(ISCTech 2024)将于2024年11月8日至11日在…

BK145FRC10HSK、BK165FRC10HSK电液比例开环控制变量泵放大器

BK15FRC10HAK、BK35FRC10HAK、BK45FRC10HAK、BK55FRC10HAK、BK70FRC10HSK、BK80FRC10HSK、BK90FRC10HSK、BK100FRC10HSK、BK120FRC10HSK、BK145FRC10HSK、BK165FRC10HSK、BK180FRC10HSK电液比例开环控制柱塞泵主要是在传统的液压泵基础上,增加了电液比例控制先导阀。…

git基本使用(一):git的基本概念

Git 是一种分布式版本控制系统,最初由 Linus Torvalds 于 2005 年为 Linux 内核开发。它主要用于跟踪文件的更改,特别是在软件开发过程中,可以帮助团队成员协同工作。它在实际项目开发中,应用非常广泛,我们这一节来掌握…

【web3】分享一个web入门学习平台-HackQuest

前言 一直想进入web3行业,但是没有什么途径,偶然在电鸭平台看到HackQuest的共学营,发现真的不错,并且还接触到了黑客松这种形式。 链接地址:HackQuest 平台功能 学习路径:平台有完整的学习路径&#xff…

博途(TIA Portal)自动化工程软件下载安装,TIA Portal V18软件安装包获取

博途(TIA Portal)不仅仅是一款自动化工程软件,它更是西门子自动化领域的璀璨明珠。 它能够将西门子的所有自动化产品无缝集成在一起,无论是PLC、人机界面,还是伺服系统、马达、变频器、网络组件等,博途都能…

SMS群发信息API接口安全性有哪些保障方法?

SMS群发信息API接口支持哪些格式?如何使用API接口? SMS群发信息API接口被广泛应用于企业营销、客户服务、身份验证等多个领域。确保SMS群发信息API接口的安全性,已成为企业和开发者们必须重视的问题。AoKSend将探讨几种保障SMS群发信息API接…

容器技术-docker5

一、docker-compose 常用命令和指令 1. 概要 默认的模板文件是 docker-compose.yml,其中定义的每个服务可以通过 image 指令指定镜像或 build 指令(需要 Dockerfile)来自动构建。 注意如果使用 build 指令,在 Dockerfile 中设置…

前端技术(说明篇)

Introduction ##编写内容:1.前端概念梳理 2.前端技术种类 3.前端学习方式 ##编写人:贾雯爽 ##最后更新时间:2024/07/01 Overview 最近在广州粤嵌进行实习,项目名称是”基于Node实现多人聊天室“,主要内容是对前端界…

【RabbitMQ实战】邮件发送(直连交换机、手动ack)

一、实现思路 二、异常情况测试现象及解决 说明:本文涵盖了关于RabbitMQ很多方面的知识点, 如: 消息发送确认机制 、消费确认机制 、消息的重新投递 、消费幂等性, 二、实现思路 1.简略介绍163邮箱授权码的获取 2.编写发送邮件工具类 3.编写RabbitMQ配置文件 4.生产者发起调用…

8617 阶乘数字和

这是一个关于计算阶乘结果所有位上的数字之和的问题。我们可以通过以下步骤来解决这个问题: 1. 首先,我们需要一个函数来计算阶乘。由于n的范围可以达到50,阶乘的结果可能非常大,所以我们需要使用一个可以处理大整数的数据类型&a…

零成本、高效率:免费可视化工具的魅力所在

在如今这个数据驱动的时代,免费可视化工具越来越受到人们的欢迎。这些工具不仅降低了数据分析的门槛,还为用户提供了强大的功能和极高的灵活性,使得各行各业的人们都能够轻松地利用数据做出明智的决策。首先,免费可视化工具的零成…

软件鉴定测试的工作内容是什么?专业软件鉴定测试报告获取指南

软件鉴定测试是指对软件产品进行全面的检测和评估,以验证其是否符合规定的标准和要求。通过测试,能够发现软件中存在的问题和缺陷,并提供相应的改进建议。在不同的测试阶段,使用不同的测试方法和工具,包括功能测试、性…

智慧公厕系统改变了人们对服务区公厕的看法

在过去,服务区公厕常常给人留下脏乱差的印象,成为人们在长途旅行途中不愿停留的地方。然而,随着智慧科技的不断发展和应用,智慧公厕系统的出现改变了人们对服务区公厕的看法,为公共卫生设施的提升注入了新的活力。 一、…

链路全贯通,价值引领数据能力升级|爱分析报告

数据能力已经成为企业的核心竞争力。政策驱动数据产业发展加速,如2023年国家数据局成立;2024年,《“数据要素”三年行动计划(2024-2026年)》正式发布;并且 2024年起正式将数据资源视为资产纳入财务报表&…

一键变身!Cloud-Init让PVE镜像华丽转身,快来看看怎么做!

在虚拟化环境中,自动化配置虚拟机(VM)是提高效率的关键。Proxmox VE(PVE)是一款流行的开源虚拟化平台,而Cloud-Init是一种用于初始化云实例的工具。结合PVE和Cloud-Init,我们可以快速创建和配置…