• この機能はバージョン3.5.xから利用できます。
  • このトピックはFTP・FTPS・SFTP経由での外部接続を行った場合のみ有効です。他の動作モードでは作用しませんのでご注意ください。

外部接続先で対象ファイルをリストアップしておくことでスキャンを省略

LightFileコマンドは、指定されたディレクトリ内のファイルをすべて探索して追加されたファイルや変更されたファイルを検出します。この探索をファイルのスキャンと呼びます。

FTP・FTPS・SFTP経由での実行では、ローカルディスク上での実行に比べ、このスキャンの処理時間が著しく長くなります。

そこで、まずは接続先のサーバー上で簡単なスクリプトを定期的に実行して最近更新(作成)されたファイルの一覧(インデックスファイル)を作成しておき、LightFileコマンドはそのファイルを参考にすることでスキャンを省略する方法があります。

このような用途に

次のような状況でのLightFile利用時に有効です。

  • ファイル数が非常に多い(数百万枚以上)。
  • 差分に対する実行時間を短くしたい。
  • 対象のWebサーバー上ではLightFileコマンドを実行したくない。
  • 対象のWebサーバー上で簡単なスクリプトは定期実行できる。

対象のWebサーバー上でLightFileコマンドを実行すると、スキャンは同一のファイルシステムに対して実行されます。これは非常に高速に行われます。

毎日の差分ファイルへの定期的な実行を高速化するためには、Webサーバー上で直接LightFileコマンドを実行する方法も考えられます。

インデックスファイルのフォーマット

インデックスファイルは、1行ごとに次の情報がタブ区切りで連なったテキストファイルです。

  1. ディレクトリパス(FTP/SFTPルート)からの相対パス
  2. ファイルサイズ
  3. UNIXタイムスタンプ(1970年1月1日0時からの秒数)

例えば次のような内容になります。パスの順序に制約はありませんが、ディレクトリパス順に並んでいる方が処理が効率よく行われます。

path/to/image1.jpg	16399	1546931279
path/to/deep/image1.jpg	17542	1546931279
path/to/deep/image2.jpg	336210	1546931279
path/to/another/image1.jpg	300192	1546931279 

インデックスファイルの作成スクリプト例

Linuxサーバーでのスクリプト例

Linuxではfindコマンドにより容易にインデックスファイルを作成できます。例えばindex.shファイルとして次のファイルを作成します。

#!/bin/sh

ROOT="."
DAYS=7

if [ "$1" != "" ]; then ROOT="$1"; fi
if [ "$2" != "" ]; then DAYS="$2"; fi

cd $ROOT
find -type f \( -name '*.jpg' \) \
    -mtime -$DAYS \
    -printf "%p\t%s\t%T@\n" \
  | sed -e 's!^\./!!g' -e 's!\.[0-9]\+$!!g'

次の条件でインデックスファイルを作成する場合、以下のようにcronを設定します。

  • index.shのパスを/path/to/index.sh
  • FTPディレクトリを/ftproot
  • 直近3日間に作成または更新されたファイルをリストアップ
  • 毎日0時に実行
0 0 * * * /path/to/index.sh /ftproot 3 > /ftproot/.lightfile-index

Windowsサーバーでのスクリプト例

Windowsでは次のようなPowerShellスクリプトでインデックスファイルを作成できます。

$root = "."
$days = 7

if ([bool]$Args[0]) { $root = $Args[0] }
if ([bool]$Args[1]) { $days = $Args[1] }

$from = (Get-Date).AddDays(-[Int]$days)
$unixOrigin = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0

$root = Resolve-Path $root
Get-ChildItem $root -Recurse -ErrorAction SilentlyContinue |
    Where-Object {$_.mode -notmatch "d"} |
    Where-Object {$_.Extension -eq ".jpg"} |
    Where-Object {$_.LastWriteTime -gt $from} |
    Select-Object @{Name="path";Expression={$_.FullName.Substring($root.Path.Length + 1).Replace('\', '/')}}, `
      @{Name="size";Expression={$_.Length}}, `
      @{Name="mtime";Expression={[Int]($_.LastWriteTime - $unixOrigin).TotalSeconds}} |
    ForEach-Object {"{0}t{1}t{2}" -f $_.path, $_.size, $_.mtime}

このPowerShellスクリプトをC:\path\to\index.ps、インデックスファイルの作成先をC:\ftproot\.lightfile-indexとした場合、次のようにタスクスケジューラにタスクを登録します。

  • プログラム/スクリプトpowershell.exeのパス(例: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe)
  • 引数-Command "C:\path\to\index.ps > C:\ftproot\.lightfile-index"
  • 開始ディレクトリは任意

LightFileコマンドでのインデックスファイルの指定

上記のスクリプトで定期的に作成されるインデックスファイルを参照する場合は、コマンドラインオプション--index-fileにそのパスを指定します。

例えばFTP接続時に、FTPのルートディレクトリ直下に.lightfile-indexファイルとしてインデックスが作成されている場合、次のようにコマンドを実行します。

$ lightfile --serial <シリアルコード> \
  --file-system ftp \
  --host <接続先ドメイン名またはIPアドレス> \
  --user <FTPユーザ名> \
  --password <FTPパスワード> \
  --dir <FTP接続先での対象ディレクトリ> \
  --index-file .lightfile-index

インデックスファイルをローカルに作成する場合 (バージョン4.4.1以降)

インデックスファイルは通常、LightFileコマンドで画像を軽量化する対象と同じファイルシステムに作成します。

例えばFTP経由で画像を軽量化する場合は、FTPサーバーにインデックスファイルを作成する必要があります。

バージョン 4.1.1から、--local-indexオプションを追加で指定することで、ローカルファイルシステム、つまりLightFileを実行する環境と同じファイルシステムに作成したインデックスファイルを指定できます。

$ lightfile --serial <シリアルコード> \
  --file-system ftp \
  --host <接続先ドメイン名またはIPアドレス> \
  --user <FTPユーザ名> \
  --password <FTPパスワード> \
  --dir <FTP接続先での対象ディレクトリ> \
  --index-file /path/to/lightfile-index \
  --local-index

上記の実行例では、インデックスファイルとしてFTPサーバー上の/path/to/lightfile-indexではなく、lightfileコマンドを実行した環境における/path/to/lightfile-indexを参照します。

運用上の課題について

何日前からのファイルをリストアップするか

インデックスファイルがカバーする日数は、LightFileの実行頻度に対して多少長くても問題ありません。

例えばLightFileの軽量化が1日1回だとしても、インデックスファイルは過去7日間に作成または更新されたファイルを対象にリストアップしても問題ありません。

そのように長めに作成しておくことで、もし何らかのトラブルでLightFileの実行が数日停止しても、その後実行を再開したときに停止中に作成または更新されたファイルが処理対象に上がります。

処理済みのファイルは記載されているファイルサイズと更新時刻により照合されるので、無駄なダウンロードなどは発生しません。

初回実行時からの設定例

例えば大量のファイルがあるWebサーバーについて、FTP接続による外部実行でLightFileを導入するケースでは、インデックスファイルを利用して次のように運用することをおすすめします。

  1. 初回実行はインデックスファイルなしで通常通りに実行します。初回実行に3日間を要したとします。
  2. 完了後、1日1回毎朝7時に差分に対し定期実行する設定をします。
    • Webサーバー上にインデックスファイル作成スクリプトを設置し、少し早めの1日1回毎朝5時に実行します。
    • インデックス作成スクリプトは、初回実行のタイムラグに少しバッファを持たせた過去5日間を対象にします。
    • ファイルのインデックスとして.lightfile-indexファイルが作成されるように設定します。
    • LightFileは、.lightfile-indexをインデックスファイルとして毎朝7時に実行します。
  3. 定期実行開始から5日間は初回実行でサイズが削減されたファイルも載るためインデックスファイルが大きなサイズになりますが、5日以降は純粋に作成または更新されたファイルのみが定期処理の対象になっていきます。