Previous Post | Top | Next Post |
TOC
正直なところ、今は Git Annexを 使っていません。rsync と btrfs の 組み合わせでバックアップしています。(2021/07/07)
Git関連ツールで、写真等の大きなデーターの分散保存・世代管理をする Git Annexというツールを walkthrough を読みながら学びました。間違っているかもしれませんが、 自分なりに簡単に以下にまとめて見ます。
Git Annexの基本コンセプト
Gitはデーターの分散管理では非常に便利ですが、 大きなデーターを直接扱うのが不得意 です。そこで、このGitが不得意な部分のデーターの分散管理を協調的に補完す るのがGit Annexです。
写真等の大きなファイルを含むデーターは、ソースコードなどのテキスト ファイルを含むデーターと違い、ファイル自体がすでに圧縮されていて 保存の際のさらなるデーター圧縮のメリットが少ないことや、世代間の 詳細なデーター差分の検出には大きな労力が必要な割に、詳細な差分は サイズも大きくなりがちでメリットが少ないという特徴があります。
そこで大きなファイルは、Gitの本体で直接扱かわずに、労力とのバランス
を考えGitの上に構築したGit Annexで扱うのが望ましいです。Git Annexでは
データー保存の効率化対象を単純なファイルの重複保存や世代間のファイル
の位置移動に絞ります。この制約の下では、ファイル実体によって決まる
「ユニークな特定パスに保存する」ことで、ファイル実体の効率的な保存
が実現できます。「ユニーク」ということはファイル内容のハッシュ値
等を用いた文字列(Key)で実現します。Git Annexではファイル実体データー
(Value)をGit本来のデーター保存インフラとは別の.git/annex/objects/
以下に書き込み禁止のファイルパーミッションで保存します。
一方、作業ディレクトリーツリー中のファイルがあった場所には Git Annex管理下に保存されたファイルへのシムリンクを置きます。 このシムリンクのデーターサイズは小さいので、本来のGitで問題なく 場所の保存や世代管理ができます。
このままでは他のプログラムによるデーターの編集・更新ができな いので、Git Annexはシムリンクをファイルで置き換え編集可能化する unlock機能と、Git Annexに編集結果を戻すlock機能を提供します。
さらにGit Annexは、「特定パスに保存する」という部分に関して、 「分散保存を管理するインフラを提供する」とすることで、すべての 分散管理レポジトリー内に全ファイルを保持しなくても良い とします。ここは全ファイルを保持する本来のGitレポジトリーと 大きく異なるところです。Git Annexは、分散管理レポジトリー間で それぞれが保存するファイルに関するメタ情報を交換するインフラも 提供します。
Git Annexがチェックアウトした作業ディレクトリーツリー中で、 ローカルに保持していないファイルは、ダングリングシムリンク (宙ぶらりシムリンク)となってしまいます。その際に、保有するメタ 情報に基づき指定範囲のファイル実体をリモートサイトから簡単に オンディマンドでコピーしてくる部分チェックアウト機能や、 作業ディレクトリーツリー中ダングリングシムリンクを簡単に消す 機能もサポートします。
Git Annexによるリモートサイトへのアクセスは抽象化されていて、 単純なファイルシステム経由のアクセスはもちろん、SSH経由のアクセス、 Amazon S3等の各種クラウドへのアクセスが、既成のバックエンドを 利用し、ほぼ同じ手順で簡単に実現出来るようになっています。
Git Annexの注意点
Git Annexは、バックアップファイルの数を自由に設定できたり、保存 ファイルのコピーの代わりに保存ファイルへのハードリンクを利用する ように設定できたり、ユーザーが自由にカスタマイズできる機能が多い 汎用性のあるツールです。それだけに、しっかり基本機能を学ぶことや、 良く各機能の動作を考えて使うことが重要です。
Git Annexは、大きなファイルをチャンクに分割して保存しません。これは ファイルシステムのトラブルの際等に被害範囲を限定的にできるので大きな メリットがあります。確かにこれは成長する巨大ログファイル等のデーター ではデメリットがある保存手法です。もしそのような成長するデーターを Git Annexが扱い保存することが避けられない際には、事前にそのデーターに logrotate(8) を適用してチャンクに分割・圧縮しておきましょう。 参考情報:2019年 参考情報:2019年
Git Annexは、ファイルを圧縮してて保存することをしません。圧縮が必須な ケースは限定的でしょうが、Git Annexのレポジトリーを作るファイルシステム に透過的な圧縮をサポートする、 NTFS (NT File System) (Linux上ではNTFS-3G経由で利用)・ F2FS (Flash-Friendly File System)・ ZFS・ Btrfsを利用し設定すれば、ファイルは 圧縮してディスクに保存されます。
作業ディレクトリーツリー中でシムリンクではない本来のファイルを 安全に他のソフトにGit Annexが提供するのは難しい問題です。また 当初はUnix系のファイルシステム上の操作のみが対象でしたが、FATや NTFSシステム上の操作も対象にしてきました。そういった経緯も有り Git Annexのサポートデーターを保持するレポジトリーは、 バージョンアップ が繰り替えされ、2020年(Debian buster + buster-backports) の「git-annex version: 8.2020033」では V8 になっています。
チョット古いネット情報は現行バージョンには当てはまらないことがある ので要注意です。(「direct mode」はもう存在しません)
Git Annexの基本操作
Git Annexレポジトリーの初期化(init)
Git Annexレポジトリーの初期化は、ベースとなるGitの初期化と、Git Annex の初期化の2段階で行われます。
$ mkdir ~/annex
$ cd ~/annex
$ git init
$ git annex init "my laptop"
Git Annexレポジトリーは、上記のように区別できるdescriptionを与えることが 望ましいです。
最初のdescription設定に関わらず、git annex describe "my laptop"
と後からも設定・変更できます。
ファイル実体のGit Annexへの追加(add)
作業ディレクトリーツリー中にGit Annexに管理させる新規ファイル
foo
を追加するのは、ファイルを目的位置に移動し、その場所で
$ git annex add foo
とします。こうするとファイルがシムリンクで置き換えられます。 さらにシムリンク先のGit Annexがファイル実体を保持するファイルは、 書き込み禁止にファイルパーミッションが設定され保護(「lock」)され ています。
作業ディレクトリーツリー中のファイルの編集・更新(unlock/lock)
作業ディレクトリーツリー中のシムリンクに対応するGit Annexが保持 するファイルを編集するには、まず対応するシムリンクの場所で
$ git annex unlock foo
とします。こうするとシムリンクがファイルのコピーで置き換えられ、 ファイルパーミッションは書き込み可能に設定され保護解除(「unlock」) されます。このファイルを他のソフトに提供し編集します。編集後の ファイルに
$ git annex lock foo
とします。こうするとファイルはシムリンクで置き換えられます。 さらにシムリンク先のGit Annexがファイル実体を保持するファイルが 新たな場所に作成され、Git Annexのデーターが更新されます。
作業ディレクトリーツリー中のファイル移動・複製
作業ディレクトリーツリー中のGit Annexが保持するデーターを 移動・複製する際には、ファイルの内容には変更が無いので、 Git AnnexのコマンドではなくGitのコマンド操作で充分です。
移動:
$ git mv foo bar
複製:
$ git cp foo bar
サブディレクトリーに移動・複製する際には、シムリンクがおかしく なりそうですが、Git Annexがpre-commit hookを導入しているので 丸く収まりますので安心しましょう。
後述するように、Git Annexのmove
やcopy
は、レポジトリー間の
ファイルの移動です。混乱しないようにしましょう。
リモートの追加と初期化(init)
それぞれレポジトリーは、Gitのレポジトリーとして初期化や クローン後、Git Annexとしての初期化をします。
レポジトリー間のリモート設定の追加方法は通常のGitと変わりなく
git remote add <name> <url>
です。ただ、Git Annexに保存した
ファイルは、必ずしも全レポジトリーが常に保有するわけではなく、
レポジトリー間で双方向に授受しながら保存するので、リモート設定
を双方向でしましょう。
例えばUSBメモリーを差し込み、それが/media/usb
に自動マウント
される場合は以下のようにします。
$ cd /media/usb
$ git clone ~/annex
$ cd annex
$ git annex init "portable USB drive"
$ git remote add laptop ~/annex
$ cd ~/annex
$ git remote add usbdrive /media/usb/annex
注: 上記では分かり易い様にlaptop
というremote
を設定しているが、わざわざ
設定しなくともclone
しているのでorigin
というremote
が設定されている。
Git Annexレポジトリー間の同期(sync)
Git Annexが管理する大きなデーターのレポジトリー間の操作の前に、 大きなデーターに関するメタデーターを、登録されたリモートレポジトリー 最新情報を問い合わせて更新する同期操作が必要です。
例えば、laptop上の~/annex
にあるGit Annexレポジトリーの場合には
以下のように操作します。
$ cd ~/annex
$ git annex sync
...
例えば、USBメモリー上のローカルのGit Annexレポジトリーの場合には USBメモリーを差し込んだあとに以下のように操作します。
$ cd /media/usb/annex
$ git annex sync
...
メタデーターだけでなく、Git Annexが管理するファイル実体の更新も同時
に行いたい時にはgit annex sync --content
とします。
ファイル実体のGit Annexレポジトリー間移動(move)
USBメモリーを差し込んだまま、laptop上の~/annex
にあるGit Annex
レポジトリーからmy_cool_big_file1
をusbdriveに移動(move)するには
以下のように操作します。
$ cd ~/annex
$ git annex move my_cool_big_file1 --to usbdrive
ファイル実体のGit Annexレポジトリー間複製(copy)
USBメモリーを差し込んだまま、laptop上の~/annex
にあるGit Annex
レポジトリーからmy_cool_big_file2
をusbdriveに複製(copy)するには
以下のように操作します。
$ cd ~/annex
$ git annex copy my_cool_big_file2 --to usbdrive
ファイル実体のGit Annexレポジトリーからの削除(drop)
USBメモリーを差し込んだまま、laptop上の~/annex
にあるGit Annex
レポジトリーからmy_cool_big_file2
ファイル実体を削除(drop)する
には以下のように操作します。
$ cd ~/annex
$ git annex drop my_cool_big_file2
この時もしUSBメモリーを差し込んでいないと、Git Annexは重複データー の存在を確認できないので削除を拒否します。
ファイル実体の他Git Annexレポジトリーからの獲得(get)
USBメモリーを差し込んだまま、laptop上の~/annex
にあるGit Annex
レポジトリーのファイル実体がなくなりダングリングシムリンクとなった
my_cool_big_file2
のファイルの実体を外からの獲得(get)する
には以下のように操作します。
$ cd ~/annex
$ git annex get my_cool_big_file2
この時もしUSBメモリーを差し込んでいないと、Git Annexは外部の重複 データーにアクセスできない旨のメッセージを表示します。
未使用ファイル実体のGit Annexレポジトリーからの整理(unused)
Git Annexレポジトリーの未使用ファイル実体の確認は以下のように操作します。
$ git annex unused
未使用ファイルを効率的にGit Annexレポジトリーから削除drop
するには、
例えば以下のように操作します。
$ git annex dropunused 1-1000
未使用ファイルを効率的に移動move
や複製copy
するには、以下のように操作します。
移動:
$ git annex move --unused --to archive
複製:
$ git annex copy --unused --to backup
Git Annex操作のヒント集
Git AnnexのGUI操作
コマンドラインでのGit Annexの基本操作がある程度分かると、 もう少し使いやすいGUIでの操作がしたくなります。
git-annex webapp
を実行すると、Git Annexレポジトリーと
git-annex assistant
の実行コントロールのセットアップがウエッブブラウザーから簡単にできます。
GNOME等のGUI環境では
git-annex assistant
がバックグラウンドで自動実行されリモートとの同期がとられるとともに、
GUIファイラーや
コンソールのmc
からGit Annexのdrop
やget
の操作ができます。
Git Annexレポジトリーの重複保存数
全レポジトリーに対して以下でファイルの重複保存数をNに設定します。
$ git annex numcopies N
デフォルトは N=1 です。レポジトリーの 信頼性 にも注意しましょう。
.gitattributes
ファイルを使って、ファイル毎にオーバーライドできます。
– 情報源
Git Annexレポジトリーのファイルの探索や適度の冗長保存
保存状況の重複も含めた探索確認を以下でします。
$ git annex whereis
例えばそれぞれ2つづつの適度の冗長保存は以下でできます。 – 情報源
$ git annex get --auto --numcopies=2
...
$ git annex drop --auto --numcopies=2
...
Git Annexレポジトリーの整合性確認
レポジトリーデーターの整合性確認は以下のように操作します。 – 情報源
git annex fsck
Git Annexレポジトリーの変更回復(undo)
Git Annexのundoをするとファイルやディレクトリーにした変更をもとに 戻しますが、マルチレベルundoではないので、2回目の実行はundoをundo します。
作業ディレクトリーからのダングリングシムリンク削除
ダングリングシムリンクがあると混乱するソフト (例えばDebian 10 BusterのShotwell 0.30.1)には、 ダングリングシムリンクを削除して対応できます。 – 情報源
$ git annex adjust --hide-missing
git config
とgit annex config
の違い
git config
の設定はコマンドを実行したレポジトリーにのみ有効だが、
git annex config
の設定はクローンしたレポジトリーにも有効です。
ハードリンク利用によるディスクスペース節約
もちろん使う際には常識的注意は必要ですが、ファイルのコピーの 代わりにハードリンクを利用するとディスクスペースが節約できます。
同一ファイルシステム上のレポジトリー間だと下記のように設定した 共有cacheをハードリンクを利用して作成してダウンロードとディスク スペースの両方を節約できます。 – 情報源
$ git config annex.hardlink true
$ git annex untrust here
Unlockした作業ディレクトリー中のファイルとGit Annexのレポジトリー間 だとハードリンクを利用してディスクスペースを節約できます。 – 情報源
$ git config annex.thin true
$ git annex fix
レポジトリーの連結
複数のディレクトリーのデーターの連結してGit Annexのレポジトリーにするには、
それぞれをGit Annexのレポジトリーとして、リーモートを設定しsync
やimport
をして連結するのが効率的手法です。
この他に、リーモートを設定しgit merge --allow-unrelated-histories ...
と
gitを直接操作する手法もあります。
– 情報源
ファイル数の多いレポジトリー
- Repositories with large number of files – ベストプラクティス: そのままでの対応と分割での対応
- scalability – 大量のファイルの同時追加には
annex.queuesize
を大きな値に調整等 - Splitting a git-annex repository – 分割の参考情報
ファイルの自動振り分け保存
作業ディレクトリーツリー中に異種のコンテントを含み、 コンテント内容によってGit AnnexとGitのいずれかに保存したい 際には、これを設定で自動化できます。
かなりGit Annexに精通するまでは、Git AnnexとGitの両方データーをレポジトリー内で混ぜない方がシンプルなので賢明な感があります。
ファイルパーミッションやタイムスタンプ
Git Annexが通常使うハッシュから生成するkeyにはファイルパーミッションや タイムスタンプ情報が含まれません。だから、ファイルパーミッションや タイムスタンプの違いが区別されないはずなので、そこは理解して使うのが 良いようです。
暗号化保存
git-remote-gcryptパッケージを導入するとgpgを使った暗号化保存ができます。 – 情報源
暗号化保存した際には、使用したパスワードや暗号化キーが後で自分自身で分からなくならないように注意しましょう。(笑)
MetadataとView
まだよく分からないが、Git Annexの Metadataと View は面白そうです。GUIエディターもあるようです。 – Git-Annex-Metadata-Gui
Git Annexを使っての所感
ちょっと使ってみただけなので、判断が怪しいところがありますが、現状の所感をまとめてみました。
Git Annexの良い点は:
- 基本ユーザーランドコマンドだけで動く
- gitと透過的に連携できる分散dedup保存ができるファイルレポジトリーを提供 → source code 中に
git-submodule
の乗りで大データーを読み込みたいときに便利かな? - 汎用クラウドストレージを使って、改変履歴が残るファイルレポジトリーが提供できます
- 大ファイルに便利な部分チェックアウト機能があり、保存数管理もできます
ちょっと使ったあとのGit Annexの所感は:
- git annexのコマンド操作が複雑で、ハッシュ照合が遅く、簡単に透過的に使うのにはハードルが高い印象が残りました
- 写真の場合ならユーザーランドのアプリ(shotwell)がデーターをimportする際に日付などを使って適当なディレクトリーに読み込みdupチェックをすれば、改変履歴対応はbtrfs等を使えるので充分の気がしました
- 文書ファイル等などの、dedup問題・圧縮問題もファイルシステム(btrfs等)で対応可能な気がしました
- 共有バックアップ用ファイルレポジトリーならスナップショット履歴ができるファイルシステムと、web/ssh/rsyncのいずれかのserverと、cronを組み合わせる事などでも、改変履歴対応や部分チェックアウトが可能の気がしました
因みにDebianにある、バックアップツール以外の気になるdedupツールはfdupes
, jdupes
, duperemove
, duff
, hardlink
, rdfind
, rmlint
, rmlint-gui
でした。
歴史的には圧倒的にfdupesが人気ですが、
最近(2020年5月)はjdupesが急に伸びてきていますし、duperemoveやduffやrmlint-guiも健闘しています。
画像が同じだが日付等変更をしたEXIFファイルの重複検出は目に入らなかったので、昔書いたスクリプトをここに特化して書き直すのも良いかもと思いました。
Previous Post | Top | Next Post |