検索

クリアフィルター
記事
Megumi Kakechi · 2025年7月31日

データベースのジャーナルを無効にした場合の影響について

これは InterSystems FAQ サイトの記事です。アプリケーション保全のために、データベースのジャーナルは必ず有効にしておく必要がありますが、何らかの理由でジャーナルを無効にしなければならない場合があるかと思います。 ディスク容量の縮小や、データ更新時のシステム負荷の削減など理由は様々です。 ここで注意していただきたいのは、データベースのジャーナルを無効にした場合にどのような影響がでてくるのか、ということです。 こちらのトピックでは、「データベースのジャーナルを無効にした場合の影響について」ご説明します。 ジャーナルを無効にする方法は、以下の2種類があります。 1. システム全体で無効にする方法(こちらを行う場合は【慎重】に!) Set $namespace="%SYS" Do ^JOURNAL > 2) Stop Journaling (^JRNSTOP) 2. プロセス単位で無効にする方法 ※ご参考 do DISABLE^%SYS.NOJRN // ジャーナリングを停止 do ENABLE^%SYS.NOJRN // ジャーナリングを開始 ※ミラーリング対象のデータベースは、ジャーナルを無効にすることはできません。ジャーナルを無効にした場合、以下のことができなくなります。 ・ジャーナルが記録されないため、バックアップのジャーナルリストアができなくなります ・通常のトランザクションがロールバックできないだけではなく、インスタンス開始時のロールバックも対象とならないため、開始時のジャーナルリカバリおよびトランザクションロールバックができなくなります。 →IRIS終了時に、データベースキャッシュ(バッファ)のみ更新されてまだデータベースファイルに反映されていない最新データが失われていたり、トランザクションロールバックが行われなくなります。 →システム全体で無効にした場合、トランザクションでロールバックしようとすると <ROLLFAIL> エラーとなります。 ジャーナルを無効にすると、突然のシステム障害など何かあった場合に元に戻すことができなくなってしまいます。やむを得ない理由でジャーナルを無効にする場合は、そのリスクも十分に考慮したうえで操作されますようお願いします。 以下のドキュメントもあわせてご覧ください。データベースをジャーナリングしない場合の影響
記事
Megumi Kakechi · 2025年8月13日

$ZF(-100) で指定できる便利なキーワード

これは InterSystems FAQ サイトの記事です。$ZF(-100) は、OSコマンドまたはプログラムを子プロセスとして実行するのに使われますが、一緒に便利なキーワードを指定することが可能です。 $ZF(-100)でコマンドの実行がうまくできない、という経験をされた方も多いかと思います。 そんな時は、この便利なキーワードを使って原因の調査をしていきましょう。 キーワードには以下のようなものがあります。 /SHELL シェルを使用して program を実行する。既定では、シェルは使用されない。 /STDIN=filename 入出力リダイレクト入力ファイル /STDOUT=filename 入出力リダイレクト標準データ出力ファイル /STDERR=filename 入出力リダイレクト標準エラー出力ファイル /LOGCMD 結果として得られるコマンド行を messages.log に記録する /NOQUOTE コマンド、コマンド引数、またはファイル名の自動引用を禁止する 使用方法は、以下のようになります。 write $zf(-100,"/SHELL /LOGCMD /STDERR=err.log","command1","command2",...) 例:ネットワーク共有の設定がうまくいかないので原因を調べたい。  →STDERR キーワードで、入出力リダイレクト標準エラー出力ファイルを取得してみる TEST1>write $zf(-100,"/SHELL /stdout=output.log /stderr=err.log","net", "use", "\\172.xxx.xxx.xxx\c$", "/user:Administrator", ^pass) 1 TEST1>!type err.log システム エラー 86 が発生しました。 指定されたネットワーク パスワードが間違っています。 '5cm' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 これは、ネットワーク共有にアクセスするパスワードに & などの特殊文字含まれるため、パスワードが途中の 5cm までしか認識しなかった例です。この場合は、^&でエスケープするか、/NOQUOTE キーワードを指定し、パスワードにクオートをつけて対応します)※クオートいるなしを、$ZFが勝手に判断するので、本当はいるとき(パスワードに&が含まれるときとか)でも、付けてくれなくてエラーになることがあるそんなときの対応に使える(クオートはあえて付けない=NOQUOTE、いるときは自分でつける) 対応例: USER>write $zf(-100,"/SHELL /NOQUOTE /stdout=output.log /stderr=err.log","net", "use", "\\172.xxx.xxx.xxx\Public", "/user:Administrator",""""_ ^pass_"""") 0 USER>!net use 新しい接続は記憶されます。 ステータス ローカル名 リモート名 ネットワーク名 ------------------------------------------------------------------------------- OK \\172.xxx.xxx.xxx\Public Microsoft Windows Network コマンドは正常に終了しました。 USER>
記事
Megumi Kakechi · 2025年8月4日

Webゲートウェイでサーバ接続最大数を設定し、Webアクセス数を制限する方法

これは InterSystems FAQ サイトの記事です。 Webゲートウェイ管理ページで、サーバ毎の最大接続数を設定したり、最大接続に達した場合に待ち時間(キュー)や静的なビジーページを設定することが可能です。 実際にサーバに接続する最大接続数を設定すると、それに達した場合に待ち時間(キュー)で設定した秒数待って、それを過ぎても接続数に空きが出なかった場合に、静的なビジーページに移行するような設定が可能となります。 設定箇所は以下になります。※Webゲートウェイ管理ページ:例(URLは環境・バージョンによって変わります):http://<webserver>/<instancename>/csp/bin/Systems/Module.cxw ★全サーバに適用される設定(デフォルトパラメータ) サーバ単位の個別の設定がない場合は、こちらの設定が適用されます。 構成 > デフォルトパラメータ: 最大接続:各サーバの合計接続数の最大数(既定:1024)。 キューイングされたリクエストのタイムアウト:最大接続まで接続がある場合に、空きが出るまで待つ時間のタイムアウト値(秒) ビジーページ:上記タイムアウトに達した場合に表示するビジーページ(例:只今混みあっております) ★接続サーバ単位で適用される設定(サーバ接続) サーバごとに接続数を制限し、アクセス集中によりサーバに負荷がかかりすぎないよう調整する手段として、こちらの設定が有用です。例:同時アクセス数(最大接続数)が30を超えたらビジーページを表示、等 構成 > サーバ接続 > 既存サーバをクリックして編集:実行 最大接続:このサーバの最大接続数(デフォルトパラメータで設定した最大値以上設定しても、デフォルトパラメータが最大値) 最小接続:処理が終わった後も残る待機プロセス(この数分プロセスは残るため、新規プロセスの生成が起こりにくくなる) ビジーページ:設定がない場合は、デフォルトパラメータで指定したページが継承される 設定後、Webサーバの再起動を行うか、Webゲートウェイの「システムステータス」より接続を全て終了してください。Webゲートウェイより、接続を全て終了する方法は以下になります。
記事
Toshihiko Minamoto · 2020年9月28日

Arduino で気象観測

InterSystems ハッカソンの時、Artem Viznyuk と私のチームは Arduino ボード(1 台)とその各種パーツ(大量)を所有していました。 そのため、私たちは活動方針を決めました。どの Arduino 初心者もそうであるように、気象観測所を作ることにしたのです。 ただし、Caché のデータ永続ストレージと DeepSee による視覚化を利用しました! デバイスの操作 InterSystems の Caché は、次のようなさまざまな物理デバイスと論理デバイスを直接操作することができます。 ターミナル TCP スプーラー プリンター 磁気テープ COM ポート その他多数 Arduino は通信に COM ポートを使用しているため、私たちの準備は万端でした。一般的に、デバイスの操作は次の5つのステップに分けることができます。 OPEN コマンドでデバイスを現在のプロセスに登録し、デバイスにアクセスする。 USE コマンドでデバイスをプライマリにする。 実際の操作を行う。 READ でデバイスからデータを受信し、WRITE でデータを送信する。 もう一度 USE でプライマリデバイスを切り替える。 CLOSE コマンドでデバイスを解放する。 理論上はこうなりますが、実際はどうなのでしょうか? Caché からの点滅操作 まず、私たちはCOM ポートから数値を読み取り、指定したミリ秒の間だけ LED に電力を供給する Arduino デバイスを作りました。 回路: C のコード(Arduino 用) /* Led.ino * COM ポートでデータを受信 * led を ledPin に接続 * // led を接続するピン #define ledpin 8 // 受信したデータバッファ String inString = ""; // 開始時に 1 回だけ実行 void setup() { Serial.begin(9600); pinMode(ledpin, OUTPUT); digitalWrite(ledpin, LOW); } // 無期限に実行 void loop() { // com からデータを取得 while (Serial.available() > ) { int inChar = Serial.read(); if (isDigit(inChar)) { // 同時に 1 文字 // さらにデータバッファに追加 inString += (char)inChar; } // 改行を検出 if (inChar == '\n') { // led の電源をオン digitalWrite(ledpin, HIGH); int time = inString.toInt(); delay(time); digitalWrite(ledpin, LOW); // バッファをフラッシュ inString = ""; } } } 最後に、COM ポートに 1000\n を送信する Caché のメソッドを掲載します。 /// 1000\n を com ポートに送信 ClassMethod SendSerial() { set port = "COM1" open port:(:::" 0801n0":/BAUD=9600) // デバイスを開く set old = $IO // 現在のプライマリデバイスを記録 use port // com ポートに切り替え write $Char(10) // テストデータを送信 hang 1 write 1000 _ $Char(10) // 1000\n を送信 use old // 古いターミナルに戻る close port // デバイスを解放 } «0801n0» は Com ポートにアクセスするためのパラメーターを含む文字列であり、ドキュメントに記載されています。 また、/BAUD=9600 は言うまでもなく接続速度です。 このメソッドをターミナルで実行する場合、次のようになります。 do ##class(Arduino.Habr).SendSerial() 上記を実行しても何も出力されませんが、LED が 1 秒間点滅します。 データ受信 次はキーパッドを Cache に接続し、入力データを受信します。 これは、 認証委任と ZAUTHENTICATE.mac ルーチンを使用するカスタムユーザー認証として使用できます。 回路: C のコード /* Keypadtest.ino * * Keypad ライブラリを使用します。 * Keypad を rowPins[] と colPins[] で指定されているように * Arduino のピンに接続します。 * */ // リポジトリ: // https://github.com/Chris--A/Keypad #include const byte ROWS = 4; // 4 行 const byte COLS = 4; // 3 列 // 記号をキーにマッピングします char keys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; // キーパッドのピン 1-8(上下)を Arduino のピン 11-4 に接続します: 1->11, 2->10, ... , 8->4 // キーパッド ROW0, ROW1, ROW2, ROW3 をこの Arduino ピンに接続します byte rowPins[ROWS] = { 7, 6, 5, 4 }; // キーパッド COL0, COL1, COL2 をこの Arduino ピンに接続します byte colPins[COLS] = { 8, 9, 10, 11 }; // Keypad の初期化 Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); void setup() { Serial.begin(9600); } void loop() { char key = kpd.getKey(); // 押されたキーを取得 if(key) { switch (key) { case '#': Serial.println(); default: Serial.print(key); } } } また、以下は同時に 1 行ずつ COM ポートからデータを取得するために使用される Caché メソッドです。 /// 行末文字を検出するまで COM1 から 1 行を受信します ClassMethod ReceiveOneLine() As %String { port = "COM1" set str="" try { open port:(:::" 0801n0":/BAUD=9600) set old = $io use port read str // 行末文字を検出するまで読み込みます use old close port } catch ex { close port } return str } ターミナルで以下を実行します。 write ##class(Arduino.Habr).ReceiveOneLine() また、(行末文字として送信される)# が押されるまで入力待ち状態になります。その後、入力されたデータがターミナルに表示されます。 以上が Arduino-Caché I/O の基本です。これで、自前の気象観測所を作る準備が整いました。 気象観測所 これで気象観測所に着手できる状態になりました。 私たちはフォトレジスタと DHT11 温湿度センサを使用し、データを収集しました。 回路: C のコード /* Meteo.ino * * 湿度、気温、光の強度を記録して * それらを COM ポートに送信します * 出力例: H=1.0;T=1.0;LL=1; */ // フォトレジスタのピン(アナログ) int lightPin = ; // DHT-11 のピン(デジタル) int DHpin = 8; // DHT-11 の一次データを保存する配列 byte dat[5]; void setup() { Serial.begin(9600); pinMode(DHpin,OUTPUT); }   void loop() { delay(1000); // 1 秒ごとにすべてを測定 int lightLevel = analogRead(lightPin); //輝度レベルを取得 temp_hum(); // 気温と湿度を dat 変数に格納 // And output the result Serial.print("H="); Serial.print(dat[], DEC); Serial.print('.'); Serial.print(dat[1],DEC); Serial.print(";T="); Serial.print(dat[2], DEC); Serial.print('.'); Serial.print(dat[3],DEC); Serial.print(";LL="); Serial.print(lightLevel); Serial.println(";"); } // DHT-11 のデータを dat に格納 void temp_hum() { digitalWrite(DHpin,LOW); delay(30); digitalWrite(DHpin,HIGH); delayMicroseconds(40); pinMode(DHpin,INPUT); while(digitalRead(DHpin) == HIGH); delayMicroseconds(80); if(digitalRead(DHpin) == LOW); delayMicroseconds(80); for(int i=;i
記事
Megumi Kakechi · 2025年6月1日

ロックテーブルの参照方法とその見方

これは InterSystems FAQ サイトの記事です。ロックテーブルを参照する方法として、主に以下の3つの方法が挙げられます。 1. 管理ポータルで参照する方法 ⇒ 管理ポータル:システムオペレーション > ロック > ロックを表示(または管理) 2. ^LOCKTAB ユーティリティ を使用する方法 ⇒ %SYS> do ^LOCKTAB 3. プログラムで参照する方法 ⇒ プログラム内でロック情報を取得する方法 こちらの記事では、ロックテーブルで参照できる情報について、以下の3つのケースに分けて、かかるロックとその意味をご説明します。 1.トランザクションで更新クエリ実行時、他のプロセスで更新・参照した状態 2.デッドロックとなった状態 3.テーブルロックがかかった状態 目視で一番わかり易いのは、1の 管理ポータルで参照する方法 になるので、こちらで説明したいと思います。 最初に、1.トランザクションで更新クエリ実行時、他のプロセスで更新・参照をすると、どのようなロックがかかるのか見ていきます。 a. プロセスA(PID=10044)にてトランザクションで、Sample.Personテーブルの ID=1 を更新します。 ⇒ Exclusive_e->Delock ロック [SQL]TL1:USER>>update Sample.Person(Name) values('bbb') where ID=1 b. プロセスB(PID=46952)にて、Sample.Personテーブルの ID=1 を更新します。 ⇒ WaitExclusiveExact ロック → ロックタイムアウト後(既定10秒)、[SQLCODE: <-110>:<ファイル中にロック競合が発生しました>] エラーが返ります。 [SQL]USER>>update Sample.Person(Name) values('ccc') where ID=1 c. プロセスC(PID=45680)にて、read commit モード で、Sample.Personテーブルの ID=1 を参照します。 ⇒ WaitSharedExact ロック → ロックタイムアウト後(既定10秒)、[SQLCODE: <-114>:<ひとつまたはそれ以上のマッチする行が別のユーザによりロックされています>] エラーが返ります。 [SQL]USER>>set transaction isolation level read committed [SQL]USER>>select * from Sample.Person where ID=1 管理ポータルでロックテーブル情報を見てみます。青四角がそれそれでの持しているロックになります。※複数の増分ロックがかかっているときは、「Exclusive/5」のように、ロック数も表示されます。1つのロックの時は表示されません。 次に、2.デッドロックが発生しているとき、どのようなロックの状態になるのか見てみます。 1. プロセス A(PID:43468) で次のコマンドを発行します : lock +^MyGlobal(15) 2. プロセス B(PID:2198) で次のコマンドを発行します : lock +^MyOtherGlobal(15) 3. プロセス A で次のコマンドを発行します : lock +^MyOtherGlobal(15) ⇒ この LOCK コマンドは返りません。このプロセスは、プロセス B がロックを解放するまでブロックされます。 4. プロセス B で次のコマンドを発行します : lock +^MyGlobal(15) ⇒ この LOCK コマンドも返りません。このプロセスは、プロセス A がロックを解放するまでブロックされます。 プロセスA、プロセスB、ともにロックの解放待ちで、応答が返らない状態(デッドロック)になりました。 管理ポータルでロックテーブル情報を見てみます。 プロセスA(PID:43468) ・^MyGlobal(15) に対する Exclusive(排他ロック)を保持 ・^MyOtherGlobal(15) に対し、WaitExclusiveExactで同一ロックに対する排他ロックの待機(ロック解放待ち) プロセスB(PID:2198) ・^MyOtherGlobal(15) に対する Exclusive(排他ロック)を保持 ・^MyGlobal(15) に対し、WaitExclusiveExactで同一ロックに対する排他ロックの待機(ロック解放待ち) お互いに、それぞれが保持しているロックの解放待ちで、デッドロック状態となっていることが分かります。 デッドロックを防止するには以下のような方法があります。 常に timeout 引数を使用する。 増分 LOCK コマンドを発行する際にその順序に関して厳格なプロトコルに従う。すべてのプロセスが、ロック名に関して同じ順序に従っている限り、デッドロックが発生することはありません。単純なプロトコルは、照合順序でロックを追加するものです。 増分ロックではなく単純ロックを使用する (つまり、+ 演算子を使用しない)。前述のとおり、単純ロックでは、LOCK コマンドは最初に、プロセスによって以前から保持されていたすべてのロックを解放します (ただし、実際には単純ロックはあまり使用されません)。 最後に、3.テーブルロックがかかった状態では、どのようなロックがかかるのか見ていきます。 今回は、Create Table で作成した、SQLUser.tab1 テーブルで実験してみます。現在、ロック閾値 が 1000(デフォルト) なので、トランザクションでそれ以上の更新をしてみます。 1回目の Insert で、「Exclusive_e->Delock」のロックが1つかかっているのが分かります。 2回目の Insert で、「Exclusive_e->Delock」のロックが2つになったのが分かります。 1001回目の Insert では、テーブルロック閾値(1000)を超えたために、「Exclusive/1001E->Delock」というテーブルロックにまとめられたことが分かります。 今回は、管理ポータルで参照する方法をご紹介しましたが、^LOCKTABユーティリティ や、プログラムで取得する方法 でも、同様の情報を見ることが可能です。 なお、正常に終了したプロセスは取得していたロックを全て解放します。 【ご参考】InterSystems製品のロックの基本
記事
Toshihiko Minamoto · 2022年2月14日

統合AIデモサービススタックにML/DLモデルをデプロイする

**キーワード**: IRIS、IntegratedML、Flask、FastAPI、Tensorflow Serving、HAProxy、Docker、Covid-19 ## 目的: 過去数か月に渡り、潜在的なICU入室を予測するための単純なCovid-19 X線画像分類器やCovid-19ラボ結果分類器など、ディープラーニングと機械学習の簡単なデモをいくつか見てきました。  また、ICU分類器のIntegratedMLデモ実装についても見てきました。  「データサイエンス」の旅路はまだ続いていますが、「データエンジニアリング」の観点から、AIサービスデプロイメントを試す時期が来たかもしれません。これまでに見てきたことすべてを、一式のサービスAPIにまとめることはできるでしょうか。  このようなサービススタックを最も単純なアプローチで達成するには、どういった一般的なツール、コンポーネント、およびインフラストラクチャを活用できるでしょうか。   ## 対象範囲 ### **対象:** ジャンプスタートとして、docker-composeを使用して、次のDocker化されたコンポーネントをAWS Ubuntuサーバーにデプロイできます。 * **HAProxy ** - ロードバランサー * **Gunicorn** と **Univorn ** - Webゲートウェイ****サーバー * **Flask** と **FastAPI** - WebアプリケーションUI、サービスAPI定義、およびヒートマップ生成などのアプリケーションサーバー * **Tensorflow Model Serving** と **Tensorflow-GPU Model Serving** - 画像や分類などのアプリケーションバックエンドサーバー * IRIS **IntegratedML** - SQL インターフェースを備えたアプリとデータベースを統合した AutoML * **ベンチマーキング**用クライアントをエミュレートする、**Jupyterノートブック**のPython3 *  Dockerと**docker-compose** * Testla T4 GPU搭載の**AWS Ubuntu** 16.04  注意: GPUを使用したTensorflow Servingはデモのみを目的としています。GPU関連の画像(dockerfile)と構成(docker-compose.yml)は、単純にオフにできます。 ### **対象外**またはウィッシュリスト: * **Nginx **または**Apache**などのWebサーバーは、今のところこのデモでは省略されています。 * **RabbitMQ**とRedis  - IRISまたはEnsembleと置き換えられる、信頼性の高いメッセージングキューブローカー。    * **IAM**([Intersystems API Manger](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AIAM))または**Kong**はウィッシュリストに含まれます。 * **SAM **(InterSystemsの[システムアラートと監視](https://docs.intersystems.com/sam/csp/docbook/DocBook.UI.Page.cls?KEY=ASAM))  * **Kubernetes** Operator付きの**ICM**([InterSystems Cloud Manager](https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=PAGE_DEPLOYMENT_ICM))- 誕生したときからずっとお気に入りの1つです。 * **FHIR**(IntesyStems IRISベースのFHIR R4サーバーとFHIRアプリのSMART用FHIRサンドボックス) * **CI/CD**開発ツールまたは**Github Actions** 「機械学習エンジニア」は、サービスのライフサイクルに沿って本番環境をプロビジョニングする際に、必然的にこれらのすべてのコンポーネントを操作しなければならないでしょう。 今後徐々に、焦点を当てていきたいと思います。   ## GitHubリポジトリ 全ソースコードの場所: また、新しいリポジトリとともに、[integratedML-demo-templateリポジトリ](https://github.com/intersystems-community/integratedml-demo-template)も再利用します。   ## デプロイメントのパターン 以下に、この「DockerでのAIデモ」テストフレームワークの論理的なデプロイパターンを示します。 デモの目的により、意図的にディープラーニング分類とWebレンダリング用に個別のスタックを2つ作成し、HAProxyをソフトロードバランサーとして使用して、受信するAPIリクエストをこれらの2つのスタックでステートレスに分散できるようにしました。 * Guniorn + Flask + Tensorflow Serving * Univcorn + FaskAPI + Tensorflow Serving GPU 前の記事のICU入室予測と同様に、機械学習デモのサンプルには、IntegratedMLを使用したIRISを使用します。 現在のデモでは、本番サービスでは必要または検討される共通コンポーネントをいくつか省略しました。 * Webサーバー: NginxまたはApacheなど。 HAProxyとGunicorn/Uvicornの間で、適切なHTTPセッション処理を行うために必要となります(DoS攻撃を防止するなど)。 * キューマネージャーとDB: RabbitMQやRedisなど。Flask/FastAPIとバックエンドサービングの間で、信頼性のある非同期サービングとデータ/構成の永続性などに使用されます。   * APIゲートウェイ: IAMまたはKongクラスター。単一障害点を作らないように、HAProxyロードバランサーとAPI管理用Webサーバーの間に使用されます。 * 監視とアラート: SAMが適切でしょう。 * CI/CD開発のプロビジョニング: クラウドニューラルデプロイメントと管理、およびその他の一般的な開発ツールによるCI/CDにはK8を使用したICMが必要です。 実際のところ、IRIS自体は、信頼性の高いメッセージングのためのエンタープライズ級のキューマネージャーとしても、高性能データベースとしても確実に使用することができます。 パターン分析では、IRISがRabbitMQ/Redis/MongoDBなどのキューブローカーとデータベースの代わりになることは明らかであるため、レイテンシが大幅に低く、より優れたスループットパフォーマンスとさらに統合する方が良いでしょう。  さらに、IRIS Webゲートウェイ(旧CSPゲートウェイ)は、GunicornやUvicornなどの代わりに配置できますよね?     ## 環境トポロジー 上記の論理パターンを全Dockerコンポーネントに実装するには、いくつかの一般的なオプションがあります。 頭に思い浮かぶものとしては以下のものがあります。   * docker-compose * docker swarmなど * Kubernetesなど  * K8演算を使用したICM このデモは、機能的なPoCといくつかのベンチマーキングを行うために、「docker-compose」から始めます。 もちろん、いつかはK8やICMを使いたいとも考えています。  [docker-compose.yml](https://github.com/zhongli1990/covid-ai-demo-deployment/blob/master/docker-compose.yml)ファイルに説明されているように、AWS Ubuntuサーバーでの環境トポロジーの物理的な実装は、以下のようになります。   上図は、全Dockerインスタンスの**サービスポート**が、デモの目的でどのようにマッピングされており、Ubuntuサーバーで直接公開されているかを示したものです。 本番環境では、すべてセキュリティ強化される必要があります。 また、純粋なデモの目的により、すべてのコンテナは同じDockerネットワークに接続されています。本番環境では、外部ルーティング可能と内部ルーティング不可能として分離されます。   ## Docker化コンポーネント  以下は、[docker-compose.yml](https://github.com/zhongli1990/covid-ai-demo-deployment/blob/master/docker-compose.yml)ファイルに示されるとおり、ホストマシン内でこれらの**ストレージボリューム**が各コンテナインスタンスにどのようにマウントされているかを示します。  ubuntu@ip-172-31-35-104:/zhong/flask-xray$ tree ./ -L 2 ./ ├── covid19 (Flask+GunicornコンテナとTensorflow Servingコンテナがここにマウントされます) │ ├── app.py (Flaskメインアプリ: WebアプリケーションとAPIサービスインターフェースの両方がここに定義されて実装されます) │ ├── covid19_models (CPU使用の画像分類Tensorflow Servingコンテナ用のTensorflowモデルはここに公開されてバージョン管理されます) │ ├── Dockerfile (Flask サーバーとGunicorn: CMD ["gunicorn", "app:app", "--bind", "0.0.0.0:5000", "--workers", "4", "--threads", "2"]) │ ├── models (.h5形式のFlaskアプリ用モデルとX線画像へのGrad-CAMによるヒートマップ生成のAPIデモ) │ ├── __pycache__ │ ├── README.md │ ├── requirements.txt (全Flask+Gunicornアプリに必要なPythonパッケージ) │ ├── scripts │ ├── static (Web静的ファイル) │ ├── templates (Webレンダリングテンプレート) │ ├── tensorflow_serving (TensorFlow Servingサービスの構成ファイル) │ └── test_images ├── covid-fastapi (FastAPI+UvicornコンテナとGPU使用のTensorflow Servingコンテナはここにマウントされます) │ ├── covid19_models (画像分類用のTensorflow Serving GPUモデルは、ここに公開されてバージョン管理されます) │ ├── Dockerfile (Uvicorn+FastAPIサーバーはここから起動されます: CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4" ]) │ ├── main.py (FastAPIアプリ: WebアプリケーションとAPIサービスインターフェースの両方がここに定義されて実装されます) │ ├── models (.h5形式のFastAPIアプリ用モデルとX線画像へのGrad-CAMによるヒートマップ生成のAPIデモ) │ ├── __pycache__ │ ├── README.md │ ├── requirements.txt │ ├── scripts │ ├── static │ ├── templates │ ├── tensorflow_serving │ └── test_images ├── docker-compose.yml (フルスタックDocker定義ファイル。 Docker GPU「nvidia runtime」用にバージョン2.3を使用。そうでない場合はバージョン3.xを使用可) ├── haproxy (HAProxy dockerサービスはここに定義されます。 注意: バックエンドLBにはスティッキーセッションを定義できます。 ) │ ├── Dockerfile │ └── haproxy.cfg └── notebooks (TensorFlow 2.2とTensorBoardなどを含むJupyterノートブックコンテナサービス) ├── Dockerfile ├── notebooks (機能テスト用に外部APIクライアントアプリをエミュレートするサンプルノートブックファイルとロードバランサーに対してPythonによるAPIベンチマークテストを行うサンプルノートブックファイル) └── requirements.txt 注意: 上記の[docker-compose.yml](https://github.com/zhongli1990/covid-ai-demo-deployment/blob/master/docker-compose.yml)はCovid-19 X線画像のディープラーニングデモ用です。  別の[integratedML-demo-template](https://github.com/intersystems-community/integratedml-demo-template)の[docker-compose.yml](https://github.com/intersystems-community/integratedml-demo-template/blob/master/docker-compose.yml)とともに、環境トポロジーに表示されるフルサービススタックを形成するために使用されています。     ## サービスの起動  すべてのコンテナサービスを起動するには、単純な**docker-compose up -d**を使用します。 ubuntu@ip-172-31-35-104:~$ docker psCONTAINER ID        IMAGE                                 COMMAND                  CREATED             STATUS                PORTS                                                                              NAMES31b682b6961d        iris-aa-server:2020.3AA               "/iris-main"             7 weeks ago         Up 2 days (healthy)   2188/tcp, 53773/tcp, 54773/tcp, 0.0.0.0:8091->51773/tcp, 0.0.0.0:8092->52773/tcp   iml-template-master_irisimlsvr_16a0f22ad3ffc        haproxy:0.0.1                         "/docker-entrypoint.…"   8 weeks ago         Up 2 days             0.0.0.0:8088->8088/tcp                                                             flask-xray_lb_171b5163d8960        ai-service-fastapi:0.2.0              "uvicorn main:app --…"   8 weeks ago         Up 2 days             0.0.0.0:8056->8000/tcp                                                             flask-xray_fastapi_1400e1d6c0f69        tensorflow/serving:latest-gpu         "/usr/bin/tf_serving…"   8 weeks ago         Up 2 days             0.0.0.0:8520->8500/tcp, 0.0.0.0:8521->8501/tcp                                     flask-xray_tf2svg2_1eaac88e9b1a7        ai-service-flask:0.1.0                "gunicorn app:app --…"   8 weeks ago         Up 2 days             0.0.0.0:8051->5000/tcp                                                             flask-xray_flask_1e07ccd30a32b        tensorflow/serving                    "/usr/bin/tf_serving…"   8 weeks ago         Up 2 days             0.0.0.0:8510->8500/tcp, 0.0.0.0:8511->8501/tcp                                     flask-xray_tf2svg1_1390dc13023f2        tf2-jupyter:0.1.0                     "/bin/sh -c '/bin/ba…"   8 weeks ago         Up 2 days             0.0.0.0:8506->6006/tcp, 0.0.0.0:8586->8888/tcp                                     flask-xray_tf2jpt_188e8709404ac        tf2-jupyter-jdbc:1.0.0-iml-template   "/bin/sh -c '/bin/ba…"   2 months ago        Up 2 days             0.0.0.0:6026->6006/tcp, 0.0.0.0:8896->8888/tcp                                     iml-template-master_tf2jupyter_1 **docker-compose up --scale fastapi=2 --scale flask=2 -d**   for example will horizontally scale up to 2x Gunicorn+Flask containers and 2x Univcorn+FastAPI containers: ubuntu@ip-172-31-35-104:/zhong/flask-xray$ docker psCONTAINER ID        IMAGE                                 COMMAND                  CREATED             STATUS                PORTS                                                                              NAMESdbee3c20ea95        ai-service-fastapi:0.2.0              "uvicorn main:app --…"   4 minutes ago       Up 4 minutes          0.0.0.0:8057->8000/tcp                                                             flask-xray_fastapi_295bcd8535aa6        ai-service-flask:0.1.0                "gunicorn app:app --…"   4 minutes ago       Up 4 minutes          0.0.0.0:8052->5000/tcp                                                             flask-xray_flask_2 ... ... 「integrtedML-demo-template」の作業ディレクトリで別の「docker-compose up -d」を実行することで、上記リストのirisimlsvrとtf2jupyterコンテナが起動されています。   ## テスト ### **1. 単純なUIを備えたAIデモWebアプリ** 上記のdockerサービスを起動したら、一時アドレスのAWS EC2インスタンスにホストされている[Covid-19に感染した胸部X線画像の検出](https://community.intersystems.com/post/run-some-covid-19-lung-x-ray-classification-and-ct-detection-demos)用デモWebアプリにアクセスできます。 以下は、私の携帯でキャプチャした画面です。  デモUIは非常に単純です。基本的に「Choose File」をクリックして「Submit」ボタンを押せば、[X線画像](https://github.com/zhongli1990/Covid19-X-Rays/tree/master/all/test)がアップロードされて分類レポートが表示されます。 Covid-19感染のX線画像として分類されたら、DLによって「検出された」病変領域をエミュレートする[ヒートマップが表示](https://community.intersystems.com/post/explainability-and-visibility-covid-19-x-ray-classifiers-deep-learning)されます。そうでない場合は、分類レポートにはアップロードされたX線画像のみが表示されます。          このWebアプリはPythonサーバーページです。このロジックは主に[FastAPI's main.py](https://github.com/zhongli1990/covid-ai-demo-deployment/blob/master/covid-fastapi/main.py)ファイルと[Flask's app.py](https://github.com/zhongli1990/covid-ai-demo-deployment/blob/master/covid19/app.py)ファイルにコーディングされています。 もう少し時間に余裕がある際には、FlaskとFastAPIのコーディングと規則の違いを詳しく説明かもしれません。  実は、AIデモホスティングについて、FlaskとFastAPIとIRISの比較を行いたいと思っています。    ### **2. テストデモAPI**       FastAPI(ポート8056で公開)には、以下に示すSwagger APIドキュメントが組み込まれています。 これは非常に便利です。 以下のようにURLに「/docs」を指定するだけで、利用することができます。  ![](/sites/default/files/inline/images/images/image(875).png) いくつかのプレースホルダー(/helloや/itemsなど)と実際のデモAPIインターフェース(/healthcheck、/predict、predict/heatmapなど)を組み込みました。   **これらのAPIに簡単なテストを実行してみましょう**。[私がこのAIデモサービス用に作成したJupyterノートブックサンプル](https://github.com/zhongli1990/covid-ai-demo-deployment/tree/master/notebooks/notebooks)の1つで、Python行を(APIクライアントアプリエミュレーターとして)いくつか実行します。   以下では、例としてこちらのファイルを実行しています。 まず、バックエンドのTF-Serving(ポート8511)とTF-Serving-GPU(ポート8521)が稼働していることをテストします。  !curl http://172.17.0.1:8511/v1/models/covid19 # tensorflow serving !curl http://172.17.0.1:8521/v1/models/covid19 # tensorflow-gpu serving { "model_version_status": [ { "version": "2", "state": "AVAILABLE", "status": { "error_code": "OK", "error_message": "" } } ] } { "model_version_status": [ { "version": "2", "state": "AVAILABLE", "status": { "error_code": "OK", "error_message": "" } } ] }   次に、以下のサービスAPIが稼働していることをテストします。 Gunicorn+Flask+TF-Serving Unicorn+FastAPI+TF-Serving-GPU 上記の両サービスの手間にあるHAProxyロードバランサー r = requests.get('http://172.17.0.1:8051/covid19/api/v1/healthcheck') # tf srving docker with cpu print(r.status_code, r.text) r = requests.get('http://172.17.0.1:8056/covid19/api/v1/healthcheck') # tf-serving docker with gpu print(r.status_code, r.text) r = requests.get('http://172.17.0.1:8088/covid19/api/v1/healthcheck') # tf-serving docker with HAproxy print(r.status_code, r.text) そして、以下のような結果が期待されます。 200 Covid19 detector API is live! 200 "Covid19 detector API is live!\n\n" 200 "Covid19 detector API is live!\n\n"   入力X線画像の分類とヒートマップ結果を返す、**/predict/heatmap**などの機能的なAPIインターフェースをテストします。  受信する画像は、API定義に従ってHTTP POST経由で送信される前にbased64にエンコードされています。 %%time # リクエストライブラリをインポート import argparse import base64 import requests # api-endpointを定義 API_ENDPOINT = "http://172.17.0.1:8051/covid19/api/v1/predict/heatmap" image_path = './Covid_M/all/test/covid/nejmoa2001191_f3-PA.jpeg' #image_path = './Covid_M/all/test/normal/NORMAL2-IM-1400-0001.jpeg' #image_path = './Covid_M/all/test/pneumonia_bac/person1940_bacteria_4859.jpeg' b64_image = "" # JPGやPNGなどの画像をbase64形式にエンコード with open(image_path, "rb") as imageFile: b64_image = base64.b64encode(imageFile.read()) # APIに送信されるデータ data = {'b64': b64_image} # POSTリクエストを送信しレスポンスをレスポンスオブジェクトとして保存 r = requests.post(url=API_ENDPOINT, data=data) print(r.status_code, r.text) # レスポンスを抽出 print("{}".format(r.text)) このようなすべての[テスト画像もGitHubにアップロード済み](https://github.com/zhongli1990/Covid19-X-Rays/tree/master/all/test)です。  上記のコードの結果は以下のようになります。 200 {"Input_Image":"http://localhost:8051/static/source/0198f0ae-85a0-470b-bc31-dc1918c15b9620200906-170443.png","Output_Heatmap":"http://localhost:8051/static/result/Covid19_98_0198f0ae-85a0-470b-bc31-dc1918c15b9620200906-170443.png.png","X-Ray_Classfication_Raw_Result":[[0.805902302,0.15601939,0.038078323]],"X-Ray_Classification_Covid19_Probability":0.98,"X-Ray_Classification_Result":"Covid-19 POSITIVE","model_name":"Customised Incpetion V3"} {"Input_Image":"http://localhost:8051/static/source/0198f0ae-85a0-470b-bc31-dc1918c15b9620200906-170443.png","Output_Heatmap":"http://localhost:8051/static/result/Covid19_98_0198f0ae-85a0-470b-bc31-dc1918c15b9620200906-170443.png.png","X-Ray_Classfication_Raw_Result":[[0.805902302,0.15601939,0.038078323]],"X-Ray_Classification_Covid19_Probability":0.98,"X-Ray_Classification_Result":"Covid-19 POSITIVE","model_name":"Customised Incpetion V3"} CPU times: user 16 ms, sys: 0 ns, total: 16 ms Wall time: 946 ms   ### **3. デモサービスAPIをベンチマークテストする** HAProxyロードバランサーインスタンスをセットアップします。 また、Flaskサービスを4個のワーカーで開始し、FastAPIサービスも4個のワーカーで開始しました。 ノートブックファイルで直接8個のPythonプロセスを作成し、8個の同時APIクライアントがデモサービスAPIにリクエストを送信する様子をエミュレートしてみてはどうでしょうか。  #from concurrent.futures import ThreadPoolExecutor as PoolExecutor from concurrent.futures import ProcessPoolExecutor as PoolExecutor import http.client import socket import time start = time.time() #laodbalancer: API_ENDPOINT_LB = "http://172.17.0.1:8088/covid19/api/v1/predict/heatmap" API_ENDPOINT_FLASK = "http://172.17.0.1:8052/covid19/api/v1/predict/heatmap" API_ENDPOINT_FastAPI = "http://172.17.0.1:8057/covid19/api/v1/predict/heatmap" def get_it(url): try: # 画像をループ for imagePathTest in imagePathsTest: b64_image = "" with open(imagePathTest, "rb") as imageFile: b64_image = base64.b64encode(imageFile.read()) data = {'b64': b64_image} r = requests.post(url, data=data) #print(imagePathTest, r.status_code, r.text) return r except socket.timeout: # 実際のケースではおそらく # ソケットがタイムアウトする場合に何かを行うでしょう pass urls = [API_ENDPOINT_LB, API_ENDPOINT_LB, API_ENDPOINT_LB, API_ENDPOINT_LB, API_ENDPOINT_LB, API_ENDPOINT_LB, API_ENDPOINT_LB, API_ENDPOINT_LB] with PoolExecutor(max_workers=16) as executor: for _ in executor.map(get_it, urls): pass print("--- %s seconds ---" % (time.time() - start)) したがって、8x27 = 216個のテスト画像を処理するのに74秒かかっています。 これは負荷分散されたデモスタックが、(分類とヒートマップの結果をクライアントに返すことで)1秒間に3個の画像を処理できています。 --- 74.37691688537598 seconds --- PuttyセッションのTopコマンドから、上記のベンチマークスクリプトが実行開始されるとすぐに8個のサーバープロセス(4個のGunicornと4個のUvicorn/Python)がランプアップし始めたことがわかります。   ## 今後の内容 この記事は、テストフレームワークとして「全DockerによるAIデモ」のデプロイメントスタックをまとめるための出発点に過ぎません。 次は、Covid-19 ICU入室予測インターフェースなどさらに多くのAPIデモインターフェースを理想としてはFHIR R4などによって追加し、サポートDICOM入力形式を追加したいと思います。 これは、IRISがホストするML機能とのより緊密な統合を検討するためのテストベンチになる可能性もあります。 医用画像、公衆衛生、またはパーソナル化された予測やNLPなど、さまざまなAIフロントを見ていく過程で、徐々に、より多くのMLまたはDL特殊モデルを傍受するためのテストフレームワーク(非常に単純なテストフレーム)として使用していけるでしょう。 ウィッシュリストは、[前の投稿(「今後の内容」セクション)](https://jp.community.intersystems.com/node/507006)の最後にも掲載しています。   
質問
makoto fukunaga · 2024年11月21日

IRISインスタンスが起動できない。

IRISを起動しようとするとエラーとなり起動できません。どなたか解決策をご存知でしょうか?よろしくお願い致します。 環境:Windows11 事前作業: 下記URLと同症状が発生し、アップグレードインストールを行っています。 https://jp.community.intersystems.com/post/iris%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%83%86%E3%82%A3%E7%89%88%E3%81%AE%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9%E3%82%AD%E3%83%BC%E3%81%AE%E6%9B%B4%E6%96%B0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6 操作: 1.タスクトレイアイコンから「InterSystems IRIS 開始(S)[IRIS]」を選択。 2.エラーメッセージが表示される。 イベントビューアのエラー: - <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">- <System> <Provider Name="IRIS Config IRIS" /> <EventID Qualifiers="49409">263</EventID> <Version>0</Version> <Level>2</Level> <Task>0</Task> <Opcode>0</Opcode> <Keywords>0x80000000000000</Keywords> <TimeCreated SystemTime="2024-11-21T05:48:35.4717029Z" /> <EventRecordID>216772</EventRecordID> <Correlation /> <Execution ProcessID="13828" ThreadID="0" /> <Channel>Application</Channel> <Computer>DESKTOP-4OOPUSU</Computer> <Security UserID="S-1-5-18" /> </System>- <EventData> <Data>(99) スタートアップ(^STU)プロセスが中断しました。</Data> </EventData> </Event> mgr/messages.logのエラー: *** Recovery started at Thu Nov 21 15:08:37 2024 Current default directory: d:\iris\mgr Log file directory: d:\iris\mgr\ WIJ file spec: d:\iris\mgr\IRIS.WIJRecovering local (d:\iris\mgr\IRIS.WIJ) image journal file...Starting WIJ recovery for 'd:\iris\mgr\IRIS.WIJ'. 0 blocks pending in this WIJ.Exiting with status 3 (Success)11/21/24-15:08:37:095 (16084) 0 [Generic.Event] Global buffer setting requires attention. Auto-selected 25% of total memory.11/21/24-15:08:37:169 (16084) 0 [Generic.Event] Allocated 5024MB shared memory (large pages)11/21/24-15:08:37:170 (16084) 0 [Generic.Event] 3937MB global buffers, 393MB routine buffers, 64MB journal buffers, 307MB buffer descriptors, 300MB heap, 5MB ECP, 17MB miscellaneous11/21/24-15:08:37:171 (16084) 0 [SIMD] SIMD optimization level: DEFAULT11/21/24-15:08:37:204 (16084) 0 [WriteDaemon.UsingWIJFile] Using WIJ file: d:\iris\mgr\IRIS.WIJ11/21/24-15:08:37:204 (16084) 0 [Generic.Event] No journaling info from prior system11/21/24-15:08:37:217 (16084) 0 [Generic.Event] Startup of InterSystems IRIS [IRIS for Windows (x86-64) 2024.2 (Build 247U) Tue Jul 16 2024 09:57:03 EDT] in d:\iris\bin\ with mgr: d:\iris\mgr with wij: d:\iris\mgr\IRIS.WIJ from: d:\iris\mgr\ OS=[NT], version=[6.2.9200], 16 processors. Processor architecture=[9], level=[25], revision=[5000], active processor mask=[ffff]. System Initialized.11/21/24-15:08:37:236 (12300) 0 [WriteDaemon.Started] Write daemon started.11/21/24-15:08:38:616 (1780) 0 [Database.MountedRW] Mounted database d:\iris\mgr\ (SFN 0) read-write.11/21/24-15:08:38:621 (1780) 0 [Utility.Event] Instance 'IRIS' starting on node DESKTOP-4OOPUSU by user 'SYSTEM' on 11/21/2024 06:08:38.621 UTC11/21/24-15:08:38:621 (1780) 0 [Utility.Event] Using parameters from file 'D:\IRIS\iris.cpf'11/21/24-15:08:38:621 (1780) 0 [Utility.Event] Loading DLLs11/21/24-15:08:38:622 (1780) 0 [Database.MountedRO] Mounted database d:\iris\mgr\irislib\ (SFN 1) read-only. Database label is marked read-only. 11/21/24-15:08:38:623 (1780) 0 [Utility.Event] Switching to temporary %SYS Namespace11/21/24-15:08:38:628 (1780) 0 [Utility.Event] Loading Locale jpww (Japanese for Windows, Japan, Unicode) from objects11/21/24-15:08:38:660 (1780) 0 [Database.MountedRW] Mounted database d:\iris\mgr\irislocaldata\ (SFN 2) read-write.11/21/24-15:08:38:661 (1780) 0 [Utility.Event] Using OpenSSL 3.1.4 24 Oct 202311/21/24-15:08:38:676 (1780) 0 [Database.MountedRW] Mounted database d:\iris\mgr\iristemp\ (SFN 3) read-write.11/21/24-15:08:38:678 (1780) 0 [Utility.Event] D:\IRIS\mgr\iristemp\ initialized as IRISTEMP11/21/24-15:08:38:679 (1780) 0 [Utility.Event] Switching to default %SYS Namespace11/21/24-15:08:38:690 (1780) 3 [Utility.Event] Error: 繧ィ繝ゥ繝シ #5002: ObjectScript 繧ィ繝ゥ繝シ:<SUBSCRIPT>CheckSecurityTables+1184^Security.System.1 ^SYS("Security","ServersD","") Checking security tables - Shutting down the system : $zu(56,2)=$Id: //iris/2024.2.0/kernel/common/src/gformat.c#1 $ 2173 011/21/24-15:08:43:698 (1780) 0 [Utility.Event] Shutting down InterSystems IRIS11/21/24-15:08:43:702 (1780) 0 [Utility.Event] Notifying Clients11/21/24-15:08:43:703 (1780) 0 [Utility.Event] No user shutdown routines to execute11/21/24-15:08:43:703 (1780) 0 [Utility.Event] Stopping User Jobs11/21/24-15:08:43:706 (1780) 0 [Utility.Event] Stopping Network Servers11/21/24-15:08:43:707 (1780) 0 [Utility.Event] Withdrawing from License Domain Printing the last 0 entries out of 0 total occurrences.Err Process Date/Time Mod Line Routine Namespace11/21/24-15:08:43:719 (1780) 0 [Utility.Event] Stopping Client Networking11/21/24-15:08:43:719 (1780) 0 [Utility.Event] Updating Journal File11/21/24-15:08:43:719 (1780) 0 [Utility.Event] Journal restore not required at next startup11/21/24-15:08:43:719 (1780) 0 [Utility.Event] Transaction rollback not required at next startup11/21/24-15:08:43:834 (1780) 0 [Utility.Event] Removing database locks11/21/24-15:08:43:836 (1780) 0 [Utility.Event] Waiting for database updates to complete11/21/24-15:08:43:836 (1780) 0 [Utility.Event] Database updates complete11/21/24-15:08:43:837 (1780) 0 [Utility.Event] Stopping System Jobs11/21/24-15:08:43:944 (4500) 0 [Generic.Event] EXPDMN exited due to system shutdown11/21/24-15:08:43:944 (4920) 0 [Generic.Event] JRNDMN exited due to system shutdown11/21/24-15:08:43:945 (12300) 0 [Generic.Event] No blocks pending in WIJ file11/21/24-15:08:43:946 (12300) 0 [Generic.Event] WRTDMN exited due to system shutdown11/21/24-15:08:43:944 (8828) 0 [Generic.Event] GARCOL exited due to system shutdown11/21/24-15:08:43:976 (16084) 0 [Generic.Event] CONTROL exited due to system shutdown11/21/24-15:08:43:991 (1780) 0 [Utility.Event] Shutdown complete @m.fuku さん、こんにちは。 エラーの状況を詳細に添付いただきありがとうございます。 アップグレード前のIRISのバージョンは何をお使いだったでしょうか。 IRISには2種類のリリースサイクル(CDリリースとEMリリース)があり、CDリリースの場合アップグレードパスにルールがあります。 現在、コミュニティエディションダウンロードページから IRIS 2024.2 をダウンロードいただけるのですが、このバージョンにアップグレードするためには、アップグレード前バージョンが IRIS 2024.1である必要があります(CDリリースのアップグレードパスについて詳細は「製品リリースサイクルの変更」をご参照ください)。 もし、アップグレード前のIRISのバージョンが2024.1より前のバージョンであった場合、CDリリースのアップグレードパスと異なるため、messages.log に以下のエラーメッセージが出力されるようです。 11/21/24-15:08:38:690 (1780) 3 [Utility.Event] Error: 繧ィ繝ゥ繝シ #5002: ObjectScript 繧ィ繝ゥ繝シ:<SUBSCRIPT>CheckSecurityTables+1184^Security.System.1 ^SYS("Security","ServersD","") Checking security tables - Shutting down the system : $zu(56,2)=$Id: //iris/2024.2.0/kernel/common/src/gformat.c#1 $ 2173 0 コミュニティエディションのIRIS 2024.1キットをお持ちであれば、一旦バージョン2024.1にアップグレードし、その後バージョン2024.2にアップグレードできるのですが、WRCアカウントをお持ちでない場合、バージョン2024.1をダウンロードいただけません。 バージョン2024.2をインストールするためには、一旦現在のIRISをアンインストールし、バージョン2024.2を新規でインストールします。 いままで使用中だったユーザ用DB(作成されたものも含む)はそのまま2024.2環境でもご利用いただけますので、その方法を含めて手順をご案内します。 (ユーザ用データベースはIRISのアンインストールで削除されることはありませんが、以下手順では、念のため別の場所に退避する手順を記載しています) 1) バージョン2024.2でも使用したいユーザ用DBを退避します。 IRISをインストールすると、空のDBとしてUSERデータベースが用意されています。この他、ご自身で作成されたデータベースがある場合には、一旦データベースディレクトリごと退避します。 USERデータベースについては、<IRISインストールディレクトリ >\mgr\user に配置されています。userディレクトリごと、他の場所に退避します。 ※念のための確認で、退避したディレクトリ以下に iris.lckがある場合は削除しておいてください。 2) Windowsの「プログラムの追加と削除」メニューを利用してIRISをアンインストールします。 ご参考:Windowsで InterSystems 製品をアンインストールするときの注意点 3) IRISのインストールディレクトリを削除します。 4) IRIS2024.2をインストールします。 5) 退避していいたユーザ用DBを新環境で利用できるようにデータベースの定義を作成します。 管理ポータルを開き、[システム管理] > [構成] > [システム構成] > [ローカルデータベース] メニュー進みデータベースを新規で作成します。 データベース名を決定した後、データベースディレクトリに退避したユーザ用データベースディレクトリを指定します。 図例は c:\temp\user に退避したディレクトリをそのまま指定した場合の例です。 「次へ」で次ページに進むと、以下の案内が出ます。 前バージョンで使用していたデータベースファイル(IRIS.dat)がある場合、上記メッセージが表示されます。 「完了」ボタンを押して作成を終了します。 ここまでの手順でデータベースの作成ができましたので、次にネームスペースを作成します。 6) 作成したデータベースを使用するネームスペースを作成します。 管理ポータルの[システム管理] > [構成] > [システム構成] > [ネームスペース] メニュー進みネームスペースを新規で作成します。 図例では、USER2ネームスペースを作成し、5)で作成したUSER2データベースを使用するように設定しています。 画面下部の「相互運用プロダクション用にネームスペースを有効化」のチェックがデフォルトで入っています。管理ポータルのInteroperabilityメニューを使用する場合はチェックしたままとします。 最後に保存を押してネームスペース作成を完了します。 7) 作成したネームスペース内のクラス(テーブル)をコンパイルします。 ターミナルを起動し、作成したネームスペースに移動します。例はUSER2ネームスペースに移動して全クラスを一括コンパイルしています。 set $namespace = "USER2" do $system.OBJ.CompileAll("u") 退避したユーザ用DBが複数だった場合、作成した新規ネームスペースも複数存在することになり、上記実行を各ネームスペースで実施するのが少し面倒になりますので、その場合は、全ネームスペースに対して一括でコンパイルする方法もあります。 do $system.OBJ.CompileAllNamespaces("u") 以上です。 ぜひお試しください。 詳細な返信ありがとうございます。 作業ボリュームがあるようですので、あらためてまとまった時間が取れたタイミングで試させて頂きます。 その際にまた結果ご報告させて頂きます。 > アップグレード前のIRISのバージョンは何をお使いだったでしょうか。 「2023.3.0.254.0」でした。 > コミュニティエディションのIRIS 2024.1キットをお持ちであれば 残念ながら所持しておりません。 そもそも現時点でダウンロードできたのが今回の「2024.2」バージョンの一択だったと記憶しております。 バージョン情報ありがとうございます。 コミュニティエディションのダウンロードサイトですが、最新バージョンのみをダウンロードいただけるようになっていますため、お手数おかけいたしますが、一度IRISをアンインストールしてから新規インストールでご対応いただくことになりそうです。 また後日、結果をお知らせください! ご提示頂いた手順を行ってみました。無事、IRISインスタンスが実行されるようになりユーザ・ロール・リソースあたりの設定を追加して(この辺りもバックアップ・復旧の手順があったのでしょうか?)元の通りDB接続できるようになりました。 ご対応ありがとうございました。 無事、実行できるようになってよかったです! お試しいただきありがとうございました。 ユーザやロールなど、管理ポータルのセキュリティ管理以下の設定についてですが、IRIS開始中に定義をエクスポートし、新しい環境にインポートする手順で復旧することができます。 以下、参考記事です。 セキュリティ設定のエクスポートとインポートに関するTips 💡 この質問は重要な質問とみなされます。詳細はこちらをご覧ください。
お知らせ
Mihoko Iijima · 2024年5月10日

Windows:InterSystems製品を2024.2以降にアップグレードする際 スタジオが削除されます

開発者の皆さん、こんにちは。 2023年5月にご案内した記事「2023.2 からスタジオが非推奨となります」でもご案内しましたが、インターシステムズは、IRIS 2023.2のリリースからスタジオの廃止を発表しました。 詳細な非推奨計画は2023年11月にお知らせした記事「InterSystems Studio の非推奨に関するお知らせ」でご案内していましたが、バージョン2024.2のプレビューリリースが始まり現在その計画の最初のマイルストーンに到達しました。 バージョン2024.2 プレビューキット以降、Windows キットにはスタジオが含まれなくなります。つまり、このキットを使用した新規インストールでは スタジオがインストールされません。既存のインスタンスをバージョン 2024.2以降にアップグレードした場合は、インスタンスの bin ディレクトリから スタジオが削除されます。 スタジオをこれからも利用されたい方は、WRC 配布ページから 2024.1 スタジオの独立したコンポーネントをダウンロードできます。独立したスタジオが独自のディレクトリにインストールされるため、Windows上の IRIS インスタンスをアップグレード/追加/削除してもスタジオはアンインストールされません。 スタジオのバージョン2024.1には上位互換性があるため、新しいバージョンのIRISがリリースされるたびに更新する必要はありません。 IRIS 2024.2 のリリース後、最低 24 か月間は WRC 配布ページでスタジオのインストールキットは利用可能ですが、まだVSCodeを試されていない開発者の皆さん、ぜひ利用を開始してみてください。 VSCodeをスタジオのような使い勝手で利用する方法については「VSCode を使ってみよう (2021年4月20日版)」をぜひご参照ください。 現時点(2024/5/10)では、一部アイコンの表示が変わっています。以下の内容に置き換えてお試しください。 ObjectScriptエクステンションのインストール補足 「VSCode を使ってみよう (2021年4月20日版)」の「2.接続するサーバの登録」でご紹介しているときのアイコンが から に変わっています。 VSCodeのObjectScriptエクステンション利用方法についてはドキュメントに、またスタジオからの移行時の注意点については「Migrate from Studio」に掲載していますが、開発者コミュニティに日本語記事も豊富にありますのでVSCodeタグの記事もぜひご参照ください。
記事
Megumi Kakechi · 2022年3月23日

ジャーナルレコードに記録されるタイプについて

これは、InterSystems FAQサイトの記事です。ジャーナル・ファイルの処理でジャーナルファイルに記録されるタイプが、それぞれどのような状況下で記録されるのかについて説明します。 処理 (管理ポータルの)タイプ 説明 具体的にどのような処理で記録? JRNSET SET ローカルノードを設定 Set コマンドによりグローバルを更新した場合 JRNMIRSET MirrorSET ミラーノードを設定 ミラー環境にてSet コマンドによりグローバルを更新した場合 JRNBITSET BitSET ノード内の指定されたビット位置を設定 $Bit関数によりグローバルを更新した場合 JRNKILL KILL ローカルノードを削除 Kill コマンドによりグローバルを更新した場合 JRNKILLDES KILLdes 下位ノードを削除(※1) トランザクション中に従属ノードが存在するグローバルノードを削除した場合 JRNMIRKILL MirrorKILL ミラーノードを削除 ミラー環境にてKill コマンドによりグローバルを更新した場合 JRNZKILL ZKILL 従属ノードを削除せずにローカルノードを削除 ZKill コマンドによりグローバルを更新した場合 JRNNSET 現在使用されていません JRNNKILL 現在使用されていません JRNNZKILL 現在使用されていません JRNMIRSET 内部ミラー処理 ミラーリングのシステムグローバルに対する内部的な更新 JRNMIRKILL 内部ミラー処理 ミラーリングのシステムグローバルに対する内部的な更新 ※1:JRNKILLDESの例 USER>zw ^test^test(1)=1^test(1,1)=1 USER>ts TL1:USER>k ^test(1) ジャーナルレコード: 以下のタイプはデータベースへの更新は行いません。 処理 (管理ポータルの)タイプ 説明 JRNBEGTRANS BeginTrans トランザクションを開始 JRNTBEGINLEVEL BeginTrans with level トランザクション・レベルを開始 JRNCOMMIT CommitTrans トランザクションをコミット JRNTCOMMITLEVEL CommitTrans with level 分離されたトランザクション・レベルをコミット JRNTCOMMITPENDLEVEL CommitTrans Pending with level 保留中のトランザクション・レベルをコミット JRNMARK Marker ジャーナル・マーカ JRNBIGNETECP netsyn ECPネットワーキング JRNTROLEVEL Rollback トランザクションをロールバック(ECPクライアントからのトランザクションのみ) あわせて、以下の関連記事も是非ご覧ください。 ジャーナルファイルを削除する方法 ジャーナルファイルが長時間消されずに残ってしまう原因 コマンドでジャーナルファイルにある特定のグローバル変数を検索する方法 誤って削除したグローバルを復旧させる方法 ジャーナルファイルの内容を管理ポータル以外で参照する方法 ジャーナルファイルの使用量をチェックする方法
記事
Tomoko Furuzono · 2023年4月11日

データ更新中にインデックスの再構築を実行する

これは、InterSystems FAQサイトの記事です。データの登録/更新/削除を実行中でも、インデックスを再構築することは可能です。ただし、再構築中は更新途中の状態で参照されますので、専用ユーティリティを使用することをお勧めします。手順は以下の通りです。 追加予定のインデックス名をクエリオプティマイザから隠します。 インデックス定義を追加し、再構築を実施します。 再構築が完了したら、追加したインデックスをオプティマイザに公開します。 実行例は以下の通りです。Sample.Person の Home_State(連絡先住所の州情報)カラムに対して標準インデックス HomeStateIdx を定義する目的での例で記載します。 1、追加予定のインデックス名を Caché のクエリオプティマイザから隠します。 >write $system.SQL.SetMapSelectability("Sample.Person","HomeStateIdx",0)1 2、インデックス定義を追加した後、再構築を実施します。  定義例)Index HomeStateIdx On Home.State; >do ##class(Sample.Person).%BuildIndices($LB("HomeStateIdx")) 3、再構築が完了したら、追加したインデックスをオプティマイザに公開します >write $system.SQL.SetMapSelectability("Sample.Person","HomeStateIdx",1)1 インデックスが使用されたか/されないか、の確認はクエリプランを参照します。以下の例では、ターミナルを $system.SQL.Shell() でSQL実行環境に切り替えた状態でのプラン確認結果を表示しています(管理ポータルで参照する場合は、クエリ実行画面でSQL実行後「プラン表示」ボタンを押下します)。 SAMPLES>do $system.SQL.Shell()SQL Command Line Shell----------------------------------------------------The command prefix is currently set to: <>.Enter q to quit, ? for help.SAMPLES>>select ID,Name from Sample.Person where Home_State='NY'1. select ID,Name from Sample.Person where Home_State='NY'ID Name61 Alton,Debby O.138 Isaksen,Charlotte L.175 Walker,Emily O.3 Rows(s) Affectedstatement prepare time(s)/globals/lines/disk: 0.0026s/35/974/0ms execute time(s)/globals/lines/disk: 0.0017s/216/2447/0ms cached query class: %sqlcq.SAMPLES.cls1---------------------------------------------------------------------------SAMPLES>>show plan // ★ インデックス未使用時のプラン表示 DECLARE QRS CURSOR FOR SELECT ID , Name FROM Sample . Person WHERE Home_State = ?Read master map Sample.Person.IDKEY, looping on ID.For each row: Output the row.SAMPLES>>show plan // ★ インデックス使用時のプラン表示 DECLARE QRS CURSOR FOR SELECT ID , Name FROM Sample . Person WHERE Home_State = ?Read index map Sample.Person.HomeStateIdx, using the given %SQLUPPER(Home_State), and looping on ID.For each row: Read master map Sample.Person.IDKEY, using the given idkey value. Output the row.SAMPLES>> 詳細は、以下ドキュメントをご参照ください。READ および WRITE アクティブシステム上でのインデックスの構築について【IRIS】READ および WRITE アクティブシステム上でのインデックスの構築についてまた、下記の関連トピックもご確認ください。アプリケーション使用中にインデックス再構築を複数プロセスで実行する方法クエリをチューニングする方法
記事
Megumi Kakechi · 2023年3月28日

テーブル名、カラム名、インデックス名の変更方法

これは InterSystems FAQ サイトの記事です。 テーブル名/カラム名/インデックス名を変更したい場合、以下のケース別に変更方法をご案内します。 A. テーブル名・カラム名の変更B. インデックス名の変更 -------------------------------------------------------------------------A. テーブル名・カラム名の変更する方法------------------------------------------------------------------------- テーブル(クラス)名とカラム(プロパティ)名は基本的には変えないようにしてください。 もし「SQLアクセス時の名前だけ変更したい」場合は、以下のように新しい名前を SqlTableName(テーブル名)、SqlFieldName(カラム名) として指定することができます。 Class User.test Extends %Persistent [ SqlTableName = test2 ] { Property p1 As %Integer [ SqlFieldName = xx ]; .... 以後 "SELECT xx from test2" としてアクセス可能になります。こちらの方法の場合は、スタジオで定義を記述し、再コンパイルすると即座に反映されます。 どうしてもクラス名を変更したい場合は以下の(1)、プロパティ名を変更したい場合は以下の(2)が必要となります。 (1) クラス名変更はできないため、新規クラス作成し、定義を丸ごとコピーする必要があります。  コピーには、スタジオの「ツール > クラスをコピー」を使用できます。  ストレージ定義やクラス名のインスタンスもすべてコピーする場合は、以下のようにチェックを入れます。 ※元のクラスは、新規クラスをコンパイルする前にコマンドで削除してください。 以下の実行例を参考にしてください。 実行例: USER>do $SYSTEM.OBJ.Delete("User.Test") クラスを削除中 User.Test USER>write ##class(%ExtentMgr.Util).DeleteExtentDefinition("User.Test","cls") 1 (2) プロパティ名変更は、スタジオで定義を変更するだけです。  ただしグローバルのストレージ場所が変わらないように、手動でストレージ情報を編集する必要があります。 【注意】クラス名やプロパティ名を変える場合、手順を間違えると 【ご参考】にある関連トピックのような問題が発生します。十分に注意した上で行うようにしてください。 -----------------------------------------------------B. インデックス名の変更----------------------------------------------------- インデックス名の変更については、以下の手順になります。旧インデックスを削除 → スタジオでインデックス名を変更 → 新インデックス再構築 【例】Index a1 を Index b1 に変更する場合 (1) インデックスa1データ削除 do ##class(User.test).%PurgeIndices($LB("a1")) (2) スタジオでインデックス名を変更し、コンパイル (3) インデックス b1データ再構築 do ##class(User.test).%BuildIndices($LB("b1")) 【ご参考】クラス定義でプロパティ名を変更するとそれまで参照できていたデータが参照できなくなる/参照時にエラーが発生する場合の対処方法
記事
Mihoko Iijima · 2024年12月24日

Interoperability(Ensemble)の大量にたまったイベントログやメッセージをAPIを利用して削除する方法

これは InterSystems FAQ サイトの記事です。 イベントログの削除には、Ens.Util.LogクラスのPurge()メソッドを使用します。実行時以下の引数を指定します。 第1引数:削除数(参照渡し) 第2引数:保持日数(デフォルト7) メッセージの削除には、2種類の方法があります。 1) 2022.1.2以降の導入されたマルチプロセスで削除する方法 Ens.Ens.Util.MessagePurgeクラスのPurge()メソッドを使用します。実行時以下の引数を指定します。 第1引数:削除数(参照渡し) 第2引数:保持日数(デフォルト7) 第3引数:1を指定(Completeではないメッセージの削除を防止するための指定) 第4引数:メッセージボディも一緒に削除する場合は1を指定 第5引数:デフォルトは500(秒)が設定されていますが、大量のメッセージをパージするとクリアされたビットマップの最適化に時間を要して最適化が完了しない場合があるため、大量削除の場合は 10000000000など大きな値を指定します。 2) Ens.MessageHeaderクラスのPurge()メソッドを使用する方法。 実行時以下の引数を指定します。 第1引数:削除数(参照渡し) 第2引数:保持日数(デフォルト7) 第3引数:1を指定(Completeではないメッセージの削除を防止するための指定) 第4引数:メッセージボディも一緒に削除する場合は1を指定 上記パージ用メソッド実行時、ログ削除の内容もジャーナルに記録されますので、Purge()メソッド実行中プロセスのジャーナルファイルへの書き込みを無効にする設定を使用します。 ※ジャーナルファイルへの書き込みが無効化されるのは、以下ユーティリティを実行しているプロセスのみのため、システム全体に影響はありません。 ※注意※ ミラーリングを使用している環境でミラーデータベースへの更新ではこのジャーナル無効化の影響を受けず、ジャーナルが記録されますのでご注意ください。 以下実行例です。 //使用中プロセスのジャーナルファイルへの書き込み無効化 do DISABLE^%NOJRN //イベントログを直近7日分を保持して削除 set st=##class(Ens.Util.Log).Purge(.cnt,7,1) //削除数確認 write cnt,! //マルチスレッド対応のメッセージヘッダとボディを直近7日分を保持して削除する set st=##class(Ens.Util.MessagePurge).Purge(.cnt2,7,1,1,10000000000) //削除数確認 write cnt2,! //メッセージヘッダとボディを直近7日間分を保持して削除 set st=##class(Ens.MessageHeader).Purge(.cnt3,7,1,1) //削除数確認 write cnt3,! //使用中プロセスのジャーナルファイルへの書き込み有効化 do ENABLE^%NOJRN
記事
Megumi Kakechi · 2024年6月23日

IRISでシャドウイングの代わりにミラーリングを構成する方法

これは InterSystems FAQ サイトの記事です。 InterSystems IRIS では、シャドウイングは非推奨機能となりました。 こちらのトピックでは、これまでにCachéでシャドウイングを使用していたお客様に対して、IRISへの移行後に、代わりに使用できるミラーリングの構成方法をご紹介します。 ミラーリングには機能的に2つの種類があります。 1.同期ミラーによるフェールオーバー(常にデータベースが同期されて複製、障害時に自動でフェールオーバー) 2.非同期ミラー(シャドウイングと同様の機能を提供)  - DR非同期(DR構成で利用、フェールオーバーへの昇格が可能、複製DBへの書き込み不可)  - レポーティング非同期(データマイニング/BIアプリでの利用、複製DBへの書き込み可能) シャドウイングに代わって、IRISでは「プライマリ・フェイルオーバー」+「非同期ミラー」でミラーリングを構成する機能を利用することができます。 以下は、シャドウイングとミラーリングのサーバ役割の対比表になります。※ミラー構成内の1つのインスタンスを “ミラーメンバ” または単に “メンバ” と呼びます。 シャドウイング ミラーリング DBサーバ プライマリ・フェイルオーバーメンバ シャドウサーバ 災害復旧 (DR) 非同期メンバ レポーティング非同期メンバ では、ミラーの構成手順をご紹介します。手順は以下になります。 1) それぞれのサーバでISCAgent の構成・起動2) それぞれのサーバでMIRRORDATAネームスペース(データベース)を作成 3) 正サーバでミラーを作成し、フェイルオーバー・メンバを構成・ミラーへデータベースの追加4) 副サーバで非同期ミラー・メンバを構成・ミラーへのデータベースの追加 (IRIS.DATのファイル自体をコピーして複製する場合は、必ずディスマウントした状態で行ってください。) 今回は、各設定を管理ポータルを使用して行う方法をご紹介します。 【今回のサンプル・ミラー構成について】   正サーバ(ミラー・プライマリ) 副サーバ(ミラー・非同期) ミラー名 MIRRORSET MIRRORSET ミラーメンバ名 MACHINEA MACHINEC IPアドレス 192.168.2.100 192.168.2.101 ★1) ISCAgent の構成・起動 ISCAgent は、IRISインストール時にインストールされます。 こちらは、IRIS起動時に開始するよう設定する必要があります。開始/停止方法は、OSごとに異なりますのでドキュメントをご覧ください。ISCAgent は、各ミラーメンバ上の専用ポート (既定値は 2188) を使用します。 ★2) MIRRORDATAネームスペース(データベース)の作成 それぞれのサーバで、MIRRORDATAという名前の新しいネームスペースを作成し、参照するデータベースとしてMIRRORDATAデータベースをデフォルト設定の状態で作成します。 ★3) 正サーバでミラーを作成し、フェイルオーバー・メンバを構成 1.ミラーサービスを有効にします 管理ポータル: [システム管理] > [構成] > [ミラー設定] > [ミラーサービス有効] サービス有効 にチェックをして保存します。   2.ミラーを作成します 管理ポータル: [システム管理] > [構成] > [ミラー設定] > [ミラーサービス作成]  [ミラー情報] セクションに以下の情報を入力して保存します。 ※プライマリ-非同期ミラー構成の場合は、アービターを使用する必要はありません。 ※ミラーメンバ名は、既定で $sysytem 変数の内容が設定されています。 (<デバイス名>/<インスタンス名> 例:JP001ISJ/IRIS) こちらをそのまま使用するのでも構いません。3.TESTMIRRORへMIRRORDATAデータベースを追加します。ミラーデータベース名には、MIRRORDATAを使用します  管理ポータル: [システム管理] > [構成] > [システム構成] > [ローカルデータベース] MIRRORDATAの編集 → ミラー○○に追加  メモ:もし、画面中に「ミラーに追加」のリンクが表示されない場合、ディスマウントを実行し、マウントし直してください。   ※ミラーが有効なライセンスを使用していない場合、以下のようなエラーになりますのでご注意ください。 エラー #2076: 'TESTMIRROR' のミラーメンバ情報取得中にエラーが発生しました。 エラー情報: Failed to create InterSystems IRIS context, error = -1 ★4) 副サーバで非同期ミラー・メンバを構成 1.ミラーサービスを有効にします 管理ポータル:[システム管理] > [構成] > [ミラー設定] > [ミラーサービス有効] サービス有効 にチェックをして保存します。 2.ミラーに非同期として参加します 管理ポータル:[システム管理] > [構成] > [ミラー設定] > [非同期として参加]  [ミラー情報] セクションに、2) で設定した正サーバの情報を入力し、「次へ」をクリックします。   3.非同期メンバとして登録したいマシンの情報を指定して保存します 今回は、非同期メンバシステムタイプ=災害復旧(DR)の構成とします。 ※ミラーメンバ名は、既定で $sysytem 変数の内容が設定されています。こちらをそのまま使用するのでも構いません。   4.非同期ミラーへデータベースの追加・キャッチアップを行います  非同期データベースにMACHINEA(正サーバ)のバックアップファイルをリストアします。 【補足】 データベースファイル(IRIS.DAT)のコピーによるバックアップの場合は(=Backup.GeneralクラスのExternalFreeze()/ExternalThaw() を利用してバックアップを取っている場合)、非同期データベースをディスマウントした状態でデータベースファイル(IRIS.DAT)を置換します。 ※外部/オンラインバックアップ・リストアについては、以下の記事で詳細手順を説明していますので、参考になさってください。・外部バックアップについて・オンラインバックアップについて※バックアップからのリストアの場合、 Limit restore to mirrored databases? →Yes でリストアします(リストア後、ミラーが有効化&キャッチアップされます) ★2025/07/25 追記★ ※2025.1以降のバージョンでは、「ミラーメンバーからの自動データベースダウンロード」機能を使用して、プライマリから簡単にミラーデータベースをダウンロードすることができるようになりました。手順は、ローカルデータベース作成時に、「ミラーデータベース?(はい)」を選択し、「ミラーデータベース名」を指定するだけです。この設定のみで、プライマリのミラー環境から、対象のデータベースを自動でダウンロードし、非同期DR環境に設定します。 こちらの機能を使用する場合、5と6の手順は必要ありません。7のミラーモニタでステータスを確認して終了です。 ※この機能は、新規作成ミラーデータベースに対しては非常に便利ですが、元のデータベースのサイズが大きい場合は非常に時間がかかるため、注意が必要です。サイズの大きいデータベースの場合は従来の方法をお勧めします。 5.リストア(置換)後、ミラーモニタ画面にて非同期データベースに対するミラーの「有効化」を行います  ※「ミラーメンバーからの自動データベースダウンロード」機能を使用しない場合  管理ポータル: [システムシステムオペレーション] > [ミラーモニタ]   6.有効化した後、キャッチアップします ※「ミラーメンバーからの自動データベースダウンロード」機能を使用しない場合   7.キャッチアップしたことを確認します(こちらで構成は終了です)   ※非同期メンバのシステム・タイプを変更したい場合(DR非同期 --> レポーティング非同期) 管理ポータルで変更できます。 管理ポータル:[システム管理] > [構成] > [ミラー設定] > [非同期を編集] 1.非同期メンバシステムタイプを「読み書き可能なレポーティング」に変更します。 2.非同期レポーティング(読み書き可能)は、フェールオーバーメンバに昇格する条件を満たしません。  読み書き可能に変更するためには、フェールオーバーデータベースフラグをクリア します。  ※ [FailoverDB] フラグをクリアすると、データベースは読み書き可能に変更されます。   そのため、ミラーのプライマリコピーとしては使用できなくなります。   非同期レポーティング(読み取り専用)の場合、この設定は推奨されません。 3.保存します。 ※詳細は、ドキュメント をご覧ください。 【注意】[読み書き可能] または [読み取り専用のレポート] から [災害復旧 (DR)] に変更することはできません。※一部の条件を満たした場合を除きます。詳細は ドキュメント をご覧ください。 【ご参考】Cache Mirroring 101:簡単なガイドとよくある質問 ミラーリングの機能についてミラージャーナルファイルの削除のタイミングと要件IRISでシャドウイングの代わりにミラーリングを構成する方法-プログラム編 ★2025/07/25 追記★★4)-3 非同期DRの環境にミラーデータベースを追加する手順として 、2025.1以降のバージョンより追加された、「ミラーメンバーからの自動データベースダウンロード」機能を使用して、プライマリから簡単にミラーデータベースをダウンロードする方法を追記しました。
記事
Toshihiko Minamoto · 2021年10月28日

REST経由でファイル転送しプロパティに格納する - パート1

InterSystems開発者コミュニティにおいて、CachéアプリケーションへのTWAINインターフェースの作成の可能性に関する質問が上がりました。 Webクライアントの撮像装置からサーバーにデータを取得し、そのデータをデータベースに保管する方法について、素晴らしい提案がいくつかなされました。  しかし、こういった提案を実装するには、Webクライアントからデータベースサーバーにデータを転送し、受信データをクラスプロパティ(または質問のケースで言えばテーブルのセル)に格納できなければなりません。 この方法は、TWAINデバイスから受信した撮像データを転送するためだけでなく、ファイルアーカイブや画像共有などの整理といったほかのタスクにも役立つ可能性があります。  そこで、この記事では主に、HTTP POSTコマンドの本体から、raw状態またはJSON構造にラップしてデータを取得するRESTfulサービスを記述する方法を説明することにします。 RESTの基本 具体的な話に入る前に、まずREST全般と、IRISでRESTfulサービスがどのように作成されるかについて簡単に説明しましょう。 Representational state transfer(REST)は、分散ハイパーメディアシステムのためのアーキテクチャスタイルです。 RESTにおける情報の重要な抽象化は、適切な識別子を持ち、JSON、XML、またはサーバーとクライアントの両方が認識するほかの形式で表されるリソースです。  通常、クライアントとサーバー間でのデータの転送にはHTTPが使用されます。 CRUD(作成、読み取り、更新、削除)操作ごとに独自のHTTPメソッド(POST、GET、PUT、DELETE)があり、リソースまたは一連のリソースには独自のURIがあります。 この記事では、POSTメソッドのみを使用して新しい値をデータベースに挿入するため、その制約を知る必要があります。  「[IETF RFC7231 4.3.3 POST](https://tools.ietf.org/html/rfc7231#section-4.3.3) 」の仕様によると、POSTには本文に格納されるデータサイズに関する制限はありません。 しかし、Webサーバーやブラウザでは独自の制限が適用され、通常は1 MBから2 GBとなっています。 たとえば、[Apache](https://httpd.apache.org/docs/2.4/mod/core.html#limitrequestbody)の制限は最大2 GBとなっています。 いずれにせよ、2 GBのファイルを送信する必要がある場合は、アプローチを考え直すことをお勧めします。 IRISにおけるRESTfulサービスの要件 IRISでRESTfulサービスを実装するには、次を行う必要があります。 抽象クラス%CSP.RESTを拡張するクラスブローカーを作成します。 これは逆に、%CSP.Pageを拡張するため、さまざまな便利なメソッド、パラメーター、オブジェクト、特に%requestへのアクセスが可能になります。 ルートを定義するUrlMapを指定します。 オプションとしてUseSessionパラメーターを設定し、各REST呼び出しが独自のWebセッションで実行されるのか、ほかのREST呼び出しで1つのセッションを共有するのかを設定します。 ルートで定義された演算を実行するクラスメソッドを提供します。 CSP Webアプリケーションを定義し、そのセキュリティをWebアプリケーションページ(システム管理 > セキュリティ > アプリケーション > Webアプリケーション)に指定します。Dispatchクラスには、ユーザークラスの名前とNameが格納されています。これはREST呼び出しのURLの最初の部分です。 一般に、大きなデータ(ファイル)のチャンクとメタデータをクライアントからサーバーに送信するには、次のようにいくつかの方法があります。 ファイルとメタデータをBase64-encodeで暗号化し、サーバーとクライアントの両方に暗号化/復号化を行うための処理オーバーヘッドを追加します。 最初にファイルを送信し、クライアントにIDを返します。すると、そのIDを持つメタデータが送信されます。 サーバーはファイルとメタデータをもう一度関連付けます。 最初にメタデータを送信し、クライアントにIDを返します。すると、そのIDのファイルが送信されます。サーバーはファイルとメタデータをもう一度関連付けます。 この第1回目の記事では、基本的に2つ目のアプローチを使用しますが、クライアントへのIDの送信とメタデータ(別のプロパティとして格納するためのファイル名)の追加については、このタスクでは特に意味を持たないため、行いません。 第2回目の記事では、最初のアプローチを使用しますが、私のファイルとメタデータをサーバーに送信する前にJSON構造にパッケージ化します。 RESTfulサービスの実装 では、具体的な内容に入りましょう。 まず、設定しようとしているクラスとプロパティを定義しましょう。 Class RestTransfer.FileDesc Extends %Persistent {   Property File As %Stream.GlobalBinary;   Property Name As %String; } もちろん、通常はファイルに使用するメタデータがほかにもありますが、私たちの目的にはこれで十分です。 次に、クラスブローカーを作成する必要があります。これは、ルートとメソッドを使用して後で拡張します。 Class RestTransfer.Broker Extends %CSP.REST {   XData UrlMap   {     <Routes>     </Routes>   } } そして最後に、前段階のセットアップとして、このアプリケーションをWebアプリケーションのリストに指定する必要があります。 前段階のセットアップが完了したので、RESTクライアント([Advanced REST Client](https://install.advancedrestclient.com/install)を使用します)から受信するファイルをクラスRestTransfer.FileDescのインスタンスのFileプロパティとしてデータベースに格納するメソッドを記述できるようになりました。 では、POSTメソッドの本体にRawデータとして格納されている情報から始めましょう。 まず、新しいルートをUrlMapに追加しましょう。 <Route Url="/file" Method="POST" Call="InsertFileContents"/> このルートは、サービスがURL/RestTransfer/fileでPOSTコマンドを受信すると、InsertFileContentsクラスメソッドを呼び出すことを指定します。 より簡単に行うために、このメソッドの中にクラスRestTransfer.FileDescの新しいインスタンスを作成して、そのFileプロパティを受信データに設定します。 これにより、ステータスと、成功またはエラーのいずれかを示すJSON形式のメッセージが返されます。 以下はそのクラスメソッドです。 ClassMethod InsertFileContents() As %Status {   Set result={}   Set st=0       set f = ##class(RestTransfer.FileDesc).%New()   if (f = $$$NULLOREF) {     do result.%Set("Message","Couldn't create an instance of the class")   } else {     set st = f.File.CopyFrom(%request.Content)     If $$$ISOK(st) {       set st = f.%Save()       If $$$ISOK(st) {         do result.%Set("Status","OK")       } else {         do result.%Set("Message",$system.Status.GetOneErrorText(st))       }     } else {       do result.%Set("Message",$system.Status.GetOneErrorText(st))     }   }   write result.%ToJSON()   Quit st } まず、クラスRestTransfer.FileDescの新しいインスタンスを作成し、正常に作成されたこととOREFがあることをチェックします。 オブジェクトを作成できなかった場合は、JSON構造を作成します。  {"Message", "Couldn't create an instance of class"} オブジェクトが作成された場合は、リクエストのコンテンツがプロパティFileにコピーされます。 コピーに成功しなかった場合は、エラーの説明を含むJSON構造を作成します。  {"Message",$system.Status.GetOneErrorText(st)} コンテンツがコピーされた場合は、オブジェクトを保存し、保存に成功した場合は、JSON {"Status","OK"}を作成します。 そうでない場合、JSONはエラーの説明を返します。  最後に、このJSONをレスポンスに書き込んで、ステータスstを返します。 画像を転送する例を次に示します。 データベースへの保存方法: このストリームをファイルに保存して、変更されずに転送されたことを確認できます。 set f = ##class(RestTransfer.FileDesc).%OpenId(4) set s = ##class(%Stream.FileBinary).%New() set s.Filename = "D:\Downloads\test1.jpg" do s.CopyFromAndSave(f.File) テキストファイルでも同じことができます。 これはグローバルでも表示可能です。 また、実行可能ファイルやその他の種類のデータを保存できます。 グローバルでサイズを確認できます。正しいサイズを確認できます。 この部分は正常に動作するようになったので、2番目のアプローチを確認することにしましょう。ファイルのコンテンツとJSON形式で格納されているメタデータ(ファイル名)を取得し、POSTメソッドの本体で転送するアプローチです。  RESTサービスの作成についての詳細は、InterSystemsの[ドキュメント](https://docs.intersystems.com/iris20191j/csp/docbook/Doc.View.cls?KEY=GREST)をご覧ください。  両方のアプローチのサンプルコードは[GitHub](https://github.com/Gra-ach/RESTFileTransfer)と[InterSystems Open Exchange](https://openexchange.intersystems.com/package/RESTFileTransfer)にあります。 いずれかに関連する質問や提案があれば、お気軽にコメント欄に書き込んでください。
記事
Mihoko Iijima · 2021年6月9日

管理ポータルのメモリ関連設定項目について

これは InterSystems FAQ サイトの記事です。 管理ポータルで設定できるメモリ関連の項目は、以下の通りです。(項目としては他にもありますが、ここでは、ほとんど設定する必要のないものについては記載していません。) 管理ポータル [ホーム] > [システム管理] > [構成] > [システム構成] > [メモリと開始設定] 古いバージョンのメニューは以下の通りです。 【バージョン5.1~2010.x】システム管理ポータル [ホーム] > [構成] > [メモリと開始設定] の設定内容* データベースキャッシュ用メモリ* ルーチンキャッシュ用メモリ 【バージョン2011.1.0~】管理ポータル [ホーム] > [システム管理] > [構成] > [追加の設定] > [メモリ詳細設定] 【バージョン 5.1~2010.x】システム管理ポータル [ホーム] > [構成] > [メモリ詳細設定] の設定内容* 一般メモリヒープ【gmheap】* ロックテーブル【locksiz】* IJCバッファ【ijcbuff】* IJCデバイス【ijcnum】※カテゴリ:IO* 照合テーブル最大数【nlstab】 設定の詳細は以下の通りです。 2023/9/1更新 添付のPDFに古い記載がありましたので、本文内を最新情報に更新しています。添付ではなく本文をご参照ください。 管理ポータル:メモリと開始設定 設定内容 管理ポータルのメニューは以下の通りです。 [システム管理] > [構成] > [システム構成] > [メモリを開始設定] 【~Caché2010.2】 [構成] > [メモリと開始設定] (1) データベースキャッシュ用メモリ この項目はMB単位で指定する項目です。メモリは、自動的に構成するか手動で構成するか選択できます。 [手動] を選択した場合、データベース・ブロックに割り当てるグローバル・バッファ・プール・メモリのサイズを指定できます。 なお、データベース・ブロックは規定では 8KB のみが有効になっています。他のブロックサイズを利用したい場合は、事前に下設定項目を修正します。 [システム管理] > [構成] > [追加の設定] > [開始] > DBSizesAllowed 【Caché2008.2.x~2010.2】[構成] > [開始設定] > DBSizesAllowed 規定(8KB)以外の他のブロックサイズを有効とした場合は、システムで使用するデータベース・ブロックに対してメモリを割り当てる必要があります。 [自動] が既定値となります。デフォルトの[自動]設定の場合、アプリケーションにとって不適切な値となる場合もあるため、[手動]に設定変更いただくことを推奨しています。 ご参考:自動取得の場合のサイズ一覧 バージョン 取得サイズ 最小 最大 2020.3以降 物理メモリの25%の値 32MB 16TB 2020.3より前 物理メモリの12.5%の値 なし 1GB 設定値の最適な値はアプリケーションで使用する全てのグローバルの合計サイズで、理論上、全てのデータをキャッシュにのせることができます。これによりグローバル参照に伴う物理ディスク I/O数を最小限に抑えることが可能です。 手動設定の場合、この値の適正値の決定には、アプリケーション実行中に管理ポータルの「システム使用」または、システムルーチンGLOSTAT による統計データの収集を繰り返し行いながら、統計データの「キャッシュ効率(Cache Efficiency)」の値を利用して決定します。 キャッシュ効率(Cache Efficiency)の値はディスクへの物理I/Oと論理I/O(キャッシュから取得)の比で、ここの数値が大きいほどキャッシュヒット率が高い状態です。 この値が常時100を下回る、または正常時のキャッシュ効率よりも大幅に減少している場合は、本値を増加させることを検討してください。 システムルーチンGLOSTATの使用方法詳細は、下記ドキュメントページをご参照ください。 GLOSTATについて【IRIS】/GLOSTATについて システムルーチンGLOSTATはインタラクティブツールであるため、実行時に指定秒数間のキャッシュ効率を確認するツールとして最適です。バックグラウンドで情報収集を繰り返し実行する場合は、mgstatルーチンが最適です。詳しくはドキュメントをご参照ください。 ^mgstat を使用したパフォーマンスの監視【IRIS】/ ^mgstat を使用したパフォーマンスの監視 (2) ルーチンキャッシュ用メモリ ルーチンキャッシュの総サイズをMB単位で指定します。 3種類 のサイズ(4KB、16KB、64KB)のバッファプールにてルーチンキャッシュが構成されます。 ルーチンキャッシュ全体の 1/2 が 64KB 、3/8 が 16KB 、1/8 が 4KB のバッファに割り当てられ、それぞれのプールに割り当てるバッファ数は 300~65,529になります。(これにより、ルーチンバッファのサイズを設定する RoutineBufSize は廃止されました。) ルーチンがルーチンキャッシュに読み込まれる際に、個々のルーチンのサイズに適切なサイズのバッファが割り当てられます。 ルーチンキャッシュの総サイズの適正値の決定には、アプリケーションの実行中に管理ポータルの「システム使用」による(または、システムルーチンGLOSTATによる)統計データの参照を繰り返す必要があります。 管理ポータルの「システム使用」およびシステムルーチンGLOSTATでルーチンバッファの読み込みと保存(Routine buffer loads and saves)の値をモニターします。 この値はルーチンの読み出しが物理ディスクI/Oを伴う場合にカウントされます。通常、起動直後しばらくはこの値が増加し続けますがルーチンキャッシュが十分に確保されている環境では、この値はいずれ収束します(0が理想値です)。 メモリ詳細設定 管理ポータルのメニューは以下の通りです。 [システム管理] > [構成] > [追加の設定] > [メモリ詳細] 【Caché2008.2~Caché2010.2】 [構成] > [メモリと詳細設定] 【~Caché2008.1】 [構成] > [詳細設定] > カテゴリ:Memory (1) 一般メモリヒープ:gmheap 管理メモリ領域をKB単位で指定します。本領域には下記の情報が含まれます。(以下の領域を増加する場合には、合わせてgmheapの領域も増加する必要があります。) プロセステーブル(動的に拡張) InterSystems製品で使用するプロセスの情報を格納したテーブル ロックテーブル (管理ポータルで変更可能) NLSテーブル など 詳細はドキュメントをご参照ください。 一般(共有)メモリ・ヒープ使用状況 / Caché/Ensemble:一般(共有)メモリ・ヒープ使用状況 (2) ロックテーブル:locksiz インスタンス全体で使用出来るロックの総量をバイト単位で指定します。 アプリケーションがLockを取得する度にこの領域が消費されます。 個々の消費量は可変長です。下記の処理により空き容量を知ることができます。ロック実行前と実行後で下記の処理を実施することにより、おおよその消費量を推定することができます。 実行例は、以下の通りです。 %SYS>set size=##Class(SYS.Lock).GetLockSpaceInfo() write $Piece(size,",",3) 1172400 %SYS>lock +^a(1) %SYS>set size=##Class(SYS.Lock).GetLockSpaceInfo() write $Piece(size,",",3) 1172800   //消費量は1172800-1172400=400(byte) %SYS>lock %SYS>set size=##Class(SYS.Lock).GetLockSpaceInfo() write $Piece(size,",",3) 1172400 ロックテーブルの空きが不足すると、新たなLockコマンドは空きができるまで待たされます。この場合、タイムアウト付きのLockはタイムアウトします。 【Caché2008.2~2010.2】 [構成] > メモリ詳細設定 > locksiz (3) IJCバッファ:ijcbuff ジョブ間通信で使用できる個々のバッファのサイズをバイトで指定します。 アプリケーションでOpenコマンドの Open 224 などの機能を使用していない場合は、デフォルト設定で問題ありません。 詳細は下記ドキュメントをご参照ください。 プロセス間通信について【IRIS】/ プロセス間通信について 【Caché2008.2~2010.2】 [構成] > メモリ詳細設定 > ijcbuff (4) IJCデバイス:ijcnum ジョブ間通信で使用できるデバイスの個数を指定します。 アプリケーションでOpenコマンドの Open 224 などの機能を使用していない場合は、デフォルト設定で問題ありません。 詳細は下記ドキュメントをご参照ください。 プロセス間通信について【IRIS】/ プロセス間通信について 【Caché2008.2~2010.2】 [構成] > メモリ詳細設定 > ijcnum (5) 照合テーブル最大数:nlstab インスタンスが保持可能な照合(collation)テーブルの最大数を指定します。 通常デフォルト値で十分です。 本項目は、照合テーブルへのポインタを保持するだけで、実際に照合テーブルがロードされるかどうかは、NLSのロケール設定に従います。 日本語環境ではデフォルトで照合テーブルは最大1つ(Japanese1)しかロードされません。 【Caché2008.2~2010.2】 [構成] > メモリ詳細設定 > nlstab 関連記事/FAQトピック InterSystems製品のプロセスが使用するメモリ量を教えてください。 最大ネームスペース数を教えてください。