MODD SaaSの技術

MODD SaaS-CMSの技術

CMSテンプレートエンジン概要

MODD SaaS-CMSは MODD SaaS の基盤となるアプリケーション実行エンジンであり、ASP.NETインフラを拡張します。

一般的な EC エンジンと異なり、MODD SaaSではショッピングカートも CMS のテンプレートエンジン配下で実行されます。このため、ショッピングカート内での表示等もCMSのテンプレート修正により変更する事が可能です。

CMS内部には独自のテンプレートエンジンが実装されており、このテンプレートエンジンは積極的なキャッシュ処理を内在し参照系データバインディングを実行してCMS表示用データを高速にHTMLテキスト化します。キャッシュ処理は標準で全ての参照処理にデフォルトで有効にされており、キャッシュヒット時にはオンメモリデータをHTMLにまつわるエンコード出力するのと同等の処理となり、1サーバあたり数百リクエスト毎秒以上の性能を実現すると共にDBを負荷集中から切り離します。

技術的には CMS は ASP.NET のルーティングにより実行される HTTP ハンドラであり、ASP.NET MVCにおけるViewEngineを実装します。

テンプレートエンジンは独自のテンプレート言語によって記述されたテンプレートを完全なC#ソースコードに変換したうえで、オンメモリにてコンパイルした結果を呼び出す事でテンプレートに記述された処理を実行します。テンプレートのコンパイル結果等は同様にキャッシュされており、テンプレート記述内容に変更が無い限りにおいては繰り返し実行に利用されており、コード生成およびコードのコンパイルにまつわる負荷は初回表示時にしか発生しません。

テンプレートエンジンは汎用のテキスト整形エンジンでもあります。このため電子メールの整形等も同様のテンプレート言語で整形を行う事が出来ます。

積極的なキャッシュ処理

テンプレートには C#言語による LINQ 式によるデータ取得クエリと、それの表示出力を定義できます。

クエリからのデータ取得処理その物はテンプレート上での実行コードとして記述する必要が無い点で、テンプレート言語はデータ取得とそれのレンダリングについてのドメイン特化言語を構成しています。必要なキャッシュ処理は生成されるコードによって自動的に実行され、このコード生成時に必要なキャッシュ処理が全てのデータ取得部に自動的に埋め込まれ、取得したデータを可能な限りキャッシュし再利用します。

キャッシュの管理処理は実際は相当に複雑な処理です。一般的にキャッシュを適切に処理するデータの取得処理は以下の全てを満たす必要があります。

  1. クエリ定義からキャッシュのキーを構築します
  2. 全てのパラメータをキーに重畳し、パラメータによってキーがユニークになる様にします
  3. データ取得に行く前にキャッシュに項目が無い事を確認します。
  4. データの取得を行ったらキャッシュに項目が無い事を再度確認します。
  5. キャッシュをロックします
  6. ロックするまでの間にキャッシュに項目が追加されるケースを避ける為再度キャッシュに項目が無い事を確認します。(Double-checked locking
  7. キャッシュに項目を書き込みます

CMSでのコード生成では LINQ to SQL の為の最適化として CompiledQuery を利用する事や、データの現在バージョンを取得するためのクエリの変換処理等、キャッシュ処理にまつわる事以外の処理も実装される事になり、これらをテンプレートでのデータ取得の全てに適切かつ正しく実装してくれるという事になります。(CompiledQueryや、変換したクエリもキャッシュ対象としており、追加されるコードは足し算というよりもむしろ掛け算で発生する事になります)

これと同等な事をするのは一回のデータ取得だけでも困難な事で、全てのページで使われる全てのクエリに対して実現するのはコード生成を内部的に行っているから可能となる事です。

 

スパイク時におけるDB負荷低減作用

積極的なキャッシュ処理によって、DBが一度返したデータは基本的にWebサーバにキャッシュされます。

以下は CMS のWebサーバの一台についてのクエリについてのキャッシュ効果を示しています。(平常運用状態におけるWebサーバのパフォーマンスグラフとなります。)

1分40秒間の平均として毎秒65回のクエリをキャッシュ応答で返し、DBサーバへ実際にクエリを行ったのは秒間平均3回となっており、比率としては 20分の1になります。

スパイク時等、負荷集中時にはこのキャッシュからより多くのレスポンスが返される為に、DB負荷としては平常時と変わらなくなります。

Query Cache Hit Rate

Query Cache Miss Rate

商用に供されるWebサーバの基本性能としてキャッシュは非常に重要であり、それをトータルに実現する事で弊社Webサーバはサーバ1台で大手メーカーのショッピングサイトを複数収容する性能を持っております。またキャッシュは負荷集中時においてDBへのアクセスを効果的に軽減する効果が高く、複数のWebサーバがDB上で競合する状況も減らします。結果的にシステム全体としての負荷耐性が高くなると同時にスケールアウト特性も満たします。

2010年後半期におけるWebサーバの性能値と主に内在する問題

2010年後半という現在において、Webアプリケーションサーバ性能値(1台あたり)を見た場合の実装レベルは概ね以下の様になります。(Intel Core2 アーキテクチャCPU、Quadコアサーバの場合)

公表性能値 主要な実装方法と問題
2000 request/sec 以上 Webサーバ(IIS/Apache)等に直接コンテンツを収容しており、Webサーバは適切にチューニングされています。性能値としてはWebサーバその物の値と考えられます。CMSとして利用する場合、動的コンテンツを利用できなかったり、動的ページをサーバ間でのデータ同期等の運用負担が存在する事が多い構成です。
1000 request/sec~2000 request/sec Webサーバ(IIS/Apache)に直接コンテンツを配置している場合にはWebサーバが適切にチューニングされていない可能性が高いか仮想化等のメカニズムを介する事がオーバーヘッドとなっています。Webアプリケーションが動作している場合には一般的なチューニングは必要十分に行われています。
200 request/sec~1000 request/sec Webサーバ(IIS/Apache)固有の出力キャッシュ機構の利用ができていません。Webサーバに配置されたアプリケーションが何らかの処理介在をしている場合のパフォーマンスです。DBからのデータキャッシュ等は十分に行われている場合の値です。
200 request/sec~100 request/sec 基本的なDB接続処理等がリクエスト毎に実行されているなど、DB処理周りのチューニングができていない等、アプリケーション性能を意識された実装がされていない場合の性能値です
100 request/sec以下 システム全体として性能を出す事を意識して構築されていないと推測されます。低速な CGIメカニズムを利用している、DB接続のプーリング等の基本機能を利用できていない、複合的な問題が存在する場合の値となります。

弊社CMSは、ユーザーのログインセッションの確認や販売可能数等のDB参照を実施する部分においては 200~500 request/sec程度、コンテンツを単純応答できる最適ケースで1000 request/sec を超えた実績がございます。