简介:华为HCNA-Storage培训教材V4.0以单个PDF文件交付,压缩包约39.06MB,面向准备华为存储认证、希望系统补齐数据中心存储基础的工程师与学员。教材从广义与狭义存储定义切入,梳理存储系统由硬件架构、软件组件和解决方案构成的关系,并重点比较直连存储、网络附加存储、存储区域网络三类架构的差异、典型协议与适用场景,涵盖内部与外部直连存储、文件共享协议、光纤通道存储区域网络与IP存储区域网络等内容,同时延伸至分布式存储和软件定义存储。读者可据此建立从存储设备、存储网络到数据管理功能的整体认知,理解镜像、复制、备份等软件能力及总体拥有成本考量,为后续存储选型、规划与运维排错打下基础。已有1241人学习,内容体系化较强,适合作为入门到进阶的参考资料。
1. 三种架构的真相:硬盘没变,变的是“谁掌握地址翻译权”
很多人默认 DAS、NAS、SAN 是三代产品,新的淘汰旧的。把这三套东西拆到最底层看,磁盘、闪存颗粒、控制器几乎没变,变的只是服务器交出去的那一层地址:DAS 交块号,NAS 交文件名,SAN 把块号延伸到了另一个专用网络上。这份存储培训教材 V4.0 开篇先区分“狭义存储”和“广义存储”,看着像概念铺垫,实际是在给后面所有架构划边界——狭义指软盘、光盘、磁带、硬盘这类具体设备,广义指数据中心里的硬件系统、软件系统和存储网络的组合。搞不清这条边界,后面 LUN、Zoning、挂载点这些词就会互相打架。下面把三种架构拆到地址翻译这一层来看。
2. DAS 的物理边界:内部总线为什么注定被外置存储取代
2.1 块级服务的本质:服务器拿到的是一串编号
直连存储(DAS)为服务器提供的是块级服务,注意不是文件系统级。服务器内核里看到的是一块裸设备,比如/dev/sdb,文件系统是服务器自己在这块裸设备上建的,inode、目录项、日志、位图全在服务器这一侧。存储设备那一侧只认一个东西:从某个逻辑块地址(LBA)开始的多少个定长块。
这个分工决定了很多后面会反复出现的现象。设备不知道也不关心这些块属于哪个文件,它无法判断写请求是否合理——一台服务器如果把文件系统写坏了,它下发的垃圾块会被阵列原样落盘,设备没有任何能力阻止。反过来,DAS 的性能上限就是单台服务器 I/O 栈的上限,阵列再快,也要过服务器这一道。
用一个最小模型把块级语义说明白:
class BlockTarget: """模拟一个只认 LBA 的块设备:没有文件名,没有目录,只有编号""" def __init__(self, name, capacity_blocks, block_size=512): self.name = name self.capacity = capacity_blocks # 总块数,决定 LBA 上界 self.block_size = block_size # 块大小,传统 512B,现代盘常见 4KB self._store = {} # 稀疏字典:只有写过的块才占空间 def read(self, lba, count): # 服务器视角:读到的是定长块,没有任何文件语义 if lba < 0 or lba + count > self.capacity: # 越界由设备侧直接拒绝,因为设备根本不知道"文件边界"在哪 raise IOError("LBA out of range: %d+%d" % (lba, count)) return [self._store.get(lba + i, b"\x00" * self.block_size) for i in range(count)] def write(self, lba, payload): for i, blk in enumerate(payload): assert len(blk) == self.block_size, "块长度必须对齐" self._store[lba + i] = blk disk = BlockTarget("/dev/sdb", capacity_blocks=1024 * 1024) disk.write(0, [b"A" * 512]) print(disk.read(0, 1)[0][:4]) # b'AAAA'这段代码里三个参数值得记住:capacity_blocks决定 LBA 的上界,block_size决定一次 I/O 的最小粒度,_store的稀疏特性说明块设备天然支持“没写过的位置读出来是全零”——这也是精简置备能成立的前提之一。write里的对齐断言对应现实中“块设备只接受整块写入”,任何非对齐的写都要由上层补齐。理解了这一层,再看 NAS 就会明白它到底把什么东西挪走了。
2.2 内部 DAS 的三个天花板
内部 DAS 指的是存储设备通过服务器机箱内部的并行或串行总线连接,最典型的就是机箱里的那几块硬盘、内置磁带机。它有三个硬约束,而且这三个都不是厂商偷懒,是物理规律。
第一个是距离。早期并行总线(窄带 SCSI 的 50 针排线、IDE 的 40/80 芯排线)靠多条线同时传一个字的多个 bit,线一长,各 bit 到达时间就不一致,这种偏斜会让接收端的时钟沿对不齐,误码率陡增。所以机箱内排线的长度通常被压在几十厘米到一两米。后来的串行总线(SAS、SATA)改用 SerDes,把并行字拆成高速串行比特流,靠编码和时钟恢复来对抗偏斜,这才把距离和速率同时拉起来——代价是每条链路变成点对点,要靠 expander 才能扩出更多端口。
第二个是设备数。并行 SCSI 一条总线最多 15 个设备(窄带只有 7 个),还要占掉一个 ID 给控制器,设备一多,总线仲裁和终端匹配就变得敏感。串行总线虽然靠 expander 可以扩到上百个盘位,但机箱内的盘位、背板走线、供电和散热仍然是硬限制。
第三个是维护性,也是实际运维里最疼的一个。盘在机箱里,换一块盘意味着停机、开盖、动风道,风道一乱,旁边那些盘的进风温度立刻上去。对 7×24 的业务来说,这不叫麻烦,叫可用性缺口。培训教材里那句“存储设备放在服务器机箱内部会占用大量空间,对服务器其它部件的维护造成困难”,说的是同一件事。
2.3 外部 DAS:把总线变成网络,代价是什么
外部 DAS 把存储设备搬出机箱,服务器与外置盘阵、磁带库直接相连,大多数情况走 FC 协议或者 SCSI 协议。它解决了两件事:距离和数量。FC 在光纤上可以跑到几百米甚至更远,外置盘阵可以挂几十上百块盘,集中供电、集中散热、集中管理,换盘不用停机开服务器盖子。
但“直连”这两个字没有变。一条链路对应一台服务器(或者一组 HA 服务器),LUN 被这台服务器独占,除非上集群文件系统,否则别的服务器看不到这块容量。三台服务器要用同一批空间,只能各划一块,容量孤岛随之出现——A 服务器上剩 8TB 用不上,B 服务器却要申请扩容,采购单照批。这个矛盾正是 SAN 出现的直接动因,也解释了为什么教材在讲完 DAS 之后马上切到 SAN,中间没有别的过渡。
| 维度 | 内部 DAS | 外部 DAS |
|---|---|---|
| 连接方式 | 机箱内并行/串行总线 | FC 或 SCSI 线缆直连 |
| 距离约束 | 几十厘米到一两米 | 几十米到数百米(取决于介质) |
| 设备数量 | 受盘位与总线 ID 限制 | 受阵列规格限制,可扩展 |
| 管理方式 | 随服务器,分散 | 集中到阵列管理面 |
| 共享能力 | 无 | 无,LUN 仍被单机独占 |
这张表里最后一行是重点。外部 DAS 解决了物理层的问题,没有解决共享的问题,而共享恰恰是文件级和网络级存储要回答的问题。
3. NAS 的重心转移:文件系统为什么必须搬到存储设备那一侧
3.1 一次 open 背后交换了什么
网络附加存储(NAS)是连接到局域网、基于 IP 的文件共享设备。它和 DAS 最根本的差别不在接口,在于文件系统跑在谁那边。DAS 的文件系统在服务器上,NAS 的文件系统在存储设备上,客户端通过网络协议请求“打开路径/project/a.dwg并从偏移 4096 开始读 64KB”,请求用 NFS 或者 CIFS 封装,跑在 TCP/IP 之上。
请求粒度一变,设备侧要维护的东西就完全不同了:目录树、文件记录、权限(UID/GID 或 ACL)、文件锁、客户端缓存一致性。这几样加起来相当于一个小型操作系统,所以 NAS 设备有自己的操作系统一点都不奇怪——它必须能独立回答“这个文件在哪、谁能读、现在有没有人锁着”。教材里说 NAS 设备“使用自己的操作系统和集成的硬件、软件组件”,讲的就是这个必然结果。
还有一个容易被忽略的差异:块级请求基本是定长的,4KB 或 8KB;文件级请求里元数据操作(readdir、stat、rename、lookup)占比很高,这些操作的数据量极小但对延迟极其敏感。所以 NAS 的性能调优思路和块存储完全不是一回事,给 NAS 配大缓存、优化目录索引,往往比堆带宽更有效。
3.2 NFS 与 CIFS 的语义鸿沟
NFS 的早期设计(v2/v3)追求无状态:每个请求自带文件句柄,服务器不保存“这个客户端打开了哪个文件”这类会话上下文。好处很实在,服务器重启后客户端重发请求就行,不需要重建会话;坏处是文件锁必须单独用 NLM 协议解决,缓存有效性要靠客户端自己按超时判断。
CIFS/SMB 是另一条路,有状态:会话建立、认证、树连接、文件句柄都在服务端维护,还带机会锁来减少网络往返。语义更完整,贴近本地文件系统的行为,代价是断线重连、会话迁移这些事复杂得多。
所以教材里“UNIX 通常用 NFS,Windows 用 CIFS”这句话,背后是语义匹配而不是操作习惯。真正麻烦的是同一台 NAS 同时开两种协议、共享同一个目录:UID/GID 和 SID 之间没有天然映射,同一个文件在 NFS 客户端看来属于 1000:1000,在 SMB 客户端看来属于某个账户,两边的权限判断可能不一致。这是跨平台共享里最常见的翻车点,上线前一定要把身份映射策略定死。
# 服务端:导出一个目录给指定网段 # rw/no_root_squash 决定写权限与 root 身份是否被压缩 # sync 保证落盘后再应答,async 快但掉电可能丢最近写入 /export/share 10.0.0.0/24(rw,sync,no_subtree_check,root_squash) # 客户端:一次挂载里藏着四个关键决策 mount -t nfs -o vers=3,rw,hard,timeo=600,retrans=2,rsize=1048576,wsize=1048576 \ 10.0.0.10:/export/share /mnt/sharevers=3决定了走无状态还是有状态语义;hard表示服务端无响应时无限重试,业务不会收到错误但可能卡死;timeo=600的单位是 0.1 秒,也就是 60 秒超时;rsize/wsize是单次读写的数据块大小,设小了协议开销占比高,设大了在小文件场景反而浪费。这几个参数怎么配,取决于业务能容忍“数据不一致”还是能容忍“卡住”,没有统一答案。
3.3 专用化:砍掉什么,换来什么
NAS 是单一用途设备,这句话不是贬义。硬件上砍掉显卡、多余的 PCIe 槽、通用外设;软件上砍掉通用发行版里那一堆用不上的服务,把 CPU 时间和内存几乎全留给文件服务和网络栈。换来的是三样东西:单设备能接入的客户机数量远高于通用服务器;文件 I/O 路径更短,没有本地磁盘调度和其他业务抢 CPU;配额、快照、共享权限收敛到一个管理界面里。
代价同样明确。文件级接口不满足所有场景,数据库、虚拟机镜像、需要裸设备语义的应用,仍然要块级。于是有了统一存储:同一套硬件同时暴露块接口(FC/iSCSI)和文件接口(NFS/CIFS),教材里那句“兼容 SAN 和 NAS 两种方式,满足业务弹性发展,简化业务部署,提升存储资源利用率”说的就是它。
但统一存储不是免费午餐。同一套控制器要同时处理块和文件两类负载,缓存要分区、前端端口要分配、故障域要提前规划。混跑时一个文件业务的元数据风暴把块业务的时延拉高,是运维里非常常见的抱怨——不是设备不行,是两类负载的资源竞争没在设计阶段算清楚。
4. SAN 的分层设计:SCSI 命令为什么要被“打包”进另一个网络
4.1 三层映射:从 SCSI 命令到 FC 帧
存储区域网络(SAN)是服务器和存储资源之间专用的、高性能的网络体系,为大量原始数据的传输做过专门优化。教材里有一句很关键的判断:FC SAN 可以看成 SCSI 协议在长距离应用上的扩展。这句话把 SAN 的本质说透了——它不是新的存储语义,是把原来只能在机箱里跑的 SCSI,换了一套传输层送到几公里外。
分层看就很清楚。最上面是 SCSI 层,产生命令描述块(CDB),比如 READ(10) 就是一个 10 字节的数组;中间是 FC 层,把 CDB 塞进 FC 帧的数据区,加上 24 字节帧头,帧头里有源地址 S_ID、目的地址 D_ID、交换 ID 和序列 ID;最下面是 FC-0,光模块、光纤、编码。SCSI 是货物,FC 是卡车,货物本身没变。
def read10(lba, blocks, flags=0): """构造 SCSI READ(10) 的 CDB,共 10 字节,iSCSI 会把它原样放进 PDU 头""" return bytes([ 0x28, # opcode:READ(10) flags, # FUA / DPO / RDPROTECT 等标志位 (lba >> 24) & 0xFF, # LBA 高字节,大端序 (lba >> 16) & 0xFF, (lba >> 8) & 0xFF, lba & 0xFF, 0x00, # group number,老设备用,通常填 0 (blocks >> 8) & 0xFF, # 传输长度:要读多少个逻辑块 blocks & 0xFF, 0x00, # control 字节 ]) cdb = read10(0x1A2B3C, 8) print(len(cdb), cdb.hex()) # 10 281a2b3c00000008000lba占 4 字节,理论寻址空间是 2 的 32 次方个块,按 512 字节算就是 2TB,这也是为什么大容量场景要用 READ(16) 或者变长 CDB。blocks只占 2 字节,单条命令最多 65535 个块,超过就要拆成多条命令——这条限制直接影响了主机侧 I/O 调度器怎么切分大请求。flags里的 FUA 位表示“绕过阵列缓存直接落盘”,做数据一致性校验时经常用到。
FC 世界里还有一个概念绕不开:WWN。它是 64 位地址,pWWN 标识端口,nWWN 标识节点,相当于 FC 的 MAC 地址,但硬编码在 HBA 或阵列端口上,比 MAC 稳定得多。所有的 Zoning、LUN 映射,最终都是围绕这串地址在做。
4.2 Zoning 与 LUN Masking:可见性的两道闸门
Zoning 在交换机上做,控制“哪些端口能互相看见”。硬 zoning 按端口划,软 zoning 按 WWN 划,生效之后不在同一个 zone 里的端口连登录都完不成。LUN Masking 在阵列上做,控制“这台主机能访问哪些 LUN”,阵列根据 HBA 的 pWWN 或 iSCSI 的 IQN 建立映射表,主机登录后只能看到属于自己的那些 LUN。
为什么两道闸门都得有?只做 zoning,主机仍然可能扫到并写入不属于自己的 LUN——操作系统扫描总线是很积极的行为,扫到就敢往上建文件系统。只做 masking,交换机侧的登录风暴、链路状态变化通知仍然会在不该互通的主机之间互相干扰,一台配置错误的主机甚至能把整个 fabric 搞乱。两道闸门一个管“能不能通信”,一个管“能看见什么”,职责不重叠。
有个细节特别容易踩:LUN ID 是主机视角的编号,不是设备的全局编号。同一个物理 LUN,在 A 主机上可能是 LUN 3,在 B 主机上可能是 LUN 7,甚至是 LUN 0。这解释了为什么同一条链路在两台服务器上看到的/dev/sdX名字不同——sd 名字是主机内核按扫描顺序给的,跨主机对账必须靠 LUN 序列号或者阵列侧的映射表,拿 sd 名字对账早晚出事。
4.3 iSCSI:同一批命令换个信封
IP SAN 是以 TCP/IP 为底层传输协议、用以太网作为承载介质构建的存储区域网络,典型协议是 iSCSI,它定义了 SCSI 指令集在 IP 网络中的封装方式。封装结构是:48 字节的基本头(BHS,里面有一段 16 字节的 CDB 区)、可选的附加头、头校验、数据段、数据校验。
能跑在以太网上的原因不复杂:SCSI 命令本身与传输介质无关,它只要求可靠、有序、有时延上限的传输。TCP 提供可靠有序,以太网提供带宽,两者一拼就能承载。代价也很清楚:软件协议栈吃 CPU(可以用卸载卡缓解)、以太网的拥塞和丢包会让时延抖动比 FC 大、VLAN/QoS/流控这些网络侧配置得和存储侧对齐,否则出了问题两边互相甩锅。
# 发起端:先发现目标,再登录,注意 -p 指的是业务口不是管理口 iscsiadm -m discovery -t sendtargets -p 10.0.0.20:3260 iscsiadm -m node -T iqn.2024-01.example:array01 -p 10.0.0.20:3260 -l # 登录成功后内核才会生成块设备,多路径必须能认出两条链路是同一个设备 multipath -ll-m discovery只负责列出目标上有哪些 target,不做登录;-m node -l才是真正建立会话,会话建立后内核才会创建块设备。multipath -ll里如果同一个 WWID 下面挂了两个sd设备,说明多路径识别正常;如果出现两个独立条目,先别往上建文件系统,那是数据损坏的前奏。
| 维度 | FC SAN | IP SAN(iSCSI) |
|---|---|---|
| 承载介质 | 光纤、FC 交换机 | 以太网、普通交换机 |
| 协议栈开销 | 硬卡卸载,主机 CPU 占用低 | 软件栈为主,可配卸载卡 |
| 典型时延 | 低且稳定 | 受网络拥塞影响,抖动更大 |
| 运维技能栈 | 存储与光纤网络 | 存储与以太网 |
| 适用场景 | 高性能、低时延的核心库 | 中低端业务、远程复制、成本敏感 |
5. 避坑与排查:链路上“ping 通但业务不通”的五个现场
5.1 坑一:能 ping 通存储,却扫不到任何 LUN
现象很典型:主机能 ping 通阵列的管理地址,但lsscsi或者fdisk -l里一块新盘都没有,看起来像“网络没问题但存储不认我”。
原因通常是平面搞混了。管理口是带外管理,跑的是 Web 界面和告警;LUN 映射走的是业务口,FC 或者 iSCSI 的业务网。另外 iSCSI 场景下,如果发起端没有登录 target,网络再通也不会有块设备,因为块设备是会话建立之后才被内核创建的。
解决要按固定顺序走,别跳步:先确认业务口连通性(iscsiadm -m discovery能不能列出 target),再确认主机发起端的 IQN 或 HBA 的 pWWN 已经被加进阵列的主机组,然后确认 LUN 已经映射到这个主机组,最后在主机侧rescan-scsi-bus.sh触发扫描。四步任何一步没做,前面的都白搭。
5.2 坑二:多路径的两条链路被识别成两块盘
现象:multipath -ll里出现两个独立设备,/dev/sdb和/dev/sdc内容看起来一样;更糟的情况是有人在这两块盘上各建了一个文件系统,写进去的数据互相覆盖。
原因有两个常见分支。iSCSI 场景下,主机用两个不同的 IQN 登录了同一个 target,或者两条路径的 target portal group 不一致,内核就认为是两个不同设备。FC 场景下通常是 multipath 服务没装、没启动,或者multipath.conf里的黑名单把设备过滤掉了。
解决:一台主机只用一个 IQN;确认 target 侧把两个门户放在同一个 portal group;multipath.conf里按阵列型号配好prio和path_grouping_policy,支持 ALUA 的阵列用service-time或alua;上线前一定用multipath -ll逐条确认所有路径归到同一个 WWID 下面。这个检查花三十秒,能省掉后面几天的事故复盘。
5.3 坑三:NFS 挂载后客户端彻底卡死
现象:服务端网络抖动或者重启之后,客户端ls卡住,Ctrl+C 退不出来,负载一路飙升,重启都费劲。
原因是hard挂载加上默认超时。hard的语义是“服务端不响应就一直重试”,客户端进程会卡在不可中断状态,只要服务端不回来,它就一直等。
解决要按业务性质分。能容忍读不一致的场景可以上soft配合timeo/retrans,超时后返回错误;不能容忍写丢失的场景保留hard,但必须把timeo调大、把监控做在前面,让告警先于人发现服务端异常。另一个思路是用自动挂载控制挂载的生命周期,按需挂载、空闲卸载,把故障影响面压到最小。
5.4 坑四:阵列扩容了,主机侧容量没变
现象:阵列侧把 LUN 从 2TB 扩到 4TB,主机侧df -h还是 2TB,反复刷新也没用。
原因是容量扩展是分层生效的,缺一层就不动:阵列 LUN 扩容 → 主机内核重新识别块设备大小(要 rescan)→ 分区表扩展(growpart)→ LVM 物理卷扩展(pvresize)→ 逻辑卷扩展(lvextend)→ 文件系统扩展(xfs_growfs或resize2fs)。任何一层漏掉,df都不会变。
解决就是按层往下查,每层都有对应命令和日志。还要记住两个文件系统的差异:XFS 只能扩不能缩,ext4 可扩可缩但缩之前必须卸载。规划时如果预判未来会缩容,文件系统选型就要提前定,别等扩容扩完了才发现退不回去。
5.5 坑五:双控切换,业务断了半分钟
现象:控制器主备切换,预期几秒内恢复,实际断了 20 到 40 秒,上层应用已经报超时。
原因是主机侧多路径没识别 ALUA 状态,切换发生时仍然往失效路径发 I/O,一直等到默认超时(30 秒或 60 秒)才切到可用路径。这中间的时间完全是被超时参数吃掉的,不是阵列切换慢。
解决:开启 ALUA,确认阵列上报的路径状态在multipath -ll里能正确显示为 active 或 ghost;path_checker设成tur或tut,让探测更轻更快;把fast_io_fail_tmo调到 5 到 10 秒,让失败尽快上报给上层而不是干等。这些参数改完必须做一次真实的切换演练,纸面推算不算数。
6. 从入门级到中端,再到分布式与软件定义:TCO 这笔账怎么算
把教材里几类产品放在一张表里对比,取舍就清楚了:
| 定位 | 核心能力 | 关键指标口径 | 典型场景 |
|---|---|---|---|
| 入门级 | 简单、经济、易用,全冗余双控,按需扩展,几步完成配置 | 7×24 在线,同时支持 FC 与 iSCSI,硬盘智能休眠降能耗约 40%,16 档风扇调速 | 企业数据中心入门平台、分支节点 |
| 中端 | 全协议覆盖(FC/iSCSI/NFS/CIFS/FTP/FCoE/IB),热点分层、缓存加速、精简置备、自愈合 | 前后端带宽高出业界 50%,随机 IOPS 基准高出 30%,缓存与容量扩展倍数更高,30 分钟/TB 重构 | 通用业务平台、虚拟化与数据库混跑 |
| 分布式 | 标准 x86 服务器本地 HDD/SSD 组成大规模资源池,数据分散到多节点 | 横向扩展能力、副本或纠删码带来的可用性 | 海量非结构化数据、对象与文件场景 |
| 软件定义 | 通用 x86 介质经分布式技术池化,对外提供标准 SCSI/iSCSI 接口 | 硬件解耦、按需弹性、与虚拟化平台集成 | 非虚拟化上层应用与虚拟机的统一供给 |
入门级那段里最容易被低估的是能耗手段:硬盘按负载智能休眠、16 档风扇调速、按业务压力调 CPU 频率,这几项叠起来能把电费和散热成本压下去一大截,而 TCO 里电费占比往往比采购价更持久。中端那段里最容易被高估的是峰值性能数字,前后端带宽和 IOPS 基准只说明上限,真正决定体验的是热点分层准不准、精简置备的空间回收及不及时、重构时业务掉不掉速。
我个人判断一台中端存储值不值,不看它把多少高端功能下放,而看它把哪些能力做成了默认开启、不需要在项目里额外规划。热点分层如果要在实施阶段人工设计迁移策略,精简置备如果要靠脚本定期回收,自愈合如果要在故障后才手动触发,那这些功能的价值就打了一半折扣。分布式和软件定义也一样,把一堆 x86 服务器堆成资源池只是第一步,真正的成本在运维:节点扩容时的数据重平衡、坏盘后的重构窗口、版本升级时的滚动策略,这些才是三年后账单上的大头。
那年做一次容量规划,我按阵列标称容量算的比例,忘了给快照和精简置备的元数据留余量,上线三个月就触发了水位告警,临时扩容的采购流程走了六周。从那以后我每次做容量方案,都强制把“有效容量、快照预留、精简置备超配比、重构预留”四项分开列,任何一项不写清楚就不签字。教材里的架构图能帮你理解机制,但真正让你少踩坑的,是这些把数字落到纸面上的习惯。希望帮到你。
本文还有配套的精品资源,点击获取