ソースの表示以前のリビジョンバックリンク全て展開する/折り畳む文書の先頭へ Share via Share via... Twitter LinkedIn Facebook Pinterest Telegram WhatsApp Yammer Reddit Teams最近の変更Send via e-Mail印刷パーマリンク × MozJPEGのjpegtranによるJPEG圧縮最適化が凄い件 とても今更なんですけどね、Mozilla謹製JPEGライブラリ群の一部、jpegtranによるJPEG最適化の効果に驚愕しとるわけです。 PENTAX K-1を買ってからというものPCのストレージの減り方が半端なく、そりゃJPEG+RAWで撮ってれば1シャッターにつき60MB前後の容量を食うので当たり前なわけでありますが、冗談抜きで空き容量が逼迫しとるんですわ。1TBのSSDうち820GBをデータ用に割り当ててるのに、現時点で残り2.3GBですよ。使用量のうち8割が写真であるからして、白羽の矢が立ったのがMozJPEGというわけ。(RAWが一番容量食ってるってツッコミはなしなんだぜ。) とりあえず急場凌ぎで、画像の品質には一切影響を与えないjpegtranで最適化してみたら、縮むこと縮むこと。元の画像サイズが大きいことも相まって、1枚あたり1MB弱ほど小さくなった。論より証拠ってなもんでスクショをご覧頂こう。 圧縮データの最適化、つまり無劣化でここまで縮むんだから大したもんですよ。もっとも、演算能力や処理時間の制約が厳しいデジカメで生成されたJPEGデータなので、最適化の余地が大きかろう点は考慮の必要があるだろうが…。 画像右端の「算術符号」ってのは、-arithmeticオプションで最適化した結果である。ハフマン符号最適化(-optimizeオプション)より更に小さくなっており、その効果には目を見張るばかりだが、哀しい哉、特許の関係で算術符号でエンコードされたJPEGに対応したソフトは皆無…。試した範囲では、MacOS X v10.9のプレビュー.app、Photoshop CC 2015.5、Firefox 58のいずれにおいても表示する事ができなかった。フォトショとLightroomで使えれば、手元のデジタル写真ライブラリの容量削減に大きく寄与するんだがなー。口惜しい…。 ついでに言うと、-optimizeより-arithmeticの方が処理時間が短かったりするのよね。軽くて縮むとかどんだけだよ。本当に口惜しい……。MacBook Pro (Late 2013)での処理時間は↓こんな感じ。 ・-optimizeの時 real 3m35.907s user 3m22.685s sys 0m11.282s ・-arithmeticの時 real 3m12.291s user 2m57.712s sys 0m11.897s -copy allオプションを付ければJPEGに含まれるメタデータは全て引き継がれる。少なくともexiftoolで比較した限りでは、元ファイルと最適化後のファイルでExifの相違はなかった。 個人的には元ファイルのタイムスタンプも継承したかったので、下記のようなシェルスクリプトで処理した。 #!/bin/sh TARGETDIR="$1" OUTDIR="$1/out" FILES=`find "$TARGETDIR" -maxdepth 1 -type f -name '*.JPG'` echo `pwd` mkdir -p $OUTDIR for file in $FILES; do echo $file CTIME=`GetFileInfo -d "$file"` MTIME=`GetFileInfo -m "$file"` OUTFILE="$OUTDIR/$file" jpegtran -optimize -progressive -copy all "$file" > "$OUTFILE" #jpegtran -arithmetic -progressive -arithmetic -copy all "$file" > "$OUTFILE" SetFile -d "$CTIME" "$OUTFILE" SetFile -m "$MTIME" "$OUTFILE" done ご覧の通り、エラー処理とか何も入れてないので、元ファイルが無関係のファイルが無くなってもしらにゃい(´・ω・`)。GetFileInfoとSetFileを使ってるのでXcodeを入れとく必要がある、つまりこのスクリプトはMac専用なんだぜ。 ブリッジネットワーク接続の仮想マシンを使う時はport-securityに気をつける ブリッジネットワーク接続の仮想マシンがあり、その通信がCiscoのCatalystスイッチを通るネットワーク構成の時は、スイッチのポートセキュリティ設定に気をつけなければならない。さもないと仮想マシンが通信できなくてハマる。VMとLAN内の物理マシンとでARP RequestとReplayは通っており、互いのARPテーブルは正しく作られているように見えるのに通信が出来なくて超ハマる。3ヶ月くらい悩んでた…(ヽ´ω`) port-securityが有効なポートでは、最初に通過したMACアドレス以外のフレームが破棄される。 ここで、ブリッジ接続の仮想マシンのフレームは、物理マシンが繋がってるポートに流れる事になる。つまり、1ポートに対して複数のMACアドレスが関連付けられるわけだが、port-securityが有効だと最初の通信のMACアドレスしか有効にならない。それは殆どのケースで物理マシンのMACアドレスになるので、VMは一切通信出来なくなるという寸法。逆にいえば、物理マシンの通信ならOKなので、NATでVMの通信を物理マシンの通信に変換してやれば通信できるということだ。実際、NAT接続でなら通信出来てた。 対策方法は次の3つ。 port-securityを無効化する 信頼するMACアドレスを静的に追加する 学習するMACエントリの上限を引き上げる(デフォルトでは1個) 自宅ネットワークならport-security無効化が簡単で影響も殆どないかと。 この問題を調べてる時に、ブリッジ接続が上手くいかないと嘆いているロシアのフォーラムを見つけたんだけど、結局使ってるホスティング業者を変えたら動いた!って結末だったので、恐らくダメだった方の業者のスイッチで似たようなセキュリティ設定になってたんだろうと思う。 原因がわかって全てが繋がった感じ。通信だけにね(´・∀・` ) 参考サイト Catalystスイッチ - ポートセキュリティ DAI(Dynamic ARP Inspection)とは FreeBSD 11.1 Release, bhyve и сетевой мост if_bridge - forum.lissyara.su VirtualBox上のWin 7でディスクイメージとzvolの速度比較(ついでにbhyveも) 仮想マシンのストレージ形式について、一般的にはイメージファイルよりもzvolの方が適していると言われている。ホストのファイルシステムレイヤを通過したファイル上にゲストのFSレイヤを通したFSを構築するよりかは、zvol(の薄いレイヤしか通らない)のブロックデバイスをゲストのFSレイヤに渡した方が効率が良さそう、ってのは理屈としても合っている。 以前から実際に速度比較しようと思いつつ、ようやく実行に移せた。環境は以下の通り。 ホスト FreeBSD 11.1-RELEASE-p1 VirtualBox 5.2.0 CPU: Xeon E5-2648Lv3 1.8GHz 12C24T RAM: 64GB SSD: Intel DC S3500 480GB SATA 3接続 ZFSのLZ4で透過圧縮している ゲスト Windows 7 Ultimate (x64) CPU: 4コア RAM: 8GB SSD: VirtIO 40GB ゲストのストレージを、同一内容のイメージファイルとzvolデバイスとで切り替えてCrystalDiskMark 6.0.0で速度を計測した。なお、イメージファイルからzvolへの変換は以下のコマンドで行った。 VBoxManage clonehd /path/to/vms/Windows/HDD.vmdk /path/to/vms/HDD.raw --format RAW zfs create -V 40G zvm/zvols/Windows dd if=/path/to/vms/Windows/HDD.raw of=/dev/zvol/zvols/Windows bs=4096 VBoxManage internalcommands createrawvmdk -filename /path/to/vms/Windows/zvol.vmdk -rawdisk /dev/zvol/zvols/Windows おろ、殆ど変わらんがな…(´・ω・`)。シーケンシャルR/W共にSATA 3の上限ぶっちぎっちゃってるし、ホストのキャッシュが効いちゃってる? というわけで、VirtualBoxの「ホストのI/Oキャッシュを使う」オプションを切って再計測。 すごく、、、速いです………。こりゃZFSのキャッシュが効いてるなー。確認してみるとARCで4.8GB持ってるしなー。ベンチ中にtopで見てるとARCがもりもり増えてくし。 ついでにイメージファイルをHDDに置いた時のベンチも取ってみた。 うっは2.5インチHDDとは思えぬ速さwwwww zpool iostatの結果を見るに、ランダムライトはZFS側でまとめられ、ほぼシーケンシャルライトとしてHDDに書き出されているようだ。 capacity operations bandwidth pool alloc free read write read write ---------- ----- ----- ----- ----- ----- ----- zhome2 1.33T 1.38T 1 922 153K 105M mirror 1.33T 1.38T 1 922 153K 105M ada3p1 - - 0 861 25.5K 105M ada2p1 - - 0 875 127K 107M logs - - - - - - mirror 40K 3.97G 0 0 0 0 ada0p4 - - 0 0 0 0 ada1p4 - - 0 0 0 0 ---------- ----- ----- ----- ----- ----- ----- capacity operations bandwidth pool alloc free read write read write ---------- ----- ----- ----- ----- ----- ----- zhome2 1.33T 1.38T 2 932 277K 111M mirror 1.33T 1.38T 2 932 277K 111M ada3p1 - - 0 919 50.4K 114M ada2p1 - - 1 890 227K 110M logs - - - - - - mirror 40K 3.97G 0 0 0 0 ada0p4 - - 0 0 0 0 ada1p4 - - 0 0 0 0 ---------- ----- ----- ----- ----- ----- ----- capacity operations bandwidth pool alloc free read write read write ---------- ----- ----- ----- ----- ----- ----- zhome2 1.33T 1.38T 0 962 102K 119M mirror 1.33T 1.38T 0 962 102K 119M ada3p1 - - 0 941 102K 117M ada2p1 - - 0 965 0 120M logs - - - - - - mirror 40K 3.97G 0 0 0 0 ada0p4 - - 0 0 0 0 ada1p4 - - 0 0 0 0 ---------- ----- ----- ----- ----- ----- ----- capacity operations bandwidth pool alloc free read write read write ---------- ----- ----- ----- ----- ----- ----- zhome2 1.34T 1.38T 1 940 153K 113M mirror 1.34T 1.38T 1 940 153K 113M ada3p1 - - 0 918 76.7K 113M ada2p1 - - 0 906 76.7K 112M logs - - - - - - mirror 40K 3.97G 0 0 0 0 ada0p4 - - 0 0 0 0 ada1p4 - - 0 0 0 0 ---------- ----- ----- ----- ----- ----- ----- 結論としては、イメージファイルでもzvolでも大差なさそう。ストレージ形式の差よりも、ZFSそのものの動作環境やチューニングの差の方が覿面に影響しそう。なので、好きな方を使えばいいんじゃないかな。俺は扱いやすいイメージファイルの方を選ぶんだぜ。 とりあえずZFSパネェ…。 (2017-11-25 追記) ついでにbhyveでもやってみた。 ストレージは同一SSDだけど、計測環境は新規インストールのWindows 10なので厳密な比較にはならんけど。なお、ストレージはahci-hdで繋いでる。virtio-blkはWindowsでは現状未対応らしい。 ベンチ結果は左から、gzip-5のZFS上のイメージファイル、同zvol、lz4なzvol。 FreeBSD 11で「warning: total configured swap (X pages) exceeds maximum recommended amount (Y pages).」と言われた時の対処法 「対処法」と言いつつ、FreeBSD 11.1-RELEASE-p4で試した限り、なぜか上手く行かないので対処法になってない。折角調べたので参考情報として残しておく…(´・ω…:.;::.. 物理メモリ1.5GBのFreeBSD 11.1-RELEASE環境で、16GBのスワップを追加したら以下のメッセージが表示された。 warning: total configured swap (4194304 pages) exceeds maximum recommended amount (2994784 pages) warning: increase kern.maxswzone or reduce amount of swap. カーネルが扱えるサイズを超えるスワップを追加すると出るそうで。本事例だと、最大スワップサイズは2994784ページで、1ページ=4KiBなので約11.4GiBとなる。 この値はどこで決まるかと言えば、warningの2つ目で示されているkern.maxswzoneカーネルパラメータである。スワップ管理用メモリの最大バイト数を指定するパラメータで、11.1Rではスワップ約200MiBにつき1MiBが必要とのこと。特に指定しなければ、物理メモリの8倍のスワップを扱うのに十分な容量が確保される。 実際に確保された量は恐らくvm.swzoneパラメータの値。本事例では53904384バイトとなっており、計算するとwarning中の最大スワップサイズと概ね一致する。 というわけで、/boot/loader.confに次の一行を追加してみた。 kern.maxswzone="75464704" 値はまー適当。11.4GiBで53904384バイト必要なんだから、16GBなら1.4倍して一応4KiB単位に揃えた感じ。 これで再起動すればOK! ……のハズだったんだけど、なぜか値が反映されないの(´・ω・`)。kern.maxswzoneには反映されるんだけど、肝心のvm.swzoneが変わってない。警告も相変わらず出る。kern.maxswzoneは名前の通り最大値を制限するものであって、スワップの最大サイズは物理メモリの8倍という制限は超えられないって事なのかしら…?これ以上はソース見ないとわからんな。 参考サイト loader(8) kern.maxswzone FreeBSD で swap デバイスを増やし続けると…: uyota 匠の一手 ZFSのメンバだったディスクを再利用する時はzpool labelclearすべき 一度でもZFSで使ったことがあるストレージを別のzpoolに使い回す際は、zpool labelclearコマンドで当該デバイスからZFSラベル情報を消した方が良さそうだ。 再利用デバイスで新しいプールを作ろうとすると、殆どの場合は以下のようなエラーが出て作ることができない。 # zpool create ztank da0p3 invalid vdev specification use '-f' to override the following errors: /dev/da0p3 is part of potentially active pool 'zroot' 「有効なプールzrootの一部かもよ」とZFS先生は仰ってるものの、zrootは間違いなくdestroy済みで、僕は確信を以てda0p3でztankを作りたいのだよ。先生ったらお節介~。destroyしたんだからラベル情報も一緒に消しとけよ!と思わなくもないが、ZFSではdestroyの取り消しをサポートしてたりする関係で、こういう仕様なのだろう。削除済みプールの復元については、zpool importの-Dオプションを調べておくんなまし。 ところがである、条件は不明だが、このお節介が働かず以前のラベル情報を残したまま新プールが作れちゃうことがある。こうなるとマジで大惨事。新しいプールと昔のプールが管理情報の上では存在する事になり、見るからにヤバげな状態となる。その時の再現ログが↓これ。 # zpool status pool: newtank state: ONLINE scan: none requested config: NAME STATE READ WRITE CKSUM newtank ONLINE 0 0 0 da0p3 ONLINE 0 0 0 errors: No known data errors pool: oldtank state: UNAVAIL scan: none requested config: NAME STATE READ WRITE CKSUM oldtank UNAVAIL 0 0 0 1234567890123456789 UNAVAIL 0 0 0 errors: No known data errors ログ上からは、別々のストレージで構成される2つのプール、newtankとoldtankがあるようにしか見えない。しかし実際のところ、oldtankはnewtank以前にda0p3で使っていたもので、既にdestroy済みのプールなのである。newtankとして実際にデータが書き込まれ、意味消失してるハズの削除済みプールoldtankが認識されているのだ…! こうなると最早手遅れ。oldtankを再度destroyしようにも「そんなプールは存在しない」と言われるし、ならばとデバイス1234567890123456789をどうにかする方向で頑張ってもどうにもならず…。かと言って、この段階でlabelclearは絶対にしてはいけない。newtankもろとも消えてしまうので_:(´ཀ`」∠):_(実体験)。 というわけで、ZFSプールを作る時は忘れずにlabelclearで以前の情報を消すようにしたい。 (2017-11-14 追記) タイミングよく本症状が発生したのでスクショをうp。 やった事はと言うと… 以前のzroot(赤い方)を削除しlabelclear 新しいzroot(緑の方)を作成 FreeBSD 11.0-RELEASEをインストール freebsd-updateで11.1-RELEASEに更新するも、ブート時のTrying to mount root~で失敗して起動しなくなる 今にして思えば、この時点で古いプールが認識されて旧zrootの方をマウントしようとしてたのかも…? kernel.oldの方から起動してfreebsd-updateで11.0の最新にしようとする 見事に失敗して起動しなくなる。起動スプラッシュのシェルでload kernelもload zfsも失敗する状態。 インストーラメディアから起動してzpool importしたらこの状態 確かにlabelclearしたハズなんだけどなぁ…。変なzpool.cacheでも食ってんのかなぁ…?わからん。 (2017-11-16 追記) あ、ありのまま起こったことを(ry。 症状が出たHDDの各パーティションを再度labelclearしてddでゼロフィルまでしたにもかかわらず、古い方のzrootが認識されやがったぜ……。最終的にzpool labelclear da0してようやく認識されなくなった。(が、当然GPTは壊れる。セカンダリテーブルは生きてるからパーティションの認識と復旧は可能だが…。)GPTの領域にZFSラベルが書き込まれそうな使い方─つまりディスク全体をzpoolにするような使い方はした記憶がないんだが、どうしてこうなった……? 結論としては、zpoolを作る時は対象デバイスの/dev/daXと/dev/daXpYを全てlabelclearするのが安全、可能なら全体をゼロフィルするということで。 < Newer Posts 1 2 ... 28 29 30 31 32 33 34 ... 83 84 Older Posts > start.txt 最終更新: 2022-07-27 15:26by Decomo