ZFSのdedup地獄から命からがら逃げ延びた話
はじめに
これはついうっかり大きなデータを書き込むようなZFSファイルシステムにおいてdedup=on
してしまった挙げ句,気付かないでガンガン運用してすでに数TB書き込んでしまったという全国のドジっ子メイドさんが一人でも救われれば良いなと思って書いています.ちなみに最初に言っておくと今回も前回と同様*1救いはないです.
環境
サーバー構成
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04.2 LTS" $ sudo zfs upgrade This system is currently running ZFS filesystem version 5. All filesystems are formatted with the current version. $ modinfo zfs filename: /lib/modules/4.4.0-70-generic/kernel/zfs/zfs/zfs.ko version: 0.6.5.6-0ubuntu15 license: CDDL author: OpenZFS on Linux description: ZFS srcversion: D82FFDF4C1394A435E2B38A depends: spl,znvpair,zunicode,zcommon,zavl vermagic: 4.4.0-70-generic SMP mod_unload modversions ... $ cat /etc/modprobe.d/zfs.conf options zfs zfs_arc_max=10737418240
zpoolの構成は以下
$ sudo zpool status pool: data state: ONLINE scan: resilvered 33.8M in 0h0m with 0 errors on Tue Jun 27 21:38:30 2017 config: NAME STATE READ WRITE CKSUM data ONLINE 0 0 0 raidz1-0 ONLINE 0 0 0 ata-WDC_WD30EFRX-68EUZN0_WD-WCC4N0YZ2854 ONLINE 0 0 0 usb-I-O_DATA_HDCL-UT_000277B591400351-0:0 ONLINE 0 0 0 ata-WDC_WD30EFRX-68AX9N0_WD-WMC1T0534235 ONLINE 0 0 0 errors: No known data errors
ここから以下の様に領域を切っています.(救われた後の様子です)
$ sudo zfs list NAME USED AVAIL REFER MOUNTPOINT data 1.66T 3.61T 139K /data data/tank 1.48T 3.61T 1.48T /data/Nas data/timemachine 167G 133G 167G /data/timemachine
dedup=on
に気付くまで
実はサーバを構築した当初からdedup
というオプションは絶対onにしないようにしようと堅く心に誓っていました.少なくともそう思って構築して運用してきていたので,どうもファイル操作をするとサーバが不安定になるがこれはなぜだろう,メモリが足りない?でも1GBとかでも動かしている人はいるしなぁ…とずっと不思議に思っていました.
うちのサーバはprometheusでリソースの監視をしている*2のですが,数十GB単位のファイル削除を行ったり,ファイルを連続して数十GB書き込んでいくとloadの値がぐっと上がり,node-exporterのnode_cpu
メトリクスを見るとiowait
の値が急激に上がり,メモリを食い潰し,大量のスワップが発生することが分かったのもつい最近のことです.監視始めて良かった.
救われる前のZFSの領域はdata/Nas
として領域を切って以下の用途で運用していました.
だいたい3TBぶんほど消費していました.
実はこの運用の仕方をし始めてからずっと以下の症状に悩まされていました.
- Windowsからの書き込み時に十数GBを超えた当たりから一気に速度が落ち,エラーが出て書き込みに失敗する
- 大量に書き込んだ後極端にsambaの共有領域が重くなり,開けない,検索が出来ない,などが頻発する
- 数十GB単位で削除すると同様にファイルが開けない,検索ができない,などが頻発する.
実際の所そんなに激しいデータの読み書きをすることは少なく,これまでもなんとなくで運用は出来ていました.が,残り領域が2TBを切ったあたりからどうもパフォーマンスが悪くなったような気がしてならず,重い腰を上げて調べ始めたのがこの春のことでした.
ARCに制限を加える
まず最初にわかったのはメモリがあまりにも大量に使用されることです.何の設定もしない状態ではARCキャッシュとして
搭載メモリーが 4G バイト未満のシステムでは、メモリーの 75%
搭載メモリーが 4G バイトを超えるシステムでは、physmem から 1G バイトを引いた値
が使用されることになっているようです*3.
うちのサーバではprometheus以外にもMinecraftサーバやGitlabサーバなどそれなりにメモリを消費するアプリケーションが複数あり,メモリが逼迫されることでレスポンスが異常に悪くなっていました.
とりあえず重くなっても動作はしてくれるようにZFSのARCサイズに制限を加えることとしました.これは/etc/modprobe.d
以下に適切に配置することによって可能です.
$ sudo bash - c 'echo "options zfs zfs_arc_max=10737418240" > /etc/modprobe.d/zfs.conf' $ sudo reboot
これでとりあえず10GBまでしかARCとして消費されなくなりました.
が,結果的に消費メモリが減ったおかげで書き込みや削除はより頻繁にフリーズするようになりました.
ZFS以外の領域に書き込んでみる
システムドライブに書き込んでみたところ全く問題なし.SSDなので速いだけかなぁ,やっぱりHDDは遅いしダメだな,とか思っていました.
sambaの設定を見直す
とくに悪さをしていそうな所は無し.実は一番最初はここを疑っていましたが,macからscp
コマンドなどを使って書き込んでも再現したので疑うのを辞めました.
ZFSのパラメータを疑う
このあたりからだんだんと「あれ…?もしかしてdedup=onになってたりする?そんな馬鹿な」という疑惑が持ち上がってきていました.
$ sudo zfs get dedup data NAME PROPERTY VALUE SOURCE data dedup off default
ほら大丈夫じゃん!とここで放置してしまったのが運の尽きでした.当初このオプションは全体に適用されると思っていたため,ここを調べれば分かるだろうと思っていました.
しばらく悩んだある日,なんとなくでdata/Nas
のオプションを調べたところビンゴでした.
$ sudo zfs get dedup data/Nas NAME PROPERTY VALUE SOURCE data dedup on default
dedup=offに出来ないか
絶対先人がいるだろうと思ってググったらやっぱりおられました.
ZFSを運用する者が知っておくべきこと(障害対策) – 日曜研究室
FreeBSD:zfsが調子悪いです(´Д`;) | 猫鯖の部屋
とりあえず
ということが分かりました.
頑張る
前回も新しいプールを作成してashift値を変更するとかそういう強引なことをしましたが,今回も強引に行きます.
- dedup=offな領域
data/tank
を切る(/data/tank
にマウント) - サーバ上にしかないなくなると困るデータを
/data/tank
にrsync
でコピー data/Nas
のマウントポイントを/data/Nas_old
に,data/tank
のマウントポイントを/data/Nas
に変更- どうにかして
data/Nas
を消す
1. 新しい領域の作成
$ sudo zfs create data/tank # 念のため $ sudo zfs set dedup=off data/tank $ df -h | grep data/tank data/tank 1.9T 0 1.9T 0% /data/tank
2. データのコピー
バカみたいに時間がかかるのでscreen
を使いましょう.また,普段使いに極力影響しないように帯域制限をかけて負荷を抑えています.
容量に余裕がない場合,データの取捨選択をするか,少しずつデータをコピーし,その都度dedup=on
な領域から少しずつ削除すると良いと思います.
$ screen -S rsync $ rsync -ahvP -bwlimit=2048 \ --exclude="hoge" \ --exclude="fuga" \ --exclude="piyo" \ /data/Nas/* /data/tank
3. マウントポイントの変更
この操作の前にこれらの領域を使用するアプリケーションを全て止めましょう.
# アンマウントする $ sudo zfs umount data/Nas $ sudo zfs umount data/tank # マウントポイント変更 $ sudo zfs set mountpoint=/data/Nas_old data/Nas $ sudo zfs set mountpoint=/data/Nas data/tank # 再びマウント $ sudo zfs mount -a
4. dedup=onな領域を削除
ここで「意外とdestroyでいけるんじゃないか?」と思い,実行.
$ screen -S del
$ sudo zfs destroy data/Nas
最初は順調にいっているように思いましたが,途中からサーバが完全に応答しなくなり,強制的に落とすとディスクを一枚ちゃんと認識しなくなって焦り,ひどい目にあいましたので皆さん絶対に辞めておきましょう.
書き込み済みのデータが多すぎることが問題なので少しずつ消していくスクリプトを書きます.
$ vim delete.sh #! /bin/bash TOTAL_SIZE=0 TARGET_DIR=/data/Nas_old LIMIT=2048 INTERVAL=120 find $TARGET_DIR -type f | while read FILE do SIZE=`wc -c "$FILE" | awk '{print $1}'` TOTAL_SIZE=`expr $TOTAL_SIZE + $SIZE` echo "Found $FILE" echo -e "\tFile size: $SIZE" echo -e "\tTOTAL: $TOTAL_SIZE" echo -e -n "\tTry to delete $FILE ... " ionice -c 3 rm -f "$FILE" >& /dev/null 2>&1 if [ $? -eq 0 ]; then echo "[SUCCESS]" else echo "[FAIL]" fi S=`expr $TOTAL_SIZE / 1048576` if [ $S -ge $LIMIT ]; then echo "TOTAL_SIZE is over than $LIMIT MB. Sleep $INTERVAL sec." sleep $INTERVAL TOTAL_SIZE=0 fi done
何も考えず10分ほどで書いたので保証はしません…
一応各ファイルのサイズを見て,2GB以上削除するごとに120秒スリープするようにしています.1ファイル当たりの容量が数十GBになっても120秒しかスリープしないので,大きなファイルがある場合もっと賢い処理をした方が良いかも知れません.
$ screen -r del
$ sudo ./delete.sh
何日かかかりましたがこれで全て削除出来ました.
最後にdestroyすれば完了です.
$ sudo zfs destroy data/Nas
ちゃんと完了しました.
まとめ
メモリ24GB程度でdedup=on
にすることはもはや災害に等しいので皆さん絶対に辞めましょう.
脚注
ライフサイエンス辞書で単語を引くAlfred Workflowを作った
きっかけ
生物学を学んでいる身としては論文を読んでるときとかにパパッとライフサイエンス辞書を引けたら嬉しいなと思ったのと,ただ単に検索結果のURLをブラウザで開くだけなら最初からブラウザ使えば良いよねと思ったので,自作してみることにしました.
Go言語を使ったわけ
ライフサイエンス辞書は通常開くウインドウとは別に,こういった検索方法も存在します.最初はこれをただURL開くだけで良いかとも思ったのですが味気なく,しかしJSONやXMLなどのAPIでもないためこれを再利用するにはスクレイピングが必須です.
AlfredのWorkflowでは様々なスクリプトを実行できますし,そのままターミナルを叩けるのですが,スクリプト言語の利用できるライブラリはその環境に依存してしまいます.スクレイピングをするのに外部ライブラリ無しという縛りはあまりにも鬼畜であるので,どうにかしてライブラリを使いつつ,環境依存を減らしたいなと考えたときにGoを思い出しました.
バイナリ一発で動くというのが魅力で,今回の用途に適しているのではないかと考えやったことも無いのにとりあえず書いてみることにしました.
環境
- Alfred v3.3.1
- Go 1.8.1
- Glide 0.12.3
今回はGoのパッケージ管理にGlideを使用しました.なお,このWorkflowを動作させるだけであればGoもGlideも必要ありません.自分でビルドする場合のみ導入してください.
lsd-alfred
リポジトリは以下になります.
できること
ライフサイエンス辞書から単語を引くことが出来ます.英語,日本語どちらでも検索可能です.
検索方法は以下の4通りあります.
- 前方一致:
lsd begin "{query}"
- 後方一致:
lsd end "{query}"
- 部分一致:
lsd in "{query}"
- 完全一致:
lsd eq "{query}"
検索してブラウザで開く
検索した後Shift
+ Enter
でデフォルトブラウザを使用して開きます.
検索してクリップボードにコピー
検索した後Command
+ Enter
でクリップボードにコピーします.
また,最前面の入力ウインドウに対して自動的に入力を行います.この設定はWorkflow中のCopy to Clipboard
中のオプションを変更することで無効にもできます.
検索結果から再検索
検索した後Fn
+ Enter
で再検索をかけます(意味があるのかは分からない…)
検索結果をさらに検索エンジンにかける
検索した後Ctrl
+ Enter
でググります.
検索結果をSpotlight検索にかける
検索した後Alt
+ Enter
でSpotlight検索にかけることができます.(GIF略)
検索結果の一覧ページを開く
See all results
の項目でShift
+ Enter
すると一覧が開きます.(GIF略)
ホットキーを使用して選択文字列を検索
初期では使用できません.使いたい場合,Alfred Workflowの設定を開いてlsd-alfredのHotKeyの項目に好きなキーを割り当ててください.デフォルトでは部分一致検索を行います.
できないこと
まだシソーラスとコーパス検索には対応していません.が,原理的には同様にスクレイピングをするだけで実現可能であるため,実装すれば実現は容易です.
まとめ
作ろうと思い至ってからGoに入門して完成までだいたい2日でここまできたので個人的には満足です.が,まだまだ常用ツールとしては未熟な作りでひどいコードなので少しずつリファクタリングしていきたい…たぶんバグたくさんあるのでPR待ってます(他力本願)
一応.alfredworkflow
なパッケージは以下からダウンロードできます.使用は自己責任で…
Releases · pddg/go-lsd-alfred · GitHub
Alfred Workflowの作り方
ネットを検索していると何か色々とWorkflowの作り方が出てきますが大抵古いです.現在は標準でAlfred 3がエクスポートの機能を持っており,外部ツールを用いる必要はありません.
Alfred無しで(CI等で).alfredworkflow
なパッケージを作るにはどうもzip圧縮して拡張子を変更してやれば良いだけ?っぽいです.
以下簡単に手順です.
- Blank Workflowを作成し,詳細情報を入力
- 作成したWorkflowを二本指タップすると
Open in Finder…
が出てくるのでそれを押す - 開いた場所に実行するスクリプトや必要な設定ファイル等を置く
- 編集する
- Exportする
以上です.
Workflowとスクリプトの連携について
phpなどを使う場合,あらかじめ用意されたworkflow.php
などを利用する方法が出てきますが,今回のように自作バイナリを叩く場合の記述に関しては全然見当たらなかったので本家の英語ドキュメントを軽く読んでやりました.今でも合っている自信が無いです.
Alfred 3からはXMLだけでなくJSONも使用できます.一応XMLは後方互換のために残しているだけのような感じなので,JSONを使用していこうと思います.Workflowで使用するのはScript Filter
です.
{"items": [ { "uid": "ID", "type": "file|default|skipcheck", "title": "title", "subtitle": "subtitle", "arg": "url", "autocomplete": "title", "valid": true "icon": { "type": "fileicon", "path": "path" }, "mods": { "alt": { "valid": true, "arg": "url", "subtitle": "subtitle" } }, "text": { "copy": "Text to copy", "largetype": "Large Text" }, "quicklookurl": "url" } ]}
uid
: ユニークキー.ここの値を元にソートされるっぽい.type
: このオブジェクトがファイルなのか,それ以外なのかを示す.file
を指定すると存在するかのチェックが入るので嫌な場合はskipcheck
にせよと書いてある.arg
: 表示されたオブジェクトを選択してEnterを押したとき,次に渡される値.URLなど.icon
:type
もpath
も空欄にしておくとパッケージに含めたicon.png
が勝手に使用される.valid
: Enter押したときに次のアクションを行うかどうかmods
: 修飾キーと組み合わせたとき,次に渡す値を変化させることが出来る.例えばalt
+Enter
のときはタイトルを出力するが,Cmd
+Enter
のときはURLを出力すると言った挙動に出来る.使える修飾キーはCmd
,Alt
,Ctrl
,Shift
,Fn
text
:copy
の値はコピーしたときクリップボードにコピーされる値.largetype
はCmd
+L
を押したときに表示されるLargeTypeに表示するテキスト.
最終的に上記の形式(全てを含めなくても良い)のJSONを標準出力にPrintするだけで簡単に使えます.最高.
まとめ
Goは言語自体はシンプルなのですが,どうにもエラー処理やスライスの周りで頭が混乱してしまいます.もう少し使えるようになればかなり便利そう…
Alfred 3,Workflowでできることがとても多くて重宝しています.課金して良かった.
続・授業ノートをMarkdownでとって管理する
以前こういう記事を書きましたが,以降いくつか新しいエディタを発掘したのでメモを残しておきます. 今回は事情によりMacのスクリーンショットのみですが,全てマルチプラットフォーム対応です.
wri.pe
StackEditと同様のオンラインエディタです.
良いところ
やはりオンラインエディタの良いところは,手元にブラウザとインターネット環境があれば使用可能なところでしょう.iPhoneやiPad,Androidでも使用が可能です.
このエディタはEvernote及びDropboxに接続してノートを管理することが出来ます.ただしDropboxについては即時反映ではなく,"Daily Backup"な模様です.(以下,wri.peより)
Daily automatic backup to Dropbox. It stores up until 14 generations of changes. Your files are private and can’t be accessed by our service.
面白いのはカレンダーが内包されており,そのノートを作成した日などがカレンダーに記録されていくようです.そこからノートの編集画面へと飛んだりも出来ます.
微妙なところ
数式やフローチャートなど,拡張機能には一切対応していません.コードブロックの記述は出来ますがシンタックスハイライト等はできないようです.
また,pdfなどへの出力機能はなく,保存形式としてはDropboxまたはEvernoteの二択となり,正直劣化版StackEditな気はしないでもないです.一応ノートのExportの項目もありますが,全ノートがテキストファイルとしてzipで固められているだけのものになります.
また,使用に際してはFacebookまたはGithubのアカウントが必要になります.
ノートの管理方法
Evernoteとの同期が最も適しているとは思いますが,タグの付与がエディタ上から出来ない*1ため,使い勝手は微妙と言えます.Dropboxへの同期もテキストファイルとなり,.md
ですらないので微妙…
総評
うーん,正直StackEditの拡張性に比べるとしょぼいというかなんというか…他の選択肢を選ぼうかなという気になります.
QOwnNotes
ownCloudとの連携が強いエディタです.
良いところ
とにかくownCloudとの親和性が高いです.自前のownCloudサーバがあれば,版管理からToDo管理,バックアップまで全てをこなしてくれます.
GUIが充実しており,Wordなどのように太字,斜体などをGUIから設定できます.また,PhotoshopなどのようなパネルスタイルのGUIが実装されており,カスタマイズが豊富です.例えば,Markdwonのプレビュー画面だけ独立させたり,編集画面とプレビュー画面を横並びにすることもも縦並びにすることもできます.多くのMarkdownエディタはシンプルなUIを実装していることから,それらの画面に納得できなかった人には良い選択肢でしょう.
ノートの保存先はownCloudのディレクトリ以外に,ローカルに指定したディレクトリも設定できます(複数設定・切り替え可).
微妙なところ
ownCloudサーバが無ければちょっとGUIが豊富なだけの普通のエディタです.補完はそこそこ気持ちよく効きますが,コードブロックのシンタックスハイライトは非対応,数式非対応,シーケンス図やフローチャート非対応など拡張性は微妙です.
ノートの管理方法
ownCloudで管理するのが最も適しています.ただし,そうでない場合でもディレクトリを複数選択して保存先として設定できることから,gitで管理も可能でしょう.
総評
UIがリッチなのはリッチなのですが,個人的にはたかがメモ,ノートにそれほど複雑なUIを求めていないのでちょっと装飾過多かなぁと感じました.
Simplenote
WordPress.comを運営するAutomattic社が作ったシンプルなエディタです.
良いところ
モダンでシンプルなUIになっており,使い方がわかりやすいです.また,app.simplenote.comに全て同期されており,サインインすることで全てのノートブックにアクセスできます.
以下の画像のように履歴が保存されており,いつでも任意の地点に戻ることが出来るのも良いところだと思います.
Webへのパブリッシュがかなりお手軽なのも良いところです.Make public linkをオンにするだけで閲覧可能なURLが発行されます.
微妙なところ
サインアップ必須です.メールアドレスがあればアプリからアカウントを作成できるので簡単ではあります.
エクスポートが全ノート一括でのzip出力しかありません.クラウドで保存されているとはいえ,何らかの外部出力はやはり欲しいものです.ローカルでの保存先も不明なので,simplenote.com次第ということになります.
また,Macのβ版クライアントではコードブロック及びシンタックスハイライトに対応していましたが,Web編集画面ではコードブロックに対応していません.
publlish画面ではコードブロックには対応していますが,シンタックスハイライトには対応していません.なぜWeb版とクライアント版で対応の可否が変わっているのか不思議です…
また全体を通して数式,フローチャート等の拡張機能には非対応です.つらい.
ノートの管理方法
simplenote.comでの同期一択となります.Evernoteのようにタグでの管理が可能なので,これ単体での運用は難しくないかと思います.publish以外の共有方法としてCollaboratorの追加が可能で,simplenote.comにサインアップしたユーザ同士で編集が可能になっています.
総評
Macのクライアントは非常に快適ですが,Webでのプレビューと必ずしも一致しないことがかなり不満です.特にシンタックスハイライトはまだしもコードブロック非対応がかなり苦痛で,#
でのコメントアウトが全て<h1>
タグとして認識されてしまいます.
当然Webベースであり現在も開発が進んでいるようなので,今後改善される可能性は高そうです.Macのメモアプリの上位互換と考えればかなり有用であると思うので,マルチプラットフォームかつ特殊な記法が不要,メモをタグで管理したいというユーザには良いのではないでしょうか.
Typora
真 打 ち 登 場
Typora — a minimal markdown reading & writing app
良いところ
- マルチプラットフォーム
- 数式,フローチャート,シーケンス図,上付き文字下付き文字対応
- ワードカウント,アウトラインの表示
- タイプライターモード(文字入力地点が常に画面中央に来る)搭載
- 複数のカラーテーマ
- 無料
エディタの画面がスッキリしていて不要な情報が排除されているため,書くことに専念できます.カスタマイズが豊富で,先ほど上げた各種機能はデフォルトではオフになっています.
プレビュー画面では,対象の行にフォーカスするとプレビュー画面でも元のMarkdown構文が表示され,編集が可能になっています.これはシーケンス図やコードブロックでも同様で,プレビュー画面でもしっかりと編集できます.
残念ながらクラウドとの同期機能などは全く備わっていません.が,独自のデータベースを構築したりもしないため,gitやDropboxなどとの連携は容易でしょう.
さらにExport機能も豊富です.
微妙なところ
やはりクラウドとの連携がデフォルトでついていない所でしょうか.バックアップや同期の手段は自分で用意する必要があります.Gitを使う場合は別でソフトウェアを使うなり,コマンドを叩くなりする必要があります.そういう意味では玄人向けです.
また,それに絡んでノートにタグを付けたりすることが出来ません.そういう意味でこれは「ノートやメモを取るソフトウェア」ではなく,「Markdown特化エディタ」です.
ノートの管理方法
色々考えられますが,結局のところこれはエディタです.後からの検索性という意味では他のタグをつけることのできるソフトウェアと比較してかなり劣ります.
プロジェクトのドキュメントを書く,すぐPDFにする,クラウドに頼りたくないなどの場面で活躍できるのではないでしょうか.
総評
高機能かつ使いやすい,そして無料とあって非常に魅力的です.個人的にはタイプライターモードが気に入りました.常に視線は中央に置いておいてどんどん書き進められるのが快適で気持ちよかったです.
まとめ
- 金を払いたくない・高機能が良い・管理は自分でやる
→ Typora - 金を払いたくない・機能はそれほど求めない・ファイル管理を気にしたくない
→ Simplenote - Evernoteを使っている・高機能が良い・検索性を良くしたい
→ Marxico - オフラインで使うことはない・高機能が良い
→ StackEdit
Marxicoはローカルに保存したファイルを開いてエディタとして使うには不向きなソフトウェアです.僕はTyporaとMarxicoを使い分けて使っています.
Typoraは前回コメントで教えていただき非常に気に入ってしまいました.今後もコメント等でこんなのもあるとか,あんなのもあるとか,教えていただければ幸いです.
*1:もしかしたら僕が項目を見つけ切れていないだけかも…