このエントリはMagento Advent Calendar 2017の4日目です。

今回はMagentoに備わっている「インデックス」の動作モードについて解説したいと思います。
動作モードを理解しておくことで、データの量や更新頻度に合わせた適切な設定ができるようになります。

Magentoのインデックスとは

Magentoのインデックスは、リレーショナルデータベースでよく使われるインデックスとは異なります。
もちろんMagentoもMySQLを使用していますから、データベース上のテーブルには色々なインデックスが張られています。

ですがMagnetoのアプリケーション上で頻出するインデックスはこれとは異なるものです。

複雑なMagentoのテーブル構造

Magentoは300以上のテーブルから構成されるアプリケーションです。
大規模な業務用アプリケーションに携わる方からすると大したことがないように感じられますが、一般的に用いられるWebアプリケーションと比較した場合、多いと感じられることが多いようです。

この原因としては、

  • EAVモデルの採用
  • インデックス作成用の中間テーブル
  • ストアビュー別のテーブル

があげられますが、これらはMagentoの機能と密接に関連しているためMagentoを使う上では避けて通れないものになっています。

Magento2で廃止された管理画面からのインデックス手動更新機能

さて、Magentoを使う上では避けられないインデックス。Magento2では管理画面から任意のタイミングで更新できないようになっています。
(あくまで標準の状態では、です)

Magento1では任意のタイミングで更新ができたので、Magento1に慣れ親しんだ方からは「どうしてできなくなったのか?」というご質問をよくいただきます。
これには大規模運用サイト向けに比重を移したMagentoの事情があります。

Magento Enterprise Edition 1.13で導入された自動更新

実は管理画面からインデックスが更新できなくなったのは、厳密にはMagento2からではありません。
Magento Enterprise Edition 1.13あたりから、一部のインデックスはMagento2と同じく自動更新になるよう変更が加えられてきました。
ですから、Enterprise Editionのユーザーにとっては若干「何を今更」という感がある話なのですが、Community Editionを使ってきたユーザーには機能が廃止されたように感じられると思います。

自動更新を支えるマテリアライズドビュー

インデックスの自動更新を導入するにあたり、Magentoにはマテリアライズドビューという仕組みが導入されました。

この仕組は以下の流れで動作し、インデックスが頻繁に更新される環境や、データ量が非常に多い環境でも安定した更新性能を獲得することを目的としています。

  • インデックス対象のデータが更新される
  • 変更リストテーブルに更新されたデータのIDを記録する
  • 定時処理による更新処理で対象データに関連するインデックスを更新する
  • 変更リストテーブルから処理済みデータのIDを削除する

マテリアライズドビューと自動更新を導入することで、非常に大きなデータ量の商品マスタやカテゴリマスタをもつサイトであっても、安定した運用ができるようになりました。
Magento2はアプリケーション全体として大規模運用よりになっているため、Open SourceでもCommerceでもインデックスに関する実装は全くおなじになっています。

インデックスモードと動作の違い

ここまではインデックスに関する前提知識の解説でした。
いよいよ今回の本題に入ります。

Magentoのインデックスには2つのモードがあり、微妙に動作が異なります。
この違いを知っているのと知らないのとでは大きな差が出るシーンがあります。

逐次更新モード

インストール直後のMagentoに設定されているモードです。
逐次更新という名前の通り、データに更新(追記・変更・削除)が行われたことをトリガーにして、Magento内部のイベント処理によるインデックス更新が1件ずつに対して行われます。

データ量が少ない場合には特段問題にはならないのですが、データ量が多い場合にこのモードを採用しているとデータ更新が終わらなくなるケースがでてきます。
できれば大規模なデータ更新の際はこのモードを使用しないほうが良いでしょう。

スケジュール更新モード

スケジュール更新モードは、前述のマテリアライズドビューを用いた定時処理による更新を行うモードです。
標準設定では毎分定時処理による更新が行われるので、システム全体の負荷を一定化することができます。

ただし、データによっては更新間隔がやや長いものがあり、スケジュール更新モードでは遅く感じられることがあるかもしれません。

基本的にこのモードはデータ量の多いサイトや、更新頻度の多いサイト向けです。

スケジュール更新モードとMySQLユーザーの権限

スケジュール更新モードを使用する際は、Magentoがデータベース接続に使用するMySQL上のユーザーの権限に注意が必要です。
というのも、スケジュール更新モードで使用するマテリアライズドビューは、MySQLのトリガーを用いて更新データの検知を行っています。

MySQLユーザーに対象データベースに対するトリガー作成権限がない場合、スケジュール更新モードが正しく動作しません。
インデックスモードを切り替える前に、MySQLユーザーの権限を確認しておくことをおすすめします。

とくにAmazon RDSは標準状態でトリガーの作成権限がないため、パラメータグループで設定しておく必要があります。
運用が始まってから切り替える場合、マルチAZ運用でなければサイトの停止が発生してしまいます。

終わりに

今回はMagentoのインデックスモードについて取り上げました。
インデックスはMagentoには不可欠なもので、Magentoを使っていく上では避けては通れません。
サイトの規模に合わせて適切なモードを選ぶようにしたいものです。

明日はMagento Advent Calendar 5日目。弊社のMariaによるMeet Magento 2017 Japanの開催レポートです。