メインコンテンツにスキップ
バージョン: 1.x

同期のパフォーマンスとサーバーへの配慮

v1.10.0の新機能

このページでは、WCPOS v1.10.0 で導入された同期エンジンについて説明します。エンジンの動作の仕組みについては、まず同期エンジンの仕組みをご覧ください。

WCPOSのストアの多くは共有PHPホスティング上で動作しています。PHPワーカーはわずかで、RESTリクエストのたびにWordPressのフルブートストラップが走り、セキュリティプラグインがバーストをレート制限します。クライアントが無料だとみなしているリクエストは、ストアフロントの表示を遅くし、レート制限に引っかかり、キャッシャー自身の通信と競合します。しかもその影響は、稼働しているレジとブラウザータブの数だけ倍増します。

v1.10.0の同期エンジンは、これを後付けの課題ではなく設計上の制約として扱います。販売者のホスティングを守ることは、同期エンジンの仕事の一部です。 このページでは、エンジンが従うルールと、その裏付けとなる測定結果を説明します。

4つの原則​

エンジンでスケジュール実行されるすべての同期処理には、次の4つの不変条件が適用されます:

  1. コストはカタログの規模ではなく、変更量に応じて増えます。 大量のデータを取得する前に、必ず低コストのダイジェストまたは早期終了できるチェックを行います。変更のない商品50,000件の店舗を同期状態に保つコストは、変更のない商品500件の店舗とほぼ同じです。
  2. リクエストが無制限に増えることはありません。 各バックグラウンドレーンには1回の実行あたりのリクエスト上限が定められ、自動テストで検証されます。大規模な処理は再開可能なカーソルを使う上限付きのバッチで実行され、走査をスケジュールに分散して、一度にリクエストが集中しないようにします。
  3. メンテナンスがキャッシャーの邪魔をすることはありません。 レジが販売できる状態にするためのリクエストが先に実行され、整合性の監査やバックグラウンドの事前読み込みは、その後のアイドル時間に実行されます。
  4. 負荷がかかると、まずメンテナンスが後退します。 サーバーが不調のシグナルを出すと、エンジンはキャッシャーに関わる処理に手を付ける前に、自身のバックグラウンド処理を減速させます。

同期がサーバーにかけるコスト​

定常状態のコストは、ストアヘルス → パフォーマンス でデバイスごとに選択する同期プリセットによって決まります。

プリセットチェック間隔リクエストあたりのレコード数1日あたりの名目チェック回数
エコ5分25288
バランス(既定)60秒501,440
リアルタイム10秒758,640

どちらのダイヤルも重要ですが、共有ホスティングで実際にコストになるのはたいていページの重さです。レコード数の多いページはサーバーの処理時間を実際に消費し、間隔はそれを掛け算するだけです。最大値である100件のページを使うプリセットはありません。これはカスタムのスライダー(間隔5秒〜5分、レコード数10〜100)でのみ設定できます。

プリセットに加えて、次の仕組みがあります。

  • アイドル時のチェックは低コストです。 エンジンは条件付きリクエストを送信するため、変更がなければ本文のない304 Not Modifiedが1回返ります。リクエストは1回発生しますが、ペイロードはなく、サーバーの処理負荷も最小限です。
  • チェックには±20%のジッターがかかります。 そのため、多数のレジがバーストとして同期することなく、リクエストを分散します。
  • アイドル状態のレジは減衰します。 10分間操作がないと間隔が長くなり、バーコードスキャンを含むあらゆる操作で即座に元に戻ります。
  • バックグラウンド保守には上限があります。 ドリフトがない整合性チェックでは、低コストの集計ページを数回取得するだけで、詳細データの取得は0件です。サーバーと一致することが確認できたバケットはスキップされます。ドリフトが見つかった場合、詳細確認は1回の実行につき2件までとし、保存済みカーソルから再開します。削除の完全監査は1回の実行につき11リクエスト、ダイジェストの初期化は1回につき5チャンクまでです。上限はコードで宣言され、CIで検証されます。
アプリ内の「1日あたりのリクエスト数」は概算です

店舗の健全性では、設定間隔から1日あたり約N件のリクエストを推定します。これは上限や予測ではなく、概算のチェック頻度です。±20%のジッターにより実際の件数は増減し、304もリクエストとして数えられます。アイドル時の減衰は、60秒の下限より速いプリセットでのみ件数を減らします。デフォルトのバランス型プリセットをさらに遅くすることはありません。

サーバーが苦しいときのバックオフ​

エンジンが受け取るすべてのレスポンスは、ストアごとの負荷モニターに送られます。モニターは次の状況に反応します。

  • HTTP 429(即座に反応)
  • 5xxエラーまたは通信障害が繰り返し発生する場合(1分間に3回)、
  • 継続的な遅さ(応答時間の中央値が2秒超)
  • Retry-After ヘッダー(次回のチェックの下限として厳密に適用されます)

いずれかの条件に達すると、エンジンは変更チェックの間隔を段階的に2倍に延ばし、保守レーンの実行をすべてスキップします。レジ係が操作するリクエスト(検索、バーコード検索、チェックアウト)が制限されることはありません。目的は延期可能な負荷を減らすことであり、販売を遅らせることではありません。

復旧の動作は意図的に非対称です。負荷軽減は直ちに行われますが、間隔を短くするのは正常な応答が10回連続した後に限られます。これにより、不安定なサーバーで高速と低速の間隔が頻繁に切り替わるのを防ぎます。店舗管理者がより速いプリセットを選択しても、負荷状態は維持されます。保護機能は設定されたプランの下で動作し、無効にはできません。

デバイス側の応答性を保つ​

パフォーマンスのもう半分はレジ自体です。バックグラウンドの同期がUIをカクつかせてはいけません。

  • 監査処理はイベントループに制御を返します。 整合性監査では作業を分割し、チャンクごとに処理を中断することで、連続実行時間を約30 msに抑えます。これは人が遅延を感じる約100 msのしきい値を下回ります。ローカル商品10,000件で監査全体の計算時間は約68 ms(17回以上の中断に分散)、商品50,000件でも300 ms未満です。
  • 負荷がかかっても最初の結果は速く返ります。 一括適用や完全監査と並行して実行している場合でも、ベンチマーク環境で一般的なカタログ規模なら、最初の結果が返るまでの時間を1桁ミリ秒に保つ契約がCIで検証されます。
  • 表示中のページだけをアプリに渡します。 クエリ処理(フィルター、並べ替え、ページネーション)はストレージ層内で実行されるため、画面更新で移動するのは1万行ではなく10行です。

上記の数値は、エンジンの固定パフォーマンス契約テストによるものです。このテストはCIで分離して実行され、予算は定常状態の実測値のおよそ1桁上に設定されています。実行環境が遅い場合に失敗させるのではなく、桁違いの性能低下を検出するよう設計されています。

実際のストアでの検証​

サーバーへの配慮のルールは、ユニットテストだけで確認しているわけではありません。実際のWordPressストアに対するエンドツーエンドのライブチェックにより、実際のホスティングで最も重要な不変条件を検証しています。

  • ストアを開いたとき、商品カタログが描画されるまでのメンテナンスリクエスト(整合性やダイジェストの通信)はゼロであること。
  • 起動後の保留時間が終わった後は、低コストの集計ページを数件まで取得し、詳細確認は2件以内にとどめます。

このシナリオは、実際に発生したリグレッションから作られました。開発中の初期ビルドでは、監査がストアを開くたびにデバイスごとに約41件のリクエスト(1.2MB)を発行していました。これを置き換えたダイジェストによるゲート方式の設計では、ずれのない監査は集計ページだけで済み、それ以外は発生しません。この種のバグは現在、レビューの注意深さではなく、CIで宣言された上限によって防がれています。

主張しないこと​

裏付けとなる数値がまだ揃っていないため、このページでは意図的に述べていないことがいくつかあります。

  • 「初回同期はX分かかる」というエンドツーエンドの数値はありません。 初回ダウンロード時間は、主にサーバーの応答時間とカタログの規模によって決まります。デバイス側でレコードを適用するコストは小さく、商品10,000件の一括適用に必要な計算時間は10 ms未満です。大部分を占めるのは通信とサーバーの処理です。
  • 「v1.9よりX%高速」という主張はありません。 アーキテクチャが大きく異なるため、単一の比較数値では有益な情報より誤解を招くおそれがあります。構造上の違いはv1.10.0での変更点で説明しています。
  • 上記のベンチマーク値は、エンジンのテスト環境(メモリ内ストレージ、分離されたランナー)で測定したものです。実際のデバイスや店舗によって結果は異なります。そのため、店舗の健全性 → パフォーマンスでは推定値ではなく、レジで測定された過去24時間のリクエスト数と一般的な応答時間を表示します。データ量は下限値です。サイズが宣言されていない応答は、データ量に0として計上されます。

サーバー側のチューニング(ホスティング要件、HPOS、キャッシュ、応答が遅い場合の診断)については、サーバーのパフォーマンスをご覧ください。