📚 第三章 数据链路
📄 一句话概括

iSCSI 的思路是「用普通以太网跑存储」,代价是每块数据都要付一笔固定开销。 这笔开销对 64 KB 的块无所谓,对 512 字节的块就是灾难。

📝 本节和前面几节的关系

3.6.6 的光纤通道是「专用网」,iSCSI 是「复用现有网」,两者是一对。 这一节把两边的开销算清楚,你就知道什么时候该选哪个。

一、每一层都要加一个头

把一层层的头拆开数一遍:

层 字节 说明
以太网头 14 含源目 MAC
IP 头 20 两端地址
TCP 头 20 端口与序号
iSCSI 头 48 含读写块号、长度
以太网尾 4 FCS 校验

加起来 106 字节:前三个头是「网络」的成本(54 字节),第四个是「存储」的成本(48 字节)。 48 字节的 iSCSI 基本头比 TCP 头还大—— 因为它要说清「读哪个 LUN、从哪个块开始、读多长、命令编号是多少」。 注意「数据」那一行不在表里:它是变量,块多大就多大。 而前面五个是常量,不管块多小都要付。 这就是「小数据块吃亏」的全部机制。

二、块越小越亏

把三档常见的块大小算一遍:

数据块 线上一共 数据占比
512 字节 618 82.8%
4096 字节 4202 97.5%
65536 字节 65642 99.8%

第一行 512 字节的块,有 17% 的带宽在传头:这是数据库最常见的块大小(一个页 8 KB, 一次读几个 512 字节的扇区)。 第三行 64 KB 的块几乎没浪费:文件服务器的顺序读写就是这种形状。 所以存储圈有句经验话:iSCSI 上跑文件服务舒服,跑数据库得算一算。 不是协议不行,是「每块固定 106 字节」这个结构决定的。 要缓解只能「合并小 IO」—— 把多个小块拼成一个大请求发出去,这就是操作系统里「IO 合并」在做的事。

三、和光纤通道比什么

开销上的差距其实不算大:

方案 每块开销 关键差别
光纤通道 约 36 字节 专用网、不丢包
iSCSI 约 106 字节 复用以太网、会丢包

106 对 36,多出来 70 字节——放在 4 KB 的块上,就是 1.7 个百分点的效率差,不算致命。 第二列那个「会丢包」才是真正的分界: TCP 丢包要重传,重传的等待是毫秒级;而存储的读写是同步的,等着就是业务卡住。 所以在同一个机房里,光纤通道仍然比 iSCSI 稳。 但第三列另一半也得看:iSCSI 不用另建一张网。 一台服务器两块网卡就能同时跑业务和存储,运维、备件、人员都是同一套。 对中小规模来说,这个好处远远压过那点延迟差。 现在的答案又多了一种: NVMe over Fabrics——把 NVMe 命令直接跑在 RDMA 或光纤通道上,跳过 SCSI 那一层。 本质还是「把存储命令装进某个链路层」,只是换了个更轻的信封。

四、动手 Demo:iSCSI——把磁盘命令装进 TCP 里

把五层头加起来,再算三档块大小的效率。 注意 512 字节那一行:整整 17% 的带宽在传头。

overhead = 14 + 20 + 20 + 48 + 4
print('每块固定开销 %d 字节' % overhead)

for blk in (512, 4096, 65536):
    total = blk + overhead
    print('%6d 字节 -> 线上 %6d 字节,数据占 %.1f%%'
          % (blk, total, 100.0 * blk / total))

print('光纤通道约 36 字节,iSCSI 约 %d 字节,多 %d'
      % (overhead, overhead - 36))

实跑输出:

--------------------------------------------------------------------
iSCSI——把磁盘命令装进 TCP 里
--------------------------------------------------------------------
**iSCSI 的思路是「用普通以太网跑存储」**:
**把 SCSI 命令封装进 TCP,就不用专门建一套光纤通道网了。**
**代价是「每一层都要加一层头」。**

  层                          字节       说明
  --------------------------------------------------------------------
  以太网头                    14         —
  IP 头                       20         —
  TCP 头                      20         —
  **iSCSI 基本头(BHS)**     **48**     **含 CDB 与各种字段**
  SCSI CDB                    16         **读写命令本身就在这 48 里**
  以太网尾 FCS                4          —

**前三个头是「网络」的成本,第四个是「存储」的成本**:
**48 字节的 BHS 比 TCP 头还大,因为它要带上「读哪个块、读多少」这些信息。**
**所以「小数据块」在 iSCSI 上特别吃亏。**

  数据块 字节     线上一共 字节     数据占比
  -------------------------------------------
  512             618               82.8%
  4096            4202              97.5%
  65536           65642             99.8%

**第一行 512 字节的块,效率只有 82%**:**因为开销 106 字节是固定的,块越小占比越高。**
**第三行 64 KB 的块效率 99.8%**,几乎没浪费。
**这解释了存储配置里一个很实际的建议**:
**iSCSI 上跑数据库(小块随机读写)比跑文件服务器(大块顺序读写)更吃力**——
**不是协议不行,是「每块都要付 106 字节的固定成本」。**
**和光纤通道比一比**:
  方案             每块开销 字节     关键差别
  --------------------------------------------------------------
  **光纤通道**     **约 36**         **专用网,不丢包**
  **iSCSI**        **约 106**        **复用现有以太网,会丢包**

**第二行那个「会丢包」是真正的差别**:**TCP 丢包要重传,重传的延迟是毫秒级;而存储要的是微秒级。**
**所以在同一个机房里,光纤通道仍比 iSCSI 稳。**
**但 iSCSI 的好处是「不用另建一张网」。**
**对中小规模来说,这个好处远远压过那点延迟差。**

106 这个数是可以背下来的:14 + 20 + 20 + 48 + 4。 换成 IPv6 就是 14 + 40 + 20 + 48 + 4 = 126,所以纯 IPv6 环境里的 iSCSI 效率会再低一点。 「BHS」这个名字值得记一下:Basic Header Segment,iSCSI 基本头段,固定 48 字节。 后面还可能有「附加头」(AHS),用于更复杂的命令。 所以 106 是下限,不是定值。 为什么不用 UDP 而用 TCP:存储要求「一定送到、顺序不错」,这正是 TCP 保证的。 UDP 快但没有这些保证,得自己在应用层重做一遍——而重做的那套东西,比 TCP 复杂得多。 所以在「可靠传输」这件事上,复用 TCP 是最省事的选择。

30 秒实验

  1. 算一下:块大小是 8192 字节时,iSCSI 的数据占比是多少?
  2. 想一下:为什么 iSCSI 选 TCP 而不选 UDP?
  3. 查一下你公司服务器用的是本地盘、iSCSI 还是光纤通道?

常见误区

  1. 以为「iSCSI 比光纤通道慢很多」。 带宽上差距不大,差的是「丢包后的重传延迟」。
  2. 以为「开销是每字节摊的」。 它是每块固定的 106 字节,所以块越小越亏。
  3. 以为「iSCSI 就是网络硬盘」。 它给的是「块设备」,主机看到的是裸磁盘,不是共享文件夹。
自测三问(点开对答案) 1. iSCSI 的 106 字节是哪几层? —— **以太网头 14 + IP 头 20 + TCP 头 20 + iSCSI 头 48 + FCS 4**。 2. 为什么小数据块在 iSCSI 上吃亏? —— **106 字节是每块固定的**,512 字节的块有 17% 的带宽在传头,64 KB 的块只有 0.2%。 3. iSCSI 和光纤通道真正的差别是什么? —— **光纤通道设计上不丢包,延迟是微秒级;iSCSI 会丢包,重传要等毫秒级。**开销反而不是关键。

下一节看 InfiniBand:把「可靠」这件事从 CPU 手里拿走。

相关笔记