Linux

為什麼 blktrace 只寫 8 個塊?

  • January 14, 2014

我想了解數據庫寫入磁碟的 I/O 模式,以決定使用多少磁碟以獲得最佳性能。要分析 I/O 模式,我想使用 blktrace,我必須先了解它。這就是我在這裡嘗試的。

我有一個連接到電腦的 USB 記憶棒,它變成 /dev/sdd。現在我開始

dd if=/dev/sdd of=/dev/null

在一個單獨的視窗上我開始

blktrace -d /dev/sdd -o - | blkparse -i -

並期望看到合併 (M) 並放入隊列 (Q) 的讀取 (R) 操作。這行得通,但據我了解,塊大小始終為 8:

8,48   6    15257     2.157995037  2470  M   R 816696 + 8 [dd]
8,48   6    15258     2.157996273  2470  Q   R 816704 + 8 [dd]
8,48   6    15259     2.157996520  2470  M   R 816704 + 8 [dd]
8,48   6    15260     2.157997794  2470  Q   R 816712 + 8 [dd]

現在我停止一切並告訴系統只讀取一個字節:

dd if=/dev/sdd of=/dev/null count=1 bs=1
1+0 records in
1+0 records out
1 byte (1 B) copied, 0.00325544 s, 0.3 kB/s

這顯示在 blkparse 控制台上,如下所示:

8,48   6        1    17.220316681  2543  G   N [dd]
8,48   6        2    17.220317209  2543  I   N 0 (00 ..) [dd]
8,48   6        3    17.220317707  2543  D   N 0 (00 ..) [dd]
8,48   6        4    17.220787473  2543  Q   R 0 + 8 [dd]
8,48   6        5    17.220790545  2543  G   R 0 + 8 [dd]
8,48   6        6    17.220791330  2543  P   N [dd]
8,48   6        7    17.220793515  2543  Q   R 8 + 8 [dd]
8,48   6        8    17.220794597  2543  M   R 8 + 8 [dd]
8,48   6        9    17.220796134  2543  Q   R 16 + 8 [dd]
8,48   6       10    17.220796419  2543  M   R 16 + 8 [dd]
8,48   6       11    17.220797695  2543  Q   R 24 + 8 [dd]
8,48   6       12    17.220797943  2543  M   R 24 + 8 [dd]
8,48   6       13    17.220798862  2543  I   R 0 + 32 [dd]

這裡發生了什麼?為什麼讀取一個字節會顯示為 3 個“R”請求,每個請求都有一個 Q 和一個 M 動作?為什麼它“似乎”讀取 32 或 24 個字節?文件娛樂在哪裡可以進一步教育我?

因為您正在執行緩衝 IO,並且頁面記憶體在整個頁面中工作,在 PC 上為 4k,或 8 512 字節扇區。假設 dd 將繼續讀取,核心預讀機制也會讀取更多內容。如果你想避免這種情況,那麼你需要通過傳遞 dd 的 iflag=direct 選項來使用直接 IO,但是你不能讓它讀取一個字節這樣做——直接 IO 必須對齊,並且甚至是扇區大小的倍數。

在blktrace中,+後面的數字是扇區大小的請求大小(通常為512字節,可以使用blockdev –report查看)

所以在你的跟踪中,總讀取實際上是 16kbytes。

那麼為什麼有4個’R’請求,我能想到的原因是提前閱讀。我通過使用以下命令將預讀設置為 512 字節進行了測試:

blockdev --setra 1 /dev/sdd

查看 read_ahead_kb 顯示 0

more /sys/block/sdd/queue/read_ahead_kb
0

我從執行你的 dd 命令得到的跟踪如下:

8,48   0        1     0.000000000 14412  Q   R 0 + 8 [dd]
8,48   0        2     0.000002577 14412  G   R 0 + 8 [dd]
8,48   0        3     0.000004467 14412  P   N [dd]
8,48   0        4     0.000005627 14412  I   R 0 + 8 [dd]
8,48   0        5     0.000007362 14412  U   N [dd] 1
8,48   0        6     0.000008238 14412  D   R 0 + 8 [dd]
8,48   0        7     0.018772074     0  C   R 0 + 8 [0]
CPU0 (dd_bs1_c1):
Reads Queued:           1,        4KiB  Writes Queued:           0,        0KiB
Read Dispatches:        1,        4KiB  Write Dispatches:        0,        0KiB
Reads Requeued:         0               Writes Requeued:         0
Reads Completed:        1,        4KiB  Writes Completed:        0,        0KiB
Read Merges:            0,        0KiB  Write Merges:            0,        0KiB
Read depth:             1               Write depth:             0
IO unplugs:             1               Timer unplugs:           0

至於為什麼它讀取 4kbytes 而不是 1 字節,我相信這是因為 FS 塊大小為 4kBytes。因此,這是將被讀取的最小值。

引用自:https://unix.stackexchange.com/questions/105612