Linux ディスクのシーケンシャル書き込みとランダム書き込みの方法

Linux ディスクのシーケンシャル書き込みとランダム書き込みの方法

1. はじめに

● ランダム書き込みではヘッドがトラックを頻繁に変更するため、効率が大幅に低下します。一方、シーケンシャル書き込みではヘッドがトラックを変更する必要はほとんどないか、変更時間が非常に短くなります。● この記事では、2つの具体的な違いと対応するカーネル呼び出しについて説明します。

2. 環境整備

コンポーネントバージョン
OS Ubuntu 16.04.4 LTS
フィオ2.2.10

3. fioの紹介

fio テストは、読み取りと書き込みの状態を反映できます。fio 出力レポートのいくつかの重要な指標に注目する必要があります。
slat: I/O 送信から実際の I/O 実行までの時間を指します (送信レイテンシ)
clat: I/O 送信から I/O 完了までの時間 (完了待ち時間) を指します。
lat: fio が I/O を作成してから I/O が完了するまでの合計時間を指します。
bw: スループット
iops: 1秒あたりのI/O操作数

4. 同期書き込みテスト

(1)同期ランダム書き込み

fio は主にテストツールとして使用されます。システムコールを確認するには、strace ツールを使用します。コマンドは次のようになります。

まずはランダム書き込みをテストしてみましょう

strace -f -tt -o /tmp/randwrite.log -D fio -name=randwrite -rw=randwrite \
-direct=1 -bs=4k -size=1G -numjobs=1 -group_reporting -filename=/tmp/test.db

重要な情報を抽出する

root@wilson-ubuntu:~# strace -f -tt -o /tmp/randwrite.log -D fio -name=randwrite -rw=randwrite \
> -direct=1 -bs=4k -size=1G -numjobs=1 -group_reporting -filename=/tmp/test.db
randwrite: (g=0): rw=randwrite、bs=4K-4K/4K-4K/4K-4K、ioengine=sync、iodepth=1
fio-2.2.10
1 プロセスを開始
...
randwrite: (グループID=0、ジョブ=1): err= 0: pid=26882: 2019年8月14日水曜日10:39:02
 書き込み: io=1024.0MB、bw=52526KB/s、iops=13131、runt= 19963msec
 clat (usec): 最小=42、最大=18620、平均=56.15、標準偏差=164.79
  緯度 (usec): 最小=42、最大=18620、平均=56.39、標準偏差=164.79
...
 bw (KB /s): 最小=50648、最大=55208、パーセンテージ=99.96%、平均=52506.03、標準偏差=1055.83
...

実行ステータス グループ 0 (すべてのジョブ):
 書き込み: io=1024.0MB、aggrb=52525KB/秒、minb=52525KB/秒、maxb=52525KB/秒、mint=19963ミリ秒、maxt=19963ミリ秒

ディスク統計(読み取り/書き込み):
...
 sda: ios=0/262177、マージ=0/25、ティック=0/7500、in_queue=7476、util=36.05%

注目すべき情報は次のとおりです。

(1)クラット、平均持続時間は約56ミリ秒

(2)緯度、平均持続時間は約56ミリ秒

(3)帯域幅、スループット、約52M

カーネル呼び出し情報を見てみましょう。

root@wilson-ubuntu:~# /tmp/randwrite.log の詳細
...
26882 10:38:41.919904 lseek(3, 665198592, SEEK_SET) = 665198592
26882 10:38:41.919920 書き込み(3, "\220\240@\6\371\341\277>\0\200\36\31\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
26882 10:38:41.919969 lseek(3, 4313088, SEEK_SET) = 4313088
26882 10:38:41.919985 write(3, "\220\240@\6\371\341\277>\0\200\36\31\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
26882 10:38:41.920032 lseek(3, 455880704, SEEK_SET) = 455880704
26882 10:38:41.920048 書き込み(3, "\220\240@\6\371\341\277>\0\200\36\31\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
26882 10:38:41.920096 lseek(3, 338862080, SEEK_SET) = 338862080
26882 10:38:41.920112 write(3, "\220\240@\6\371\341\277>\0\2402\24\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
26882 10:38:41.920161 lseek(3, 739086336, SEEK_SET) = 739086336
26882 10:38:41.920177 書き込み(3, "\220\240@\6\371\341\277>\0\2402\24\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
26882 10:38:41.920229 lseek(3, 848175104, SEEK_SET) = 848175104
26882 10:38:41.920245 write(3, "\220\240@\6\371\341\277>\0\2402\24\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
26882 10:38:41.920296 lseek(3, 1060147200, SEEK_SET) = 1060147200
26882 10:38:41.920312 書き込み(3, "\220\240@\6\371\341\277>\0\2402\24\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
26882 10:38:41.920362 lseek(3, 863690752, SEEK_SET) = 863690752
26882 10:38:41.920377 書き込み(3, "\220\240@\6\371\341\277>\0\2402\24\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
26882 10:38:41.920428 lseek(3, 279457792, SEEK_SET) = 279457792
26882 10:38:41.920444 書き込み(3, "\220\240@\6\371\341\277>\0\2402\24\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
26882 10:38:41.920492 lseek(3, 271794176, SEEK_SET) = 271794176
26882 10:38:41.920508 書き込み(3, "\220\240@\6\371\341\277>\0\2402\24\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
26882 10:38:41.920558 lseek(3, 1067864064, SEEK_SET) = 1067864064
26882 10:38:41.920573 書き込み(3, "\220\240@\6\371\341\277>\0\2402\24\0\0\0\0\202\2\7\320\343\6H\26P\340\277\370\330\30e\30"..., 4096) = 4096
...

各ランダム読み取りの前に、lseek を使用して現在のファイル オフセットを特定します。

同期シーケンシャル書き込み

先ほどの方法を使って書き順をテストする

root@wilson-ubuntu:~# strace -f -tt -o /tmp/write.log -D fio -name=write -rw=write \
-direct=1 -bs=4k -size=1G -numjobs=1 -group_reporting -filename=/tmp/test.db
書き込み: (g=0): rw=書き込み、bs=4K-4K/4K-4K/4K-4K、ioengine=同期、iodepth=1
fio-2.2.10
1 プロセスを開始
ジョブ: 1 (f=1): [W(1)] [100.0% 完了] [0KB/70432KB/0KB /s] [0/17.7K/0 iops] [eta 00m:00s]
書き込み: (グループID=0、ジョブ=1): エラー= 0: pid=27005: 2019年8月14日水曜日 10:53:02
 書き込み: io=1024.0MB、bw=70238KB/s、iops=17559、runt= 14929msec
 clat (usec): 最小=43、最大=7464、平均=55.95、標準偏差=56.24
  緯度 (usec): 最小=43、最大=7465、平均=56.15、標準偏差=56.25
...
 bw (KB /s): 最小=67304、最大=72008、パーセンテージ=99.98%、平均=70225.38、標準偏差=1266.88
...

実行ステータス グループ 0 (すべてのジョブ):
 書き込み: io=1024.0MB、aggrb=70237KB/秒、minb=70237KB/秒、maxb=70237KB/秒、mint=14929ミリ秒、maxt=14929ミリ秒

ディスク統計(読み取り/書き込み):
...
 sda: ios=0/262162、マージ=0/10、ティック=0/6948、in_queue=6932、使用率=46.49%

以下が見られます:

スループットが約70Mに増加

カーネル呼び出しをもう一度見てみましょう。

root@wilson-ubuntu:~# /tmp/write.log をさらに表示
...
27046 10:54:28.194508 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\360\t\0\0\0\0\0\0\320\17\0\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.194568 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.194627 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.194687 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.194747 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.194807 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.194868 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.194928 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.194988 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195049 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195110 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195197 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195262 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195330 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195426 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195497 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195567 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195637 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195704 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195757 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195807 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195859 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195910 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.195961 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196012 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196062 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0\220\24\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196112 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0 \26\0\0\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196162 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0 \26\0\0\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196213 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0 \26\0\0\0\0\0\0\0\0\320\17\0\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196265 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0 \26\0\0\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196314 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0 \26\0\0\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196363 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0 \26\0\0\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196414 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0 \26\0\0\0\0\0\0\0\0\320\17\0\0\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196472 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0 \26\0\0\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196524 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0 \26\0\0\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
27046 10:54:28.196573 書き込み(3, "\0\0\23\0\0\0\0\0\0\300\16\0\0\0\0\0\0 \26\0\0\0\0\0\0\0\0\320\17\0\0\0\0\0"..., 4096) = 4096
...

シーケンシャル読み取りのため、ファイルオフセットを繰り返し探す必要がなく、書き込み操作に集中できます。

5. スラットインジケーター

上記のテストでは、fio テスト レポートに slat が見つかりませんでした。これは、上記がすべて同期操作であるためです。同期 I/O の場合、I/O の送信と I/O の完了は 1 つのアクションであるため、slat は実際には I/O が完了した時間です。

非同期順次書き込みの場合は、同期順次書き込みのコマンドに -ioengine=libaio を追加します。

root@wilson-ubuntu:~# fio -name=write -rw=write -ioengine=libaio -direct=1 -bs=4k -size=1G -numjobs=1 -group_reporting -filename=/tmp/test.db
書き込み: (g=0): rw=書き込み、bs=4K-4K/4K-4K/4K-4K、ioengine=libaio、iodepth=1
fio-2.2.10
1 プロセスを開始
ジョブ: 1 (f=1): [W(1)] [100.0% 完了] [0KB/119.3MB/0KB /s] [0/30.6K/0 iops] [eta 00m:00s]
書き込み: (グループID=0、ジョブ=1): エラー= 0: pid=27258: 2019年8月14日水曜日11:14:36
 書き込み: io=1024.0MB、bw=120443KB/s、iops=30110、runt= 8706msec
 スラット (usec): 最小=3、最大=70、平均= 4.31、標準偏差= 1.56
 clat (usec): 最小=0、最大=8967、平均=28.13、標準偏差=55.68
  緯度 (usec): 最小=22、最大=8976、平均=32.53、標準偏差=55.72
...
 帯域幅 (KB /秒): 最小=118480、最大=122880、パーセンテージ=100.00%、平均=120467.29、標準偏差=1525.68
...

実行ステータス グループ 0 (すべてのジョブ):
 書き込み: io=1024.0MB、aggrb=120442KB/秒、minb=120442KB/秒、maxb=120442KB/秒、mint=8706ミリ秒、maxt=8706ミリ秒

ディスク統計(読み取り/書き込み):
...
 sda: ios=0/262147、マージ=0/1、ティック=0/6576、in_queue=6568、使用率=74.32%

スラットインジケータが表示され、latはslat + clat(平均平均値)の合計にほぼ等しいことがわかります。非同期IOに切り替えた後、スループットが大幅に改善され、約120Mになりました。

VI. 結論

● fio はディスクのベースライン ツールとして使用する必要があります。マシン (物理またはクラウド) を入手したら、できるだけ早くマシンのディスクでベースライン テストを実行して、状況を明確に把握する必要があります。● この記事のすべてのテストはキャッシュをバイパスしました。実際のアプリケーションでは、キャッシュの影響を考慮する必要があります。

以上が、Linux ディスクのシーケンシャル書き込みとランダム書き込みについてご紹介した内容です。お役に立てれば幸いです。ご質問がございましたら、メッセージを残していただければ、すぐに返信いたします。また、123WORDPRESS.COM ウェブサイトをサポートしてくださっている皆様にも感謝申し上げます。
この記事が役に立ったと思われた方は、ぜひ転載していただき、出典を明記してください。ありがとうございます!

以下もご興味があるかもしれません:
  • Linux システムでルート ディレクトリのディスク領域を拡張する方法
  • Linux の Centos7 における LVM ディスク拡張の問題
  • Linux ディスク管理ソフトウェア RAID の実装原理と方法の分析と共有
  • Linuxでディスクスペースを転送する方法
  • Linux ディスクフォーマットコマンドの詳細な説明
  • Linux仮想マシンのルートパーティションディスク拡張スペースレコードの詳細な説明
  • 不明なリソースによって Linux ディスク領域が枯渇する問題の解決方法
  • Linux のディスク容量サイズを表示するコマンド
  • Linux サーバーのディスク容量を拡張する方法 (画像)
  • 2T を超える Linux ディスクで GPT パーティションを使用する方法

<<:  MySQL でトリガーを無効化および有効化するチュートリアル [推奨]

>>:  Vue でのキープアライブコンポーネントの使用例

推薦する

CentOS で Mysql を再起動するさまざまな方法 (推奨)

1. rpm パッケージ経由でインストールされた MySQL サービスmysqldを再起動 /et...

Navicat 経由で MySQL にリモート接続する方法

Navicat を使用して IP 経由で直接接続すると、次のようなさまざまなエラーが報告されます: ...

Vue で v-for を更新する方法

ヒント:配列変更メソッドによりv-forが更新され、ページが更新されます。配列を変更しないメソッド:...

選択ドロップダウンボックスの値をIDに渡してコードを実装する方法

完全なコードは次のとおりです。 HTMLコード:コードをコピーコードは次のとおりです。 <!-...

初心者がHTMLタグを学ぶ(3)

関連記事:初心者が学ぶ HTML タグ (2)導入された HTML タグは、必ずしも XHTML 仕...

Mysql テーブルコメントフィールド取得操作

余計なことは言わないで、コードだけ見てみましょう〜 -- テーブル内のフィールドコメントを表示および...

js の parseInt() の奇妙な動作の調査と修正

背景: parseInt(0.006) または parseInt(0.0006) は 0 という値を...

RedHat 6.5/CentOS 6.5 に MySQL 5.7.20 をインストールするための詳細なチュートリアル

rpmインストールパッケージをダウンロードするMySQL公式サイト: https://dev.mys...

CSS で実現される HTML 背景色のグラデーション

エフェクトのスクリーンショット:実装コード:コードをコピーコードは次のとおりです。 <!DOC...

両側にCSS固定レイアウト、中央に適応レイアウトを実装

フローティング、フローティング埋め込み div、配置、フレックスという 4 つの一般的な方法と原則を...

MySQL の不正な文字列値の解決方法

MySQL を使用して中国語の文字を挿入すると、多くの友人から次のエラーが報告されます。 これは、文...

IDEA は MySQL への接続時にエラーを報告します。サーバーが無効なタイムゾーンを返します。タブに移動して serverTimezone プロパティを設定してください。

これからの道は常に困難で、棘だらけです。歯を食いしばって、乗り越えられると信じてください。さあ、さあ...

WHMCS V7.4.2 グラフィカル インストール チュートリアル

1. はじめにWHMCS は、ユーザー管理、請求書の支払い、ヘルプ サービスなど、オンライン ビジネ...

Vueはアコーディオン効果を実装する

この記事の例では、アコーディオン効果を実現するためのVueの具体的なコードを参考までに共有しています...

時刻を保存するために適切な MySQL の datetime 型を選択する方法

データベースを構築してプログラムを書くとき、日付と時刻の使用は避けられません。データベースには、ti...