zfsの圧縮オプションの違いによる圧縮率、計算速度の違いを測定

zfsにはファイルシステムの機能として圧縮の機能があります。ファイルの種類に応じて自動的に圧縮がかかるため、特に意識すること無くxfs, ext4より多くのデータを保存することが可能になります。

圧縮機能をONにするとデフォルトではlz4のアルゴリズムが使われますが、他にもgzip(gzip-1〜gzip-9)、lzjb、zleなども選択することができます。
今回は、圧縮率の違いとアプリケーション実行時における速度の違いを見てみたいと思います。

環境

OS : CentOS7.5 (kernel: 3.10.0-862.9.1.el7.x86_64)
CPU : Xeon Gold 6134 (8core, 3.2GHz) x2
Memory : 64GB
Disk : NVMe P4500 4TB x1
zfs : version 0.7.9

圧縮アルゴリズム

下記6種類のアルゴリズムに圧縮無しを加えた7つのケースについて比較を行いました。

lz4(default)
gzip-1
gzip-6
gzip-9
lzjb
zle

zfsの作成

# zfs create NVMe/db
# zfs create NVMe/lz4 -o compress=on
# zfs create NVMe/gzip-1 -o compuress=gzip-1
# zfs create NVMe/gzip-6 -o compress=gzip   ## gzipとした時のデフォルトがgzip-6のため
# zfs create NVMe/gzip-9 -o compress=gzip-9
# zfs create NVMe/lzjb -o compress=lzjb
# zfs create NVMe/zle -o compress=zle

圧縮率の比較

NCBI ntデータベース

まずは、NCBIのntデータベースで比較してみたいと思います。
ファイルサイズの合計は、NVMe/db(圧縮OFF)の通り21GBです。
それぞれの圧縮アルゴリズムによってUSEDのサイズが変わっていることがわかります。

# zfs list
NAME          USED  AVAIL  REFER  MOUNTPOINT
NVMe/db      21.0G  3.40T  21.0G  /NVMe/db
NVMe/gzip-1  14.0G  3.40T  14.0G  /NVMe/gzip-1
NVMe/gzip-6  13.8G  3.40T  13.8G  /NVMe/gzip-6
NVMe/gzip-9  13.8G  3.40T  13.8G  /NVMe/gzip-9
NVMe/lz4     14.9G  3.40T  14.9G  /NVMe/lz4
NVMe/lzjb    16.2G  3.40T  16.2G  /NVMe/lzjb
NVMe/zle     21.0G  3.40T  21.0G  /NVMe/zle

zfsのコマンドで圧縮率も取得できます。
gzip-Xの圧縮率が高く、次いでlz4, lzjbと続きますが、zleは何も圧縮されていません。

# zfs get compressratio -o name,value
NAME                                             VALUE
NVMe/db                                          1.00x
NVMe/gzip-1                                      1.49x
NVMe/gzip-6                                      1.51x
NVMe/gzip-9                                      1.52x
NVMe/lz4                                         1.41x
NVMe/lzjb                                        1.29x
NVMe/zle                                         1.00x

fastqファイル

次にfastqファイル(text形式)について比較を行いました。
比較に使用したfastqファイルは8.6GBのDRR081404.fastqです。

# ls -sh DRR081404.fastq 
8.6G DRR081404.fastq

上で作ったそれぞれのzfsの下にfastqという名前を付け加えたzfsを作成し、
そこにDRR081404.fastqをコピーします。

# zfs get compress -t filesystem |grep -e NAME -e fastq
NAME               PROPERTY     VALUE     SOURCE
NVMe/db/fastq      compression  off       default
NVMe/gzip-1/fastq  compression  gzip-1    inherited from NVMe/gzip-1
NVMe/gzip-6/fastq  compression  gzip      inherited from NVMe/gzip-6
NVMe/gzip-9/fastq  compression  gzip-9    inherited from NVMe/gzip-9
NVMe/lz4/fastq     compression  lz4       inherited from NVMe/lz4
NVMe/lzjb/fastq    compression  lzjb      inherited from NVMe/lzjb
NVMe/zle/fastq     compression  zle       inherited from NVMe/zle

コピー後のUSED使用量と圧縮率は以下の通りとなりました。
ntと比較すると全体的に圧縮率は上がっていますが(zleは除く)、gzip-X勢の伸びが顕著でした。
圧縮率だけを考えた場合、gzip-6,gzip-9に設定するのが良さそうです。

# zfs list |grep -e NAME -e fastq
NAME                USED  AVAIL  REFER  MOUNTPOINT
NVMe/db/fastq      8.57G  3.24T  8.57G  /NVMe/db/fastq
NVMe/gzip-1/fastq  3.77G  3.24T  3.77G  /NVMe/gzip-1/fastq
NVMe/gzip-6/fastq  3.46G  3.24T  3.46G  /NVMe/gzip-6/fastq
NVMe/gzip-9/fastq  3.43G  3.24T  3.43G  /NVMe/gzip-9/fastq
NVMe/lz4/fastq     5.66G  3.24T  5.66G  /NVMe/lz4/fastq
NVMe/lzjb/fastq    5.87G  3.24T  5.87G  /NVMe/lzjb/fastq
NVMe/zle/fastq     8.57G  3.24T  8.57G  /NVMe/zle/fastq

# zfs get compressratio -o name,value |grep -e NAME -e fastq
NAME                                                VALUE
NVMe/db/fastq                                       1.00x
NVMe/gzip-1/fastq                                   2.27x
NVMe/gzip-6/fastq                                   2.48x
NVMe/gzip-9/fastq                                   2.49x
NVMe/lz4/fastq                                      1.51x
NVMe/lzjb/fastq                                     1.45x
NVMe/zle/fastq                                      1.00x

アプリケーションの動作比較 

次にアプリケーションで実行速度の比較を行います。
以下のようなスクリプトを実行し、それぞれの圧縮アルゴリズム毎の実行時間の比較を行います。
fastq-dumpとbwaのindexはシングルスレッド、bwa memとsamtoolsは全16コアを使ったマルチスレッドオプションで実行しました。

[スクリプト抜粋]

#!/bin/bash

NP=`nproc`

## fastq-dump
spack load sra-toolkit
fastq-dump DRR081404.sra

## bwa index
spack load bwa
bwa index -a bwtsw -p chr1_index chr1.fa

## bwa mem
bwa mem -t ${NP} chr1_index DRR081404.fastq > DRR081404.sam

## samtools sam2bam
spack load samtools
samtools sort -@ ${NP} -O bam -o DRR081404.bam DRR081404.sam

実行時間比較(単位=秒)

Compress=off lz4(default) gzip-1 gzip-6 gzip-9 lzjb zle
fastq-dump (1thr) 97.84 95.73 95.56 95.79 93.44 97.14 97.18
bwa index (1thr) 210.41 210.9 215.64 214.71 236.12 224.54 221.92
bwa mem (16thr) 495.9 499.37 517.31 554.25 589.41 503.69 496.11
samtools sam2bam (16thr) 59.36 64.02 101.31 102.37 102.63 81.42 60.06

グラフ (compress=off を1.00として比較)

Single Threadで実行したfastq-dump, bwa indexの場合には性能上の大きなペナルティはありませんでしたが、
全コア計算に使用したbwa memとsamtoolsのsam2bamではCPUリソースの競合により性能上のペナルティが大きくなりました。
特にsamtoolsを実行したケースのgzipではその傾向が顕著に表れています。
上の圧縮率も含めて考えると、lz4のバランスの良さが際立っており、これがデフォルト設定になっているというのも納得できます。

まとめ

上記の結果を考えると
一般的なファイルサーバーやヘッドノードではデフォルト通りのlz4を、バックアップ専用のサーバーなどにはgzip-6, gzip-9を、というのが良い選択なのではないかと思います。

また、今回は触れませんでしたがzfsには重複排除(dedup)の機能もあり、x3からx4程度の重複排除が可能です。
圧縮機能と併用することでディスク占有率をかなり抑えることができるのですが、重複排除には膨大なメモリ容量が必要となるため実際にONにするケースは少ないですしお薦めもできないといった難点があります。

その他、現行のXeonの一部のチップセットにはQAT(Quick Assist Technology)という暗号化や圧縮を専用にて行うチップが載っているものがあります。
zfs on linuxも0.7以降でQATに対応しているため、CPUリソースを消費すること無く圧縮を利用できるようになることが期待できます。

spack package managerを使って最新のgccをインストール

CentOS7にデフォルトでインストールされるgccはバージョンが4.8.5ですが、ここ数年のgccはかなり高頻度にバージョンを上げていて、現在はなんと8.1にまでバージョンが上がっています。gcc 4.8.5でも問題が無いケースは多いのですが、バイオインフォマティクス系の新しいアプリケーションを入れる際にライブラリが古くて入らないといったことは時折起こることですし、またSkylake世代のCPUから新しく搭載されたAVX512の命令セットを使いたい場合にはそもそも4.8.5では対応していません。もちろん、gccをソースからコンパイルすることは可能ですが、gccのコンパイルはrequirementsのライブラリなどが多く手間がかかりがちです。そんなケースではspackというパッケージ管理ツールを使うと比較的容易に新しいバージョンのgccを導入できます。

(注 : 1つ前の記事のApache SparkとSpackは何の関係もありません)

Spackとは

SpackはLLNL(Lawrence LivermoreNational Laboratory)で主としてはスパコン向け(もしくはスパコンユーザー向け)に開発されたパッケージ管理ツールです。MPIの種類、CPUアーキテクチャの違い、コンパイラの違い、ソフトウェアのバージョン、これらについて全部の組み合わせを一元的に管理するのは組み合わせの数が多くなりすぎて現実的ではない、といった背景から開発されたものです。

Spackは以下のような特徴を持っています。

  • 依存関係も含めてSourceからコンパイルしてくれる
  • コンパイラ自体をspackでインストールして登録可能。登録した後はコンパイラの使い分けも可能
  • インストールしたパッケージは、デフォルトではユーザーの$HOME以下に配置される(ユーザー権限で各ユーザー毎にソフトウェアの追加が可能)
  • インストールと同時に、Environment Moduleの登録が行われ、環境変数を切り替えることで、アプリケーションの使い分けが可能

バイオインフォマティクス系のアプリケーションではAnaconda, Bioconda、Deep Learning向けツールではpyenv, irtualenvなどの方が使えるパッケージは多いのですが、最近ではspackでもバイオインフォマティクス系のパッケージが増えてきています。ちなみにNABEでは、納入用システムの負荷試験、性能テストを行う際などのスクリプトの中でspackを活用しています。

github : https://github.com/spack/spack

基本的な使い方

  • 公式tutorial : http://spack.readthedocs.io/en/latest/tutorial.htmlhttps://spack.io/slides/Spack-SC17-Tutorial.pdf

  • 導入

    $ git clone https://github.com/spack/spack
    $ cd spack/bin
    $ ./spack [コマンド]
    
    ## bash/zshの場合は.bashrc/.zshrcに下記行を追記してください
    export SPACK_ROOT=~/spack   # PATHはspackをダウンロードしたディレクトリに合わせてください
    . $SPACK_ROOT/share/spack/setup-env.sh
    
    $ source .bashrc
    
    • Requirements : CentOSユーザーの場合は、Environment Modulesが必要です。yum install environment-modulesでインストールします。
  • spackの基本コマンド

    $ spack list : availableなパッケージを一覧表示

    $ spack find : インストール済みパッケージの一覧表示

    $ spack install [package] : パッケージのインストール

    $ spack info [package] : パッケージの情報を参照 (インストール可能なバージョンの一覧やインストールオプション、依存パッケージなどの確認ができる)

    $ spack load [packge] : $ module load [package] と同様、パッケージの環境変数をロードできる

  • インストール後の利用方法について

    • # spack findと実行するとインストール済みのソフトウェアが表示されます。
    # spack find
    
    -- linux-centos7-x86_64 / gcc@4.8.5 -----------------------------
    autoconf@2.69    fftw@3.3.7        isl@0.18             ncurses@6.0     samtools@1.6
    automake@1.15.1  gcc@7.3.0         libpciaccess@0.13.5  openmpi@3.0.0   sqlite@3.21.0
    boost@1.66.0     gdbm@1.14.1       libsigsegv@2.11      openssl@1.0.2n  sra-toolkit@2.8.2-1
    bowtie2@2.3.1    gmp@6.1.2         libtool@2.4.6        perl@5.24.1     tophat@2.1.1
    bwa@0.7.17       htslib@1.6        libxml2@2.9.4        pkgconf@1.4.0   util-macros@1.19.1
    bzip2@1.0.6      hwloc@1.11.8      m4@1.4.18            python@2.7.14   xz@5.2.3
    cmake@3.10.1     intel-tbb@2018.2  mpc@1.0.3            python@3.6.1    zlib@1.2.11
    cufflinks@2.2.1  ior@3.0.1         mpfr@3.1.5           readline@7.0
    
    • # module avail と実行しても似たような同様のソフトウェア、バージョンが並びますが、それらに続いてgccのバージョン、ランダムな英数字が追加されています。これは冒頭でも書いた通り、同じバージョンのソフトウェアでコンパイラやオプション、MPIが異なる場合でも併用して使用できるようにこのようになっています。
    # module avail
    
    ---------- /root/spack/share/spack/modules/linux-centos7-x86_64 ------------
    autoconf-2.69-gcc-4.8.5-dquvd2k         libxml2-2.9.4-gcc-4.8.5-p7wmc5o
    automake-1.15.1-gcc-4.8.5-4gqhira       m4-1.4.18-gcc-4.8.5-jwvjtud
    boost-1.66.0-gcc-4.8.5-x3grlyj          mpc-1.0.3-gcc-4.8.5-h3sbthg
    bowtie2-2.3.1-gcc-4.8.5-jiu5gdq         mpfr-3.1.5-gcc-4.8.5-rmi7bmi
    bwa-0.7.17-gcc-4.8.5-fusrahs            ncurses-6.0-gcc-4.8.5-zxqghp3
    bzip2-1.0.6-gcc-4.8.5-4vcfqu3           openmpi-3.0.0-gcc-4.8.5-hbngn74
    cmake-3.10.1-gcc-4.8.5-pj7haun          openssl-1.0.2n-gcc-4.8.5-cibkbry
    cufflinks-2.2.1-gcc-4.8.5-cjiekfb       perl-5.24.1-gcc-4.8.5-oucoesz
    fftw-3.3.7-gcc-4.8.5-vyzm5ml            pkgconf-1.4.0-gcc-4.8.5-xiymx6n
    gdbm-1.14.1-gcc-4.8.5-ttariy6           python-2.7.14-gcc-4.8.5-4ipldug
    gmp-6.1.2-gcc-4.8.5-6bsovvk             python-3.6.1-gcc-4.8.5-6b34kap
    htslib-1.6-gcc-4.8.5-sawucah            readline-7.0-gcc-4.8.5-elgoxoq
    hwloc-1.11.8-gcc-4.8.5-ctwvb2m          samtools-1.6-gcc-4.8.5-birxczn
    intel-tbb-2018.2-gcc-4.8.5-wp2y7ez      sqlite-3.21.0-gcc-4.8.5-ffmjav6
    ior-3.0.1-gcc-4.8.5-4u2zxsc             sra-toolkit-2.8.2-1-gcc-4.8.5-5ncmk2i
    isl-0.18-gcc-4.8.5-l4somr6              tophat-2.1.1-gcc-4.8.5-wikx2qq
    libpciaccess-0.13.5-gcc-4.8.5-5chyfxo   util-macros-1.19.1-gcc-4.8.5-p66qdrt
    libsigsegv-2.11-gcc-4.8.5-qpmaxx6       xz-5.2.3-gcc-4.8.5-kgp7olc
    libtool-2.4.6-gcc-4.8.5-bcbiddk         zlib-1.2.11-gcc-4.8.5-64vg6e4
    
    # module show bowtie2-2.3.1-gcc-4.8.5-jiu5gdq
    -------------------------------------------------------------------
    /root/spack/share/spack/modules/linux-centos7-x86_64/bowtie2-2.3.1-gcc-4.8.5-jiu5gdq:
    
    module-whatis    Bowtie 2 is an ultrafast and memory-efficient tool for aligning sequencing reads to long reference sequences 
    prepend-path     PATH /root/spack/opt/spack/linux-centos7-x86_64/gcc-4.8.5/bowtie2-2.3.1-jiu5gdqwx6c5vla4zdsy3xg2j3vfgkny/bin 
    prepend-path     CMAKE_PREFIX_PATH /root/spack/opt/spack/linux-centos7-x86_64/gcc-4.8.5/bowtie2-2.3.1-jiu5gdqwx6c5vla4zdsy3xg2j3vfgkny/ 
    -------------------------------------------------------------------
    
    • # module availで表示されたモジュール名は長いのでloadする場合は# spack loadと実行する方が便利です。ただ、spackのサブコマンドはmoduleのサブコマンドをほとんど引き継いでいないので、load以外は通常のmoduleコマンドを使用する必要があります。
    # module list
    No Modulefiles Currently Loaded.
    
    # spack load bowtie2@2.3.1  # "module load bowtie2-2.3.1-gcc-4.8.5-jiu5gdq" と同じ
    # module list
    Currently Loaded Modulefiles:
      1) bowtie2-2.3.1-gcc-4.8.5-jiu5gdq
    
    # which bowtie2
    /root/spack/opt/spack/linux-centos7-x86_64/gcc-4.8.5/bowtie2-2.3.1-jiu5gdqwx6c5vla4zdsy3xg2j3vfgkny/bin/bowtie2
    
    # module purge  # ロードされたモジュールを全て破棄
    # module list
    No Modulefiles Currently Loaded.
    

spackでgcc-8.1をインストール

  • spackで使用可能なコンパイラの一覧表示
    # spack compilers
    ==> Available compilers
    -- gcc centos7-x86_64 -------------------------------------------
    gcc@4.8.5
    
  • spackでgccを追加
    # spack install gcc  ## spack info gccの出力で表示される "Preferred version"がデフォルトインストールされます。
    
    ## バージョンを指定したい場合は、 # spack install gcc@7.2.0 のように@[version]という形で指定します。
    ## 
    (# spack info gcc の出力)
    ## Preferred version:  
    ##     8.1.0    http://ftp.gnu.org/gnu/gcc/gcc-8.1.0/gcc-8.1.0.tar.xz
    ## 
    ## Safe versions:  
    ##     8.1.0    http://ftp.gnu.org/gnu/gcc/gcc-8.1.0/gcc-8.1.0.tar.xz
    ##     7.3.0    http://ftp.gnu.org/gnu/gcc/gcc-7.3.0/gcc-7.3.0.tar.xz
    ##     7.2.0    http://ftp.gnu.org/gnu/gcc/gcc-7.2.0/gcc-7.2.0.tar.xz
    ##     ...
    ##     ...
    
    ==> Staging archive: /root/spack/var/spack/stage/gcc-8.1.0-7ci7edvlswswwvq5undrshns6pxzpqdn/gcc-8.1.0.tar.xz
    ==> Created stage in /root/spack/var/spack/stage/gcc-8.1.0-7ci7edvlswswwvq5undrshns6pxzpqdn
    ==> Ran patch() for gcc
    ==> Building gcc [AutotoolsPackage]
    ==> Executing phase: 'autoreconf'
    ==> Executing phase: 'configure'
    ==> Executing phase: 'build'
    ==> Executing phase: 'install'
    ==> Successfully installed gcc
    

    最後にこのようなメッセージが出ればインストール完了です。(依存パッケージも多いためけっこう時間がかかります) インストールしたgccをspack外のパッケージのコンパイルなどに使用する場合、# spack load gcc@8.1.0とするだけで利用できるようになります。

  • 追加したcompilerをspackで使用出来るようにする

    インストールしたgcc-8.1.0をspackで使用するコンパイラとして登録します。(spack以外の通常のパッケージをコンパイルするだけであればspack loadするだけで構いません)

    # spack find gcc
    # spack load gcc@8.1.0
    # spack compiler find  # これを実行すると自動的にPATHを探してコンパイラを見つけて、spackのコンパイラ設定ファイルへの設定も行われます。
    ==> Added 1 new compiler to /root/.spack/linux/compilers.yaml
      gcc@8.1.0
    ==> Compilers are defined in the following files:
      /root/.spack/linux/compilers.yaml
    
    # spack compilers  # spackで使用可能なコンパイラのリストを表示します。gcc@8.1.0が追加されていることがわかります。
    ==> Available compilers
    -- gcc centos7-x86_64 -------------------------------------------
    gcc@8.1.0  gcc@4.8.5
    
    

その他の活用法

今回は、gccの例を挙げましたが、spackはパッケージマネージャなので登録されていればspackからコンパイルして利用することが可能です。例えば、とあるソフトウェアをSourceからコンパイルしようとしてもzlibなどのライブラリが古くてエラーになるような場合、spackでzlibをインストールしてコンパイル時にそのzlibをloadしてコンパイルに利用するといった使い方も可能です。また、システム全体には入っていないけれど screen/tmux/byobuなどのターミナルマルチプレクサやzsh/fishなどのシェルを使いたいと言った場合にも簡単に自身だけのバージョンの導入ができます。

ここまでは良い点を挙げてきましたが、逆に手間がかかる点、困る点などを挙げると下記のような点があります。

  • インストールに時間がかかる (依存関係のパッケージが多い場合は特に。全てSourceからコンパイルするため)
  • コンパイル時にエラーが出ることがある。当然と言えば当然ですが、エラーが出ると普通にコンパイルするより手間がかかることもあります。

spack自体は上記の通り、git cloneするだけで使えますし、既存の環境への影響なく使えるといった点で比較的気軽に導入することができると思いますので一度試してみてもらえればと思います。

GATK4とApache Spark

Dear GATK4 !

今年に入り、GATK4.0が発表されました。
これまでと大きく異なる点がいくつもある、ビッグニュースでした。

まずはライセンスが大幅に変わっています。これまでアカデミックでしか無償利用ができなかったのですが、BSD 3-clauseライセンスになり、Commercial useが許可されています。

次に、GATK4に内包されるツールが拡大し、機能アップ、
さらに、並列分散処理基盤であるApache Sparkに対応してきました。

ツールの中にはHaplotypeCallerSparkやBwaSparkといったものがあり、
ツール名が示す通りSparkの力を使ってmappingからvariant callingをカバーし、高速化しようとしていることがわかります。

Sparkによる高速化

Apache Sparkは大規模データ処理のための分析エンジンで、hadoopのhdfsあるいはその他のコンポーネントと共に利用します。
Sparkそのものの特徴としては中間データを途中でディスクに書き出したりしないことによる高速化などが挙げられますが、
NGSデータの分野にとっては、そもそもそれ以前にデータをhadoop hdfs上に持つことからして大きな変化と思われます。

hadoop hdfsはデータの持ち方がこれまでと大きく変わります。
データやデータ群を複数の計算ノードにあるローカルディスクに分散して持たせ、
 どの計算機からも分散処理ができるようにアクセスすることができます。
分散と同時に重複して持たせることができ、分散による高速処理と耐障害性とを同時に満たしつつ、
高い拡張性を持っていることが特徴です。
従来であれば高価な共有ディスクを使っていたような局面でも、比較的安価なローカルディスクでその性能を超えることができるというものです。

また、インメモリーで処理ができることも見逃せないポイントのひとつです。
 1TBものメインメモリを積むことがDual Socketのサーバーでも当たり前にできるようになりましたが、
そうしたサーバーを複数持つことでかなり大きなデータをメモリに納めて計算することができるため、
これまでの常識ではできないと思っていた処理が可能になり、ゲノムデータや医用画像、顕微鏡などの巨大なデータから新たな知見が導き出されることを期待せずにはいられません。

GATK4+Sparkについて(2018年5月時点)

まず、ひとつだけ注意しなければならないのはまだBeta版のツールが多いということです。
gatk –list
で使用可能なツールが表示されるのですが、Spark対応のものは軒並み「Beta」バージョンです。

この点はいずれ正式リリースがなされることと思われるのでその前提で、試しにHaplotypeCallerSparkを動作させてみました。
結果、数台の試験機にvariant callingの処理が分散実行され、高速化に期待が持てることがわかりましたが、
バグによりまだ結果が安定していないことも確認されました。

Beta版なので当然といえば当然で、この点は正式リリースに期待しましょう。


実際、バグレポートはすでにあがっていて、パッチをあてることで改善できることも確認できています。

まとめ

今回はGATK4やSparkのお話をしましたがいかがでしたでしょうか。
 GATKはとても人気の高いソフトウェアのひとつで、使っている方も多いと思います。
大きな変化が出てきていますので、ぜひ注目して情報収集や試験導入をしていく必要がありそうです。
まだBetaバージョンの段階のものが多いですが、いずれ正式リリースされていくはずです。
NABEでも引き続きウォッチングしていく領域ですので、ご関心ある方はご相談やお話の共有をしていければと思います。

Environment Modulesについて

  • Takeru製品では、1,2年前からプリインストールされたアプリケーションのPATHなどの環境変数の設定を.bashrcではなくEnvironment Modulesを使って行うようにしています。
  • 背景としてはいくつかの要因がありますが、.bashrcのファイルでexportされている環境変数が多すぎてわかりにくくなっていることや、複数のバージョンの切り替えが容易になるといったメリットがあって導入しました。
  • もちろん、従来通りに.bashrcなどのファイルに設定することはできますので、システムとしては環境変数に関する設定の選択肢が一つ増えたということになります。
  • 今回はEnvironment Modulesの使い方について紹介します。

基本的な使い方

  • 既にあるモジュールを利用する場合は下記の6つのコマンドでほとんどのケースをカバーできるはずです。
    • # module avail : 利用可能なモジュールの一覧を表示
    • # module load [module] : モジュールをロード = 環境変数をロード
    • # module list : ロードされているモジュールを表示
    • # module unload [module] : 指定したモジュールをアンロード
    • # module purge : ロードされているモジュールを全てアンロード
    • # module show [module] : 指定したモジュールの設定ファイルを表示

実行例

  • “# module avail” : これを実行すると以下のように出力されます。
    • $MODULEPATH で指定されたPATH以下の設定ファイルが読み込まれて表示されます。
    • 複数バージョンを登録することができ、特定のバージョンをデフォルトとして登録することができます。
    • デフォルトで登録された場合、スラッシュ(/)以下のバージョンを明示的に指定しなくてもデフォルトのバージョンがロードされます。
$ module avail
------------- /etc/modulefiles -------------
abyss/2.0.2(default)
allpathslg/52488(default)
bedtools2/2.26.0
bedtools2/2.27.1(default)
bioperl/1.7.1(default)
biopython/1.69
biopython/1.70(default)
bioruby/1.5.1(default)
...
...
  • 以下でロード〜アンロードまで実行してみます。
$ which bedtools
/usr/bin/which: no bedtools in (/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin)

$ module load bedtools2 # バージョン指定無しでロードした場合、デフォルトのバージョンがロードされる

$ module list
Currently Loaded Modulefiles:
1) bedtools2/2.27.1

$ which bedtools
/usr/local/bedtools2-2.27.1/bin/bedtools

$ module list
Currently Loaded Modulefiles:
1) bedtools2/2.27.1

$ module load bedtools2/2.26.0 # バージョンを明示してロード

$ module list
Currently Loaded Modulefiles:
1) bedtools2/2.27.1 2) bedtools2/2.26.0

$ which bedtools
/usr/local/bedtools2-2.26.0/bin/bedtools

$ echo $PATH # 下記のようにPATHに追加されていることがわかります。
/usr/local/bedtools2-2.26.0/bin:/usr/local/bedtools2-2.27.1/bin:.... 以下省略

$ module purge # 全てアンロード

$ module list
No Modulefiles Currently Loaded.

 

modulefileの記載方法

/etc/modulefiles以下にアプリケーション名のディレクトリを作成、その下にバージョン名のついたファイルを作成しています

  • 例1) tophat2/2.1.1
    • 1行目は #%Module1.0 から始めます
    • 2行目以降にPATHの設定を記載します。
    • prepend-path の場合は、環境変数を冒頭に追加します。
    • append-path の場合は、環境変数を末尾に追加します。
$ cat /etc/modulefiles/tophat2/2.1.1

#%Module1.0
prepend-path PATH /usr/local/bowtie-1.1.2
prepend-path PATH /usr/local/tophat2-2.1.1/bin
  • 例2) R/3.4.0
    • PATHだけでなく、下記のようなLD_LIBRARY_PATHの他、MANPATH, CPATH, CMAKE_PREFIX_PATHなど基本的にどんな環境変数でも宣言できます。
$ cat /etc/modulefiles/R/3.4.0

#%Module1.0
prepend-path PATH /usr/local/R-3.4.0/bin
prepend-path LD_LIBRARY_PATH /usr/local/R-3.4.0/lib64
  • 例3) scypy/1.0.0
    • modulefiles内で他のmoduleのロードも可能です。
$ cat /etc/modulefiles/scipy/1.0.0

#%Module1.0
module load numpy/1.13.3
prepend-path PYTHONPATH /usr/local/scipy-1.0.0/lib64/python2.7/site-packages

デフォルトバージョンの指定方法

  • modulefiles以下のディレクトリ内に.versionというファイル内でデフォルトバージョンを指定します。
$ ls /etc/modulefiles/bedtools2/ -a
.  ..  2.26.0  2.27.1  .version

$ cat /etc/modulefiles/bedtools2/.version

#%Module1.0
set ModulesVersion "2.27.1"

$ module avail bedtools  # 以下のように2.27.1がデフォルトに設定されます。

------------- /etc/modulefiles -------------
bedtools2/2.26.0
bedtools2/2.27.1(default)

shell scriptに記載する際に注意

  • module loadは、シェルスクリプトやGrid Engineへの投入スクリプト内でも使用することができます.
  • ただ、moduleという実行バイナリがあるわけではなくaliasのため module: command not found とエラーが出ることがあります。
  • そのような場合は、スクリプトの一行目のshebangに “#!/bin/bash -i” というように-i オプションを追加すると実行できるようになります。
#!/bin/bash -i

module load bowtie2
bowtie2 -x genomes/NC_008253 e_coli_1000.fq -S testout.sam
module unload bowtie2

zfs-0.7.7 : cp実行時の問題

概要

  • zfs on linux 0.7.7 において大量のファイルを含むディレクトリをcpコマンドでコピーするとストレージの空き容量が十分にあるにも関わらず、”No space left on device”のエラーが出て一部のファイルがコピーされないという問題があることがわかりました。
    https://github.com/zfsonlinux/zfs/issuzes/7401
  • 上記URLで紹介されている例では、空のファイルを10000個作ったディレクトリをzfs上でコピーすると数千個のファイルがコピーされずにコマンドが終了してしまう
  • 修正されたバージョン 0.7.8では上記の症状は起きない
  • rsync, mvコマンドではこの症状は起きない模様

症状の確認

  • テスト環境
 
   # OS
     CentOS7.4 (3.10.0-693.21.1.el7.x86_64)
     zfs-0.7.7 -> zfs-0.7.8
  
   # Hardware Spec
     CPU : Xeon Platinum 8164 x2
     Memory: DDR4-2666 64GB
     RAID Card: 9361-8i(Firmware: 24.12.0-0020)
     HDD: HUA723030ALA640 x8 (RAID6)
# zpool list
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
Test 16T 14.5M 16.0T - 0% 0% 1.00x ONLINE -

# mkdir SRC
# for i in $(seq 1 10000); do echo $i > SRC/$i ; done
# cp -r SRC DST
cp: cannot create regular file ‘DST/4134’: No space left on device
cp: cannot create regular file ‘DST/4108’: No space left on device

# ls SRC/|wc
10000 10000 48894

# ls DST/|wc
8184 8184 40019
  • 上記の通り、エラーの出たファイルは2個だけでしたが、実際には10000個中1800個ほどのファイルがコピーされませんでした。
  • この後、0.7.8にupdateして同じことを確認しましたが、上記症状は発生せず全て正常にコピーされました。

該当するかどうかの確認方法

  • zfsのバージョンを確認する以下のように表示された場合は今回の症状が該当する可能性があります。
  • 該当している場合はupdate手順などについてご相談ください。
  • ただ、0.7.7がリリースされたのが3/21、0.7.8がリリースされたのが4/10ですのでこの間にzfsをインストール、あるいはupdateをしていなければ該当しないはずではあります。
$ rpm -q zfs
zfs-0.7.7-1.el7_4.x86_64

SkylakeとEPYCの比較 : Bioinfomatics Applications(1)

SkylakeとEPYCの双方でいくつかのbioinfomatics applicationでベンチマークを取ってみました。

今回比較に使用したのは以下の4モデルです。

CPU コア数 クロック周波数(定格) クロック周波数(ターボ最大) クロック周波数(All Core Boost) 概算価格(Web上) ※
Xeon Gold 5118 12 2.3 GHz 3.2 GHz 2.7 GHz $1,273
Xeon Gold 6126 12 2.6 GHz 3.7 GHz 3.3 GHz $1,776
EPYC 7351 16 2.4 GHz 2.9 GHz 2.9 GHz > $1,100
EPYC 7401 24 2.0 GHz 3.0 GHz 2.8 GHz $1,850

※ XeonはIntelのWebサイトの希望カスタマー価格から、EPYCはanandatech のWebサイトから

numactlで見るEPYCの特徴

性能面を考慮するときにコア数が多いという点は大きな特徴なのですが、
OSからは8コア単位で別のCPUコアとして認識されるため少し注意が必要です。

例えば、Dual CPU構成のマシンにおいてnumactl -H をXeonで実行した時、
下記のようになり、node0がCPU0、node1がCPU1を示しているのですが、

Xeon

# numactl -H
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
node 0 size: 96938 MB
node 0 free: 87276 MB
node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
node 1 size: 98304 MB
node 1 free: 92604 MB
node distances:
node   0   1 
  0:  10  21 
  1:  21  10

EPYC

EPYCの場合はDaul CPU構成でも下記のようになりまるで4coreのCPUを8個搭載しているように見えます。
末尾のnode distancesの行列は各コア間のメモリへのアクセスの相対的距離を示しているのですが
EPYCの場合はXeonに比べて同じ物理CPU間でも(node0 – node3)の間でも距離が生じ、物理的に遠いCPUの
メモリにアクセスした場合の距離はXeonに比べて1.5倍ほどになっています。

# numactl -H
available: 8 nodes (0-7)
node 0 cpus: 0 1 2 3
node 0 size: 65444 MB
node 0 free: 40188 MB
node 1 cpus: 4 5 6 7
node 1 size: 65535 MB
node 1 free: 41572 MB
node 2 cpus: 8 9 10 11
node 2 size: 65535 MB
node 2 free: 41057 MB
node 3 cpus: 12 13 14 15
node 3 size: 65535 MB
node 3 free: 41075 MB
node 4 cpus: 16 17 18 19
node 4 size: 65535 MB
node 4 free: 41153 MB
node 5 cpus: 20 21 22 23
node 5 size: 65535 MB
node 5 free: 41604 MB
node 6 cpus: 24 25 26 27
node 6 size: 65535 MB
node 6 free: 39944 MB
node 7 cpus: 28 29 30 31
node 7 size: 65535 MB
node 7 free: 41523 MB
node distances:
node   0   1   2   3   4   5   6   7 
  0:  10  16  16  16  32  32  32  32 
  1:  16  10  16  16  32  32  32  32 
  2:  16  16  10  16  32  32  32  32 
  3:  16  16  16  10  32  32  32  32 
  4:  32  32  32  32  10  16  16  16 
  5:  32  32  32  32  16  10  16  16 
  6:  32  32  32  32  16  16  10  16 
  7:  32  32  32  32  16  16  16  10 

ベンチマーク1 : Bowtie2-2.3.1

全コア使用時の比較

bowtieのベンチマークとは書きましたが、
sraファイルを取ってきてfastqを生成し、bowtie 〜 samtoolsを実行してbamファイルを生成してインデックスをつけるところまでを
一連のスクリプトで実行した場合のそれぞれの実行時間(単位:秒)です。
マルチスレッドに対応しているコマンドは全コア使用して実行するようにしています。

Xeon 5118 (24thr) Xeon 6126 (24thr) EPYC 7351 (32thr) EPYC 7401 (48thr)
fastq-dump(1thr) 286.97 241.44 295.52 280.88
bowtie2-build(All threads) 1040.15 883.99 1380.66 1374.31
bowtie2(All threads) 1138.18 982.78 904.81 672.82
sam2bam(All threads) 274.47 236.21 309.12 173.46
sam index(1thr) 133.30 109.04 131.43 124.93
合計(秒) 2873.07 2453.46 3021.54 2626.40

合計時間ではXeonが若干優位ですが、これはbowtie2-buildの実行時間に大きな差が生じていることが原因です。
bowtie2に限ってみればコア数の多さも手伝ってEPYCが優位という結果となりました。

EPYC: bind有無による性能比較

上で書いたnumactlの件があったので、
numactlでcpu,memoryをbindした場合としない場合の比較をしてみました。
bindした方の実行コマンドは以下の通りです。

  • 4thread # numactl --cpubind=0 --membind=0 bowtie2 -p 4 -x hg19chr_build -1 SRR067579_1.fastq -2 SRR067579_2.fastq -S SRR067579.sam
  • 8thread # numactl --cpubind=0,1 --membind=0,1 bowtie2 -p 8 -x hg19chr_build -1 SRR067579_1.fastq -2 SRR067579_2.fastq -S SRR067579.sam
  • 16thread # numactl --cpubind=0,1,2,3 --membind=0,1,2,3 bowtie2 -p 16 -x hg19chr_build -1 SRR067579_1.fastq -2 SRR067579_2.fastq -S SRR067579.sam
EPYC 7351(no bind) EPYC 7351 (bind)
4 threads 6238.84 5471.70
8 threads 3368.63 2871.93
16 threads 1905.74 1488.22
32 threads 904.81

bindするしないでかなりの差が出ました。
(Xeonでも測定はしましたがbind/no bindいずれもほとんど変わらない結果でした。)

このあたりは、上記のメモリが遠いことも関係してそうですし
OS/kernel周りの最適化などでEPYC向けの最適化が進めばもう少しましになるのではないかと期待したいですが、
現状ではbindしないことによるペナルティが大きいです。

ベンチマーク2 : BWA-0.7.17

全コア使用時の比較

bwaもbowtie2同様、fastq-dump〜bwa〜samtoolsの処理を一連のスクリプトにして実行した各実行結果です。

Bowtie Xeon 5118 Xeon 6126 EPYC 7351 EPYC 7401
fastq-dump(1thr) 124.66 103.15 133.93 131.68
bwa index(1thr) 261.49 227.23 228.07 231.14
bwa mem(All threads) 413.93 360.47 468.24 314.18
sam2bam(All threads) 64.85 56.85 59.45 54.48
sam index(1thr) 52.69 43.85 51.05 48.46
合計(秒) 917.62 791.55 940.74 779.94

EPYC: bind有無による性能比較

こちらもbowtie2同様にEPYC 7351を使ってbind/no bindで測定しました。
bowtie2ほどでは無いにせよ、1割前後の性能差が出ています。

EPYC 7351(numa) EPYC 7351(no-numa)
4 threads 2251.20 2671.92
8 threads 1239.04 1368.78
16 threads 670.60 714.75
32 threads 468.24

ベンチマーク3 : Stream Benchmark

bioinfomaticsのアプリケーションでは無いのですが、
冒頭のnumactlの結果を見るとやはりメモリのアクセス速度のところの性能差がどのようになるのか
気になるのではないかと思いますので載せてみます。(単位:MB/s)

メモリの仕様に関してですが、
SkylakeはCPUあたり6チャネル、EPYCはCPUあたり8チャネルを持っています。
メモリ動作速度の最大はどちらも2666MHzです。

Skylake
numa Copy Scale Add Triad 説明
numactl –cpubind=0 –membind=0(16core/96G) 64409.9 64554.2 72856.2 72906.3 同一ソケット内でのメモリアクセス
numactl –cpubind=0 –membind=1(16core/96G) 33926.9 33933.1 34168.7 34161.8 遠い方のメモリへのアクセス
no numa(32core/192G) 129168.4 129021.6 145590.5 145569.8 BindせずDual Socketの全コア使用
EPYC
numa Copy Scale Add Triad 説明
numactl –cpubind=0 –membind=0(4core/64G) 23979.4 23771.1 26700.0 26728.0 同一ソケット内の同一node
numactl –cpubind=0,1 –membind=0,1(8core/128G) 47986.7 47878.3 52967.8 53028.5 同一ソケット内の2node使用時
numactl –cpubind=0,1,2,3 –membind=0,1,2,3(16core/256G) 95562.5 95557.8 105311.1 105500.6 同一ソケット内の全コア使用時
no numa(32core/512G) 135144.3 134846.0 141459.4 142717.5 BindせずDual Socketで全コア使用

Skylakeの場合、bindせずに全コア使用した場合のメモリ帯域が、同一ソケット内でのメモリ帯域の2倍になっていることから
明示的にbindしなくても自動的に近い方のメモリアクセスをするようになっているということが上記の結果からわかります。

反面、EPYCの場合、Single Socketの結果から、Dual Socketでは200GB/s近いメモリ帯域が出るのではいないかという期待が膨らむものの
実際にはSkylakeと同程度の帯域しか得られませんでした。このあたりはOS/Kernel周りの最適化で今後改善されるか期待を持ってみたいと思います。

Optane SSDとNVMe, RAMDiskの比較

Optane SSDとは

IntelとMicronが共同開発した3D Xpointという新しい不揮発性メモリの技術を使ったSSDです。
インターフェースはNVMeで、Form FactorもNVMeと同様、PCIe拡張カードタイプ(AIC)と2.5″タイプ(U.2)があります。

DRAMとNANDの間の性能ギャップを埋める製品。今回はConsumer用の900pというモデルを使いましたが、DataCenter用のP4800xというモデルはDRAMとOptane SSDで一つのメモリプール空間を構成することが可能です。
https://www.intel.co.jp/content/www/jp/ja/architecture-and-technology/intel-optane-technology.html

特にDRAMとOptane SSDで同一のメモリ空間を構成できるという点が面白そうです。現在のSkylake世代のXeonは、通常のSKUで768GB/CPU、High Memory SKUで1.5TB/CPUですが、これを使うことで下記の動画を見ると、DRAMとSSDで階層化のやりとりを行うようです。
https://www.intel.com/content/www/us/en/software/intel-memory-drive-technology.html

今回は、Optane SSD 900pを評価してみました。従来のNVMeとの性能比較だけでなく。
Memory Drive Technologyを見据えて、RAM Diskとの性能差についても比較してみました。


NVMe SSDとOptane SSDの比較

Sequetial Read/Write (IOR)

測定概要

結果

同時I/Oファイル数(-Nの後ろの数字)に関わらず、NVMeより大幅に高速
特にファイル数が少ないケースのReadの性能差は顕著です。

** Sequential Read **

-N1 -N2 -N4 -N8
Intel SSD DC P3520 NVMe(2TB) 398.19 MB/s 641.67 MB/s 1214.79 MB/s 1758.74 MB/s
Intel Optane SSD 900p(280GB) 2070.20 MB/s 2391.51 MB/s 2707.66 MB/s 2707.15 MB/s

** Sequential Write **

-N1 -N2 -N4 -N8
Intel SSD DC P3520 NVMe(2TB) 1495.49 MB/s 1519.79 MB/s 1536.00 MB/s 1501.45 MB/s
Intel Optane SSD 900p(280GB) 1513.91 MB/s 2193.01 MB/s 2233.80 MB/s 2248.58 MB/s

Random Read/Write

測定概要

  [global]
  bs=4k
  ioengine=libaio
  size=2g
  direct=1
  directory=/xxx
  numjobs=32
  group_reporting

  [Rand-Read-4K-QD32]
  iodepth=32
  rw=randread 

  [Rand-Write-4K-QD32]
  iodepth=32
  rw=randwrite
  • 測定対象デバイス
    • Intel DC P3520(2TB)
    • Intel Optane 900p(280GB)
    • ramdisk (DDR4-2666 16GB x12 の中から100GBを切り出し)

結果

RAM Disk >>> Optane > NVMe という結果となりました。
RAM DiskとOptaneは文字通り桁が違う性能差で、これだけの差が生じると同じメモリプールに入れてもアプリケーションに
影響が出るかもしれませんがどうなのでしょうか。
いずれ実アプリケーションでのベンチマークを行なってこちらでも紹介したいと思います。

** Ramdom Read **

IOPS BandWidth
Intel SSD DC P3520 NVMe(2TB) 382 k 1494 MiB/s
Intel Optane SSD 900p(280GB) 586 k 2290 MiB/s
RAM Disk 8224k 31.4 GiB/s

** Ramdom Write **

IOPS BandWidth
Intel SSD DC P3520 NVMe(2TB) 149 k 583 MiB/s
Intel Optane SSD 900p(280GB) 246 k 963 MiB/s
RAM Disk 8020 k 30.7 GiB/s

まとめ

  • Optane SSDはNVMeよりも30%〜高速(条件次第では5倍程度高速なケースも)
  • ただ、[ここ](https://www.intel.com/content/www/us/en/products/memory-storage/solid-state-drives/gaming-enthusiast-ssds/optane-900p-series/900p-480gb-aic-20nm.htmlNVMe SSD) にもあるようにNVMeとの価格差が大きい
  • 価格とも関連するが、ラインナップされているシリーズの容量がまだまだ小さい(P4800Xで750GB: 将来的なロードマップはわからないが)
  • DataCenter向けのP4800Xで使用可能と言われる、Intel Memory Drive Technologyは要注目

閉鎖系ネットワークで環境パッケージ管理ツールpipやcondaなどを利用する

便利なパッケージ管理ツール

昨今は研究系ITの環境はとてもよくなり、以前であればソースをダウンロードし、
./configure 、 makeして、make install、
といった複数手順を踏まなければならなかった解析ソフトウェアのインストールも、
pip install chianer
や、
conda install picard
といったコマンド一発でインストールできるようになりました。それも、ソフトウエアを複数のユーザーで共有する従来からのモデルはもちろんですが、各ユーザーがroot権限を必要とすることなく、自分のホームディレクトリ内で自分の環境をつくることができます。これらのツールは、インストールしたいソフトウェアが必要としている別のソフトウェアを判断し、すべてインターネットから自動的にインストールしてくれます。

環境によって突如旧石器時代へ

 ところが、取り扱うデータの機密性の事情もあり、インターネットから切り離さざるを得ない閉鎖系ネットワーク環境では事情が激変します。pipやcondaは機能しないため、ユーザーは依存しているソフトウェアの調査から、手動でパッケージをかき集め、順番を気にしながらインストールすることになります。
例えば、pip install chainer を実行した場合、chainerのほか、filelock numpy protobuf sixなどのパッケージが自動でインストールされますが、インターネットにつながらないため、そもそもどのパッケージが必要かの判断さえも実行されなくなるのです。

解決方法

 この問題を解決するのに良い方法はふたつ、ひとつはdockerコンテナ技術を利用し、解析ツールをコンテナ化することです。コンテナはあるソフトウェアが動作するために必要な最低限の環境をパッキングしてくれるため、インターネットに接続しているマシンで解析用のコンテナをつくり、それを閉鎖系ネットワーク環境にある計算機にもってきて利用します。

 もうひとつの方法として、pipのダウンロードもとであるpypi、condaのリポジトリ、centosやepelなどのリポジトリを丸ごと閉鎖系ネットワークで動かしてしまう方法があります。この方法はインターネットに接続しているマシンを利用する感覚に最も近く、その瞬間必要で欲しいパッケージをコマンド一発で入れられるようになるため、必ずしも環境構築の専門家とはいえないデータサイエンティストを閉鎖系ネットワークであることによる困難から解放します。

mirrored repository server

update用のサーバーはjenkinsによる定期ジョブ実行で自動的に各種リポジトリを最新にしてくれます。閉鎖系への適用は随時、任意のタイミングで行うことができます。

mirrored repository を利用してできること

mirrored repositoryのある環境では、例えば作りたての新しいユーザー環境に対して、chianermnを動作させるところまで環境構築をすることができます。

管理者として必要な環境の構築・アップデート

openmpiのセッティング、cudaのアップデート、centosやepelのリポジトリにある必要なパッケージのインストール

一般ユーザー環境にpyenvを導入、必要なPythonをインストール

複数バージョンのPythonを自分のホームディレクトリにインストールし、切り替えて利用できるpyenvを導入できます。

pipコマンドで必要なpythonパッケージをインストール

virtualenvもインターネットに接続されたマシンと同様に
pip install virtulenv
でインストールできます。
ほか、
pip install numpy
pip install scipy
pip install chainer
pip install chainercv
pip install chainermn
などももちろん可能です。

condaコマンドも利用可能

condaでないと利用できないパッケージもあります。
標準リポジトリのほか、例えばbiocondaなども構築可能です。
conda install bwa
conda install bowtie2
conda install picard

まとめ

今回はインターネットから隔離された環境で、インターネットに強く依存した便利なパッケージ管理ツールを利用する方法を紹介しました。特に試行錯誤の必要な研究フェーズにおいては役に立つのではないでしょうか。詳細をご希望の際は弊社営業かエンジニアへお問い合わせください。

NFS over RDMA : NFS(tcp)やLustreとの性能比較

RHEL7.4が8月にリリースされ、それまで長らくTech Preview扱いだったNFS over RDMAが正式サポートされることになりました。ということで今回、NFS(tcp)とNFS over RDMAとの性能比較をしてみました。また、NFSではないですが同じくRDMAを使っている共有ファイルシステムということでLustreについて比較したデータも紹介したいと思います。

RDMA (Remote Direct Memory Access)
言葉の通り、ネットワーク越しの別のマシンのメモリに直接アクセスできるというもので、この場合の直接というのは、CPUを介すること無くという意味です。主にInfiniBandで使われることが多く、複数ノードでMPI並列のジョブを実行するの性能に効果を発揮するものです。
参考URL : https://community.mellanox.com/docs/DOC-1963

性能比較(IOR) : NFS(tcp) vs NFS(rdma)

テスト環境

  • NFS領域: 20本のHDD(7.2Krpm)でHardware RAID6(18+2)
  • NFS領域のFilesystem: XFS
  • NFS Client: 1台
  • Network: QDR InfiniBand
  • 測定ツール: IOR-3.0.1(openmpi-3.0.0)

結果

下記のグラフの通りRead/WriteともにNFS(tcp)に比べてNFS(rdma)の方が性能が出ていることがわかります。特にReadに関しては50%ほどの性能差が出ています。

性能比較(dd) : NFS(tcp) vs NFS(rdma)

Read性能に差がかなりの差が出ているので念の為ddでも測定してみました。Writeは差がでないものの、Readは2倍の差が出ました。

  • Write性能 :
$ time dd if=/dev/zero of=25G bs=1M count=25000
NFS(tcp) : 27.977s(937MB/s)
NFS(RDMA) : 27.421s(956MB/s)
  • Read性能 :
$ time cat 25G > /dev/null
NFS(tcp) : 19.998s(1250MB/s)
NFS(RDMA) : 9.792s(2553 MB/s)

性能比較(IOR) : NFS(tcp) vs Lustre

続いてNFS(tcp)とLustre(rdma)の性能比較です。上記とは異なる環境で実施しています。
テスト環境は下記の通りで、実際に1台のサーバーでMDS/OSSを兼ねてLustreを構築することは実運用上はほとんどないかと思いますが、
あくまでテスト用の環境です。

テスト環境

  • NFS領域: 20本のHDD(7.2Krpm)でHardware RAID6(18+2)
  • NFS領域のFilesystem: ZFS
  • LustreのBackend Filesystem: ZFS
  • NFS/Lustre Client: 4台
  • Network: QDR InfiniBand
  • 測定ツール: IOR-3.0.1(openmpi-3.0.0)
  • Lustre version: 2.9.59_32

結果

4台のNFS/Lustre ClientからIORを実行した結果は以下の通りです。
NFS(rdma)との比較同様、同じHardware構成であってもSingle構成のLustreはNFS(tcp)に対してRead/Writeともの大きな性能差を発揮しています。

まとめ

  • IORでは、NFS(rdma0はNFS(tcp)に比べてWriteで10-20%、Readで40-50%程度高い性能をIO性能が得られる
  • 同じくRDMAで通信を行うLustreで測定した場合でも同様にNFS(tcp)に対して高い性能が得られる
  • 基本的にはNFSv3,v4どちらでも使えるが、NFS ServerのNFS領域がZFSで構成されている場合は、IORがエラーとなって実行できず(v3なら問題なし)
    • Server側
      kernel: svcrdma: send: invalid request error (9/0x8a)
    • Client側
      kernel: RPC: rpcrdma_recvcq_process_wc: rep ffff88203bd60540: local length error
      kernel: rpcrdma: connection to 192.168.255.1:20049 on mlx4_0, memreg ‘frwr’, 128 credits, 16 responders

実アプリケーションでの評価も行う必要がありますが、NFS over RDMAをお使いのTakeruで使いたいという場合には担当の営業かエンジニアまで
ご連絡いただければと思います。

Galaxy Reporting機能紹介

概要

Galaxyにはより詳細な情報を得られるレポート機能があります。標準では動作していませんが、本稿ではこのレポート機能について紹介します。

レポート機能について

本機能では、Galaxyの運用上で有用な様々な情報を得ることができます。
Jobs, Histories, Tools, Workflows, Users, Systemといったメニューがあり、Galaxy上のユーザーやジョブ、データ領域などについての情報を得られます。
管理者はこれらのデータをもとにユーザーやディスク容量の管理、ツールやワークフローの改善の計画などを行うことができます。

レポート機能へのアクセス

標準ではポート9001で動作します。
正しく設定し、起動できていると、
http://[IPアドレス]:9001
でアクセスできます。

jobsメニュー

Jobsでは、今現在動作しているジョブの情報、1ヶ月毎に実行されていたジョブ数の確認、エラーや完了できなかったジョブの情報、ユーザーあたり実行していたジョブの数、ツールあたり実行されていたジョブの数、などが確認できます。

[例:実行されていたジョブの月次報告]

[例:各ユーザーのジョブ実行状況確認]

Historiesメニュー

Historiesでは、各ユーザーの持っているHistoryやデータ量の情報が得られます。例えば管理者として、エラー状態のデータを多く持っているユーザーの把握が可能になりますので、積極的に利用者の支援を行うことも可能です。

[例:各ユーザーのHistory数やデータ数確認]

[例:History毎の状況確認]

Toolsメニューについて

Toolsではツールごとにエラーの多いものや利用状況などの情報を得られます。また、実行時間についても平均値や最大値などの情報が得られます。

[例:StateがOKであるツールの上位一覧]

[例:ツール毎の平均実行時間等の情報]

Workflowsメニューについて

Workflowsではworkflowの実行状況についての情報が得られます。

[例:ワークフロー毎の実行回数一覧]

Usersメニューについて

Usersでは、ユーザーがいつ登録されたか、最後にログインしたのはいつなのか、といった情報を得られます。また、ユーザーの持つHistoryの数や、ディスク容量の使用状況も得られます。

[例:ユーザー毎のディスク使用状況一覧]

[例:月次別ユーザー作成状況一覧]

Systemメニューについて

Systemでは、ディスクの使用状況について情報が得られます。
例えば4GB以上のデータを一覧し、データの所有者やどのHistoryで使われているかなどの情報も得られます。

[例:ディスクの使用状況および、サイズの大きいデータ一覧]

まとめ

Galaxyには標準では動作していないものも多いのですが様々な機能があります。
単にGalaxyのユーザーといっても、ダウンロードして試しに動作させている方から、本家Galaxyなどのように複数のセンターを拠点とした巨大なものまであるためのようです。

今回はレポート機能を紹介いたしました。
Galaxyを運用していると出てくる、ディスク容量の把握や予測、効率良く実行できているかの確認、ユーザーの管理などに有用な情報が得られるようになります。

ユーザーや利用状況の情報が多く得られるものですので、実装の際はセキュリティに配慮する必要があります。
本機能に興味がございましたら担当営業やエンジニアに直接お問い合わせください。