【Docker】Docker Volume(存储卷)

news2024/9/21 10:43:27

一、什么是存储卷

存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着,当我们在容器中的这个目录下写入数据时,容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的目录。

在宿主机上的这个与容器形成绑定关系的目录被称作存储卷。卷的本质是文件或者目录,它可以绕过默认的联合文件系统,直接以文件或目录的形式存在于宿主机上

宿主机的 /data/web 目录与容器中的 /container/data/web 目录绑定关系,然后容器中的进程向这个目录中写数据时,是直接写在宿主机的目录上的,绕过容器文件系统与宿主机的文件系统建立关联关系,使得可以在宿主机和容器内共享数据库内容,让容器直接访问宿主机中的内容,也可以宿主机向容器写入内容,容器和宿主机的数据读写同步容器的销毁并不会影响存储卷内的内容。


二、生活案例

存储卷就相当于租了个地下室,建立对应的映射就相当于拥有了这个地下室的钥匙,能够使用房子以外的空间。如果有一天龙卷风来了,房子被吹毁了,但是地下室依然安然无恙,就相当于容器销毁了我们的这个地下室依然没有影响。


三、为什么需要存储卷

1、数据丢失问题

容器按照业务类型,总体可以分为两类:

  1. 无状态的(数据不需要被持久化)。
  2. 有状态的(数据需要被持久化)。

显然,容器更擅长无状态应用。因为未持久化数据的容器根目录的生命周期与容器的生命周期一样,容器文件系统的本质是在镜像层上面创建的读写层,运行中的容器对任何文件的修改都存在于该读写层,当容器被删除时,容器中的读写层也会随之消失。

虽然容器希望所有的业务都尽量保持无状态,这样容器就可以开箱即用,并且可以任意调度,但实际业务总是有各种需要数据持久化场景,比如 MySQLKafka 等有状态的业务。因此为了解决有状态业务的需求,Docker 提出了卷(Volume)的概念。


2、性能问题

UnionFS 对于修改删除等,一般效率非常低,如果对一于 I/O 要求比较高的应用,如 redis 在实现持化存储时,是在底层存储时的性能要求比较高。


3、宿主机和容器互访不方便

宿主机访问容器,或者容器访问要通过 docker cp 来完成,应用很难操作。


4、容器和容器共享不方便


四、存储卷分类

目前 Docker 提供了三种方式将数据从宿主机挂载到容器中:

  • volume docker 管理卷,默认映射到宿主机的 /data/var/lib/docker/volumes 目录(默认是 /var/lib/docker/volumes,我的是因为做了修改)下,只需要在容器内指定容器的挂载点是什么,而被绑定宿主机下的那个目录,是容器引擎 daemon 自行创建一个空的目录,或者使用一个已经存在的目录,与存储卷建立存储关系,这种方式极大解脱用户在使用卷时的耦合关系,缺陷是用户无法指定那些使用目录,临时存储比较适合。
  • bind mount 绑定数据卷,映射到宿主机指定路径下,在宿主机上的路径要人工的指定一个特定的路径在容器中也需要指定一个特定的路径两个已知的路径建立关联关系。
  • tmpfs mount 临时数据卷,映射到于宿主机的内存中,一旦容器停止运行,tmpfs mounts 会被移除,数据就会丢失,用于高性能的临时数据存储


五、管理卷 

1、创建卷

存储卷可以通过命令方式创建,也可以在创建容器的时候通过 -v and --mount 指定。


(1)方式一(Volume 命令操作)

命令清单如下:


A. docker volume create
a. 功能
创建存储卷。

b. 语法
docker volume create [OPTIONS] [VOLUME]

c.  关键参数
  • -d,--driver:指定驱动,默认是 local。
  • --label指定元数据。

d. 样例

匿名卷:

命名卷:


B. docker volume inspect
a. 功能
查看卷详细信息。

b. 语法

docker volume inspect [OPTIONS] VOLUME [VOLUME...]


c. 关键参数 
  • -f指定相应个格式,如 json。

d. 样例


C. docker volume ls
a. 功能
列出卷。

b. 语法

docker volume ls [OPTIONS]  


c. 关键参数 
  • --format指定相应个格式,如 json、table。
  • --filter,-f:过滤。
  • -q:仅显示名称。

d. 样例


D. docker volume rm
a. 功能
删除卷,需要容器不使用。

b. 语法

docker volume rm [OPTIONS] VOLUME [VOLUME...]


c. 关键参数
  • -f,--force:强制删除。

d. 样例 


E. docker volume prune
a. 功能
删除不使用的本地卷。

b. 语法

docker volume prune [OPTIONS]


c. 关键参数
  • --filter:过滤。
  • -f,--force:不提示是否删除。

d. 样例


(2)方式二(-v 或者--mount 指定)

-v -mount 都可以完成管理卷的创建。

A. -v 参数
a. 功能
完成目录映射。

b. 语法

docker run -v name:directory[:options] ... ...


c. 参数 
  • 第一个参数:卷名称。
  • 第二个参数:卷映射到容器的目录。
  • 第三个参数:选项,如 ro 表示 readonly。

d. 样例 

不指定 ro 选项:

指定 ro 选项:


B.  --mount 参数
a. 功能
完成目录映射。

b. 语法

--mount '<key>=<value>,<key>=<value>'


c. 关键参数
  • type:类型表示 bind,volume,or tmpfs。
  • sourcesrc:对于命名卷,这是卷的名称。对于匿名卷,省略此字段。
  • destinationdst,target:文件或目录挂载在容器中的路径。
  • ro,readonly:只读方式挂载。
完成目录映射。

d. 样例

采用 mount 创建 volume:

通过 docker inspect 可以看到: 


(3)方式三(Dockerfile 匿名卷)

通过 Dockerfile VOLUME 可以创建 docker 管理卷。也可以通过 dockerfile VOLUME 指令在镜像中创建 Data Volume,这样只需要通过该镜像创建的容器都会存在挂载点,但值得注意的是通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,而是由 docker 随机生成的。


2、操作案例 

(1)Docker 命令创建管理卷

A. 命令创建管理卷


B. 查看其中一个管理卷

可以看到对应的宿主机目录如下:


C. 进入宿主机目录

可以放到容器里面的内容已经放到该目录中:


D. 查看容器内容

可以看到具体的 mount 信息:


E. 修改 index.html


F. 通过浏览器查看

可以看到宿主机和容器是同步的。


(2)Docker -v 创建管理卷

A. -v 创建管理卷,并且启动容器


B. 查看卷目录内容


C. 修改 index.html


D. 浏览器查看


E. 容器中修改提示无法修改

结论:指定 ro 的话宿主机可以修改,但是容器里面无法修改。


(3)Docker mount 创建管理卷

A. mount 创建管理卷,并且启动容器


B. 查看卷创建成功


C. 查看卷挂载点


D. 浏览器查看


E. 宿主机上修改文件内容


F. 查看页面


G. 清理释放空间

结论:mount 创建的卷数据也会完成同步。


(4)Docker 卷生命周期

A. -v 创建管理卷,并且启动容器


B. 进入卷目录

注意:此时可以看到容器里面的内容自动的放到了宿主机里面,也就是说宿主机上没有容器会拷贝过去。


C. 修改 index.html


D. 浏览器查看


E. 清理释放空间


F. 进入卷目录查看

可以看到文件并没有被删除:


G. 删除卷

可以看到我们的卷被删除掉了:


(5)Docker 卷共享

A. -v 创建管理卷,并且启动 2 容器,指定同一个卷


B. 进入卷目录


C. 修改 index.html


D. 浏览器查看

可以看到两个都是一样的首页:


E. 清理释放空间


六、绑定卷 bind mount

-v 和 -mount 都可以完成绑定卷的创建


1、创建卷

(1)-v 参数创建卷

A. 功能
完成卷映射。

B. 语法

docker run -v name:directory[:options] .........


C. 参数
  • 第一个参数:宿主机目录,这个和管理卷是不一样的。
  • 第二个参数:卷映射到容器的目录。
  • 第三个参数:选项,如 ro 表示 readonly。

D. 样例


(2)--mount 参数创建绑定卷

A. 功能
完成目录映射。

B. 语法

--mount '<key>=<value>,<key>=<value>'


C. 关键参数
  • type:类型表示 bind,volume or tmpfs。
  • sourcesrc:宿主机目录,这个和管理卷是不一样的
  • destinationdst,target:文件或目录挂载在容器中的路径
  • ro,readonly:只读方式挂载。

D. 样例


2、操作案例

(1)mount 创建绑定卷

A. 使用 -mount 方式创建容器

创建 nginx 容器,并将宿主机 /testbindmount1​​​​​​​ 目录挂载至容器 /usr/share/nginx/html 目录,注意如果 testbindmount1 目录不存在会启动报错。


B. 查看挂载信息

提前创建好对应目录,并在宿主机上添加 index.html:


C. 进入容器的终端,查看挂载点目录,然后查看宿主机上的文件,还是存在,说明容器删除并不影响 bind 映射

如果是第一种写法,则可以发现容器该目录本身存在的文件消失不见,这是 bind mount 模式和 volume 式最大的不同点。

D. 释放空间


(2)-v 创建绑定卷

A. 使用-v 方式创建容器

创建 nginx 容器,并将宿主机 /testbindmount3 目录挂载至容器 /usr/share/nginx/html 目录。

注意:如果 testbindmount3 目录不存在,启动不会报错,这是 -v 和 --mount 方式的区别。


B. 查看挂载信息


C. 进入容器的终端,查看挂载点目录,和在宿主机上查看里面都是没有文件

可以发现容器该目录本身存在的文件消失不见,这是 bind mount 模式和 volume 式最大的不同点。

D. 在宿主机上添加 index.html


E. 删除容器,然后查看宿主机上的文件,还是存在,说明容器删除并不影响 bind 映射


(3)绑定卷共享

A. 启动两个绑定卷,都绑定到宿主机的同一个目录


B. 修改 index.html


C. 访问 2 个页面可以看到相应内容一样

可以看到我们实现了容器间的数据共享。


D. 清理空间


七、临时卷 tmpfs

临时卷数据位于内存中,在容器和宿主机之外。

tmpfs 局限性

  • 不同于卷和绑定挂载,不能在容器之间共享 tmpfs 挂载。
  • 这个功能只有在 Linux 上运行 Docker 时才可用。

1、创建卷

(1)方式一(指定 --tmpfs 创建)

A. 功能
完成临时卷映射。

B. 语法

--tmpfs /app


​​​​​​​C. 样例


(2)方式二(--mount 指定参数创建)

A. 功能

完成目录映射。


B. 语法

--mount '<key>=<value>,<key>=<value>'


C. 关键参数
  • type:类型表示 bind, volume, or tmpfs。
  • destinationdst,target:挂载在容器中的路径。
  • tmpfs-sizetmpfs 挂载的大小(以字节为单位),默认无限制。
  • tmpfs-mode:tmpfs 的八进制文件模式。例如,700 0770,默认为 1777 或全局可写。

D. 样例


​​​​​​​2、操作案例

(1)tmpfs 参数创建临时卷

A. 创建临时卷并启动容器


B. 进入容器

可以看到 nginx 里面的文件被覆盖了,也就是说 tmpfs 也会覆盖容器里面的文件


C. 添加一个首页


D. 浏览器查看


E. 停止容器


F. 启动容器 再次进入

可以看到 tmpfs 的内容完全消失了,也就是说内容是存在内存里面的。


G. 清理空间


(2)mount 创建临时卷

A. 创建临时卷并启动容器


B. 进入容器

可以看到 nginx 里面的文件被覆盖了,也就是说 tmpfs 也会覆盖容器里面的文件


C. 添加一个首页


D. 浏览器查看


E. 拷贝一个大文件到容器里面

dockerdemo-1.0-SNAPSHOT.jar 17M。

docker cp dockerdemo-1.0-SNAPSHOT.jar mynginx18:/

F. 拷贝文件到我们的卷目录
[root@VM-8-5-centos /]# docker exec -it mynginx18 bash
root@23a13a663511:/# cd /usr/share/nginx/html/
root@23a13a663511:/usr/share/nginx/html# ls -l
total 4
-rw-r--r-- 1 root root 39 Aug 16 14:44 index.html
root@23a13a663511:/usr/share/nginx/html# ls -l /
bin dev docker-entrypoint.sh 
etc lib media opt root sbin sys tmp var
boot docker-entrypoint.d dockerdemo-1.0-SNAPSHOT.jar home lib64 mnt proc run srv test usr
root@23a13a663511:/usr/share/nginx/html# cp /dockerdemo-1.0-SNAPSHOT.jar .
cp: error writing './dockerdemo-1.0-SNAPSHOT.jar': No space left on device

超过了限制,空间限制为了 1m,会提示没有空间。


G. 停止容器


H. 启动容器再次进入

可以看到 tmpfs 的内容完全消失了,也就是说内容是存在内存里面的。


(3)tmpfs 失踪了

A. 实战目的

掌握临时卷的创建方式,了解临时卷的特殊存储方式。


B. 实战步骤
a. 创建一个普通的容器​​​​​​​

b. 在容器里面写入一个文件 tmplabelbyxuyinli.txt

c. 在宿主机上查找文件

文件被找到了,是因为他在容器的可写层。


d. 创建一个临时卷


e. 进入容器在 /app 目录下创建 mynewlabel.txt


f. 在宿主机上查找 mynewlabel.txt

可以发现,文件找不到:

所以 tmpfs 的内容不是存储在我们的容器的可写层里面的。


g. 释放资源


八、综合实战-MySQL 灾难恢复

1、实战目的

掌握挂载卷的使用,将 mysql 的业务数据存储到外部。

2、实战步骤

使用 MySQL 5.7 的镜像创建容器并创建一个普通数据卷 mysql-data 用来保存容器中产生的数据。需要在容器中连接 MySQL 服务, 并创建数据库 test,并在在该数据库中创建一个简单的表并插入一些数据进来。


(1)准备镜像

如果不存在该镜像,则输入命令:docker pull mysql:5.7


(2)创建容器

-e 选项通过参数 MYSQL_ROOT_PASSWORD 来传递 MySQL 密码。


(3)查看容器挂载信息


(4)连接 MySQL shell, 创建数据库,密码是 xyl@test

创建了一个 test  数据库,并在该数据库中创建一个 student 表,在表中插入了一条数据。

(5)在宿主机中查看 volume

可以看到容器中 MySQL 创建的数据库和表数据以及持久化到宿主机挂载的目录下:


(6)有一天莫名其妙停电了,然后服务器重启了

这个时候 MySQL 没有起来,然后此时发现磁盘空间不多了,于是把所有停止的容器都删除了,结果我们的 Mysql 也没有了。


(7)幸好数据还在,此时该如何恢复呢

再次启动运行命令,确保目录映射一致就能找回我们的数据。


(8)通过 mysql 的客户端进去,再次查看数据

可以看到,之前的数据还在:


(9)释放空间


九、常见问题

1、什么时候用 Volume、bindtmpfs

  • volumevolume docker 的宿主机文件系统一部分,用于不需要规划具体目录的场景。
  • bindbind mount 完全是依赖于主机的目录结构和操作系统,用于目录需要提前规划,比如 mysql 的目录需要个空间大的,其他服务有不占用的时候,用 volume 就不太合适了。
  • tmpfs:用于敏感文件存储,文件不想存储的宿主机和容器的可写层之中。

十、扩展思考 —— 存储卷在实际研发中带来了哪些问题

1、跨主机使用

docker 存储卷是使用其所在的宿主机上的本地文件系统目录,也就是宿主机有一块磁盘,这块磁盘并没有共享给其他的 docker 主机,容器在这宿主机上停止或删除,是可以重新再创建的,但是不能调度到其他的主机上,这也是 docker 本身没有解决的问题,所以 docker 存储卷默认就是 docker 所在主机的本地,但是可以自己搭建一个共享的 NFS 来存储 docker 存储的数据,也可以实现,但这个过程强依赖于运维人员的能力。所以未来应用的存储和数据往往分离,越来越多的分布式存储方案出现,如 s3 系列,nfs 等。


2、启动参数未知

容器有一个问题,一般与进程的启动不太一样,就是容器启动时选项比较多。如果下次再启动时,很容器会忘记它启动时的选项,所以最好有一个文件来保存容器的启动,这就是容器编排工具的作用。一般情况下,是使用命令来启动操作 docker,但是可以通过文件来读,也就读文件来启动,读所需要的存储卷等,但是它也只是操作一个容器,如果要几十上百个容器操作,就需要专业的容器编排工具。这种一般像开源的 k8s,各个云厂商也有自己的企业版编排软件。


3、复杂场景仍然需要运维

对于有状态要持久的集群化组件,如 mysql 的主从。部署维护一个 Mysql 主从需要运维知识、经验整合进去才能实现所谓的部署,扩展或缩容,出现问题后修复,必须要了解集群的规模有多大,有多少个主节点,有多少个从节点,主节点上有多少个库,这些都要一清二楚,才能修复故障,这些就强依赖于运维经验。这种复杂的场景往往还是需要人力,很难有完美的工具出现。

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

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

相关文章

xss-靶场

一、环境地址 XSS Game - Learning XSS Made Simple! | Created by PwnFunction 二、案例复现 案列1——Ma Spaghet&#xff01; <!-- Challenge --> <h2 id"spaghet"></h2> <script>spaghet.innerHTML (new URL(location).searchParams…

idea2022新建jsp项目并配置Tomcat服务器

1、创建项目 2、添加jdk 步骤如下&#xff0c;然后点击下边的create 创建项目即可 3、点击file 4、选择模块添加web 5、配置tomcat 6、依次点击 7、新建jsp文件 8、成功显示

Python 全栈系列262 使用sqlalchemy(clickhouse)

说明 再补充一篇。之前连不上的原因也挺搞笑&#xff0c;大概是deepseek把我带偏了&#xff0c; 应该是 pip3 install clickhouse-sqlalchemy -i https://mirrors.aliyun.com/pypi/simple/ 但是它教我 pip3 install sqlalchemy-clickhouse -i https://mirrors.aliyun.com/py…

Keepalived总结笔记

环境准备&#xff1a;两台安装ka的服务器&#xff0c;两台客户机&#xff0c;IP无要求&#xff0c;关闭火墙和selinux 1.在两台主机上安装ka 全局配置文件在/etc/keepalived/keepalived.conf 可以改写邮件地址和发送邮件的地址和主机唯一标识以及组播地址 配置虚拟路由&…

基于单片机的智能晾衣系统设计

摘 要 &#xff1a;在网络信息技术的推动下&#xff0c;智能家居得到了广泛应用&#xff0c;文章根据当前的市场动态&#xff0c;针对基于单片机的智能晾衣系统设计展开论述&#xff0c;具体包括两个方面的内容———硬件设计和软件设计。 关键词 &#xff1a;单片机&#xff…

经方药食两用服务平台

TOC springboot226经方药食两用服务平台 绪论 1.1研究背景与意义 信息化管理模式是将行业中的工作流程由人工服务&#xff0c;逐渐转换为使用计算机技术的信息化管理服务。这种管理模式发展迅速&#xff0c;使用起来非常简单容易&#xff0c;用户甚至不用掌握相关的专业知识…

【经典算法】BFS_最短路问题

1. 最短路问题介绍 最短路径问题是图论中的一类十分重要的问题。本篇文章只介绍边权为1(或边权相同)的最简单的最短路径问题。所谓边权&#xff0c;就是两点之间的距离。 这类问题通俗的说就是告诉你起点和终点&#xff0c;要你找出最短的路径或是最短路径是多少。 解决方法&…

每日OJ_牛客_DP3跳台阶扩展问题

目录 DP3跳台阶扩展问题 题解代码1&#xff08;dp&#xff09; 题解代码2&#xff08;找规律&#xff09; DP3跳台阶扩展问题 跳台阶扩展问题_牛客题霸_牛客网 题解代码1&#xff08;dp&#xff09; 假定第一次跳的是一阶&#xff0c;那么剩下的是n-1个台阶&#xff0c;跳法…

汇编语言:jcxz 指令

‌ 在汇编语言中&#xff0c;jcxz 标号 指令是一个有条件转移指令&#xff0c;用于检测CX寄存器的值&#xff0c;如果CX寄存器的值为0&#xff0c;则跳转到指令中标号所指定的地址处执行&#xff1b;否则&#xff0c;指令将继续顺序执行。‌ 1. jcxz 标号 &#xff0…

超市收银出入库进销存库存管理系统java数据库SpringBoot前端VUE

系统设计是一个把软件需求转换成用软件系统表示的过程[9]。通过对目标系统的分析和研究&#xff0c;做出了对师范学院实习管理系统的总体规划&#xff0c;这是全面开发系统的重要基础。在对实习管理系统全面分析调查的基础上&#xff0c;制定出商品销售系统的总体规划。系统设计…

KEEPALIVED的高可用实现

目录 一.高可用集群 1.1 集群类型 Keepalived 环境准备 1.2Keepalived 相关文件 1.3实验步骤 1.3.1HTTP配置 1.3.2安装KA 1.3.3实现master/slave的 Keepalived 单主架构 1.3.4抢占模式和非抢占模式 非抢占模式 抢占模式 抢占延迟模式 preempt_delay 1.3.5开启KA…

习题2.38-2.39

2.38这个题目特别有意思,能比较深的理解什么是左侧优先右侧优先。先看看实现代码 ;;满足交换律,即操作函数的参数可相互交换,其结果不变 (defn fold-right[op initial sequences](if (empty? sequences)initial(op (first sequences)(accumulate op initial (rest sequence…

快讯 | 28页知网侵权函难挡秘塔AI:多家数据库抢着合作!

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

使用 ESP32 和 TFT 屏幕显示实时天气信息 —— 基于 OpenWeatherMap API

实时监测环境数据是一个非常常见的应用场景&#xff0c;例如气象站、智能家居等。这篇博客将带你使用 ESP32 微控制器和一个 TFT 屏幕&#xff0c;实时显示当前城市的天气信息。通过 OpenWeatherMap API&#xff0c;我们能够获取诸如温度、天气情况以及经纬度等详细的天气数据&…

【书生大模型实战营(暑假场)闯关材料】基础岛:第1关 书生大模型全链路开源体系

【书生大模型实战营&#xff08;暑假场&#xff09;闯关材料】基础岛&#xff1a;第1关 书生大模型全链路开源体系 简介一、背景介绍1.1 背景介绍1.2 全链路开源开放体系的优势 二、全链路开源开放体系的主要特点2.1 模型组件的公开和共享2.2 数据集的公开和共享2.3 模型的互操…

2024年【汽车驾驶员(技师)】报名考试及汽车驾驶员(技师)模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 汽车驾驶员&#xff08;技师&#xff09;报名考试是安全生产模拟考试一点通生成的&#xff0c;汽车驾驶员&#xff08;技师&#xff09;证模拟考试题库是根据汽车驾驶员&#xff08;技师&#xff09;最新版教材汇编出…

Paimon实战 -- paimon原理解析

一.简介 Apache Paimon 原名 Flink Table Store&#xff0c;2022年1月在 Apache Flink 社区从零开始研发&#xff0c;Flink 社区希望能够将 Flink 的 Streaming 实时计算能力和 Lakehouse 新架构优势进一步结合&#xff0c;促进数据在数据湖上真正实时流动起来&#xff0c;并为…

打靶记录12——Fawkes

靶机&#xff1a; https://download.vulnhub.com/harrypotter/Fawkes.ova这是个哈利波特系列的靶机&#xff0c;作者和本人都非常喜欢这个系列&#xff0c;因为它的漏洞和利用点都设计得很巧妙。 难度&#xff1a; 高 目标&#xff1a; 取得2个root权限 3 个flag 涉及攻…

学习二叉树遍历

class Node{ V value; Node left; Node reight; } 用递归和非递归两种方式实现二叉树的先序&#xff0c;中序&#xff0c;后续遍历 如何直观的打印一颗二叉树 如何完成二叉树的宽度优先遍历 递归序列 先序是出现的第一个数字&#xff0c;中序第二个&#xff0c;后续第三…

兼容并蓄,高效集成:EasyCVR视频综合接入能力助力多元化项目需求

随着视频技术的不断进步&#xff0c;视频监控、视频直播、执法记录仪、语音可视对讲、无人机等视频资源的应用场景日益丰富。这些视频资源不仅在数量上快速增长&#xff0c;而且在质量、格式、编码标准等方面也呈现出多样化的特点。因此&#xff0c;为了有效整合这些资源&#…