#パフォーマンス

0 フォロワー · 50 投稿

パフォーマンスタグは、ソフトウェアのパフォーマンスの問題と、パフォーマンスの問題を解決および監視するためのベストプラクティスに関する投稿をグループ化します。

記事 Toshihiko Minamoto · 12月 22, 2020 13m read

HealthShare の理想的な Apache HTTPD Web サーバー構成に関するお問い合わせをよくいただいています。 この記事では、真っ先に推奨される HealthShare 製品の Web サーバー構成について概要を説明します。

何よりもまず第一に、Apache HTTPD バージョン 2.4.x(64ビット)を使用することをお勧めします。 2.2.x のような旧バージョンも使用できますが、HealthShare のパフォーマンスとスケーラビリティを確保するにはバージョン 2.2 はお勧めできません。

Apache の構成

NSD を使用しない Apache API モジュール {#ApacheWebServer-ApacheAPIModulewithoutNSD}

HealthShare では、NSD を使用しない Apache API モジュールをインストールオプションに指定する必要があります。 動的にリンクされるモジュールのバージョンは、Apache のバージョンによって異なります。

  • CSPa24.so(Apache バージョン 2.4.x)

Apache の httpd.conf での Caché Server Pages の構成は、このドキュメントで詳しく説明する HealthShare のインストールによって実行するのが最善です。 ただし、この設定は手動で実行することもできます。 詳細については、InterSystems のドキュメントに掲載されている Apache 構成ガイド「推奨オプション:NSD を使用しない Apache API モジュール(CSPa24.so)」を参照してください。

Apache マルチプロセッシングモジュール(MPM)の推奨事項 {#ApacheWebServer-ApacheMulti-ProcessingModuleRecommendations}

Apache Prefork MPM と Worker MPM {#ApacheWebServer-ApachePreforkMPMVs.WorkerMPM}

Apache HTTPD Web サーバーには、Prefork / Worker / Event の 3 つのマルチプロセッシングモジュール(MPM)が付属しています。 MPM はマシンのネットワークポートへのバインド、リクエストの受理、およびリクエストを処理するように子プロセスに割り当てたりする役割を担います。Apache はデフォルトで通常はトランザクションが多い場合や同時接続による負荷が高い場合には適切に拡張できない Prefork MPM で構成されています。

HealthShare の本番システムでは、Apache MPM Worker を有効にしてパフォーマンスとスケーラビリティを確保する必要があります。 Worker MPM が推奨される理由は次のとおりです。

  • Prefork MPM はそれぞれ 1 つのスレッドを持つ複数の子プロセスを使用し、各プロセスが一度に 1 つの接続を処理します。 Prefork を使用する場合は各プロセスが一度に 1 つのリクエストしか処理できないため、同時リクエストが発生した場合に支障が出ます。この場合、リクエストはサーバープロセスが解放されるまでキューに格納されます。 また、スケーリングするには大量のメモリを消費する Prefork の子プロセスがさらに必要になります。
  • Worker MPM は、それぞれ多数のスレッドを持つ複数の子プロセスを使用します。 各スレッドが一度に 1 つの接続を処理することで同時実行性が大幅に向上し、メモリ要件が低くなります。 Worker の場合はビジー状態の可能性があるシングルスレッドの Prefork プロセスとは異なり、通常はリクエストの処理に使用できる空きスレッドがあるため、Prefork よりも高度に同時リクエストを処理できます。

Apache Worker MPM のパラメーター {#ApacheWebServer-ApacheWorkerMPMParameters}

Worker はスレッドを使用してリクエストを処理するため、Prefork プロセスベースのサーバーよりも少ないシステムリソースで多数のリクエストを処理できます。
Worker MPM の制御に使用される最も重要なディレクティブは、各子プロセスが生成するスレッドの数を制御する ThreadsPerChild と起動可能なスレッドの最大数を制御する MaxRequestWorkers です。
推奨される Worker MPM 共通ディレクティブの値を以下の表に詳しく記載しています。

<th scope="col">
   <p style="margin-left: 40px;">推奨値</p>
</th>

<th scope="col">
   <p style="margin-left: 40px;">コメント</p>
</th>
<td>
 <p style="margin-left: 40px;"> HealthShare Clinical Viewer の最大同時接続ユーザー数、または他の HealthShare コンポーネントの場合は定義されているすべての本番インターフェースの着信ビジネスサービスのプールサイズの合計値に設定されます。</p><p><em>* <u>注意</u>: 構成時に不明であれば「1000」で開始してください</em></p>
</td>

<td>
  <p style="margin-left: 40px;">MaxRequestWorkers は同時に処理されるリクエストの数を制限します。つまり、クライアントにサービスを提供するために使用できるスレッドの総数を制限します。<br>MaxRequestWorkers は低すぎる値に設定するとリソースが無駄になり、高すぎる値に設定するとサーバーのパフォーマンスに影響が出るため、正しく設定しなければなりません。<br>Worker の数を超える接続があった場合、接続はキューに格納されてしまいます。 デフォルトのキューは、ListenBackLog ディレクティブで調整できます。  </p>
</td>
<td>
  <p style="margin-left: 40px;">250</p>
</td>

<td>
 <p style="margin-left: 40px;"> MaxSpareThreads はサーバー全体のアイドルなスレッドの数を制御します。 サーバー上にアイドルなスレッドが多すぎる場合、アイドルなスレッドの数がこの数より少なくなるまで子プロセスが強制終了されます。 スペアスレッドの量をデフォルトより多くすると、プロセスが再生成される確率が低くなります。</p>
</td>
<td>
  <p style="margin-left: 40px;">75</p>
</td>

<td>
 <p style="margin-left: 40px;"> MinSpareThreads はサーバー全体のアイドルなスレッドの数を制御します。 サーバー上にアイドルなスレッドが不足している場合、アイドルなスレッドの数がこの数より多くなるまで子プロセスが生成されます。 スペアスレッドの量をデフォルトより少なくすると、プロセスが再生成される確率が低くなります。  </p>
</td>
<td>
 <p style="margin-left: 40px;"> MaxRequestWorkers を ThreadsPerChild で割った値</p>
</td>

<td>
  <p style="margin-left: 40px;">サーバー稼働中における MaxRequestWorkers の最大値です。 ServerLimit はアクティブな子プロセス数の厳密な上限値であり、MaxRequestWorkers ディレクティブを ThreadsPerChild ディレクティブで割った値以上である必要があります。 worker では MaxRequestWorkers および ThreadsPerChild の設定で 16(デフォルト)以上のサーバープロセスが必要な場合にのみ、このディレクティブを使用してください。  </p>
</td>
<td>
  <p style="margin-left: 40px;">20</p>
</td>

<td>
  <p style="margin-left: 40px;">StartServers ディレクティブは起動時に生成される子サーバープロセスの数を設定します。 プロセス数は負荷に応じて動的に制御されるため、サーバーが起動時に大量の接続を処理できるようにする場合を除き、通常はこのパラメーターを調整する理由はほとんどありません。  </p>
</td>
<td>
 <p style="margin-left: 40px;">25</p>
</td>

<td>
  <p style="margin-left: 40px;">このディレクティブは各子プロセスが生成するスレッドの数を設定します。デフォルトでは 25 です。 デフォルト値を増やすと単一のプロセスに過度に依存する可能性があるため、デフォルト値を維持することをお勧めします。</p>
</td>
推奨される Apache HTTPD Web サーバーのパラメーター
Apache Worker MPM のディレクティブ
MaxRequestWorkers 
MaxSpareThreads
MinSpareThreads
ServerLimit
StartServers
ThreadsPerChild

詳細については、関連する Apache バージョンのドキュメントを参照してください。

Apache 2.4 の Worker MPM 構成の例 {#ApacheWebServer-ExampleApache2.4WorkerMPMConfiguration}

このセクションでは、最大 500 人の TrakCare ユーザーが同時接続できるようにするために必要な RHEL7 の Apache 2.4 Web サーバー用に Worker MPM の構成について詳しく説明します。

  1. まず、以下のコマンドを使用して MPM を確認します。
  2. 必要に応じて、構成ファイル /etc/httpd/conf.modules.d/00-mpm.conf を編集します。コメント文字 # の追加や削除を行い、Worker MPM モジュールのみがロードされるようにしてください。 Worker MPM セクションを、以下と同じ順序で次の値に変更します。
  3. Apache を再起動します。
  4. Apache が正常に再起動したら、以下のコマンドを実行して worker プロセスを検証します。 次のような内容が表示され、httpd.worker プロセスを確認できます。

Apache の強化 {#ApacheWebServer-ApacheHardening}

Apache に必要なモジュール {#ApacheWebServer-ApacheRequiredModules}

公式の Apache 配布パッケージをインストールすると、デフォルトで特定の Apache モジュールセットが有効になります。 Apache のこのデフォルト構成では、これらのモジュールが各 httpd プロセスにロードされます。 次の理由により、HealthShare に必要のないすべてのモジュールを無効にすることをお勧めします。

  • httpd デーモンプロセスのメモリ使用量が削減されます。
  • 不正なモジュールに起因するセグメンテーション違反の可能性が低下します。
  • セキュリティの脆弱性が削減されます。

HealthShare に推奨される Apache モジュールの詳細を以下の表に記載しています。 以下に掲載されていないモジュールは無効にすることができます。

モジュール名説明
aliasホストファイルシステム内のさまざまな場所をドキュメントツリーにマッピングする機能と、URL リダイレクト機能を提供します。
authz_hostクライアントのホスト名、IPアドレスに基づいてアクセス制御を行います。
dir末尾のスラッシュを補完してリダイレクトする機能と、ディレクトリのインデックスファイルを扱う機能を提供します。
headersHTTP リクエストとレスポンスヘッダーを制御および変更するためのモジュールです。
log_configサーバーに対して発行されるリクエストのログを記録します。
mimeリクエストされたファイル名の拡張子をファイルの振る舞いと内容に関連付けます。
negotiationクライアントの特性に応じて最適なドキュメントの内容を選択する機能を提供します。
setenvifリクエストの特徴に基づいて環境変数を設定できるようにします。
statusサーバーのステータスとパフォーマンスに関する統計を表示します。

モジュールを無効にする

セキュリティの脆弱性を減らすように構成を強化するには、不要なモジュールを無効にする必要があります。 Web サーバーのセキュリティポリシーを管理するのはお客様の役割です。 少なくとも、以下のモジュールを無効にする必要があります。

モジュール名説明
asis独自の HTTP ヘッダーを含むファイルを送信する機能を提供します。
autoindexindex.html ファイルが存在しない場合にディレクトリインデックスを生成し、ディレクトリをリスト表示する機能を提供します。
envCGI スクリプトと SSI ページに渡される環境変数を変更する機能を提供します。
cgicgi - CGI スクリプトを実行する機能を提供します。
actionsメディアタイプまたはリクエストメソッドに基づいて CGI スクリプトを実行し、リクエストに応じてアクションをトリガーする機能を提供します。
includeサーバーで解析された HTML ドキュメント(サーバーサイドインクルード)を使用可能にするモジュールです。
filterリクエストの高度なフィルタリング機能を提供します。
versionIfVersion を使用して構成ファイル内でバージョン情報を処理できるようにします。
userdirリクエストをユーザー専用のディレクトリにマッピングする機能を提供します。 具体的には、URL の ~username がサーバー内のディレクトリに変換されます。

Apache SSL/TLS {#ApacheWebServer-ApacheSSLTLS}

転送中のデータを保護し、機密性を確保して認証を行うため、InterSystems は HealthShare サーバーとクライアント間のすべての TCP/IP 通信を SSL/TLS で暗号化し、さらにはユーザーのブラウザクライアントと提案されたアーキテクチャの Web サーバーレイヤー間のすべての通信に HTTPS を使用することを推奨しています。 所属する組織に固有のセキュリティ要件に準拠していることを確認するには、必ず所属する組織のセキュリティポリシーを参照してください。

SSL/TLS 証明書を提供および管理するのはお客様の役割です。
SSL 証明書を使用している場合は、ssl_module(mod_ssl.so)を追加してください。

追加の Apache 強化パラメーター {#ApacheWebServer-AdditionalHardeningApacheParameters}

Apache 構成をさらに強化するには、httpd.conf で次の変更を行ってください。

  • 潜在的なクロスサイトトレーシングの問題を防ぐため、TraceEnable をオフにする必要があります。

  • Web サーバーのバージョンが表示されないようにするため、ServerSignature をオフにする必要があります。

補足的な Apache 構成パラメーター {#ApacheWebServer-SupplementalApacheConfigurationParameters}

Keep-Alive {#ApacheWebServer-Keep-Alive}

Apache の Keep-Alive 設定は、新しいリクエストのたびに新しい接続をオープンせず、同じ TCP 接続を使用して HTTP 通信を行えるようにするものです。 Keep-Alive はクライアントとサーバー間に持続的な接続を維持します。 Keep-Alive オプションを有効にすると、ネットワークの輻輳が軽減され、後続リクエストの遅延が少なくなり、同時接続のオープンに起因する CPU 消費が低下し、パフォーマンスが向上します。 Keep-Alive はデフォルトでオンになっており、HTTP v1.1 標準では当然オンにすることが求められています。

ただし、Keep-Alive を有効にする場合は注意が必要です。Internet Explorer は古いバージョンでの既知のタイムアウトの問題を回避するため、 IE10 以降でなければなりません。 また、ファイアウォール、ロードバランサー、プロキシなどの仲介者が「持続的なTCP接続」に干渉し、予期せず接続が閉じられてしまう可能性もあります。 

Keep-Alive を有効にする場合は、Keep-Alive のタイムアウト値も設定する必要があります。 Apache デフォルトの Keep-Alive タイムアウト値は非常に小さく、壊れた AJAX(hyperevent などの)リクエストに関連して問題が発生する可能性があるため、ほとんどの構成では大きくする必要があります。 これらの問題は、サーバーの Keep-Alive タイムアウト値がクライアントのタイムアウト値よりも大きくなるように調整することで回避できます。 つまり、サーバーではなくクライアントがタイムアウトして接続を閉じるようにすべきです。 ブラウザが当然オープンしていると考えている接続を(特に POST する場合に)使用しようとすると、問題が発生します(ほとんどの場合は IE で発生し、他のブラウザではそれほど発生しません)。

HealthShare Web サーバーに推奨される KeepAlive と KeepAliveTimeout の値については、以下を参照してください。

Apache で KeepAlive を有効にするには、httpd.conf で以下のように変更を行ってください。

CSP Gateway {#ApacheWebServer-CSPGateway}

CSP Gateway の KeepAlive パラメーターについては、各リクエストの HTTP レスポンスヘッダーによって KeepAlive のステータスが決まるため、この値はデフォルトの「No Action」のままにしてください。

0
0 1280
記事 Megumi Kakechi · 12月 17, 2020 1m read

これはInterSystems FAQ サイトの記事です。

選択性(または Selectivity)の数値とは、カラムに対するユニークデータの割合を示す数値です。

例) Person テーブルの個別値である PID カラム、住所のうち都道府県名が入る Pref カラム
 Pref カラムの選択性 = 約 2%
 PID カラム(ユニーク属性のカラム)の選択性 = 1

InterSystems製品のクエリオプティマイザは、クエリ実行経路(プラン)とインデックスの選択を決定するため、エクステントサイズ(テーブル内のレコード数)と選択性の数値を使用します。

詳細は下記ドキュメントページをご参照ください。

テーブルの最適化【IRIS】

テーブルの最適化

なお、選択性の数値は、テーブル単位に計算するまで設定されていません。

計算方法については関連トピックをご参照ください。

【関連情報】(コミュニティ/FAQトピックをリンクしています)

0
0 386
記事 Minoru Horita · 12月 14, 2020 14m read

優れた執筆者は、題名で読者を引き込み、答えを記事のどこかに隠すべきだと考えられています。  だとすると、私は出来の悪い執筆者ということになってしまいます。私の自尊心は見知らぬインターネットユーザーの皆さんのご意見にかかっていますので、お手柔らかにお願いします。

私の同僚 Brendan が Developer Community に記載されている情報をレビューしていたとき、Tune Table について書き忘れがあったことに気が付いたのです!  これはクエリパフォーマンスにおいて 2番目に重要なツール (1 番はインデックス、インデックスがないと処理が遅い) なので、時間をかけて理解しておく価値があります。  今回使用する例の多くは完全なものではありませんが、詳細は簡単に入力できます。 すべての例において、特に明記が無い限り、フィールドはすべて個別にインデックスが作成されているものと想定してください。

それでは、以下のクエリがあるとしましょう。
SELECT *
FROM   People
WHERE  Home_State = 'MA'
       AND PersonId = '123-45-6789' 

どのインデックスを使うべきでしょうか?  冗談なしで、一旦読むのをやめて、答えを聞かせてください。  大声で答えてください。  同僚の皆さんに変な人だなんて思われませんよ、大丈夫です。
正解は、もちろん、PersonId のインデックスです。  なぜこれが正解なのか?  各 State (州) には何百万もの人々が生活している可能性がある中で、PersonId はほぼ一意の数値 (的な) 識別子であることが分かります。  ここで理解する必要があるのは、この答えが分かるのは、列の識別子を見るとスキーマに関する情報がある程度は分かるためである、という点です。  コンピューターにとって、これらの名前は何の意味もなしません。  この点を分かりやすく説明するために、こちらのクエリを見てみましょう。
SELECT *
FROM   TheTable
WHERE  Field1 = 32
       AND Field2 = 0 

使うのはインデックスは Field1?それとも Field2?  上のクエリは、クエリオプティマイザによって最適化されるようなクエリです。  この場合はどのようにインデックスを選べばいいのでしょう?  適切な決断をするにはデータについて知る必要があります。  これを解決するのが Tune Table です。 

Tune Table は、テーブル内のデータサンプルを調べ、テーブルに関する統計を保管することで、クエリオプティマイザが適切な決断をできるようにします。  今まで Tune Table を実行したことが無い場合は、クエリがランダムでも効果的にインデックスを選択しているということです (厳密には違いますが、ほぼそういうことです)。  実際、クエリが遅いことについてサポートに電話されることがあれば、まず最初に「Tune Table は実行されましたか?」と聞かれると思います。  ‘はい’ と言えるようにしておいてください。 

Tune Table の実行方法
Tune Table を実行するには、ターミナルに移動して、次を実行します。
d $SYSTEM.SQL.TuneTable(<Table>)
これに渡せるフラグは沢山ありますが、私のおすすめはこちらです。

d $SYSTEM.SQL.TuneTable(<Table> ,1,1,.msg,1)


 

これらのフラグにより、クラス定義が更新され、新しい値が表示されるほか、最後のフラグによりクラスが最新の状態に維持されます。  クエリが Tune Table の新しい情報を利用できるようにするには、すべての埋め込みクエリをコンパイルし、キャッシュされているクエリを消去する必要があります。  フラグに関する詳細は、こちらをお読みください。
https://docs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&LIBRARY=%25SYS&CLASSNAME=%25SYSTEM.SQL#METHOD_TuneTable

Tune Table の機能
Tune Table の実行ステップを紹介します。  まず最初に、SELECT COUNT(*) を実行してテーブル内の行数を計算します。  その行数を基に、サンプルとして使用する行数を決定します (漸近的には行数の平方根に似ています)。  そして、テーブルで定義されている各 ID に対し、加重サンプルを適切に判断した上で、その行をサンプルに含めるかどうかを決定します。  このサンプルを使って統計を算出し、それを使ってクエリを最適化します。

ここには重要なポイントが 2 つあります。  1 つ目はカウントを得る必要があること。  2 つ目は、テーブル内の各 ID を取得できる必要があることです。  この結果、エクステントインデックスがあることにより、Tune Table の実行が大幅に改善されるのです。  テーブルがビットマップに対応している (つまり正の整数 IDKEY がある) 場合は、ビットマップのインデックスがあれば、自動的にビットマップのエクステントを得ることができます。 


Tune Table はどのような指標を測定するのか?  年代順に古い方から説明していきます。

2 つの OG (旧世代の指標)

次に紹介する 2 つの指標は Tune Table の最も古い指標です。  どれだけ古いと思いますか?  私が高校に入学する前 (1999年) に追加されたものです。  Y2K 以前の Caché を実行している方がおられましたら、私までメールをください。是非、お話しさせていただきたいです。
Extent Size は、テーブル内の行数を測定します。 

これは一番理解しやすい指標で、JOIN を実行する順序を決定するのに便利です。  では、下のクエリがあるとしましょう。
SELECT *
FROM   Table1 T1
       JOIN Table2 T2
         ON T1.Field1 = T2.Field1 

T1 を読み取ってから、T2 のフィールドで JOIN を実行するべきか、またはその逆にするべきか? Extent Size は、行の数が少ない方のテーブルを示すので、どちらのテーブルから始めるべきなのかが分かります。  極端なケースとして、T1 には 100 億行あり、T2 には 100 行しかないと仮定します (T1 はこれまで病院に行った回数の合計を示すテーブルで、T2 は現在病院にいる患者の数を示すテーブルだと考えてください)。 この場合は、小さい方のテーブルから始め、大きな方で JOIN を実行すると良いでしょう。それは、JOIN を実行すると、読み取る必要のある行の数が制限されるためです。 

Selectivity は、指定されたフィールドの値の一意性を測定します。
この指標を理解するにはもう少し説明が必要です。  考え方は 2 種類あります。

  1. 1/x。x はフィールドに設定され得る値の数。
  2. クエリ SELECT * FROM T WHERE field=? の実行結果として返されるテーブルの平均パーセンテージ

いずれの説明もこれだけでは分かりにくいので、いくつか例を挙げてはっきりさせたいと思います。 

先ほどのクエリに、Home_State というフィールドがありました。  (アメリカの場合だと) そのフィールドの Selectivity は 2.0% になります。  なぜかと言いますと、 アメリカには 50 の州があるため、1/50 = .02 = 2% という計算になります。  これは簡単ですね。  しかし、分布はどうなのか?  明らかに、複数の州で人口が均等に分布しているはずがありません!  それは事実なのですが、Selectivity はそれを考慮しません。 均等な分布は、ほとんどのクエリにおいて適切な予測とされる上に、計算も簡単になるため、クエリはよりスピーディにコンパイルします。
 

もう 1 つの例として、PersonId について考えます。  人は亡くなったり、新しく生まれたりするので、 PersonId はたまに再利用する必要があるかもしれません。なので、その数字は完全に一意という訳でははありません。  しかし、一意であることに変わりはありません。  そのため、.00001% の Selectivity が見られる場合があるかもしれません。  それは非常に適切な Selectivity と言えます!  クエリ SELECT * FROM People WHERE PersonId = ? は、 実行される度に 1 つまたは 2 つの行を返します。  一般的に、Selectivity は低いほど良いとされています。  しかし、これには例外があります…

一意のフィールドがあるとしたらどうでしょう。ID はいい例ですね。  一意のフィールドの Selectivity は 1 です。  ちなみに、これまで述べた Selectivity はすべてパーセンテージです。  1 はパーセンテージではなく、行数です。  したがい、クエリ SELECT * FROM People WHERE ID = ? は、 いつも 1 行を返します。 

1 つのフィールドについて沢山の情報をカバーしましたが、おそらく一番重要な情報であると言えるでしょう。  原則として、パーセンテージは低い方が良く、1 が最適な値です。 

「昔から」存在していた指標

次に紹介する統計は、いつも予測されてはいたものの、バージョン 2013.1 までは明示的に測定されていませんでした。
Block Count – 各マップ (インデックスとマスターマップ) がディスク上で占めるブロックの数を測定します。 

Block Count は長年に渡って予測してきましたが、2013 年になって初めて明示的に測定する決断をしました。  Extent Size があるので不必要に思えるかもしれませんが、他にも実用性があります。  こちらのクエリ
SELECT COUNT(*) FROM MyTable
を説明すると理解に役立つでしょう。
各フィールドにインデックスが付いているとしたら、どれを読み取ればいいでしょうか?  読み取りたいのは、ディスク上で占めるスペースが一番少ないフィールドです。  この指標はその情報を明示的に示してくれます。  より複雑な状況でインデックスのかたまりを読み取る際のコストを予測するときにも表示されます。  通常、これはマップの幅を測定するのに優れている一方で、Extent Size はその長さを測定するのに優れています。

Block Count は、親 / 子関係を使用する場合にも便利です。  この場合は、(デフォルトで) 両方のテーブルが同じグローバル変数に格納されます。しかし、Block Count がなければ、クエリオプティマイザは、潜在的に小さな親テーブルで読み取られたマップには膨大な数の子が含まれているために、実はとても大きなマップである可能性があるということを全く知ることができません。 実に、これは私たちが新規開発において親 / 子関係の使用を一切おすすめしていない理由の 1 つです (どうしてもという場合は、サポートにお電話の上、ご相談ください!)。
 

Brendan からのメモ / トリビア: Extent Size、Selectivity、Block Count は FDBMS が使われていた時代、すなわち 1992 年には既に存在していたのですが、当時は手動で設定する必要がありました。


すべてを一変させた指標

バージョン 2014.1 では、フィールドの 1 つの値が過剰に大きな割合を占めていないかどうかを判断するための指標を追加しました。  これにより、Selectivity を計算する方法が大幅に変わりました。

Outlier Selectivity (外れ値の選択性) -  テーブル内で過剰な割合を占めるフィールドの選択性。

外れ値を伴う状況を理解するために、病院について考えてみましょう。  病院は一般的に地域のコミュニティにサービスを提供するものです。  Home_State フィールドは、そのほとんどの値が病院のある州で同じになります。  では、MA (マサチューセッツ州) の病院について考えます (私が住んでいる州なので)。  私の地元の病院は、患者の 90% が MA の人たちです。それ以外は他の州から来た人たちや州を訪れている人たちです。  Home_State=’MA’ を検索することは選択的でない一方で、それ以外の Home_State を検索することは選択的である、ということを示す必要があります。  これを実現するのが Outlier Selectivity です。 
例えば、上述した Home_State フィールドだと、Tune Table はその Selectivity を0.04% として算出し、Outlier Selectivity を 90%、Outlier 値 (外れ値) を ‘MA’ として示します。  通常、Selectivity は低下します。  Selectivity の計算方法が変わり、人々をビックリさせたクエリプランもいくつか考案されたこともあり、これは大きな変化であったと言えます。  バージョン 2014.1 全体を更新する予定の方は、この点に注意してください。

最後の指標

この最後の指標は、一時ファイルのサイズをより正確に予測することを目的に、バージョン 2015.2 で追加したものです。
Average Field Size – フィールドの平均サイズ。

これも簡単に理解できる指標です。  サンプルを取る間に、テーブル内の各フィールドの平均サイズを計算してくれます。 これは一時ファイルのサイズを判断するのに便利です。また、これにより、オプティマイザは一時ファイルをメモリ内で構築できるのか (ローカル配列)、またはディスクベースの構造 (プライベートグローバルを処理する) が必要なのかを判断できます。

実用的な検討事項

次に考えるのが「どれくらいの頻度で実行する必要があるのか?」という疑問です。  これといった答えはないのですが、 少なくとも (絶対に!!!) 一度は実行してください。でなければ、自分で値を用意しなくてはいけなくなります。  その後は、もう二度と実行しなくてもよいかもしれません。  現在のパフォーマンスに満足なら、実行する理由はありません、というのが一般的な答えでしょう。  実に、データベースの成熟度が高く、テーブル内のデータも安定したペースで成長しているのなら、今後もおそらく適切な値が得られるでしょう。 

もし、テーブルの変化と共に SQL のパフォーマンスが劣化することがあれば、Tune Table を再度実行することをおすすめします。  また、新しいデータが多く、テーブルが大幅に変化している場合は、Tune Table を実行したほうが無難かもしれません。  しかし、これは「すべてのクエリが遅い」という状況にあれば予測できることです。  この状況に陥っている方は、WRC までお問い合わせください。システム設定を確認させていただきます。

Tune Table を実行する場合は、調整するテーブルに関連しているすべてのテーブルに対して実行してください。 そうしないと、テーブル間で Extent Sizes と Block Counts を比較てきなくなります (これによりクエリのパフォーマンスが低下します)。
2016.2 よりも新しいバージョンをご利用の方は、Tune Table を実行する前にクエリプランをフリーズできる Frozen Query Plans をご利用いただけます。  このプラクティスは、Tune Table を実行したときに、新しいプランが役に立つと判断した場合にそれだけを利用できるという機能があるため、強くお奨めしています (%NOFPLAN を使ってクエリをテストすれば、新しいプランが役に立つのかどうかを確認できます)。 

Frozen Query Plans についてはもう 1 つ大切なことがあり、このテクノロジーを使えば、Tune Table を実行するときに、システム上で既に実行したクエリをもう一度実行してしまうことを避けられます。  これは、現在のパフォーマンスに影響を与えることを心配せずに、Tune Table を実行するための手段です!  もう言い訳はできません! Frozen Query Plans の詳細に興味がある方は、私が以前行ったウェビナーをご覧ください:
https://learning.intersystems.com/course/view.php?id=969

最後になりましたが、クエリパフォーマンスについては、Tune Table の統計を把握しておくことが大切です。  Tune Table は、クエリオプティマイザが適切な判断をするのに必要な情報を与えてくれます。  既にテーブルにインデックスを追加されている方は、次のステップとして Tune Table を実行すれば、クエリを超高速化できること間違いなしです。

今回の記事で使用しました SQL フォーマッタ (http://dpriver.com/pp/sqlformat.htm) を私に紹介してくれた Aaron Bentley に感謝の意を送りたいと思います。
 

また、私の記事を実際に理解できる内容に編集してくれる Brendan Bannon にも感謝いたします。

0
0 312
記事 Mihoko Iijima · 12月 3, 2020 3m read

これまでさまざまなストレージ技術とそのパフォーマンス特性の例を紹介してきましたが、今回は新しい HPE Cloudline 3150 Gen10(AMD プロセッサベースのシングルソケットサーバーで 3.2TB の Samsung PM1725a NVMe ドライブを 2 台搭載)など、内部コモディティベースのサーバーストレージの活用が増加傾向にあることを確認しました。  

ハードウェア構成と LinuxLVM のセットアップ

テストは次の構成で行われました。

  • 2 x Samsung 3.2TB PM1725a NVMe ドライブ(サーバー内蔵)
  • 1 x HPE Cloudline 3150 Gen10 サーバー
  • Red Hat Enterprise Linux 7.5 64 ビット版

このテストでは、その他のストレージデバイスや HBA は使用していません。両方の NVMe ディスク装置の IO 能力を最大化するため、16MB の PE サイズを使用して単一の LVM PE ストライプを作成しました。 LVM PE ストライピングのセットアップの詳細は、コミュニティ内の別の記事にあります。

InterSystems IRIS のインストールとセットアップ

InterSystems IRIS は、単一のボリュームグループと単一の論理ボリュームにインストールされます。 今回は複数のボリュームグループと論理ボリュームを使わず、非常に単純なセットアップを行いたいと思いました。 この例では、単一の論理ボリュームとファイルシステムを作成しました(この例では、/data がファイルシステムのマウントポイントになっています)。データベースインスタンスからのランダム読み取りのワークロードを使用し、徐々にジョブ数が増加する IO ワークロードを生成しています。 1 TBのデータベースが IO ワークロードのターゲットです。 このテストで使用された RANREAD ツールの詳細は、こちらを参照してください。

テスト結果

わずか 10 個のジョブから開始した最初の時点では、ストレージのスループットは 100 マイクロ秒(µs)と非常に低い遅延で 1 秒間に 10 万個の 8 KB データベースブロックを読み取ることができました。 ジョブの数が増えても、サーバーが実際に CPU の能力を使い果たしてストレージをさらに激しく駆動させるまでは遅延はずっと低いままでした。 観察された中で最も大きな遅延は 300µs に過ぎず、1秒間に 850 K 以上の 8KB データベースブロックの読み取りを維持していました。  

図 1 は 2 台の Samsung NVMe ディスク装置のみを使用してテストした構成で、パフォーマンスが予測可能でスループットが維持されたことを示しています。 最大値でも遅延は非常に低く、実際には NVMe ディスク装置のスループットが最大化する前にテストサーバーが実際に CPU を使い果たしたことが分かります。

図 1: 予測可能で非常に低い遅延と非常に高いスループットを維持

まとめ

Samsung PM1725a NVMe ディスク装置は非常に低い遅延と高スループット能力を示し、非常に高性能なトランザクションシステムをサポートしています。 そのため、ストレージの待機時間とスループットが必要なインジェッション・ワークロードに最適です。 これらの Samsung NVMe ディスク装置はこのような素晴らしいパフォーマンス特性を備えながら非常に魅力的な価格で提供されており、InterSystems のデータベースミラーリングと組み合わせると同じレベルのアプリケーションの可用性を実現できます。

0
0 301
記事 Toshihiko Minamoto · 10月 19, 2020 5m read

SQL パフォーマンスリソース

SQL のパフォーマンスについて語るとき、最も重要なトピックとして取り上げられるのが「Indices」、「TuneTable」、「Show Plan」の 3 つです。  添付の PDF にはこれらのトピックに関する過去のプレゼン資料が含まれていますので、それぞれの基礎を一度に確認していただけます。  当社のドキュメンテーションでは、これらのトピックの詳細に加え、SQL パフォーマンスの他のトピックについてもカバーしておりますので、下のリンクからお読みください。  eラーニングをご利用いただくと、これらのトピックをもっと深く理解していただけます。  また、開発者コミュニティによる記事の中にも SQL パフォーマンスについて書かれたものが複数ありますので、関連するリンクを下に記載しております。

下に記載する情報には同じ内容が多く含まれています。  SQL パフォーマンスにおける最も重要な要素を以下に紹介します。

  • 利用可能なインデックスの種類
  • あるインデックスの種類を他の種類の代わりに使用する
  • TuneTable がテーブルに集める情報とそれが Optimizer に対して意味する内容
  • Show Plan を読んでクエリの善し悪しを深く理解する方法
  • 以下は InterSystems IRIS SQL のパフォーマンスを詳しく理解するのに役立つリソースです

  • Worldwide Response Center (WRC)。電話番号: 617-621-0700
    WRC をご利用ください。  同センターはユーザーが理解しやすいレベルで SQL パフォーマンスを説明してくれます。  優秀な SQL サポートスタッフが数人おりますが、アドバイザーと直接お話しをされる場合は、お気軽にサポートマネージャーの Brendan Bannon までお問い合わせください。

    [訳注:日本ではカスタマサポートセンター(jpnsup@intersystems.com)にお問い合わせください。]

     
  • InterSystems オンラインドキュメンテーション
    1. 機能紹介:  InterSystems SQL:  https://docs.intersystems.com/irislatestj/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_sqlbasics
    2. 機能紹介: InterSystems 製品での SQL パフォーマンスの最適化:  https://docs.intersystems.com/irislatestj/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_sqlqueryopt
    3. InterSystems SQL 最適化ガイド:  https://docs.intersystems.com/irislatestj/csp/docbook/DocBook.UI.Page.cls?KEY=GSQLOPT
       
  • InterSystems の eラーニング
    1. リソースガイド - Caché SQL を解説: パフォーマンス: https://learning.intersystems.com/enrol/index.php?id=255
    2. リソースガイド – Caché SQL を解説: デザインと実行: https://learning.intersystems.com/enrol/index.php?id=256
    3. SQL クエリの最適化:  https://learning.intersystems.com/course/view.php?id=707
    4. アカデミー:  SQL パフォーマンスの最適化:  https://learning.intersystems.com/course/view.php?id=80
    5. SQL クエリの最適化:  https://learning.intersystems.com/course/view.php?id=1013
       
  • Intersystems 開発者コミュニティ
    1. 知っておくと便利なクエリパフォーマンスのコツとは? ずばり Tune Table です! https://community.intersystems.com/post/one-query-performance-trick-you-need-know-tune-table
    2. InterSystems IRIS が提供する水平拡張性:  https://jp.community.intersystems.com/post/intersystems-irisによる水平スケーラビリティ
    3. 外れ値の選択性とは:  https://community.intersystems.com/post/introduction-outlier-selectivity
    4. 日付範囲クエリの SQL パフォーマンスを改善する:  https://jp.community.intersystems.com/post/日付範囲クエリのsqlパフォーマンスを改善する
    5. 日付範囲クエリの SQL パフォーマンスを改善する (vol2):  https://jp.community.intersystems.com/post/日付範囲クエリのsqlパフォーマンスを改善する-vol2
    6. Caché でカスタムインデックスタイプを作成する方法:  https://jp.community.intersystems.com/post/cachéでのカスタムインデックスタイプの作成
    7. グローバルはデータを保存するための魔法の剣です パート1:  https://jp.community.intersystems.com/post/グローバルはデータを保存するための魔法の剣です- パート1
    8. グローバルはデータを保存するための魔法の剣ですパート2 - ツリー:  https://jp.community.intersystems.com/post/グローバルはデータを保存するための魔法の剣ですパート2-ツリー
    9. Globals – グローバルはデータを保存するための魔法の剣です パート3 - 疎な配列 :  https://jp.community.intersystems.com/post/グローバルはデータを保存するための魔法の剣です-パート3-疎な配列
    10. フリーテキスト検索:SQL開発者が秘密にしているテキストフィールドの検索方法*: 
      https://jp.community.intersystems.com/post/フリーテキスト検索:sql開発者が秘密にしているテキストフィールドの検索方法
    11. ノンアトミック属性のインデックス作成:  https://community.intersystems.com/post/indexing-non-atomic-attributes
    12. 配列プロパティ要素の SQL インデックス:  https://community.intersystems.com/post/sql-index-array-property-elements
       
  • 過去の PowerPoint 資料
  • 付属のプレゼン資料は古いですが、充実した内容になっています。  情報の多くは Intersystems IRIS に該当するものですが、念のために最新のドキュメンテーションをご確認ください。  以下のすべてを PDF ファイルとして本記事に添付しています。

    1. インデックス作成とは
    2. SQL パフォーマンスの最適化 (2015 年版)
    3. %PARALLEL Query のヒント (2016 年版)
    4. Frozen Plans と Parallel Queries (2017 年版)
    5. 生成された COS に対する Show Plan (2013 年版)
    6. SQL プログラミング (2006 年版)
  • (本記事の著作者は Brendan Bannan、編集アシスタントは Cliff Mason と Kyle Baxter です) 

    0
    0 232
    記事 Megumi Kakechi · 9月 27, 2020 2m read

    これはInterSystems FAQ サイトの記事です。
    コンソールログ(message.log/cconsole.log)に、以下のようなログが出力される場合があります。

    MM/DD/YY-hh:mm:ss:sss (pid) 2 CP: Pausing users because the Write Daemon has not shown
       signs of activity for xxx seconds. Users will resume if Write Daemon completes a
       pass or writes to disk (wdpass=yyyy).


    このメッセージは、コントロールプロセスが出力しています。
    このプロセスは、ライトデーモン(WriteDaemon)等の主要なシステムプロセスを監視しています。

    0
    0 420
    記事 Tomoko Furuzono · 9月 17, 2020 17m read

    Caché 2017以降のSQLエンジンには新しい統計一式が含まれています。 これらの統計は、クエリの実行回数とその実行所要時間を記録します。

    これは、多くのSQLステートメントを含むアプリケーションのパフォーマンスを監視する人や最適化を試みる人にとっては宝物のような機能ですが、一部の人々が望むほどデータにアクセスするのは簡単ではありません。

    この記事と関連するサンプルコードでは、このような情報の使用方法と、日次統計の概要を定期的に抽出してアプリケーションのSQLパフォーマンス履歴記録を保持する方法について説明します。
    ※詳細については、下記ドキュメントページもご参考になさってください。

    https://docs.intersystems.com/iris20201/csp/docbook/DocBook.UI.Page.cls?KEY=GSQLOPT_sqlstmts

    記録内容

    SQLステートメントが実行されるたびに、所要時間が記録されます。 この処理は非常に軽量であり、オフにすることはできません。 コストを最小限に抑えるため、統計はメモリに保持されてから定期的にディスクに書き込まれます。 このデータには当日にクエリが実行された回数と、その平均所要時間と合計所要時間が含まれます。

    0
    0 355
    記事 Toshihiko Minamoto · 8月 13, 2020 3m read

    皆さん、こんにちは。

    InterSystems System Alerting and Monitoring (SAM)をご存知でしょうか。InterSystems IRIS 2020.1以降に対応し、IRISやそのアプリケーションの監視を行うソリューションです。といってもシステム監視を行うPrometheus、アラートを管理するAlertManager、ダッシュボードとしてグラフ等を表示させるGrafanaなどを組み合わせたものですが、IRISの利用者に合わせて設定しやすくなっています。

    なお、これらのコンポーネントはDockerコンテナを使用しますので、Docker(19.3.098以降)ならびにDocker compose(1.25以降)をインストールいただく必要があります。

    IRISの監視APIについてはこちらをご覧ください。

    インストール手順

    1. アプリケーションのインストール

    アプリケーション自体はDockerコンテナにて提供されますので、DockerComposeのファイルやシェルスクリプトを以下のGitHubリポジトリからダウンロードします。
    https://github.com/intersystems-community/sam

    以下のgzipファイルをダウンロードし、展開します。
    sam-1.0.0.XXX-unix.tar.gz

    1
    1 346
    記事 Tomohiro Iwamoto · 8月 17, 2020 9m read

    本稿について

    本稿では、InterSystems IRISを使用してSQLベースのベンチマークを行う際に、実施していただきたい項目をご紹介します。 Linuxを念頭においていますが、Windowsでも考慮すべき点は同じです。

    メモリ自動設定をやめる

    パフォーマンスに直結する、データベースバッファサイズの自動設定はデフォルトで有効になっています。自動設定は、実メモリの搭載量にかかわらず、データベースバッファを最大で1GBしか確保しません。

    更新: 2020年11月20日   バージョン2020.3から、確保を試みるデータベースバッファが実メモリの25%に変更されました。

    搭載実メモリ64GB未満の場合は実メモリの50%程度、搭載実メモリ64GB以上の場合は実メモリの70%を目途に、明示的に設定を行ってください。

    設定するにはiris停止状態で、iris.cpfファイル(IRISインストール先\mgr\iris.cpf)を変更します。下記はブロックサイズ8KB用(既定値です)のデータベースバッファサイズの自動構成を4096(MB)に変更する例です。

    修正前

    [config]
    globals=0,0,0,0,0,0
    

    修正後

    [config]
    globals=0,0,4096,0,0,0
    

    詳細はこちらです。

    また、Linuxの場合、ヒュージ・ページ有効化の設定を行ってください。設定値の目安ですが、IRIS起動時のメッセージから、確保される共有メモリサイズ(下記だと749MB)を読み取り、その値めがけて設定するのが簡単です。

    コンテナバージョンは非rootで動作するため、ヒュージ・ページは利用できません

    $ iris start iris
    Starting IRIS
    Using 'iris.cpf' configuration file
    Starting Control Process
    Allocated 749MB shared memory: 512MB global buffers, 64MB routine buffer
    $ cat /proc/meminfo
    HugePages_Total:       0
    HugePages_Free:        0
    HugePages_Rsvd:        0
    HugePages_Surp:        0
    Hugepagesize:       2048 kB
    

    ページサイズが2048kBですので、750MB(丸めました)を確保するには750/2=375ページ必要になります。構成を変えると必要な共有メモリサイズも変わりますので、再調整してください。

    $ echo 375 > /proc/sys/vm/nr_hugepages
    $ iris start iris
    Starting IRIS
    Using 'iris.cpf' configuration file
    Starting Control Process
    Allocated 750MB shared memory using Huge Pages: 512MB global buffers, 64MB routine buffer
    

    メモリ関連の設定値は、パフォーマンスに大きく影響しますので、比較対象のDBMSが存在するのであればその設定値に見合う値を設定するようにしてください。

    データベース関連ファイルの配置

    特にクラウド上でのベンチマークの場合、ストレージのレイアウトがパフォーマンスに大きな影響を与えます。クラウドではストレージごとのIOPSが厳格に制御されているためです。

    こちらに細かな推奨事項が掲載されていますが、まずは下記のように、アクセス特性の異なる要素を、それぞれ別のストレージに配置することをお勧めします。

    Filesystem      Size  Used Avail Use% Mounted on
    /dev/sdc        850G  130G  720G  16% /irissys/data      (IRIS本体のインストール先、ユーザデータべース)
    /dev/sdd        800G  949M  799G   1% /irissys/wij       (ライトイメージジャーナルファイル)
    /dev/sde        200G  242M  200G   1% /irissys/journal1  (ジャーナルファイル)
    /dev/sdf        100G  135M  100G   1% /irissys/journal2  (予備のジャーナルファイル保存エリア)
    

    サイズは用途次第です。WIJに割り当てているサイズが大きめなのは、IOPS性能がファイルシステムの容量に比例するクラウドを使用するケースを意識したためで、IOPSとサイズが連動しないオンプレミス環境では、これほどのサイズは必要ありません。

    テーブルへのインデックス追加 

    IRISのテーブルへのインデックス追加は一部のDWH製品のように自動ではありません。多くのRDBMS製品と同様に、CREATE TABLE命令の実行時に、プライマリキー制約やユニーク制約が指定されている場合、インデックが追加されますが、それ以外のインデックスはCREATE INDEX命令で明示的に追加する必要があります。

    どのようなインデックスが有用なのかは、実行するクエリに依存します。 一般的に、ジョインの結合条件(ON句)となるフィールド、クエリやUPDATE文の選択条件(WHERE句)となるフィールド、グルーピングされる(GROUP BY)フィールドが対象となります。

    インデックスの対象を参照ください。

    データベースファイルのサイズ

    IRISのデータベースファイルの初期値は1MBです。既定では、ディスク容量が許容する限り自動拡張を行いますので、エラーにはなりませんが、パフォーマンスは劣化します。ベンチマークプログラムでそのことに気づくことはありません。お勧めは、一度ベンチマークを実行して、必要な容量まで自動拡張を行い、データを削除(DROP TABLEやTRUNCATE TABLEを実行)した後に、再度ベンチマークを実行することです。

    統計情報の取得 

    IRISはクエリの実行プランを最適化するために、テーブルデータに関する統計情報を使用します。 統計情報の取得処理(TuneTable/TuneSchema)は、初期データロード後に明示的に実行する必要があります。

    IRISバージョン2022.1以降、統計情報の取得処理が一度も実行されていない場合、初回のクエリ実行時に自動実行されるようになりました。そのため、初回のクエリに若干のオーバヘッドが発生します。

    TuneTable(テーブル対象)/TuneSchema(スキーマ対象)を実行すると、既存のクエリプランがパージされるので、次回の初回クエリ実行時はクエリ解析・プラン生成にかかる分だけ時間が多めにかかります。 また、TuneTable/TuneSchema実行後にインデックスを追加した場合には、そのテーブルに対してTuneTableを再実行してください。

    これらを考慮すると、ベンチマークで安定した計測結果を得るには、テストデータのロード後に、明示的に下記を実施することが重要になります。

    • TuneTable/TuneSchemaを実行
    • 最低でも一度は全クエリを実行する

    もちろん、これらの性能を計測したい場合は、その限りではありません。

    TuneTable/TuneSchemaは、管理ポータル及びCLIで、手動で実行可能です。ベンチマーク測定時は、データの再投入やインデックスの追加や削除といった、統計情報の更新を繰り返し実行する必要性が高くなることを考慮すると、手動での更新は避けて、下記のObjectScriptのCLIやSQL文で実施するのが効果的です。

    下記コマンドはスキーマMySchemaで始まる全てのテーブルの統計情報を取得します。

    MYDB>d $SYSTEM.SQL.Stats.Table.GatherSchemaStats("MySchema")
    

    下記コマンドは指定したテーブルのテーブルの統計情報を取得します。

    MYDB>d $SYSTEM.SQL.Stats.Table.GatherTableStats("MySchema.MyTable")
    

    あるいはSQL文として、データロード実行後にベンチマークプログラム内で実行する事も可能です。

    TUNE TABLE MySchema.MyTable
    

    タイムスタンプ型に%TimeStampではなく%PosixTimeを使用する

    更新: 2020年11月20日   使用方法を、SQL文の修正が不要な方法に変更しました

    IRISバージョン2022.1以降、SQLのTimeStamp型の既定値が%PosixTimeに変更されました。この変更によりテーブルを新規作成した際のTimeStamp型は%PosixTimeになります。

    create table TEST (ts TIMESTAMP)
    

    これを、下記のように変更してください。

    create table TEST (ts POSIXTIME)
    

    デフォルトではSQLのTIMESTAMP型は、IRIS内部では%TimeStamp型で保持されます。 %TimeStamp型は、データを文字列として保存するのに対して、%PosixTimeは64bitの整数で保持します。その分、ディスクやメモリ上のデータサイズや比較演算処理などで有利になります。両者はxDBC上は、共にTIMESTAMP型となり、互換性がありますので、DML文の修正は不要です(敢えて指摘するとすれば、ミリ秒以下の精度が異なります)。以下は、実行例です。%PosixTimeに対するクエリのほうが、程度の差こそあれ、高速になっています。

    create table TEST (ts TIMESTAMP, pt POSIXTIME)
    create index idxts on TABLE TEST (ts)
    create index idxpt on TABLE TEST (pt)
    insert into TEST ... 100万レコードほどINSERT
    
    select count(*),DATEPART(year,pt) yyyy from TEST  group by DATEPART(year,pt) 
    平均 669ミリ秒
    select count(*),DATEPART(year,ts) yyyy from TEST  group by DATEPART(year,ts) 
    平均 998ミリ秒
    
    select count(*) from TEST  where DATEPART(year,pt)='1990' 
    平均 533ミリ秒
    select count(*) from TEST  where DATEPART(year,ts)='1990' 
    平均 823ミリ秒
    
    select count(*) from TEST where pt>='1980-01-01 00:00:00' and pt<'1991-01-01 00:00:00'
    平均 350ミリ秒
    select count(*) from TEST where ts>='1980-01-01 00:00:00' and ts<'1991-01-01 00:00:00'
    平均 381ミリ秒
    

    TIMESTAMP型を%PosixTimeに変更するには、テーブルの作成を行う前、かつIRIS停止中に構成ファイル(IRISインストール先\mgr\iris.cpf)の下記を変更してください。以後、TIMESTAMP型で定義したカラムは%PosixTimeになります。

    IRISバージョン2022.1以降、既定値がPosixTimeに変更されましたので、構成ファイルの変更は不要です。

    [SQL]
    TimePrecision=0  (修正前)
    TimePrecision=6  (修正後)
    [SqlSysDatatypes]
    TIMESTAMP=%Library.TimeStamp (修正前)
    TIMESTAMP=%Library.PosixTime  (修正後)
    

    バイナリデータの保存には可能であればVARBINARYを使用する。

    バイナリデータを保存する場合、サイズの上限が指定できる場合はVARBINARYを使用してください。LONGVARBINARYはサイズ上限が無い代わりに、内部でストリーム形式で保存する機構を伴うためパフォーマンスが低下します。

    CREATE TABLE TestTable (ts TIMESTAMP, binaryA VARBINARY(512), binaryB VARBINARY(256))
    

    VARBINARY使用時には、行全体のサイズに注意が必要です。SQLの行は、IRIS内部では、既定では下記のフォーマットで、1つのノードのデータ部(IRISの内部形式の用語でKV形式のバリューに相当します)に格納されます。このノードのサイズ上限は3,641,144バイトです。

    長さ|データタイプ|データ|長さ|データタイプ|データ|...

    この長さを超えると、<MAXSTRING>という内部エラーが発生し、INSERTが失敗します。

    Query ソース保存有効化

    実行プランがコード化されたものがソースコードとして保存されます。デフォルトでは無効です。本稿では扱っていませんが、後の解析で有用になることもありますので、念のため有効化しておきます。

    [SQL]
    SaveMAC=1   <== 既定値は0です
    

    一通りのベンチマークを実行

    この時点での実行結果は思った結果が得られないかもしれません。 ベンチマークプログラムによるレコードのINSERTにより、ユーザデータベースの自動拡張、一時データべースの自動拡張、WIJの自動拡張が、クエリにより、クエリプランの作成、インデックスの不足によるテーブルフルスキャンなどが発生している可能性があるためです。

    (ベンチマーク実施により蓄積したデータの消去後の)2回目以降は、インデックスの不足以外の問題は解消されているので、パフォーマンスが向上するかもしれません。 また、これとは逆にジャーナルは、随時蓄積していきますので、ベンチマーク実施を繰り返すうちに、いずれはディスクの空き容量を圧迫します。 適宜ジャーナルファイルを削除してください。運用環境では絶対禁止の方法ですが、データベースミラーリングを使用しておらず、データの保全が必要のないベンチマーク環境でしたら、最新のジャーナルファイル以外をO/Sシェルでrmしてしまって構いません。

    これ以後の、細かな確認作業はさておき、まずは上記の項目の実施をスタートラインとすることをお勧めします。

    0
    0 587
    記事 Tomohiro Iwamoto · 6月 29, 2020 32m read

    ここ数年の間、ハイパーコンバージドインフラストラクチャ(HCI)ソリューションが勢いを増しており、導入件数が急速に増加しています。 IT部門の意思決定者は、VMware上ですでに仮想化されているアプリケーションなどに対し、新規導入やハードウェアの更新を検討する際にHCIを考慮に入れています。 HCIを選択する理由は、単一ベンダーと取引できること、すべてのハードウェアおよびソフトウェアコンポーネント間の相互運用性が検証済みであること、IO面を中心とした高いパフォーマンス、単純にホストを追加するだけで拡張できること、導入や管理の手順が単純であることが挙げられます。 

    この記事はHCIソリューションの一般的な機能を取り上げ、HCIを初めて使用する読者に紹介するために執筆しました。 その後はデータベースアプリケーションの具体的な例を使用し、InterSystems データプラットフォーム上に構築されたアプリケーションを配置する際の、キャパシティプランニングとパフォーマンスに関する構成の選択肢と推奨事項を確認します。 HCIソリューションはパフォーマンスを向上させるためにフラッシュストレージを利用しているため、選択されたフラッシュストレージオプションの特性と使用例に関するセクションも含めています。 

    0
    0 422
    記事 Tomohiro Iwamoto · 6月 5, 2020 14m read

    前回の記事では、pButtonsを使って履歴パフォーマンスメトリックを収集する方法を説明しました。 すべてのデータプラットフォームインスタンス(Ensemble、Cachéなど)にはpButtonsがインストールされていることがわかっているため、私はpButtonsを使用する傾向にありますが、 Cachéパフォーマンスメトリックをリアルタイムで収集、処理、表示する方法はほかにもあり、単純な監視や、それよりもさらに重要な、より高度な運用分析とキャパシティプランニングに使用することができます。 データ収集の最も一般的な方法の1つは、SNMP(簡易ネットワーク管理プロトコル)を使用することです。 

    SNMPは、Cachéが管理・監視情報をさまざまな管理ツールに提供するための標準的な方法です。 Cachéのオンラインドキュメンテーションには、CachéとSNMP間のインターフェースに関する詳細が説明されています。 SNMPはCachéと「単純に連携」するはずですが、構成にはいくつかの技と罠があります。 私自身、はじめに何度も過ちを繰り返し、InterSystemsの同僚から助けを得ながらCachéをオペレーティングシステムのSNMPマスターエージェントにやっと接続できた経験から、皆さんが同じような困難を避けられるようにこの記事を書くことにしました。 

    0
    0 352
    記事 Tomohiro Iwamoto · 6月 5, 2020 27m read

    この記事では、InterSystemsデータプラットフォームで実行するデータベースアプリケーションにおけるグローバルバッファ、ルーチンバッファ、gmheap、locksizeなどの共有メモリ要件のサイジングアプローチを説明し、サーバー構成時およびCachéアプリケーションの仮想化時に検討すべきパフォーマンスのヒントをいくつか紹介します。 これまでと同じように、Cachéについて話すときは、すべてのデータプラットフォーム(Ensemble、HealthShare、iKnow、Caché)を指しています。 

    このシリーズの他の記事のリストはこちら 

    0
    0 641
    記事 Tomohiro Iwamoto · 6月 5, 2020 18m read

    今週は、ハードウェアの主な”食品群” (^_^)  の1つであるCPUに注目します。お客様から、次のようなシナリオについてのアドバイスを求められました。お客様の本番サーバーはサポート終了に近づいており、ハードウェアを交換する時期が来ています。 また、仮想化によってサーバーを一元的に管理できるようにし、ベアメタルか仮想化によりキャパシティを適正化したいとも考えています。 今日はCPUに焦点を当てますが、後日の記事では、メモリやIOといったほかの主要食品群を適正化するアプローチについて説明したいと思います。 

    では、質問を整理しましょう。 

    • 5年前のプロセッサをもとに作られたアプリケーション要件を今日のプロセッサに変換するには? 
    • 現在ではどのプロセッサが適しているのか? 
    • 仮想化はCPUキャパシティプランニングにどのような影響を及ぼすのか? 

    2017年6月追記: 
    VMware CPUに関する考慮事項と計画の詳細、および一般的な質問と問題の詳細については、「大規模データベースの仮想化 - VMware CPUのキャパシティ計画」の記事も参照してください。 

    このシリーズの他の記事のリストはこちら 

    spec.orgのベンチマークを使ったCPUパフォーマンスの比較 

    0
    0 741
    記事 Tomohiro Iwamoto · 6月 4, 2020 11m read

    前回の投稿では、pButtonsを使用してパフォーマンスメトリックを24時間収集する処理をスケジュールしました。 この投稿では、収集対象の主なメトリックのいくつかと、それらの土台となるシステムハードウェアがどのように関連しているかを見ていきます。 また、Caché(または任意のInterSystemsデータプラットフォーム)メトリックとシステムメトリックの関係についても調べます。 さらに、これらのメトリックを使用してシステムの毎日の健全性を把握し、パフォーマンスの問題を診断する方法もご紹介します。 

    このシリーズの他の記事のリストはこちら 

    2016年10月に編集... 

    pButtonsデータを .csv ファイルに抽出するスクリプトの例はこちらで確認できます。 

    2018年3月に編集... 

    画像が消えていましたが、元に戻しました。 

    ハードウェア食品グループ 

    この連載を読み進めていくと、パフォーマンスに影響を与えるサーバーコンポーネントを次のように分類できることが分かってきます。 

    - CPU 

    - メモリ 

    - ストレージIO 

    - ネットワークIO 

    0
    0 278
    記事 Tomohiro Iwamoto · 6月 3, 2020 12m read

    アプリケーションがデプロイされ、すべてが問題なく動作しています。 素晴らしいですね! しかし、その後突然電話が鳴り止まなくなりました。アプリケーションが時々「遅くなる」というユーザーからの苦情の電話です。 これは一体どういうことなのでしょうか? なぜ時々遅くなるのでしょうか? このような速度低下を検出し、解決するにはどのようなツールと統計情報に注目すべきなのでしょうか? お使いのシステムのインフラはユーザーの負荷に対応できていますか? 本番環境を調べる前に、どのようなインフラ設計上の問題を問うべきなのでしょうか? 新しいハードウェアのキャパシティプランニングを、必要以上の設備投資を行うことなく自信を持って行うにはどうすればよいのでしょうか? どうすれば電話がかかってこなくなるのでしょうか? そもそも電話がかかってこないようにするには、どうすればよかったのでしょうか? 

    このシリーズの他の記事のリストはこちら 

    長い道のりの始まり 

    0
    0 290
    記事 Minoru Horita · 6月 3, 2020 10m read

    前のパート(12)では、ツリーとしてのグローバルを話題に取り上げました。 この記事では、それらを疎な配列と見なします。 

    疎な配列は、ほとんどの値が同一であると想定される配列の種類です。 

    疎な配列は実際には非常に大きいため、同一の要素でメモリを占有することには意味がありません。 したがって、疎な配列を整理し、重複した値の格納にメモリが浪費されないようにすることには意味があります。 

    疎な配列は、JMATLABなど一部のプログラミング言語では言語の一部になっています。 他の言語では、疎な配列を使用できるようにする特別なライブラリが存在します。 C++の場合は、Eigenなどがあります。 

    次の理由により、グローバルは疎な配列を実装するのに適した候補であると言えます。 

    1. 特定のノード値のみを保存し、未定義のノード値を保存しないこと。 
    1. ノード値のアクセスインターフェースが、多くのプログラミング言語が多次元配列の要素にアクセスするために提供しているものとよく似ていること。 
    Set ^a(1, 2, 3)=5 
    Write ^a(1, 2, 3) 
    1. グローバルはデータを格納するためにかなり低レベルの構造を採用しているため、優れたパフォーマンス特性を備えていること(ハードウェアによっては毎秒数十万から数千万のトランザクションを処理可能、1をご覧ください)。 
    0
    0 785
    記事 Minoru Horita · 6月 2, 2020 14m read

    最初の記事については、パート1を参照してください。 

    3. グローバルを使用する場合のさまざまな構造 

    順序付きツリーなどの構造には、さまざまな特殊ケースがあります。 グローバルを使用する上で実用的な価値があるものを見てみましょう。 

    3.1 特殊ケース1  - 枝のない1つのノード 

    グローバルは配列のようにも、通常の変数のようにも使用できます。 例えば、カウンターを作成する場合を考えてみましょう。 

    Set ^counter = 0  ; カウンターの設定 
    
    Set id=$Increment(^counter) ;  アトミックなインクリメント操作 

      

    また、グローバルには値に加えて枝を持たせることができます。 一方が他方を除外することはありません。 

    3.2 特殊ケース2  - 1つのノードと複数の枝 

    実際、これは典型的なキー・バリューベースのデータ構造です。 また、値の代わりに値のタプルを保存すると、主キーを持つ通常のテーブルが得られます。 

    グローバルに基づくテーブルを実装するには、カラムの値から文字列を作成し、主キー別にそれをグローバルに保存する必要があります。 読み取りの時に文字列をカラムに分割できるようにするため、以下のいずれかを使用することができます。 

    1. 区切り文字
    0
    0 752
    記事 Toshihiko Minamoto · 5月 10, 2020 11m read

    次の手順で、/api/monitor サービスから利用可能なメトリックのサンプル一覧を表示することができます。 

    前回の投稿では、IRISのメトリックをPrometheus形式で公開するサービスの概要を説明しました。 この投稿では、コンテナにIRISプレビューリリース2019.4 をセットアップして実行し、メトリックを一覧表示する方法をお伝えします。 

    この投稿は、Dockerがインストールされた環境があることを前提としています。 そうでない場合は、今すぐお使いのプラットフォームにインストールしてください :) 

    ステップ 1. dockerでIRISプレビューをダウンロードして実行する 

    プレビューの配布」のダウンロード手順に従い、プレビューライセンスキーとIRISのDockerイメージをダウンロードします。 この例では、InterSystems IRIS for Health 2019.4を選択しています。 

    「機能紹介:Dockerコンテナ内のInterSystems製品について」の指示に従ってください。 すでにコンテナに精通している場合は、「InterSystems IRISのDockerイメージをダウンロードする」というタイトルのセクションに進んでください。 

    0
    0 251
    記事 Tomohiro Iwamoto · 5月 1, 2020 6m read

    私や他のテクノロジアーキテクトは、Caché IOの要件と、Cachéアプリケーションがストレージシステムを使用する方法を顧客とベンダーに説明しなければならないことがよくあります。以下の表は、一般的なCaché IOプロファイルと、トランザクションデータベースアプリケーションの要件を顧客やベンダーに説明するときに役立ちます。 オリジナルの表は、マーク・ボリンスキーが作成しました。 

    今後の投稿ではストレージIOについて詳しく説明する予定なので、今後の記事の参考資料として、今回これらの表も公開します。 

    このシリーズの他の記事のリストはこちら 

    予測可能なディスクIOパフォーマンスを提供し、高可用性機能をサポートし、アプリケーションにストレージの冗長性、スケーラビリティ、および信頼性を提供するには、ストレージアレイなど、ストレージを適切に設定することが不可欠です。 

    CachéストレージIOプロファイル 

    0
    0 318
    記事 Minoru Horita · 4月 30, 2020 9m read

    データを格納するための魔法の剣であるグローバルは、かなり前から存在しています。しかしながら、これを効率的に使いこなせる人や、この素晴らしい道具の全貌を知る人はそう多くありません。 グローバルを本当に効果を発揮できるタスクに使用すると、パフォーマンスの向上やソリューション全体の劇的な単純化といった素晴らしい結果を得ることができます(12)。 

    グローバルは、SQLテーブルとはまったく異なる特別なデータの格納・処理方法を提供します。 グローバルは1966年にM(UMPS)プログラミング言語で初めて導入され、医療データベースで使用されていました。 また、現在も同じように使用されていますが、金融取引など信頼性と高いパフォーマンスが最優先事項である他のいくつかの業界でも採用されています。 

    M(UMPS)は後にCaché ObjectScript(COS)に進化しました。 COSはInterSystemsによってMの上位互換として開発されました。 元の言語は現在も開発者コミュニティに受け入れられており、いくつかの実装で生き残っています。 ウェブ上では、MUMPS GoogleグループMumpsユーザーグループISO規格といった複数の活動が見られます。 

    0
    0 809