从青铜到王者系列:对象存储服务性能调优
文章目录
【注意】最后更新于 November 20, 2022,文中内容可能已过时,请谨慎使用。
如何学习
|
|
带宽: 每秒的吞吐量,即每 秒可以完成读/写的数据量 OPS:每 秒可以处理客户端业务请求的个 数
网络调优
存储节点服务器网络检查命令
1 ifconfig
ifconfig - configure a network interface
查看接口数是否正常, IP地址是否正常,“ errors”、“ overruns”、“ frame”计
数是否正常。所谓异常
所谓异常:
– 使用的接口无统计数据。
– 与后端10GE交换机相连的网口“ error”、“ overruns”、“ frame”统计数据
不为0。
overruns有计数,需要检查对应[交换机]接口有没有配置flow-control; frame有 计数,需要抓包确认有没有重传。
– SLOT5-0、 SLOT4-0收发包数差距很大。
-
对于存储节点的RoCE网卡( 10GE组网),还应包含名称为SLOT4-0.2或
SLOT5-0.2的网口的显示结果 -
产品名称:200G网卡 Mellanox CX6 MCX653106A HDAT HDR IB卡 双口 该网卡适用于高速数据中心网络,支持InfiniBand(IB)网络技术, 适用于高性能计算(HPC)、云计算、大数据分析等场景。
接口错误计数(errors/overruns/frame)
-
关键统计项:
- errors: 物理层或协议栈错误(CRC错误、畸形包)。
- overruns: 输入队列满导致内核丢弃数据包,通常因处理速度不足。
- frame: 帧格式错误(如长度不匹配、对齐问题)。
|frame
|校验错误或重传|物理层故障、MTU不匹配、重传冲突|更换硬件、统一MTU、抓包优化|
ens47f0: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc mq master bond0 state UP group default qlen 8192
数据包分片与重组
- 若发送方 MTU(例如
9000
) > 路径中某设备 MTU(例如1500
):
发送方未设置DF(Don't Fragment)
标志:数据包被分片传输,降低效率。
发送方设置DF
标志:接收端返回ICMP Fragmentation Needed
错误,导致通信失败
2 【ethtool】ethtool 网卡诊断、调整工具、网卡性能优化| 解决丢包严重
|
|
ethtool -i SLOT4-1: 看网口驱动版本,可以识别接口类型和厂商,比如cxgb4是
Chelsio卡, ixgbe是Intel 10GE卡。
lspci |grep Ether:确认用的是什么型号的网卡
3. netstat
netstat -s |grep Retrans检查重传个数,确认是否有重传。
TCPLostRetransmit: 1146
4. 实时查看网卡流量 sar -n DEV 2
-
sar - Collect, report, or save system activity information
-
sar -r -n DEV -f /var/log/sa/sa16
-n { keyword [,…] | ALL } Report network statistics.
查看网口收发数据的速率。
对于存储节点的RoCE网卡( 10GE组网),此命令无法查询到该网卡的收发速
率。
https://my.oschina.net/u/4279744/blog/3881002
https://blog.csdn.net/volitationLong/article/details/81741754
一、重传现象的直接解读
- TCPLostRetransmit: 此计数器表示:
显式触发的重传
(如超时重传或快速重传)。- 值持续增长说明网络在持续丢包或延迟突变。
二、排查方向
1. 确定是否为偶发或持续问题
|
|
- 偶发性增长:可能与应用突发流量或短暂网络抖动相关。
- 持续增长:表明存在根因(如链路故障、MTU 不匹配、硬件故障)。
2. 关联 MTU 问题(参考历史会话)
-
确认 MTU 一致性:
1 2 3 4
# 检查服务端、客户端、交换机的 MTU 配置 ip link show eth0 | grep mtu # Linux show interfaces GigabitEthernet1/1 # Cisco display interface GigabitEthernet0/0/1 | include MTU # 华为
-
MTU 不匹配的典型影响:引起分片(ICMP Fragmentation Needed),若
DF
位被设置,则直接丢包,触发 TCP 重传。
3. 网络路径排查
-
路径延迟和抖动:
1 2
# 测试到目标地址的延迟和抖动 mtr -n -r -c 100 <目标IP>
-
路径丢包检测:
1 2
# 持续 ping 观察丢包率 ping -c 1000 -i 0.1 <目标IP> | grep "packet loss"
4. 深入分析 TCP 连接状态
-
查看活跃连接的 RTT 和重传细节:
1
ss -ti # 关注 `rtt` 和 `retrans`
-
输出示例:
1 2
ESTAB 0 0 192.168.1.100:ssh 192.168.1.2:58234 cubic wscale:6,7 rto:234 rtt:102.3/24.3 ato:40 retrans:5
rto
(重传超时时间)、rtt
(往返时间)、retrans
(该连接的重传次数)。
5. 硬件或驱动问题
-
检查网卡错误计数:
1
ethtool -S eth0 | grep -E "err|drop|fail"
- 高
rx/tx_errors
或discards
表明网卡或驱动异常。
- 高
三、优化和解决措施
1. 基础网络优化
-
调整 TCP 参数(Linux 示例):
1 2 3 4 5 6
# 增大 TCP 缓冲区 sysctl -w net.ipv4.tcp_rmem='4096 87380 6291456' sysctl -w net.ipv4.tcp_wmem='4096 16384 4194304' # 启用 TCP 窗口缩放 sysctl -w net.ipv4.tcp_window_scaling=1
-
启用 BBR 拥塞控制算法(对抗丢包):
1
sysctl -w net.ipv4.tcp_congestion_control=bbr
2. MTU 问题修复
- 若确认 MTU 不匹配(如跨设备 MTU 不一致),需全局统一 MTU。
3. QoS 或流量限速
-
对关键业务流量实施优先级标记(DSCP/TOS):
1 2 3
# Linux 使用 tc 限速和优先级调度 tc qdisc add dev eth0 root handle 1: htb tc class add dev eth0 parent 1: classid 1:10 htb rate 1gbit prio 0
4. 替换故障硬件
- 若网卡错误计数持续增长,尝试更换网卡或使用多网卡绑定(Bonding)。
四、高级诊断工具
1. 抓包分析重传详情
|
|
- Wireshark 分析:
- 过滤
tcp.analysis.retransmission
查看具体重传包。 - 确认重传是
超时重传
(间隔长)还是快速重传
(连续重复 ACK)。
- 过滤
2. 内核跟踪工具(Linux)
-
动态追踪重传事件:
1
perf record -e tcp:tcp_retransmit_skb -ag
五、总结
现象 | 可能原因 | 优先级排查项 |
---|---|---|
TCP 重传持续增长 | 网络丢包、高延迟、MTU 不匹配 | 1. 路径丢包率 2. MTU 一致性 |
伴随机 NIC 错误计数增长 | 网卡硬件/驱动故障 | ethtool -S 和 dmesg 日志 |
仅限于特定服务 | 应用层配置或服务器性能问题 | 检查服务日志和资源占用 |
关键点:
- 先区分偶发还是持续性问题,再确定是否需要深入排查。
- 高重传率常见于跨公网传输或无线网络环境,若在内网中持续出现需视为严重故障。
- 结合 MTU 配置、路径质量、硬件状态多维度分析。
提问:io_submit io_getevents 之间 需要做其他处理嘛? 例如 epoll监控什么?
Redis 通过子进程持久化、异步刷盘线程(bio) 和 写时复制(COW) 技术,保证持久化操作不阻塞单线程主事件循环。具体流程如下:
步骤 | 主线程 | 子进程/后台线程 |
---|---|---|
RDB 生成 | fork() 创建子进程 |
遍历内存生成 RDB 文件 |
AOF 日志追加 | 写命令追加到 aof_buf 缓冲区 |
—— |
AOF 刷盘(默认) | —— | 后台线程每秒调用 fsync |
设计精髓:所有磁盘 I/O 操作均委托给子进程或后台线程,主线程专注于内存数据操作和网络事件处理,确保单线程模型的高效性
另外感叹一下 antirez 代码层面上的架构能力,几年前看过 redis 2.8 的代码,从 2.8 的分支直接切到 5.0 之后,原来阅读的位置并没有偏离主线太远。历经几个大版本的迭代,加了 N 多功能之后,代码主体逻辑依旧没有大改,真的是做到了对修改关闭,对扩展开放。向大佬学习
https://www.bookstack.cn/read/aliyun-rds-core/0bca1b2aa30e6bb3.md
redis是单线程的,持久化写操作比较耗时,怎么解决的 Redis 虽然是单线程事件循环模型的主线程设计,但通过多线程辅助和异步持久化策略解决了持久化写操作的耗时问题。具体实现包括以下关键点:
一、持久化方案的分类
Redis 提供两种持久化方式,均采用子进程或后台线程异步执行,避免主线程阻塞:
-
RDB(快照持久化):
- 触发方式:
save
(阻塞主线程,已弃用) /bgsave
(后台异步)。 - 原理:主线程
fork
子进程生成内存快照并写入磁盘。 - 优势:全量备份,恢复速度快;文件紧凑,占磁盘空间小。
- 缺点:可能丢失最后一次快照后的数据。
- 触发方式:
-
AOF(追加写日志):
- 触发方式:
always
(同步写,高安全)/everysec
(每秒异步刷盘,默认)/no
(内核决定刷盘时间)。 - 原理:记录所有写操作命令,支持重写压缩(
bgrewriteaof
)。 - 优势:数据丢失风险低;可读性强。
- 缺点:文件体积大;恢复速度慢。
- 触发方式:
二、异步持久化的实现机制
1. RDB 异步处理
-
主线程:仅负责接收写请求并更新内存数据,
bgsave
命令触发时会fork
出一个子进程。 -
子进程:专用于执行
rdbSave()
,生成 RDB 文件。- 写时复制(Copy-On-Write):子进程共享父进程内存页,仅在内存修改时复制脏页,减少内存开销。
1 2 3 4 5 6 7 8 9 10 11 12
// redis/src/rdb.c int rdbSave(char *filename) { // 子进程独立完成磁盘写入 snprintf(tmpfile, sizeof(tmpfile), "temp-%d.rdb", (int)getpid()); fp = fopen(tmpfile, "w"); // 遍历数据库生成快照数据... fflush(fp); fsync(fileno(fp)); fclose(fp); // 原子替换旧RDB文件 rename(tmpfile, filename); }
2. AOF 异步处理
-
写缓冲(AOF Buffer):主线程将写操作追加到
aof_buf
内存缓冲区。 -
刷盘策略:
everysec
(默认):由后台线程bio
(Background I/O)每秒调用fsync
同步到磁盘。- 流程分离:主线程仅负责追加到缓冲区,后台线程负责刷盘,互不阻塞。
1 2 3 4 5 6 7 8 9 10
// redis/src/aof.c void flushAppendOnlyFile(int force) { // 刷盘操作由 bio 线程异步执行 if (server.aof_fsync == AOF_FSYNC_EVERYSEC && !force) { // 提交异步任务到 bio 队列 bioCreateBackgroundJob(BIO_AOF_FSYNC, NULL, NULL, NULL); } else { fsync(server.aof_fd); // 同步操作(仅强制时由主线程执行) } }
3. 后台线程(Bio)
Redis 在启动时会初始化 3 类后台线程(默认配置未开启,需手动启用):
- BIO_CLOSE_FILE:延迟关闭大文件句柄。
- BIO_AOF_FSYNC:异步执行 AOF 刷盘(
fsync
)。 - BIO_LAZY_FREE:异步内存回收(如
UNLINK
命令)。
关键函数:
|
|
三、性能优化补充
写时复制(COW)的取舍
- 优势:子进程无需阻塞主线程,内存复制量最小化。
- 风险:若主线程频繁修改数据(如大规模写入),子进程需复制大量脏页,导致 内存膨胀 和 CPU 开销。
- 建议:避免在持久化期间执行大量写入操作。
AOF 重写优化
- 机制:
bgrewriteaof
命令触发子进程生成新的 AOF 文件,与主线程共享内存数据。 - 增量写入:重写期间的新写操作会被记录到 AOF 重写缓冲区,确保数据一致性。
四、总结
Redis 通过子进程持久化、异步刷盘线程(bio) 和 写时复制(COW) 技术,保证持久化操作不阻塞单线程主事件循环。具体流程如下:
步骤 | 主线程 | 子进程/后台线程 |
---|---|---|
RDB 生成 | fork() 创建子进程 |
遍历内存生成 RDB 文件 |
AOF 日志追加 | 写命令追加到 aof_buf 缓冲区 |
—— |
AOF 刷盘(默认) | —— | 后台线程每秒调用 fsync |
设计精髓:所有磁盘 I/O 操作均委托给子进程或后台线程,主线程专注于内存数据操作和网络事件处理,确保单线程模型的高效性。
reids bioCreateBackgroundJob 怎么实现的
提问4:Redis 的 bioCreateBackgroundJob
是后台任务处理的核心接口,用于将阻塞式操作(如磁盘 I/O、内存回收等)提交到后台线程异步执行,避免主线程阻塞。以下是其实现原理的详细分析:
一、后台线程的初始化
Redis 在启动时(main()
函数)
通过 InitServerLast()
调用 bioInit()
初始化后台线程池。
其核心步骤如下:
- 线程池创建:
默认创建 3 类后台线程(通过BIO_NUM_OPS
控制类型数量):BIO_CLOSE_FILE
(异步关闭大文件句柄)BIO_AOF_FSYNC
(异步执行 AOF 刷盘)
-
BIO_LAZY_FREE
(异步内存回收)
-
任务队列初始化:
每个后台线程类型对应一个任务队列(链表结构bio_jobs[BIO_NUM_OPS]
), 用于存储待处理的任务。 -
线程启动:
每个线程执行bioProcessBackgroundJobs
函数,循环监听任务队列。
|
|
二、任务提交(bioCreateBackgroundJob)
当需要异步执行任务时(如 AOF 刷盘),主线程通过 bioCreateBackgroundJob
将任务添加到对应类型的任务队列:
-
任务参数封装:
将任务类型、待操作的文件描述符(fd
)或其他参数(如释放的内存地址)封装到bio_job
结构体。 -
线程安全入队:
对目标任务队列加锁,将任务插入链表尾部,并通知后台线程有新任务待处理。
|
|
三、任务处理(bioProcessBackgroundJobs)
后台线程的核心逻辑是循环监听任务队列,按顺序执行任务:
-
阻塞等待新任务:
若任务队列为空,线程通过条件变量pthread_cond_wait()
进入阻塞状态,等待主线程唤醒。 -
获取并执行任务:
从队列头部取出任务,执行对应的操作(如fsync
、close
、free
等)。 -
任务清理:
任务执行完毕后,释放bio_job
结构体内存。
|
|
四、关键设计点
机制 | 说明 |
---|---|
无锁主线程 | 主线程提交任务仅需对队列加锁,无时间敏感操作,不会长时间阻塞主线程。 |
线程隔离 | 每个后台线程处理独立任务类型,避免竞争(例如 AOF 刷盘与内存回收互不影响)。 |
轻量化封装 | bio_job 结构简单,仅存储必要参数,减少内存开销。 |
唤醒机制 | 条件变量通知确保后台线程及时响应新任务,降低延迟。 |
五、典型应用场景
1. AOF 刷盘(everysec
策略)
- 主线程:将写命令追加到
aof_buf
缓冲区。 - 后台线程:每秒执行一次
fsync
,将缓冲区数据刷盘。
2. 惰性删除(UNLINK
命令)
|
|
总结
Redis 通过 bioCreateBackgroundJob
将阻塞操作分配至后台线程,其核心设计是:
- 主线程与后台线程解耦:主线程仅负责提交任务,避免 I/O 阻塞。
- 任务队列机制:使用线程安全的队列和条件变量实现任务调度。
- 资源隔离:不同类型任务由独立线程处理,避免相互干扰。
|
|
//https://www.bookstack.cn/read/aliyun-rds-core/0bca1b2aa30e6bb3.md
提问:“Redis 在处理 AOF/RDB 等磁盘持久化任务时,选择通过单线程事件循环 + 后台 BIO 线程的机制实现异步化,而非直接使用 Linux 内核的异步 I/O(AIO)。这种设计是出于以下哪些考量?
这句话的核心是强调 BIO 线程的资源隔离性,即 Redis 通过 BIO 线程将磁盘操作(如持久化)与主线程的事件循环解耦,从而实现资源使用的可观测性和可控性。具体可从以下两个层面理解:
1. 线程调度优先级差异化(Scheduling Priority)
- 操作系统的线程调度策略允许为不同线程设置优先级(例如 Linux 的
nice
值或sched_setscheduler
),Redis 可配置 BIO 线程的优先级略低于主线程:- 示例:主线程负责处理客户端命令,需要快速响应,因此被设置为较高优先级(如
nice=-10
); -而 BIO 线程执行后台持久化任务,设置为较低优先级(如nice=10
)。 - 效果:当 CPU 资源紧张时,内核调度器会优先执行主线程任务,避免磁盘刷盘阻塞用户请求处理。
- 示例:主线程负责处理客户端命令,需要快速响应,因此被设置为较高优先级(如
2. 独立监控 BIO 线程状态(Observability)
-
线程级独立监控:因为 BIO 线程独立于主线程存在,运维团队可以直接观察其状态:
- 挂起检测:BIO 线程若因同步 I/O(如
fsync
)长时间阻塞,可通过top
/htop
查看线程状态(如D
状态表示不可中断 sleep),或通过strace -p <tid>
跟踪系统调用。 - 延迟分析:针对 BIO 线程独立的性能指标(如
bio_delay
)可以快速定位磁盘性能问题,避免与主线程的延迟指标混淆。
- 挂起检测:BIO 线程若因同步 I/O(如
-
资源隔离的工程意义:
- 熔断能力:若 BIO 线程堆积过多任务(如 AOF 持久化过慢),可直接触发告警并降级持久化策略(如关闭 AOF)。
- 性能调优:通过调整 BIO 线程数量(Redis 默认启动 3 个 BIO 线程)或绑定 CPU 核,优化磁盘吞吐与主线程延迟的平衡。
类比理解
想象一个公司的客服团队:
- 主线程是客服热线接线员(高优先级):需要快速接听电话,直接服务客户,若让接线员同时处理财务报销(类比磁盘 I/O),会导致电话响应延迟。
- BIO 线程是财务部(低优先级):财务流程可以独立运作(线程隔离),即使报销流程积压(磁盘负载高),客服团队仍能正常接听电话。财务部的效率也可以通过独立监控(如报销处理时长报表)来优化。
总结
“资源隔离”是通过优先级区分和独立监控两个机制实现的:
- 优先保障主线程的低延迟:通过调度策略确保主线程优先获取 CPU。
- 持久化操作的影响可观测、可控制:BIO 线程的运行状态与主线程解耦,运维干预更精、
Redis 可配置 BIO 线程的优先级略低于主线程:
提问6:Redis 可配置 BIO 优先级在redis.CONF 怎么配置
1. BlueStore 的异步 I/O 架构
BlueStore 直接管理裸设备(如 /dev/nvme0n1
),绕过文件系统,直接使用 libaio
提交异步 I/O 请求。其核心流程如下:
(1) I/O 请求的提交
- 写入路径:
- 客户端请求通过 OSD 接收后,数据先写入 RocksDB 的 WAL(Write-Ahead Log)(基于
libaio
异步刷盘)。 - 主数据通过 BlueFS(BlueStore 内部日志管理)异步提交到 NVMe SSD 的数据区域。
- 客户端请求通过 OSD 接收后,数据先写入 RocksDB 的 WAL(Write-Ahead Log)(基于
- 读取路径:
- 直接从 NVMe SSD 异步读取数据块,通过回调机制将数据返回给客户端。
(2) 多线程与队列深度控制
- 线程池模型:
- 每个 OSD 实例配置
osd_iodepth_threads
参数(默认值通常为 2-4,根据硬件调整)。 - 每个线程独立处理一批 I/O 请求,通过
libaio
批量提交给内核。
- 每个 OSD 实例配置
- 队列深度(iodepth):
- 每个线程维护一个 AIO 队列,队列深度由
bluestore_iodepth
(默认 32) 控制,表示单个线程同时未完成的 I/O 请求数。 - 总并发能力 =
osd_iodepth_threads
×bluestore_iodepth
。
- 每个线程维护一个 AIO 队列,队列深度由
|
|
(3) libaio 的事件回调
- 完成事件轮询:
- 线程通过
io_getevents
系统调用异步获取已完成的 I/O 请求事件。 - 完成事件触发回调函数,更新元数据(如 RocksDB 中的对象状态)。
- 线程通过
2. NVMe SSD 高队列深度的适配
NVMe SSD 的硬件队列深度可支持 数万级并发请求(如 64K 队列),Ceph 通过以下设计匹配这一特性:
(1) 多线程扩展
- 提高
osd_iodepth_threads
(如设置为 NVMe SSD 的 CPU 核数),增加并行提交 I/O 的通道。 - 每个线程绑定独立的 CPU 核心,避免多线程竞争(需结合
cgroup
或taskset
手动绑核)。
(2) 队列深度调优
- 增大
bluestore_iodepth
(如 128),允许单个线程提交更多未完成请求,填充 NVMe SSD 的硬件队列。 - 动态调整:BlueStore 根据负载自动扩缩队列深度,避免因突发流量导致队列枯竭。
(3) 批量请求合并
- 对小块随机写入(如 4K)合并为更大的连续请求(如 64K),减少 I/O 次数并提高 SSD 吞吐量(需 NVMe 支持 NVMe 命令融合)。
3. 性能问题排查与调优
(1) 监控指标
-
OSD 延迟分布:
1
ceph osd perf # 查看每个 OSD 的 commit/apply 延迟
-
AIO 队列状态:
1
ceph daemon osd.<id> perf dump | grep bluestore -A 20
(2) 调优建议
- SSD 配置:
mount -o loop /opt/CentOS-7-x86_64-DVD-2003.iso /var/www/html/centos7/
条命令的作用是将一个ISO镜像文件挂载到一个指定的目录,以便可以通过网络或其他方式访问其内容。具体来说,命令的各个部分含义如下:
-
mount
:这是Linux系统中的一个命令,用于将文件系统(如硬盘分区、光盘、USB存储设备或ISO镜像文件等)挂载到一个指定的挂载点,使其内容可以被访问。 -
-o loop
:这是一个选项,表示使用循环设备(loop device)。循环设备是一种虚拟设备,允许将一个文件(如ISO镜像文件)当作一个块设备来挂载。这样,ISO文件中的内容就可以像一个真实的磁盘分区一样被访问。 -
/opt/CentOS-7-x86_64-DVD-2003.iso
:这是要挂载的ISO镜像文件的路径。ISO文件通常是一个光盘镜像文件,包含了操作系统的安装文件或其他数据。 -
/var/www/html/centos7/
:这是挂载点的路径,即ISO文件将被挂载到的目录。挂载完成后,ISO文件中的内容将可以通过这个目录访问
若客户现场使用了infiniband网络,请安装第三方Mellanox驱动 。驱动信息如下:
l 下载地址:http://www.mellanox.com/page/software_overview_ib
l 版本信息:MLNX_OFED_LINUX-5.0-2.1.8.0-rhel7.8-x86_64[JZ(1] 。
[JZ(1]已修改
在 Linux 系统中,磁盘格式化和挂载是两个重要的步骤,它们的顺序和作用是相互关联的。以下是为什么需要先格式化磁盘再进行挂载的原因:
1. 格式化磁盘的作用
-
创建文件系统:格式化磁盘的目的是在磁盘上创建一个文件系统(如
ext4
、xfs
等)。文件系统是操作系统用来组织和管理磁盘数据的结构,它定义了如何存储、检索和管理文件和目录。 -
分配存储空间:格式化会将磁盘划分为多个逻辑区域,例如元数据(如文件名、权限、时间戳等)和实际数据存储区域。没有文件系统,操作系统无法识别磁盘上的数据结构。
-
初始化磁盘:格式化会清除磁盘上的旧数据(如果磁盘之前有数据),并初始化磁盘的文件系统结构,使其处于一个干净的状态。
2. 挂载磁盘的作用
-
将磁盘与文件系统关联:挂载是将格式化后的磁盘(或分区)与一个已存在的目录(挂载点)关联起来。挂载后,操作系统可以通过挂载点访问磁盘上的数据。
-
使磁盘可用:挂载操作使得磁盘上的文件系统成为文件树的一部分,用户可以通过标准的文件操作命令(如
ls
、cp
、mv
等)访问和管理磁盘上的数据。 -
指定挂载点:挂载点是一个目录路径,它决定了磁盘数据在文件系统中的位置。例如,将
/dev/sdb
挂载到/data/beegfs/beegfs_mgmtd/
,意味着/data/beegfs/beegfs_mgmtd/
下的所有文件和目录实际上存储在/dev/sdb
上。
3. 为什么必须先格式化再挂载
-
文件系统是基础:挂载操作依赖于磁盘上已经存在的文件系统。如果没有先格式化磁盘,磁盘上没有文件系统结构,操作系统无法识别磁盘的内容,也就无法将其挂载到文件系统中。
-
避免数据混乱:如果直接挂载一个未格式化的磁盘,操作系统可能会将其视为一个空设备,或者因为无法识别其内容而报错。格式化可以确保磁盘有一个清晰的结构,避免数据混乱或损坏。
-
初始化存储:格式化磁盘是一个初始化过程,它为磁盘分配了存储空间和