«前の日(05-18) 最新 次の日(05-20)» 追記

meta's blog - The Power To Serve

筆者について

FreeBSDを通じてOSSにささかな貢献を。HTTPS化したいとは思っているんです…

OSS活動をご支援いただける方を募集しています


2014-05-19 L2ARC

今さらながら ZFS 環境に SSD を足して L2ARC を使ってみる

特に技術的に目新しいものではないです。5年遅い。メモリを限界まで増設していてこれ以上足せないというケースでもなければ、この記事の最後の Togetter まとめを読んでメモリを足したほうがいいです。

普段使いで使用している ZFS な FreeBSD 環境も年季が入ってきて、遅くはないものの速くもなく、IO がボトルネックになっているのを感じるので SSD を足して L2ARC として使用してみました。

特に /usr/ports が比較的大きな git リポジトリ になっていて、そこに git pull したり tig でリポジトリをオープンするとディスクアクセスでかなり待たされる状態になっていました。

本来なら ZFS パフォーマンスにいちばん効くのはメインメモリの増設ですが、既に限界の 8GiB まで増設していてこれ以上の強化となるとプラットフォームごと刷新しなければならないので、とりあえず SSD を足して L2ARC として使用します。メモリが 8GiB しかないため、ARC サイズは 1GB に制限して運用していました。

L2ARC 以外にも ZIL を SSD に乗せると同期書き込みが速くなるのですが、SSD の寿命が尽きた場合にデータの不整合や破損が発生するのは避けたいため、今回は見送り。個人用途なので、SSD の寿命が尽きたときに停止してしまうのは許容します。

元の環境はこんな感じ。

CPU
Intel(R) Core(TM)2 CPU 6700 @ 2.66GHz (2664.05-MHz K8-class CPU)
メインメモリ
8GiB (MAX)
チップセット
Intel G965
OS
FreeBSD 10-STABLE r266177
HDD
Seagate Barracuda 7200.14 ST2000DM001

SSD は TS64GSSD340 を購入しました。キャッシュ用途と割りきっての導入なので小さめですが、もっと大きなものにしてもよかったかも。

増設した SSD は /dev/ada1 として認識されているので以下のようにして L2ARC を追加します。

# gpart create /dev/ada1
# gpart add -a 4k -s 20G -t freebsd-zfs -l l2arc0 ada1
# gpart add -a 4k -s 20G -t freebsd-swap ada1
# zpool add zroot cache gpt/l2arc0

作業後のハードディスクと SSD のパーティション構成は下記の通り。

$ gpart show
=>        34  3907029101  ada0  GPT  (1.8T)
          34           6        - free -  (3.0K)
          40         128     1  freebsd-boot  (64K)
         168    16777216     2  freebsd-swap  (8.0G)
    16777384  3890251744     3  freebsd-zfs  (1.8T)
  3907029128           7        - free -  (3.5K)

=>       34  125045357  ada1  GPT  (60G)
         34          6        - free -  (3.0K)
         40   41943040     1  freebsd-zfs  (20G)
   41943080   16777216     2  freebsd-swap  (8.0G)
   58720296   66325095        - free -  (32G)

SSD は完全にキャッシュ用途として割り切っているので、ついでにスワップも SSD に載せてしまいます。

# swapon /dev/ada1p2
# swapoff /dev/ada0p2
% swapinfo
Device          1K-blocks     Used    Avail Capacity
/dev/ada1p2       8388608        0  8388608     0%

スワップデバイスを変更したので /etc/fstab も書き換えます。

#/dev/ada0p2    none    swap            sw      0       0
/dev/ada1p2     none    swap            sw      0       0

再起動して ARC/L2ARC をクリアしてから、しばらく普通に使ってみて zfs-stats で L2ARC の様子を見てみると、

------------------------------------------------------------------------
ZFS Subsystem Report                           Tue May 20 00:52:15 2014
------------------------------------------------------------------------

L2 ARC Summary: (HEALTHY)
       Passed Headroom:                        27.89k
       Tried Lock Failures:                    18.59k
       IO In Progress:                         20.44k
       Low Memory Aborts:                      0
       Free on Write:                          1.05k
       Writes While Full:                      85
       R/W Clashes:                            22
       Bad Checksums:                          0
       IO Errors:                              0
       SPA Mismatch:                           0

L2 ARC Size: (Adaptive)                        5.19    GiB
       Header Size:                    0.85%   45.29   MiB

L2 ARC Breakdown:                              1.00m
       Hit Ratio:                      47.21%  473.82k
       Miss Ratio:                     52.79%  529.77k
       Feeds:                                  12.80k

L2 ARC Buffer:
       Bytes Scanned:                          6.51    TiB
       Buffer Iterations:                      12.80k
       List Iterations:                        818.65k
       NULL List Iterations:                   133.00k

L2 ARC Writes:
       Writes Sent: (FAULTED)                  6.59k
         Done Ratio:                   99.98%  6.59k
         Error Ratio:                  0.00%   0

------------------------------------------------------------------------

うん、効いてる気がする。キャッシュヒット率も 47% くらいらしい。キャッシュに乗っている間は

$ cd /usr/ports; tig

で tig を起動するのも少し速くなりました。めんどくさいので前後で比較もしません。いい加減に L2ARC を追加してみたけどとりあえずコレでOK!

参考

L2ARC については ftp.jaist.ac.jp の中の藤枝さんの記事が詳しい。

あとこれ。メモリを足せるならメモリを足したほうが速いです。今回は古い環境のために試しに SSD L2ARC を追加してみました。あまり本気でカリカリにチューニングする気もないので、5000円の費用でどう改善できるかなとやってみた結果です。


2020-05-19 ruby-buildのバージョンリスト表示を整理した

ruby-buildのバージョンリスト表示を整理した

すでにお気づきの方もいるかもしれませんが、昨日リリースされた ruby-build v20200518 では rbenv version -l で表示されるインストール可能なRubyバージョンのリストが大きく整理しされ、短くなりました。

これは私が2020年に入って取り組んでいたもので、多くの人にとって使い勝手の向上となる変更であると信じています。ここでは、当該機能を実装したプルリクエスト rbenv/ruby-build#1402 で改善した内容を解説します。

改善したこと: rbenv install -l の出力を整理した

ruby-build v20200518 以降では、rbenv install -l で出力されるバージョンのリストが以下のように大変スッキリした短いものになりました。以下のようなルールで、現在サポートされている系列の最新バージョンが表示されます。

  • MRIはセキュリティメンテナンス期間を含むサポート中の各マイナーリリースの最新を表示
  • それ以外のRuby実装は最新バージョンのみ表示
$ rbenv install -l
2.5.8
2.6.6
2.7.1
jruby-9.2.11.1
maglev-1.0.0
mruby-2.1.0
rbx-4.15
truffleruby-20.0.0

Only latest stable releases for each Ruby implementation are shown.
Use 'rbenv install --list-all' to show all local versions.

最後の3行は標準エラー出力へ出力されているので、実質的なリスト部分は8行です。

上記のリストに表示されていないバージョンも、非表示になっているだけでインストールは可能です。

$ rbenv install 2.7.0

背景: rbenv install -l 長すぎ問題

本機能を実装するに至った背景を解説します。

従来のruby-buildでは、ruby-buildを使ってインストールできるすべてのバージョンのRubyを表示していました。

$ rbenv install -l | head -n 5 
1.8.5-p52
1.8.5-p113
1.8.5-p114
1.8.5-p115
1.8.5-p231
(中略)
truffleruby-19.2.0.1
truffleruby-19.3.0
truffleruby-19.3.0.2
truffleruby-19.3.1
truffleruby-20.0.0

過去のすべてのバージョンが含まれるリストは大変長くなっていて、2020年5月19日現在で489行にもなります。

$ rbenv install -l | wc -l
     489

このため、多くの人はruby-buildでインストールできるRubyのリストを、lessに渡すか、ターミナルをスクロールバックする等して、500行弱のリストからインストールしたい目的のバージョンを探していたのではないでしょうか。

あるいは、リストを見ずに rbenv install 2.7.1 などと実行して、該当するバージョンがなければruby-buildのアップデートをするという方もいるかもしれません。

rbenv install -l で表示されているリストが過去のすべてのバージョンを含んでいることにより、以下のような問題がありました。

  • 多くの人は最新あるいは少し前のバージョンのRubyしかインストールしない
  • ほとんどの人によって必要とされていないバージョンがリストの大部分を占めている
  • 必要なバージョンを見るためにスクロールが必要で煩わしい
  • バージョンのリストは将来にわたって際限なく増え続ける

ruby-buildでインストールできるRubyのバージョンが、50や100だった頃はすべてのバージョンを表示していてもよかったのですが、500近くになっている現在では整理が必要ではないかという提案を行いました。

互換性への配慮

ruby-buildをバージョンアップして突然 rbenv install -l の出力が短くなっているとびっくりするでしょうから、サポート中のリリースのみを表示している旨のメッセージを表示するようにしました。また、メッセージはリストを machine readable に保つため標準エラー出力へ出力しリスト自体と混ざらないようにしています。


Only latest stable releases for each Ruby implementation are shown.
Use 'rbenv install --list-all' to show all local versions.

過去のバージョンを含んだすべてのバージョンを表示したい場合は rbenv install --list-all というオプションで実行します。大文字の -L というオプションはエイリアスです。

$ rbenv install --list-all / -L

1.8.5-p52
1.8.5-p113
1.8.5-p114
1.8.5-p115
1.8.5-p231
(中略)

ruby-build コマンドはrbenv installよりスクリプトの中でとして実行されることが多いため、こちらの動作は変更せず --list オプションを追加してサポート中のバージョンのみを表示するようにしました。

まとめ

ruby-build v20200518 では、以下のようにコマンドの仕様が変更されています。毎回 less を挟んだりスクロールするという手間がなくなり、多くの人の「ひと手間」を削減する改善となっているはずです。

コマンド オプション バージョンリスト 仕様変更 新規追加
rbenv install -l / --list サポート中のみ
rbenv install -L / --list-all すべて
ruby-build --definitions すべて
ruby-build -l / --list サポート中のみ

現状MRI以外のRuby実装はマイナーリリースを考慮せず、最新バージョンのみを表示するという実装となっていますが、これは「とりあえずこれでいいだろう」とコミュティティで合意したものです。しかし、強い理由があって決まったものではないので、マイナーリリースまで表示してほしいという要望があれば更に改善の余地はあります。