2023-12-06
SplitPageプラグインは記事などの一覧ページを指定件数で分割するオプションプラグインです。
このプラグインを使うと件数の多いページを指定件数で分割するだけでなく、ページネーションを表示させることもできて便利ですが、件数が多くなると再構築の負荷が高くなります。日付アーカイブ(月別)などと比較して効率が悪いことに留意してください。
そこで、件数が多い場合、最新の一定の件数分を取得して、それを対象に分割したいケースに対応する方法について紹介します。例として、公開日順に最新100件を対象にページ分割するビューの書き方を考えてみます。
思いつくのはループタグに limit(lastn)を指定することですが、SplitPageプラグインは条件に合致するものすべてを対象に分割するため、この指定は効きません。
そこで、conditions属性を指定して101件目の公開日を取得し、その日付以降のものをフィルタリングします。
conditions属性には「カラム名=フィルタ条件,フィルタの値」という形式でハッシュ変数を生成して渡します。
フィルタ | 説明 |
---|---|
ct (like) | Contains (含む) |
nc | Not Contains (含まない) |
gt | Greater Than (より大きい) |
lt | Less Than (より小さい) |
ge | Greater than or Equal (以上) |
le | Less than or Equal (以下) |
eq | Equal (等しい) |
ne | Not Equal (等しくない) |
bw | Begin with (から始まる) |
ew | End with (で終わる) |
<mt:setvar name="last_update" value="2020-01-01 00:00:00" note="件数に満たなかった時の初期値">
<mt:entries cols="published_on" sort_by="published_on" sort_order="descend" offset="100" limit="1">
<mt:ignore>日付順で101番目に新しい記事の公開日を取得</mt:ignore>
<mt:entrydate setvar="last_update">
</mt:entries>
<mt:ignore>gt=より新しい</mt:ignore>
<mt:sethashvars name="conditions">
published_on=gt,<mt:var name="last_update">
</mt:sethashvars>
<mt:entries conditions="$conditions" _split="1" sort_by="published_on" sort_order="descend">
...
</mt:entries>
この方法では、101件目の記事と全く同じ公開日時の記事があった時に件数が合わない(件数が不足する)可能性があります(published_onではなくidを利用すればそのようなことはなくなります)。確実に100件を取得するには「gt」の代わりに「ge(以上)」を指定すると良いでしょう(逆に多くマッチする可能性があります。)。
<mt:setvar name="last_update" value="2020-01-01 00:00:00" note="件数に満たなかった時の初期値">
<mt:entries cols="published_on" sort_by="published_on" sort_order="descend" offset="99" limit="1">
<mt:ignore>日付順で100番目に新しい記事の公開日を取得</mt:ignore>
<mt:entrydate setvar="last_update">
</mt:entries>
<mt:ignore>ge=同じか、より新しい</mt:ignore>
<mt:sethashvars name="conditions">
published_on=ge,<mt:var name="last_update">
</mt:sethashvars>
<mt:entries conditions="$conditions" _split="1" sort_by="published_on" sort_order="descend">
...
</mt:entries>
カテゴリー:テンプレート作成Tips | プラグイン | 技術情報
投稿者:Junnama Noda
2023-12-05
規模の大きなウェブサイトやアプリケーションを構成する場合に冗長化構成を求められるケースがあります。
この記事では、AWSを利用した CMSサーバー*の冗長化構成のポイントについてまとめます。
※ 公開側については AWS S3に静的ファイルを配信して Amazon CloudFrontで配信するようなケースが多いと思いますが、説明が複雑化するため、この記事では CMSサーバーに焦点を絞ります。
ポイントは 3つです。
ドキュメントルート配下のコンテンツ以外に、以下のディレクトリを共有ディスクに設定します。lsyncdを使わずに共有ディスクにする理由は以下の通りです。
※ ただし、EFSをマウントしたとして、書き込みが遅い問題やタイムラグが出ることもあります。
/home/がマウントされたディスクだとして、アプリケーションディレクトリを以下に設定します。
/home/www/PowerCMSX
他、以下のディレクトリを共有ディスク配下に設定します。
config.json
"temp_dir": "/home/www/powercmsx-files/tmp",
"cache_dir": "/home/www/powercmsx-files/cache",
"support_dir": "/home/www/powercmsx-files/support",
"assets_c": "/home/www/powercmsx-files/assets_c",
"assets_c_path": "/assets_c/",
"tmpl_paths": [
"/home/www/powercmsx-files/user-customize-files/alt-tmpl"
],
"plugin_paths": [
"/home/www/powercmsx-files/user-customize-files/plugins"
],
"model_paths": [
"/home/www/powercmsx-files/user-customize-files/models"
],
"theme_paths": [
"/home/www/powercmsx-files/user-customize-files/themes"
],
"import_paths": [
"/home/www/powercmsx-files/user-customize-files/import"
],
"htmlimporter_settings_paths": [
"/home/www/powercmsx-files/user-customize-files/import_settings"
],
"log_dir": "/home/www/powercmsx-files/logs",
/home/www/powercmsx-files/user-customize-files/ というやたらと長いパスが指定されているのは、代替テンプレートやモデル定義ファイルなどは、PowerCMS Xではパスの長いものが優先されるためです。
/home/www/PowerCMSX/Plugins/VideoCaptions/alt-tmpl/include/edit/upload_file/column_extra_path.tmpl
/home/www/powercmsx-files/user-customize-files/alt-tmpl/include/edit/upload_file/column_extra_path.tmpl //こちらが優先される
/home/www/PowerCMSX/lib/PAML/models/entry.json
/home/www/powercmsx-files/user-customize-files/models/entry.json //こちらが優先される
あらゆるファイルの読み書きのシーンで EFSが遅いと感じるかもしれませんが、スケジュールタスクについては実行時の一時ディレクトリをローカルの速いディスクに変更できます。「SearchEstraier」や「DocumentSearch」で大量のコンテンツの検索インデックスを洗い替えする時など、ディスクの速度によって実行時間に大きな差が出ます。
config.json
"work_dir": "/var/www/tmp",
※ temp_dirを共有しなければならない理由は、例えばファイルアップロード後に「保存」ボタンをクリックしてオブジェクトを保存する時、違うインスタンスにリクエストが向いてしまうとファイルを保存できないなど、リクエストをまたがって利用されるファイルがあるからです。
PowerCMS Xではデータベースへのクエリのみならず、テンプレートのコンパイル結果など様々なデータをキャッシュすることで高速に動作するようになっています。
望ましいのは Amazon Elastic Cacheを利用することです。PowerCMS Xのキャッシュドライバは「Redis」「Memcacached」に対応しています。
避けるべきは EFS配下にキャッシュディレクトリがある場合にキャッシュドライバに「File」を指定することです。読み書きの遅さの影響を受けて遅くなるからです。
Amazon Elastic Cacheが利用できない場合、「MySQL」を指定してください。最新版では、「MySQL」キャッシュの性能が向上しています。
config.json
"cache_driver": "Redis",
あるいは
"cache_driver": "MySQL",
通常スケジュールタスク(worker.phpなどによって実行されるバッチ処理)は一台で実行するように考えていると思いますが、冗長化構成の時、各々のマシンで異なるタスクを処理するような設定が可能です。
*/10 * * * * apache cd /home/www/PowerCMSX/ && /usr/bin/php ./tools/worker.php --exclude_ids searchestraier_update_idx,scheduled_publish,scheduled_replacement,scheduled_unpublish
*/10 * * * * apache cd /home/www/PowerCMSX/ && /usr/bin/php ./tools/worker.php --exclude_ids searchestraier_update_idx --task_ids scheduled_publish,scheduled_replacement,scheduled_unpublish
0 3 * * * apache cd /home/www/PowerCMSX/ && /usr/bin/php ./tools/rebuildFiles.php archive --urlmapping_ids 1,2,45,46
0 3 * * * apache cd /home/www/PowerCMSX/ && /usr/bin/php ./tools/worker.php --task_ids searchestraier_update_idx
worker.php 実行時には temp_dir配下に「.pid」ファイル(e12d4d581bc48366a79acf9f5a8b0206.pidなどのハッシュ値)が生成され、次回実行時にファイルが存在する時は実行がスキップされます。
この「.pid」ファイルは worker.php に渡す引数によって異なるファイル名になるため、上記のように実行するタスクを分けて cronに設定することができます。
上から
となります。これを 2台に分散させます。
*/10 * * * * apache cd /home/www/PowerCMSX/ && /usr/bin/php ./tools/worker.php --exclude_ids searchestraier_update_idx,scheduled_publish,scheduled_replacement,scheduled_unpublish
0 3 * * * apache cd /home/www/PowerCMSX/ && /usr/bin/php ./tools/rebuildFiles.php archive --urlmapping_ids 1,2,45,46
*/10 * * * * apache cd /home/www/PowerCMSX/ && /usr/bin/php ./tools/worker.php --exclude_ids searchestraier_update_idx --task_ids scheduled_publish,scheduled_replacement,scheduled_unpublish
0 3 * * * apache cd /home/www/PowerCMSX/ && /usr/bin/php ./tools/worker.php --task_ids searchestraier_update_idx
2023-12-03
PowerCMS Xではアセット(ファイルアップロード)機能について、ステータス管理が標準で可能になっていて、下書き(非公開)、公開、日時指定公開、時限公開(日時指定で非公開)ができます。シビアに適時開示しなければならないIR情報や事前に漏洩しては困る新商品情報などを管理するために役立ちます。
しかしながら、実際のウェブサイトの運用においては、それだけでは事足りず、色々な要求が出てきます。その一つが「記事に添付したアセットの同時公開」ですが、PowerCMS Xにはそれを実現するためのいくつかの方法が提供されています。
バイナリカラムや添付ファイルは「オブジェクトとファイルが1対1」で関連付いていてオブジェクトが公開されれば同時に公開され、削除や非公開化されると非公開になります。
問題は「UploadUtilities」プラグインの「ステータス同期」機能なのですが、添付ファイルやバイナリカラムのファイルと違い、記事アセットやページアセットなど複数のオブジェクトと関連付けされていることから、単純に参照元のオブジェクトのステータスと連動させるわけにはいきません。
そこで、「すべての参照元オブジェクトのステータスが同じ場合のみ」アセットのステータスが同期する、がこれまでの仕様でした。
しかし、実際の運用では上手くいかないケースが多発します。
自分としてはこのタイミングで公開されると思っていたのに、他の未公開の記事にも関連付けされていた、というケースで、この問題が起こりえます。自分がアップロードした画像が他の記事に使われていた、など、気付かないことがあるからです。
そこで、(互換性を維持した上で)機能を変更できるようにしました。
考え方としては
というものです。後者は「一度公開されたものはインターネット上に公開されたものなのだから非公開にする意味はなかろう」という考え方によります。ただ、それはウェブサイトを運用する側のポリシーによりますから、以下のように機能追加しました。もちろん互換性を保った上で。
この時、オブジェクトが非公開にされたときは、参照元オブジェクトのステータスのうちのステータスの最大値になる(つまり、公開されているオブジェクトと関連付いているのなら非公開にはならない)ようにします。
もしくは、公開済みのアセットは非公開にならない「一度公開されたアセットは、参照元オブジェクトのステータス変更の影響を受けない」というものです。考え方によるのですが、「一度インターネット上に公開されたものは、非公開にしたところで意味はない」と考えれば、それはそれで合理的にも思えます。
設定の組み合わせによって、以下のようにできるようになりました。