ZFSの性能劣化について

Posted on 2011/02/09(Wed) 23:24 in technical

ZFSはHDDの空き領域の現象に伴って、性能が劣化すると言われている。

自宅で動いているZFSなファイルサーバのパフォーマンスも、少し落ちてきている気もする。

そこで、簡単なテストケースを準備して、性能劣化が見られるか試してみることにした。

結論から言うと、別に容量問題は存在しないように見受けられる。

警告

空き領域が減ったら問題が起きるわけではない、と言うだけ。

一般的な書き換え頻度によって長期間運用された結果、空き領域が足りなくなった状況においては、 直接的に性能に影響を及ぼす要素は、単純な空き領域以外の要素(CoWによるデータの散らばりやフラグメント)ではないかと考えられる。 そして、性能低下と言う状況が表面化するタイミングを見極めるうえで、空き領域を指標として用いる、と言うのが直感的に理解しやすいために、空き領域が足りなくなると性能が極端に低下する、と表現されるような気がしている。

試験環境

  • GT110b + OpenIndiana v148

OpenIndianaから見た情報

  • HDD(HTS725050A9A364):

    # format
     Searching for disks...
     Failed to inquiry this logical diskdone
    
    AVAILABLE DISK SELECTIONS:
     0. c2d0 <????pHoH??[Xq???? cyl 2608 alt 2 hd 255 sec 63>
     /pci@0,0/pci-ide@1f,2/ide@0/cmdk@0,0
     1. c3t1d0 <ATA-Hitachi HTS72505-C70E-465.76GB>
     /pci@0,0/pci8086,49@1/pci1014,394@0/sd@1,0
     Specify disk (enter its number): PuTTY^C
    
  • CPUはCel G1101:

    OpenIndiana Development oi_148 X86
     Copyright 2010 Oracle and/or its affiliates. All rights reserved.
     Use is subject to license terms.
     Assembled 29 November 2010
     Status of virtual processor 0 as of: 02/08/2011 22:49:27
     on-line since 02/06/2011 20:41:25.
     The i386 processor operates at 2267 MHz,
     and has an i387 compatible floating point processor.
     Status of virtual processor 1 as of: 02/08/2011 22:49:27
     on-line since 02/06/2011 20:41:31.
     The i386 processor operates at 2267 MHz,
     and has an i387 compatible floating point processor.
     Memory size: 12280 Megabytes
     The following filesystem versions are supported:
    
  • ZFSおよびZpoolのバージョン:

    VER DESCRIPTION
     --- --------------------------------------------------------
     1 Initial ZFS filesystem version
     2 Enhanced directory entries
     3 Case insensitive and File system unique identifier (FUID)
     4 userquota, groupquota properties
     5 System attributes
    
    For more information on a particular version, including supported
    releases,
     see the ZFS Administration Guide.
    
    This system is currently running ZFS pool version 28.
    
    The following versions are supported:
    
    VER DESCRIPTION
     --- --------------------------------------------------------
     1 Initial ZFS version
     2 Ditto blocks (replicated metadata)
     3 Hot spares and double parity RAID-Z
     4 zpool history
     5 Compression using the gzip algorithm
     6 bootfs pool property
     7 Separate intent log devices
     8 Delegated administration
     9 refquota and refreservation properties
     10 Cache devices
     11 Improved scrub performance
     12 Snapshot properties
     13 snapused property
     14 passthrough-x aclinherit
     15 user/group space accounting
     16 stmf property support
     17 Triple-parity RAID-Z
     18 Snapshot user holds
     19 Log device removal
     20 Compression using zle (zero-length encoding)
     21 Deduplication
     22 Received properties
     23 Slim ZIL
     24 System attributes
     25 Improved scrub stats
     26 Improved snapshot deletion performance
     27 Improved snapshot creation performance
     28 Multiple vdev replacements
    

テストケースの概要

  1. パーティションを10個に分割
  2. 9MiBのファイルが、各パーティションで週に960個生成されるとする。(dd + /dev/urandom使用)
  3. 週に1度各パーティションでsnapshotを取る。
  4. 1ヶ月後の性能劣化たるや。

それでは、結果を見ていく。

ある意味、非常に分かりやすい感じになっている。

が、後日HDDの内周と外周の速度差を見ると、続くグラフとほぼ同様の結果が得られており、ファイルシステムによる性能劣化という程の問題は見受けられなかった。

image0

X軸はアロケートされたHDD領域を指している。

測定はddを用いて、各パーティションで1回ずつの測定結果を平均した値を使用して描画している。

プール生成時にRead: 100MB/sec、Write: 90MB/sec程度出ていたシーケンシャルRead/Writeが、後半では半分程度に下がっていることが見て取れる。

これは、単純にZFSがLBAを増加させていった結果、HDDの内周部分に読み書き範囲が移動しただけ、だと思ってる。

image1

iostat -xctを60[sec]間隔で取得したもの。

書き込み時間が徐々に伸びていっている…のはそりゃそうだ。1枚目と同様だが、時間間隔のためX軸の調整はサボった。

image2

2枚目と同様。I/Oの発行の頻度も徐々に下がっている。

image3

ランダムファイルを生成している時は、CPU(sys)がボトルネックになっており、HDDのbusyは少ない。処理量は減るので、CPU使用率はわずかながら低下していく。

image4

IO WaitとActiveに関しては、Activeの数は変わらないものの、待ち時間は増えている。

image5

最後は、zpool iostatを60[sec]間隔で取得したもの。こちらも、結果は同様。

単純に空き領域との対比で考えるなら、わざわざランダムファイル作ったり、snapshot取ったりする必要はないのだけど、これは単なるテストケースに対する加速試験という位置づけのため…とか言い訳しておきます。

最初に試験した時は、ランダムファイルを作りすぎて最後1回の試験がスペース不足だったという切なさ。:

dd: writing \`./dir4/4.dd': No space left on device
 13035+0 records in
 13034+0 records out
 6833569792 bytes (6.8 GB) copied, 217.993 s, 31.3 MB/s

使用したシェルスクリプト。

#!/bin/sh
#————————–
# 0.Init log
#————————–
date
cat /etc/release
psrinfo -v
prtconf | grep Mem
zfs upgrade -v
zpool upgrade -v

#————————–
# 1.Create Zpool
#————————–
zpool create p-test $1
zpool status
zpool list
zfs list
zpool get all p-test
iostat -ndcxM 60 > p-test_01_iostat.txt &
zpool iostat p-test 60 > p-test_01_zpool.txt &
cd /p-test

#————————–
# 2.Create ZFS Partition
#————————–
num=0
while [ ${num} -ne 10 ] ; do
echo “zfs create p-test/dir${num}”
zfs create p-test/dir${num}
num=`expr ${num} + 1`
done

#————————–
# 3.Performance Check with dd
#————————–
num=0
while [ ${num} -ne 10 ] ; do
dd if=/dev/zero of=./dir${num}/${num}.dd bs=512k count=30720
dd of=/dev/null if=./dir${num}/${num}.dd bs=512k count=30720
rm ./dir${num}/${num}.dd
num=`expr ${num} + 1`
done

#————————–
# 4.Get Snapshot
#————————–
num=0
while [ ${num} -ne 10 ] ; do
zfs snapshot p-test/dir${num}@init
num=`expr ${num} + 1`
done

#————————–
# 8.Loop for step 4,5,6,7
#————————–
loop=0
while [ ${loop} -ne 5 ] ; do
echo “loop ${loop} start.”
zpool status
zpool list
zfs list
zfs list -t snapshot
zpool get all p-test

#————————–
# 4.Make Rundom Files
#————————–
num=0
while [ ${num} -ne 10 ] ; do
files=0
while [ ${files} -ne 960 ] ; do
dd if=/dev/urandom of=./dir${num}/temp-${loop}-${num}-${files}.dd bs=512k count=18
files=`expr ${files} + 1`
done
num=`expr ${num} + 1`
done

#————————–
# 5.Get Snapshot
#————————–
num=0
while [ ${num} -ne 10 ] ; do
zfs snapshot p-test/dir${num}@${loop}
num=`expr ${num} + 1`
done

#————————–
# 6.Delete Rundom Files
#————————–
num=0
while [ ${num} -ne 10 ] ; do
files=256
while [ ${files} -ne 512 ] ; do
rm ./dir${num}/temp-${loop}-${num}-${files}.dd
files=`expr ${files} + 1`
done
num=`expr ${num} + 1`
done

#————————–
# 7.Performance Check with dd
#————————–
num=0
while [ ${num} -ne 10 ] ; do
dd if=/dev/zero of=./dir${num}/${num}.dd bs=512k count=30720
dd of=/dev/null if=./dir${num}/${num}.dd bs=512k count=30720
rm ./dir${num}/${num}.dd
num=`expr ${num} + 1`
done

loop=`expr ${loop} + 1`
done

#————————–
# 9.Destroy zpool
#————————–
sleep 10
zpool status p-test
zpool list
zfs list
zfs list -t snapshot
zpool get all p-test
sleep 10
zpool destroy p-test
kill `ps a | grep “iostat -ndcxM 60| head -1 | cut -f 2 -d ” “`
kill `ps a | grep “zpool iostat p-test 60| head -1 | cut -f 2 -d ” “`

こっそり当たり障りの無い表現に修正。