Magentoに限らず、多くの画像を扱うWebアプリケーションでは共通する問題があります。
1台のWebサーバで運用している間は全く問題がないのですが、2台以上になると、商品管理やCMS機能などで使用する画像ファイルを、Webサーバ同士の間で共有する必要性が出てきます。

このエントリではMagentoにおける複数台のWebサーバ間での画像ファイル共有について、データベースを使用した方法を解説します。

2台以上のWebサーバでMagentoを運用する際に考えること

Magentoを2台以上のWebサーバを用いて運用する際には、商品画像やCMSページ上の画像などの管理画面経由でアップロードされた画像ファイルなどの扱いについて注意する必要があります。
というのも、1台の時には起こらなかった、「アップロードしたファイルが別のサーバ上には存在しない」 という問題が起きてくるからです。

もちろん、varディレクトリ下にある、セッション情報やキャッシュファイルなども複数台のWebサーバの間で共有しなければならないのですが、それは「MagentoのセッションとキャッシュをRedisに保存する」で説明したような方法で解決することができます。

しかし、商品画像やCMSページで使用する画像については、サイトによっては数GBを超えるケースもあるため、ケース・バイ・ケースでの対策が必要になってきます。

mediaディレクトリ以下に保存されているもの

medaディレクトリ以下には、

  • 商品画像
  • カテゴリ見出し画像
  • WYSIWYGエディタでアップロードした画像
  • CSS/JSマージ機能でマージしたファイル
  • ダウンロード商品のデータ
  • XMLConnectエクステンションのデータ
  • CAPTCHAのキャッシュ

などが配置されています。
エクステンションの導入状況によってはもっと多いこともあります。 

これらのファイルは標準ではWebサーバ毎に保持するようになっているため、複数台のWebサーバで運用する際には同期をとる必要が出てきます。

データベースを使用したファイル共有の方法

データベースを使用したファイル共有の方法は、Magentoにおいては簡単にできるようになっています。
管理画面でほんの僅かな設定を変更するだけです。 

メディアストレージ設定を変更する

最初に、システム設定画面を開いて、一番下から3番目にある「システム」を選びます。
この画面の一番下のセクションを見ると、以下のような設定項目があります。

メディアストレージ設定

この「メディアストレージ」 を「ファイルシステム」から「データベース」に変更すると、次の画像のようにボタンの色がオレンジ色になり、ファイルを格納するメディアストレージを選択するセレクトボックスが表示されます。

メディアストレージ設定変更後

通常は「default_setup」を使用すればよいでしょう。
もし、データベースを読み込みと書き込みで分けている場合は、その設定にそって、 このセレクトボックスの内容を変更してください。

新旧のメディアストレージを同期する

注意書きにもある通り、メディアストレージを変更したあとには必ず「同期」ボタンをクリックする必要があります。
なぜかというと、同期をするまでは新しいメディアストレージと、古いメディアストレージの間に情報のズレがあるからです。
もし、同期をしないでメディアストレージを切り替えてしまったら、データの欠損や先祖がえりと言った現象が起きる恐れがあります。

ですから、メディアストレージを変更したら、必ず「同期」 ボタンをクリックします。
実行時間は、ファイル数によって変わりますが、実行中は図のように処理中の表示が出ますので、辛抱強く待つ必要があります。

画像同期中表示 

設定を保存する

同期が終わったら、設定を保存します。
設定を保存せずに焦って別画面に移動してしまうと、メディアストレージは切り替わらないままになってしまいます。

今回の例ではファイルシステムからデータベースへの切り替えを行いましたが、データベースからファイルシステムへの切り替えもできるようになっています。 

データベースを使用した場合、画像はどのように配信されるか

メディアストレージがファイルシステムの場合は、特に疑問はないでしょう。実際にファイルは存在していて、クライアントのブラウザに対して配信されていきます。

ところが、データベースにファイルを格納した場合、どのような流れでファイルは配信されていくのでしょうか?
その答えはMagentoのルートディレクトリにある、「get.php」にあります。 

get.phpの働きについて知る

get.phpはメディアファイルを取り扱うための専用のプログラムです。データベースがメディアストレージに設定されている場合にのみ使用されるようになっています。 

get.php内部では、実際のファイルシステム上にファイルがあるかないかを判断し、ファイルが存在しない場合はデータベース上のデータを読みだして、ファイルシステムに保存します。

つまり新たにファイルをアップロードし、かつ一度も表示していない場合は、ファイルを表示するためにデータベースへのアクセスが発生することになります。
これはWebサーバの台数分だけ発生する現象なので、管理画面用と公開画面用でWebサーバを分けている場合は、商品を公開した瞬間に注意しなければならない場合がありえます。 

データベースを使用する場合のメリット・デメリット

さて、Magentoではこのようにデータベースを使用して、簡単に複数台のWebサーバの間で画像ファイルの共有ができます。
ですが、この方法にはデメリットもあります。

1つは前述のとおり商品公開の瞬間にデータベースアクセスが増加する可能性。
そしてもうひとつは、データベースのサイズが肥大化しやすいということです。

一般的に画像データはテキストデータに対してサイズが大きく、ディスク上に保存する場合でも、油断をすると容量不足を起こす可能性があります。
これがさらにデータベースに格納することになると、

  • MySQLの使用するメモリ・ストレージ領域の増加
  • 実行するSQLクエリ数の増加(一時的であるにせよ)
  • バックアップ作成時のデータサイズの肥大化

と言った問題が起きてきます。

最近はクラウドサービスが提供するデータベース・サーバのサービスがあり、運用の煩わしさから解放してくれるものもありますが、これらのサービスはデータベース領域のサイズや、読み書き回数、データ転送量によって課金する場合があります。
そのため、安易にデータベースに画像ファイルを保存してしまうと、予想外の課金をされる可能性があります。

簡単に設定できる方法ではありますが、ご自身のサイトのサーバ構成をよく考えてから導入されることをおすすめします。