クリアフィルター
記事
Mihoko Iijima · 2021年4月2日
これは InterSystems FAQ サイトの記事です。
MM/DD-hh:mm:ss:938 ( 0) 1 Failed to allocate xxxMB shared memory using large pages. Switching to small pages.MM/DD-hh:mm:ss:938 ( 0) 0 Allocated xxxMB shared memory: yyyMB global buffers, zzzMB routine buffers
コンソールログ(cconsole.log/messages.log)に上記のようなメッセージがある場合は、Large Page でのメモリ確保に失敗して、Small Page でメモリを確保したことを示しています。
Allocated xxxMB が設定サイズと同じ場合、Small Pageでメモリ確保ができていますので、設定サイズを減らす必要はありません。
このメッセージは、起動時に十分な空きメモリが連続領域で確保されていないために発生しています。
デフォルトの設定では、WindowsOS が管理するメモリ領域の中で Large Page という領域にメモリを連続的に確保します。
このメモリ領域は、物理メモリサイズやインストールされている他のソフトによっては、WindowsOS を連続稼動し続けていると断片化しやすくなります。
この為、インスタンスのみの再起動を実施した場合、十分な連続領域が確保できず、Small Page に切り替えてメモリ確保を行ったものとなります(Small Pageの場合は連続領域にメモリを確保する必要がありません)。
詳細は、技術資料:Windows上でのCaché共有メモリの割り当てについて やドキュメントをご参照ください。
関連するFAQトピック:Windows上での共有メモリの割り当てについて
記事
Mihoko Iijima · 2021年5月23日
これは InterSystems FAQ サイトの記事です。
%Net.FtpSession クラスを使用して FTP サーバから、アップロード/ダウンロードする方法をご紹介します。
1. FTPサーバにイメージファイルをアップロードする
set tmpfile="c:\temp\test.jpg"
set ftp=##class(%Net.FtpSession).%New()
// ftp サーバへ接続する
do ftp.Connect("<サーバ名>","<ユーザ名>","<パスワード>")
// 転送モードをBINARYに設定
do ftp.Binary()
// アップロードするディレクトリに移動
do ftp.SetDirectory("/temp/upload")
// アップロードするファイルのストリームを用意
set file=##class(%File).%New(tmpfile)
do file.Open("UK\BIN\")
// ファイルをアップロード
// 第1引数: アップロード先に作成するファイル名
// 第2引数: アップロードするファイル・ストリーム
do ftp.Store("test.jpg",file)
// ftp サーバからログアウト
do ftp.Logout()
// ファイルを閉じる
do file.Close()
// (オプション) アップロードしたファイルを削除する
//do ##class(%File).Delete(tmpfile)
2. FTPサーバからイメージファイルをダウンロードする
set ftp=##class(%Net.FtpSession).%New() // ftp サーバへ接続する
do ftp.Connect("<サーバ名>","<ユーザ名>","<パスワード>") // 転送モードをBINARYに設定
do ftp.Binary() // ダウンロードして格納するファイル・ストリームを用意
set stream=##class(%FileBinaryStream).%New()
do stream.LinkToFile("c:\temp\testdownload.jpg")
// ダウンロードするディレクトリに移動
do ftp.SetDirectory("/temp/download") // ファイルをダウンロードしてストリームを閉じる
do ftp.Retrieve("test.jpg",stream)
do stream.SaveStream()
Set stream="" // ftp サーバからログアウト
do ftp.Logout()
関連する FAQ トピックもご参照ください。
%Net.FtpSession クラスを使用してファイルサイズを取得する方法はありますか?
記事
Hiroshi Sato · 2021年9月9日
これは InterSystems FAQ サイトの記事です。
%CSP.REST クラスを継承する REST 用ディスパッチクラスで REST を実装している場合は、クロスドメイン制約回避用に用意されたパラメータ HandleCorsRequest を利用します。
設定方法は以下の通りです。
REST 用ディスパッチクラスをスタジオで修正する場合は、[クラス] > [リファクタ] > [オーバーライド] を開き、[パラメータ]タブを選択 > [HandleCorsRequest] を選択後OKボタンを押下します。
以下の定義が追加されるので、1を設定します。
Parameter HandleCorsRequest=1;
REST ディスパッチクラスを Atelier で修正する場合は、オーバーライドメニューの用意がないため、パラメータの定義を追加するか、%CSP.REST クラスを開き、HandleCorsRequest の定義をコピーし修正します。
パラメータ:HandleCorsRequest 他に、REST 用ディスパッチクラスに用意する URL マップ(URL に対応するメソッドのマップ定義)の Route 要素毎に Cors 属性を true に設定する方法でも回避できます。メモ:Cors 属性はデフォルトでは false が設定されています。
XData UrlMap{<Routes><Route Url="/persons/:keyword" Method="GET" Call="REST.Person:getperson" Cors="true" /><Route Url="/persons2/" Method="POST" Call="REST.Person:getperson2"/>Routes>}
設定詳細については以下ドキュメントをご参照ください。
CORS使用のためのRESTサービスの構成について【IRIS】
CORS使用のためのRESTサービスの構成について
コードサンプルについては、関連トピックをご参照ください。
JQueryでデータをJSON形式で取得する方法
記事
Tomoko Furuzono · 2024年3月18日
これは、InterSystems FAQサイトの記事です。
【任意のXMLドキュメントの読み込み】任意のXMLドキュメントの読み込みを行うには、%XML.TextReaderクラスを使用します。Parseメソッド(※ドキュメントがファイルの場合はParseFile())を使用してドキュメントをパースし、各ノードのプロパティを取得します。
例えば、下記のXMLの場合、
<emp empid="1"> <name>Suzuki</name> <address>Tokyo</address> </emp>
各赤枠が、"ノード"の単位となり、
下記のようなイメージで取得することができます。
ノード・プロパティ名
seq
NodeType
Name
Value
(属性)
LocalName
Value
プロパティ値
1
element
emp
empid
1
2
element
name
3
chars
Suzuki
4
endelement
name
5
element
address
6
chars
Tokyo
7
endelement
address
8
endelement
emp
コード例:
readXML
set sc=##class(%XML.TextReader).ParseFile("C:\temp\aaa.xml",.treader)
d $SYSTEM.Status.DisplayError(sc)
while (treader.Read()) {
write treader.seq," "
write "[Type]",treader.NodeType," "
write "[Name]",treader.Name," "
write "[Value]",treader.Value," "
if (treader.NodeType="element"){
for i=1:1:treader.AttributeCount {
do treader.MoveToAttributeIndex(i)
write "[Att] ",treader.LocalName,"=",treader.Value
}
}
write !
}
quit
%XML.TextReaderについての詳細は、下記のドキュメントをご参照ください。[ドキュメント] %XML.TextReader の使用【任意のXMLドキュメントの書き出し】任意のXMLドキュメントを作成(書き出し)するには、%XML.Writerを使用します。
コード例:
writeXML
set xml=##class(%XML.Writer).%New()
set xml.Indent=1
do xml.OutputToFile("C:\temp\out.xml")
do xml.RootElement("employees")
do xml.Element("emp"),xml.WriteAttribute("empid","1")
do xml.Element("name"),xml.WriteChars("Suzuki"),xml.EndElement()
do xml.EndElement() // emp
do xml.EndRootElement() // employees
quit
上記を実行すると、下記の内容のファイルが出力されます。
<?xml version="1.0" encoding="UTF-8"?><employees> <emp empid="1"> <name>Suzuki</name> </emp></employees>
%XML.Writerについての詳細は、下記のクラスリファレンスをご参照ください。[クラスリファレンス] %XML.Writer
記事
Toshihiko Minamoto · 2022年2月3日
キーワード: Pandasデータフレーム、IRIS、Python、JDBS
## 目的
PandasデータフレームはEDA(探索的データ分析)に一般的に使用されるツールです。 MLタスクは通常、データをもう少し理解することから始まります。 先週、私は[KaggleにあるこちらのCovid19データセット](https://www.kaggle.com/S%C3%ADrio-Libanes/execution)を試していました。 基本的に、このデータは1925件の遭遇の行と231列で構成されており、タスクは、患者(1つ以上の遭遇レコードにリンク)がICUに入室するかどうかを予測するものです。 つまりこれは、いつものようにpandas.DataFrameを使用して、まず簡単にデータを確認する、通常の分類タスクです。
現在では、[IRIS IntegratedML](https://github.com/intersystems-community/integratedml-demo-template)が提供されています。これには強力な「AutoML」のオプションに関する洗練されたSQLラッパーがあるため、従来型のMLアルゴリズムに対抗して、多様なデータフレームのステージをIRISデータベーステーブルに保存してから、IntegratedMLを実行する方法を頻繁に採用しています。 ただし、[dataframe.to_sql()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_sql.html)はまだIRISで機能しないため、実際には、ほとんどの時間を他のデータ保存手段をいじることに充てていました。 いわば、土曜の朝の楽しい朝食の時間に素敵なオムレツを作ろうとしていたのに、一日中コンロの下で、ガスとシンクの配管作業をしていたような状況です。 さて、完璧ではありませんが、数週間後に忘れてしまわないように、簡単なメモを残しておくことにします。
## 範囲
IRISで[dataframe.to_sql()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_sql.html)を作成しませんでした。残念ながら、まだそこにはたどり着いていませんが、JDBC(JayDeBeApi)を介してデータフレームを動的に直接IRISに保存する簡単なPython関数をできるだけ単純かつ生の状態を維持してさくせいしました。 既知の問題(「MemoryError」)により、PyODBCではまだ機能しない可能性があります。
## 環境
以下のスクリプトのベースとして、[単純なdocker-coposeを介したこちらのIntegratedMLテンプレート](https://github.com/intersystems-community/integratedml-demo-template)を使って、テストしています。 [環境トポロジー](https://user-images.githubusercontent.com/8899513/85149599-7848f900-b21f-11ea-9b65-b5d703752de3.PNG)はGitHubリポジトリに含まれます。 IRISコンテナーに接続するには、こちらの[JDBC Jupyterノートブック](https://github.com/intersystems-community/integratedml-demo-template/blob/master/jupyter-samples/campaign-integratedml-jdbc.ipynb)を使用しています。
## テスト
### 1. dataframe.to_sql() をエミュレートするPython関数を定義する
ノートブックのセルで以下を実行しました。
def to_sql_iris(cursor, dataFrame, tableName, schemaName='SQLUser', drop_table=False ):
<span style="color:#999999;"> """"
Dynamically insert dataframe into an IRIS table via SQL by "excutemany"
Inputs:
cursor: Python JDBC or PyODBC cursor from a valid and establised DB connection
dataFrame: Pandas dataframe
tablename: IRIS SQL table to be created, inserted or apended
schemaName: IRIS schemaName, default to "SQLUser"
drop_table: If the table already exsits, drop it and re-create it if True; othrewise keep it and appen
Output:
True is successful; False if there is any exception.
"""</span>
if drop_table:
try:
curs.execute("DROP TABLE %s.%s" %(schemaName, tableName))
except Exception:
pass
try:
dataFrame.columns = dataFrame.columns.str.replace("[() -]", "_")
curs.execute(pd.io.sql.get_schema(dataFrame, tableName))
except Exception:
pass
curs.fast_executemany = True
cols = ", ".join([str(i) for i in dataFrame.columns.tolist()])
wildc =''.join('?, ' * len(dataFrame.columns))
wildc = '(' + wildc[:-2] + ')'
sql = "INSERT INTO " + tableName + " ( " + cols.replace('-', '_') + " ) VALUES" + wildc
#print(sql)
curs.executemany(sql, list(dataFrame.itertuples(index=False, name=None)) )
return True
基本的に、上記はIRISテーブルにデータフレームを動的に挿入しようとしています。 テーブルがすでに存在する場合は、完全なデータフレームがその最後にアペンドされますが、存在しない場合は、データフレームの次元(列名と列の型)に基づく新しいテーブルが作成され、その全コンテンツが挿入されます。 `executemanyメソッド`を使用しているだけです。
### 2. テスト - 生データファイルをデータフレームに読み込む
ノートブックで以下のコードを実行し、ローカルのドライブからデータフレームに生データを読み込みます。 生データは、[こちらのKaggleサイトからダウンロード](https://www.kaggle.com/S%C3%ADrio-Libanes/execution)可能です。
import numpy as np
import pandas as pd
from sklearn.impute import SimpleImputer
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, roc_auc_score, roc_curve
import seaborn as sns
sns.set(style="whitegrid")
import os
for dirname, _, filenames in os.walk('./input'):
for filename in filenames:
print(os.path.join(dirname, filename))
df = pd.read_excel("./input/raw_data_kaggle_covid_icu.xlsx")
df
./input/datasets_605991_1272346_Kaggle_Sirio_Libanes_ICU_Prediction.xlsx
Out[2]:
PATIENT_VISIT_IDENTIFIER
AGE_ABOVE65
AGE_PERCENTIL
GENDER
DISEASE GROUPING 1
DISEASE GROUPING 2
DISEASE GROUPING 3
DISEASE GROUPING 4
DISEASE GROUPING 5
DISEASE GROUPING 6
...
TEMPERATURE_DIFF
OXYGEN_SATURATION_DIFF
BLOODPRESSURE_DIASTOLIC_DIFF_REL
BLOODPRESSURE_SISTOLIC_DIFF_REL
HEART_RATE_DIFF_REL
RESPIRATORY_RATE_DIFF_REL
TEMPERATURE_DIFF_REL
OXYGEN_SATURATION_DIFF_REL
WINDOW
ICU
1
60th
0.0
0.0
0.0
0.0
1.0
1.0
...
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
0-2
1
1
60th
0.0
0.0
0.0
0.0
1.0
1.0
...
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
2-4
2
1
60th
0.0
0.0
0.0
0.0
1.0
1.0
...
NaN
NaN
NaN
NaN
NaN
NaN
NaN
NaN
4-6
3
1
60th
0.0
0.0
0.0
0.0
1.0
1.0
...
-1.000000
-1.000000
NaN
NaN
NaN
NaN
-1.000000
-1.000000
6-12
4
1
60th
0.0
0.0
0.0
0.0
1.0
1.0
...
-0.238095
-0.818182
-0.389967
0.407558
-0.230462
0.096774
-0.242282
-0.814433
ABOVE_12
1
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
1920
384
50th
1
0.0
0.0
0.0
0.0
0.0
0.0
...
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
0-2
1921
384
50th
1
0.0
0.0
0.0
0.0
0.0
0.0
...
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
2-4
1922
384
50th
1
0.0
0.0
0.0
0.0
0.0
0.0
...
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
4-6
1923
384
50th
1
0.0
0.0
0.0
0.0
0.0
0.0
...
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
-1.000000
6-12
1924
384
50th
1
0.0
0.0
1.0
0.0
0.0
0.0
...
-0.547619
-0.838384
-0.701863
-0.585967
-0.763868
-0.612903
-0.551337
-0.835052
ABOVE_12
1925 rows × 231 columns
### 3. テスト - Python over JDBCでIRIS DBに接続する
import jaydebeapi
url = "jdbc:IRIS://irisimlsvr:51773/USER"
driver = 'com.intersystems.jdbc.IRISDriver'
user = "SUPERUSER"
password = "SYS"
jarfile = "./intersystems-jdbc-3.1.0.jar"
conn = jaydebeapi.connect(driver, url, [user, password], jarfile)
curs = conn.cursor()
### 4. テスト - データフレームをIRISテーブルに保存する
iris_schema = 'SQLUser'
iris_table = 'Covid19RawTableFromCSV'
to_sql_iris(curs, df, iris_table, iris_schema, drop_table=True) # save it into a new IRIS table of specified name
#to_sql_iris(curs, df, iris_table) # append dataframe to an exsiting IRIS table
Out[4]: True
import pandas as pd
from IPython.display import display
df2 = pd.read_sql("SELECT COUNT(*) from %s.%s" %(iris_schema, iris_table),conn)
display(df2)
Aggregate_1
0
1925
したがって、全データが「`Covid19RawTableFromCSV`」というIRISテーブルに挿入されました。IRIS管理ポータルにログインすると、レコードが含まれるそのテーブルも表示されます。
### 5. テスト - 簡単なベンチマークを実行する
このデータフレームをたとえば10回挿入して、1つのJDBCセッションでこの基本的なCE dockerに掛かった時間を確認しましょう。
from tqdm import tqdm
import pandas as pd
import time
from IPython.display import display
start = time.clock()
for i in tqdm(range(0, 10)):
to_sql_iris(curs, df, iris_table)
print("Total time elasped: ", time.clock()-start, " for importing total records:")
df2 = pd.read_sql("SELECT COUNT(*) from %s.%s" %(iris_schema, iris_table),conn)
display(df2)
100%|██████████| 10/10 [00:14<00:00, 1.42s/it]
Total time elasped: 12.612431999999998 for importing total records:
Aggregate_1
0
19250
以上です。非常に基本的ではありますが、少なくともデータ分析パイプラインに沿って操作されたデータフレームを保存し、多少本格的なMLを試すために、SQLインターフェースを介してIntegratedMLを呼び出すことができるようになりました。
言及すべき**警告**: データフレームの文字列は、「オブジェクト」として解釈されることがあるため、df['column'].astype(str)などを使用して、IRISテーブルに挿入される前に文字列に変換する必要があります。 「DROP TABLE」は前のテーブルを上書きするために使用されます。 「DROP VIEW」は前のビューを削除するために使用できます。
記事
Toshihiko Minamoto · 2023年5月2日
InterSystems 2022.2 では、IRIS SQL テーブルを永続化する新しいオプションとして、[分析クエリを桁違いに向上](http://learning.intersystems.com/course/view.php?id=2077)させられる[カラムナーストレージ](https://learning.intersystems.com/course/view.php?name=ColumnarIntro)を導入しました。 2022.2 と 2022.3 ではこの機能は実験的としてマークされていますが、次の 2023.1 リリースでは、完全にサポートされた本番機能に「卒業」する予定です。
[製品ドキュメント](https://docs.intersystems.com/iris20222/csp/docbook/DocBook.UI.Page.cls?KEY=GSOD_storage)とこの[紹介動画](https://learning.intersystems.com/course/view.php?name=ColumnarIntro)では、IRIS では現在でもデフォルトであり、全顧客ベースで使用されている行ストレージと、このカラムナーストレージの違いがすでに説明されており、ユースケースに適切なストレージレイアウトの選択方法に関する大まかなガイダンスが提供されています。 この記事では、このテーマについて詳しく説明し、業界で実践されているモデリング原則、内部テスト、および早期アクセスプログラム参加者からのフィードバックに基づく推奨事項をいくつか紹介します。
全般的に、IRIS SQL スキーマに適したテーブルレイアウトを選択するためのガイダンスは以下のとおりです。
1. **EHR、ERP、またはトランザクション処理アプリケーションなど、IRIS SQL またはオブジェクトを利用するアプリケーションをデプロイしている場合は、現在の行ストレージレイアウトをカラムナーストレージレイアウトに変更する必要はありません。**エンドユーザーやプログラムトランザクションに対して発行されるほとんどの SQL クエリは、限られた数の行のみを取得または更新し、結果行は通常テーブルの行に対応しており、集計関数の使用もほんのわずかです。 カラムナーストレージとベクトル化されたクエリ処理から得られるメリットはこのような場合に適用されません。
2. **そのようなアプリケーションに運用分析も組み込まれおり、対応する分析クエリの現在のパフォーマンスが満足いくものでなければ、列インデックスの追加を検討してください。**これには、現在のインベントリを表示するダッシュボードやライブデータに関する基本的な財務レポートなどが含まれます。 集計に使用される数値フィールド(数量、通貨など)または範囲条件で使用されるカーディナリティの高いフィールド(タイムスタンプなど)を探します。 そのような可能性を示すのに適した指標は、通常カーディナリティの低いフィールド(カテゴリカルフィールドや順序フィールドなど)で大量の行のフィルタリングを高速化するビットマップインデックスの現在の使用状況です。 これらのビットマップインデックスを置き換える必要はありません。追加の列インデックスはそれらと連携して十分に動作し、マスターマップまたは通常のインデックスマップ(行あたり 1 つの gref)からの過剰な読み取りを回避することが目的です。
3. **IRIS SQL テーブルに含まれる行数が 100 万行未満である場合、カラムナーストレージを検討する必要はありません。**具体的な数に固執したくはありませんが、ベクトル化されたクエリ処理のメリットが、これらの低い範囲に影響を及ぼす可能性はありません。
4. **IRIS SQL スキーマをデータウェアハウス、ビジネスインテリジェンス、または同様の分析ユースケースにでデプロイしている場合は、カラムナーストレージがデフォルトとなるように変更することを検討してください。**スタースキーマ、スノーフレークスキーマ、またはその他の非正規化されたテーブル構造、およびビットマップインデックスとバッチインジェストの広範な使用は、これらのユースケースが該当することを示しています。 カラムナーストレージのメリットがある分析クエリは、大量の行をスキャンし、それらの値を集計するクエリです。 「カラムナーテーブル」を定義する場合、IRIS は、ストリーム、ロング文字列、またはシリアルフィールドなど、カラムナーストレージに適していないテーブル内の列に行レイアウトを透過的に使用します。 IRIS SQL はこのような混合テーブルレイアウトを完全にサポートしており、クエリプランの適切な部分にベクトル化されたクエリ処理を使用します。 カラムナーテーブルに対するビットマップインデックスの付加価値は限られているため、省略できます。
**環境とデータ関連のパラメーターによって、向上の程度は異なります。 したがって、代表的なセットアップで様々なレイアウトをテストすることを強くお勧めします。**列インデックスは、通常の行編成テーブルに簡単に追加でき、クエリパフォーマンスのメリットについて現実的な見通しを素早く生成することができます。 これは、混合テーブルレイアウトの柔軟性とともに、InterSystems IRIS の重要な差別化要因であり、桁違いのパフォーマンス改善を達成するのに役立ちます。
完全な本番リリースで実際のエクスペリエンスをさらに得るにつれ、これらの推奨事項をより具体化していく予定です。 もちろん、早期アクセスプログラムと POC エンゲージメントでは、お客様の実際のスキーマとワークロードに基づくより具体的なアドバイスを提供できます。お客様とコミュニティメンバーからのフィードバックを楽しみにお待ちしています。 カラムナーストレージは、InterSystems IRIS Advanced Server ライセンスの一部であり、InterSystems IRIS と IRIS for Health の Community Edition でも有効になっています。 完全にスクリプト化されたデモ環境については、[こちらの GitHub リポジトリ](https://github.com/bdeboe/isc-taxi-demo)をご覧ください。 カラムナーストレージに関しては、IRIS 2022.3のリリースセミナーにて紹介されています。
ご興味のある方は、こちらをご覧ください。
記事
Toshihiko Minamoto · 2022年1月25日
**キーワード**: PyODBC、unixODBC、IRIS、IntegratedML、Jupyterノートブック、Python 3
## **目的**
数か月前、私は「[IRISデータベースへのPython JDBC接続](https://jp.community.intersystems.com/node/507856)」という簡易メモを書きました。以来、PCの奥深くに埋められたスクラッチパッドよりも、その記事を頻繁に参照しています。 そこで今回は、もう一つの簡易メモで「IRISデータベースへのPython ODBC接続」を作成する方法を説明します。
ODBCとPyODCBをWindowsクライアントでセットアップするのは非常に簡単なようですが、Linux/Unix系サーバーでunixODBCとPyODBCクライアントをセットアップする際には毎回、どこかで躓いてしまいます。
バニラLinuxクライアントで、IRISをインストールせずに、リモートIRISサーバーに対してPyODBC/unixODBCの配管をうまく行うための単純で一貫したアプローチがあるのでしょうか。
## **範囲**
最近、Linux Docker環境のJupyterノートブック内でゼロからPyODBCデモを機能させるようにすることに少しばかり奮闘したことがありました。 そこで、少し冗長的ではありますが、後で簡単に参照できるように、これをメモに残しておくことにしました。
#### **範囲内**
このメモでは、以下のコンポーネントに触れます。
PyODBC over unixODBC
TensorFlow 2.2とPython 3を使ったJupyter Notebookサーバー
サンプルテストデータを含むIntegratedMLを使ったIRIS2020.3 CEサーバー
この環境内で:
AWS Ubuntu 16.04におけるdocker-composeによるDockerエンジン
Docker Desktop for MacOS、およびDocker Toolbox for Windows 10もテストされます。
#### **範囲外**:
繰り返しになりますが、このデモ環境で機能しない部分は評価されません。 それらは重要なことであり、以下のようにサイト固有の機能である可能性があります。
エンドツーエンドのセキュリティと監査
パフォーマンスとスケーラビリティ
ライセンスとサポート可能性など
## **環境**
以下の構成とテスト手順では、任意のバニラLinux Dockerイメージを使用できますが、以下のようにすると、そのような環境を5分で簡単にセットアップできます。
1. この[デモテンプレート](https://github.com/tom-dyar/integratedml-demo-template)をGit **clone**します。
2. クローンされた、docker-compose.ymlファイルを含むディレクトリで"**docker-compose up -d**"を実行します。
以下のトポロジーのように、2つのコンテナーのデモ環境が作成されます。 1つはPyODBCクライアントとしてのJupyter Notebookサーバー用で、もう1つはIRIS2020.3 CEサーバー用です。
上記の環境では、tf2jupyterには"Python over JDBC"クライアント構成しか含まれておらず、ODBCまたはPyODBCクライアント構成はまだ含まれていません。
そこで、わかりやすくするために、以下の手順を実行して、Jupyter Notebook内から直接それらをセットアップしましょう。
## **手順**
AWS Ubuntu 16.04サーバーで、以下の構成とテストを実行しました。 私の同僚の@Thomas.Dyarは、MacOSで実行しました。 また、Docker Toolbox for Windowsでも簡単にテストされていますが、 何らかの問題に遭遇した場合は、お知らせください。
以下の手順は、Dockerfileに簡単に自動化できます。 ここでは、どのように行われたかを数か月後に忘れてしまった場合に備えて、手動で記録しました。
### **1. 公式ドキュメント**
IRISのODBCサポート
UnixにおけるODBCデータソースの定義
IRISのPyODBCサポート
### **2. Jupyterサーバーに接続する**
私はローカルのPuttyのSSHトンネリングを使用してリモートのAWS Ubuntuポート22に接続し、上記のトポロジーのようにポート8896にマッピングしました。
(ローカルのdocker環境では、たとえば、直接dockerマシンのIP:8896にHTTP接続することもできます。)
### **3. Jupyterノートブック内からODBCインストールを実行する**
Jupyterのセル内から直接以下を実行します。
!apt-get update<br>!apt-get install gcc<br>!apt-get install -y tdsodbc unixodbc-dev<br>!apt install unixodbc-bin -y<br>!apt-get clean -y
上記は、次の手順でPyODBCドライバーをリコンパイルするために必要なgcc(g++を含む)、FreeTDS、unixODBC、およびunixodbc-devをインストールします。
この手順はネイティブWindowsサーバーまたはPCでのPyODBCインストールには必要ありません。
### **4. Jupyter内からPyODBCインストールを実行する**
!pip install pyodbc
Collecting pyodbc
Downloading pyodbc-4.0.30.tar.gz (266 kB)
|████████████████████████████████| 266 kB 11.3 MB/s eta 0:00:01
Building wheels for collected packages: pyodbc
Building wheel for pyodbc (setup.py) ... done
Created wheel for pyodbc: filename=pyodbc-4.0.30-cp36-cp36m-linux_x86_64.whl size=273453 sha256=b794c35f41e440441f2e79a95fead36d3aebfa74c0832a92647bb90c934688b3
Stored in directory: /root/.cache/pip/wheels/e3/3f/16/e11367542166d4f8a252c031ac3a4163d3b901b251ec71e905
Successfully built pyodbc
Installing collected packages: pyodbc
Successfully installed pyodbc-4.0.30
上記は、このDockerデモ用に最小化されたpip installです。 [公式ドキュメント](https://irisdocs.intersystems.com/iris20211/csp/docbookj/DocBook.UI.Page.cls?KEY=BNETODBC_support#BNETODBC_support_pyodbc)には、「MacOS Xインストール」用のより詳細なpip installが提供されています。
### **5. LinuxでODBC INIファイルとリンクを再構成する**
以下を実行して、**odbcinst.ini**と**odbc.ini**リンクを再作成します。
!rm /etc/odbcinst.ini!rm /etc/odbc.ini
!ln -s /tf/odbcinst.ini /etc/odbcinst.ini!ln -s /tf/odbc.ini /etc/odbc.ini
注意: 上記を行う理由は、**手順3と4では通常2つの空の(したがって無効な)ODBCファイルが\etc\ディレクトリに作成される**ためです。Windowsインストールとは異なりこれらの空のiniファイルは問題を生じるため、まずそれらを削除してから、マッピングされたDockerボリュームに提供されている実際のiniファイル(/tf/odbcinst.ini, and /tf/odbc.ini)へのリンクを再作成してください。
これらの2つのiniファイルをチェックしましょう。この場合、Linux ODBC構成の最も単純な形式です。
!cat /tf/odbcinst.ini
[InterSystems ODBC35]
UsageCount=1
Driver=/tf/libirisodbcu35.so
Setup=/tf/libirisodbcu35.so
SQLLevel=1
FileUsage=0
DriverODBCVer=02.10
ConnectFunctions=YYN
APILevel=1
DEBUG=1
CPTimeout=<not pooled>
!cat /tf/odbc.ini
[IRIS PyODBC Demo]
Driver=InterSystems ODBC35
Protocol=TCP
Host=irisimlsvr
Port=51773
Namespace=USER
UID=SUPERUSER
Password=SYS
Description=Sample namespace
Query Timeout=0
Static Cursors=0
上記のファイルは事前構成済みであり、マッピングされたドライブで提供されています。 IRISサーバーのコンテナーインスタンスからも取得できるドライバーファイル**libirisodbcu35.so**を参照しています。
したがって、上記のODBCインストールを機能させるには、**これらの3つのファイルがマッピングされたドライブ(または任意のLinuxドライブ)に存在**し、**適切なファイルアクセス権が適用されている**ことが必要です。
libirisodbcu35.so
odbcinst.ini
odbc.ini
**6. PyODBCのインストールを検証する **
!odbcinst -j
unixODBC 2.3.4
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /root/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
import pyodbcprint(pyodbc.drivers())
['InterSystems ODBC35']
上記の出力では、現在ODBCドライバーに有効なリンクがあることが示されています。
Jupyter NotebookでPython ODBCテストを実行できるはずです。
**7. IRISサンプルへのPython ODBC接続を実行する**
import pyodbc import time
### 1. Get an ODBC connection #input("Hit any key to start")dsn = 'IRIS PyODBC Demo'server = 'irisimlsvr' # IRIS server container or the docker machine's IP port = '51773' # or 8091 if docker machine IP is useddatabase = 'USER' username = 'SUPERUSER' password = 'SYS'
#cnxn = pyodbc.connect('DSN='+dsn+';') # use the user DSN defined in odbc.ini, or use the connection string belowcnxn = pyodbc.connect('DRIVER={InterSystems ODBC35};SERVER='+server+';PORT='+port+';DATABASE='+database+';UID='+username+';PWD='+ password)
###ensure it reads strings correctly.cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf8')cnxn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf8')cnxn.setencoding(encoding='utf8')
### 2. Get a cursor; start the timercursor = cnxn.cursor()start= time.clock()
### 3. specify the training data, and give a model namedataTable = 'DataMining.IrisDataset'dataTablePredict = 'Result12'dataColumn = 'Species'dataColumnPredict = "PredictedSpecies"modelName = "Flower12" #chose a name - must be unique in server end
### 4. Train and predict#cursor.execute("CREATE MODEL %s PREDICTING (%s) FROM %s" % (modelName, dataColumn, dataTable))#cursor.execute("TRAIN MODEL %s FROM %s" % (modelName, dataTable))#cursor.execute("Create Table %s (%s VARCHAR(100), %s VARCHAR(100))" % (dataTablePredict, dataColumnPredict, dataColumn))#cursor.execute("INSERT INTO %s SELECT TOP 20 PREDICT(%s) AS %s, %s FROM %s" % (dataTablePredict, modelName, dataColumnPredict, dataColumn, dataTable)) #cnxn.commit()
### 5. show the predict resultcursor.execute("SELECT * from %s ORDER BY ID" % dataTable) #or use dataTablePredict result by IntegratedML if you run step 4 aboverow = cursor.fetchone() while row: print(row) row = cursor.fetchone()
### 6. CLose and clean cnxn.close()end= time.clock()print ("Total elapsed time: ")print (end-start)
(1, 1.4, 0.2, 5.1, 3.5, 'Iris-setosa')
(2, 1.4, 0.2, 4.9, 3.0, 'Iris-setosa')
(3, 1.3, 0.2, 4.7, 3.2, 'Iris-setosa')
(4, 1.5, 0.2, 4.6, 3.1, 'Iris-setosa')
(5, 1.4, 0.2, 5.0, 3.6, 'Iris-setosa')
... ...
... ...
... ...
(146, 5.2, 2.3, 6.7, 3.0, 'Iris-virginica')
(147, 5.0, 1.9, 6.3, 2.5, 'Iris-virginica')
(148, 5.2, 2.0, 6.5, 3.0, 'Iris-virginica')
(149, 5.4, 2.3, 6.2, 3.4, 'Iris-virginica')
(150, 5.1, 1.8, 5.9, 3.0, 'Iris-virginica')
Total elapsed time:
0.023873000000000033
ここにはいくつかの落とし穴があります。
1. **cnxn = pyodbc.connect() ** - Linux環境では、この呼び出しに渡される接続文字列は、スペースなしで文字通り正しい必要があります。
2. 接続エンコーディングをたとえばuft8などで適切に設定してください。 この場合は、文字列のデフォルトエンコーディングは機能しません。
3. **libirisodbcu35.so** - 理想的には、このドライバーファイルはリモートIRISサーバーのバージョンと緊密に連携する必要があります。
## **今後の内容 **
これで、リモートIRISサーバーへのPyODBC(およびJDBC)接続による、Python 3とTensorFlow 2.2(GPUなし)を含むJupyterノートブックのDocker環境を得られました。 IRIS IntegratedML固有のSQL構文など、特別に設計されたすべてのSQL構文で機能するはずです。そこで、IntegratedMLの機能をもう少し探り、MLライフサイクルを駆動するSQL手法を工夫してみてはどうでしょうか。
また、次回は、Python環境でIRISネイティブSQLまたはマジックSQLを使用してIRISサーバーに接続する上で、最も単純なアプローチに触れられればと思います。 また、今では優れた[Python Gateway](https://github.com/intersystems-community/PythonGateway)を使用できるため、外部のPython MLアプリケーションとサービスをIRISサーバー内から直接呼び出してみることも可能です。これについてもさらに詳しく試せればいいなと思っています。
**付録**
上記のノートブックファイルは、こちらのGitHubリポジトリとOpen Exchangeにチェックインされます。
記事
Toshihiko Minamoto · 2022年5月17日
## はじめに
[前の記事](https://jp.community.intersystems.com/node/516111)では、ObjectScript Package Manager を使用してユニットテストを実行するためのパターンについて説明しました。 この記事では、さらに一歩踏み込み、GitHub Actions を使用してテストの実行とレポート作成を行います。 私の Open Exchange プロジェクトの 1 つである [AppS.REST](https://openexchange.intersystems.com/package/apps-rest) に CI を実行するのが、やる気の出るユースケースでしょう(この導入編の記事は、[こちら](https://jp.community.intersystems.com/node/497991)にあります)。 この記事のスニペットが使用されている完全な実装は、[GitHub](https://github.com/intersystems/apps-rest/blob/master/.github/workflows/main.yml) でご覧ください。ObjectScript Package Manager を使って他のプロジェクトで CI を実行するためのテンプレートとして簡単に利用できます。
紹介する実装の機能は以下のとおりです。
* ObjectScript パッケージの構築とテスト
* [codecov.io](https://codecov.io) によるテストカバレッジ測定のレポート([TestCoverage](https://openexchange.intersystems.com/package/Test-Coverage-Tool) パッケージを使用)
* テスト結果に関するレポートのビルドアーティファクトとしてのアップロード
## ビルド環境
GitHub Actions に関する完全なドキュメントは[こちら](https://docs.github.com/ja/actions)にあります。この記事の目的に準じ、この例で紹介される側面だけを詳しく確認します。
GitHub Actions のワークフローは、構成可能な一連のイベントによってトリガーされ、順番に、または並行して実行できる多数のジョブで構成されています。 それぞれのジョブには一連のステップがあります。このサンプルアクションのステップは、少し後の方で詳しく説明します。 これらのステップは、GitHub で提供されているアクションへの参照で構成されているか、単にシェルコマンドである場合があります。 この例での最初のボイラープレートのスニペットは、以下のようになります。
# Continuous integration workflow
name: CI
# Controls when the action will run. Triggers the workflow on push or pull request
# events in all branches
on: [push, pull_request]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
env:
# Environment variables usable throughout the "build" job, e.g. in OS-level commands
package: apps.rest
container_image: intersystemsdc/iris-community:2019.4.0.383.0-zpm
# More of these will be discussed later...
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# These will be shown later...
この例では、多数の環境変数が使用されています。 この例を ObjectScript Package Manager を使用して他のパッケージに適用する場合、ほとんどの変数を変更する必要はありませんが、一部には変更が必要です。
env:
# ** FOR GENERAL USE, LIKELY NEED TO CHANGE: **
package: apps.rest
container_image: intersystemsdc/iris-community:2019.4.0.383.0-zpm
# ** FOR GENERAL USE, MAY NEED TO CHANGE: **
build_flags: -dev -verbose # Load in -dev mode to get unit test code preloaded
test_package: UnitTest
# ** FOR GENERAL USE, SHOULD NOT NEED TO CHANGE: **
instance: iris
# Note: test_reports value is duplicated in test_flags environment variable
test_reports: test-reports
test_flags: >-
-verbose -DUnitTest.ManagerClass=TestCoverage.Manager -DUnitTest.JUnitOutput=/test-reports/junit.xml
-DUnitTest.FailuresAreFatal=1 -DUnitTest.Manager=TestCoverage.Manager
-DUnitTest.UserParam.CoverageReportClass=TestCoverage.Report.Cobertura.ReportGenerator
-DUnitTest.UserParam.CoverageReportFile=/source/coverage.xml
これを独自のパッケージに適応させるには、独自のパッケージ名と優先するコンテナイメージをドロップしてください(zpm を含める必要があります。 をご覧ください)。 また、ユニットテストパッケージが独自のパッケージの規則に一致するように変更することもお勧めします(ユニットテストを実行する前に、読み込みとコンパイルを行ってして依存関係の読み込み/コンパイルを処理する必要がある場合。私自身、このパッケージではユニットテストに特有の奇妙な問題に遭遇したためですが、他のケースでは関連性がないかもしれません)。
インスタンス名と test\_reports ディレクトリは、他の使用では変更する必要はありませんし、test\_flags には有効なデフォルトセットが備わっています。これらは、ユニットテストが失敗すると、ビルドを失敗としてフラグする機能をサポートしており、jUnit 形式のテスト結果とコードカバレッジレポートのエクスポートも処理できます。
## ビルドのステップ
### GitHub リポジトリの確認
この例では、テストされているリポジトリと、[Forgery](https://openexchange.intersystems.com/package/Forgery) のフォーク(ユニットテストで必要であるため)の2 つのリポジトリを確認する必要があります。
# Checks out this repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
# Also need to check out timleavitt/forgery until the official version installable via ZPM
- uses: actions/checkout@v2
with:
repository: timleavitt/forgery
path: forgery
$GITHUB_WORKSPACE は非常に重要な環境変数で、このすべてが実行するルートディレクトリを表します。 権限の観点では、そのディレクトリ内ではほぼあらゆる操作を実行できますが、他の場所では問題に遭遇するかもしれません。
### InterSystems IRIS コンテナの実行
最終的にテスト結果レポートを配置するディレクトリをセットアップしたら、ビルドの InterSystems IRIS Community Edition(+ZPM)コンテナを実行します。
- name: Run Container
run: |
# Create test_reports directory to share test results before running container
mkdir $test_reports
chmod 777 $test_reports
# Run InterSystems IRIS instance
docker pull $container_image
docker run -d -h $instance --name $instance -v $GITHUB_WORKSPACE:/source -v $GITHUB_WORKSPACE/$test_reports:/$test_reports --init $container_image
echo halt > wait
# Wait for instance to be ready
until docker exec --interactive $instance iris session $instance < wait; do sleep 1; done
コンテナに共有されている GitHub ワークスペース(コードを読み込めるようにするため。ここにはテストカバレッジ情報もレポートします)と jUnit テスト結果を配置する別のディレクトリの 2 つのボリュームがあります。
「docker run」が終了しても、インスタンスが完全に開始され、コマンドを処理する準備が整っているわけではありません。 インスタンスの準備が整うまで、iris セッションを通じて「halt」コマンドを実行し続けます。これは失敗となりますが、(最終的に)成功になるまで、1 秒に 1 回ずつ試行し続けます。成功になれば、インスタンスの準備は完了です。
### テスト関連ライブラリのインストール
このユースケースでは、他に [TestCoverage](https://openexchange.intersystems.com/package/Test-Coverage-Tool) と [Forgery](https://openexchange.intersystems.com/package/Forgery) という 2 つのライブラリを使用してテストします。 TestCoverage は、Community Package Manager を介して直接インストールできますが、Forgery については、(現時点では)zpm「load」を介して読み込む必要があります。いずれのアプローチも有効です。
- name: Install TestCoverage
run: |
echo "zpm \"install testcoverage\":1:1" > install-testcoverage
docker exec --interactive $instance iris session $instance -B < install-testcoverage
# Workaround for permissions issues in TestCoverage (creating directory for source export)
chmod 777 $GITHUB_WORKSPACE
- name: Install Forgery
run: |
echo "zpm \"load /source/forgery\":1:1" > load-forgery
docker exec --interactive $instance iris session $instance -B < load-forgery
一般的には、ファイルにコマンドを記述して空、IRIS セッションで実行します。 ZPM コマンドに追加されている「:1:1」は、エラーが発生したらエラーコードとともにプロセスを終了し、エラーが発生しない場合は最後に停止することを示しています。つまり、エラーが発生した場合は、失敗したビルドステップとして報告されるため、ファイルの最後に「halt」コマンドを追加する必要はありません。
### パッケージの構築とテスト
最後に、パッケージのテストを実際に構築して実行しましょう。 これはいたって単純です。始めの方で定義した $build\_flags/$test\_flags 環境変数が使用されていることに注目してください。
# Runs a set of commands using the runners shell
- name: Build and Test
run: |
# Run build
echo "zpm \"load /source $build_flags\":1:1" > build
# Test package is compiled first as a workaround for some dependency issues.
echo "do \$System.OBJ.CompilePackage(\"$test_package\",\"ckd\") " > test
# Run tests
echo "zpm \"$package test -only $test_flags\":1:1" >> test
docker exec --interactive $instance iris session $instance -B < build && docker exec --interactive $instance iris session $instance -B < test && bash <(curl -s https://codecov.io/bash)
これは、見たことのあるパターンに則っています。ファイルにコマンドを書き出してから、そのファイルを iris セッションの入力として使用しています。
最後の行の最後の部分は、コードカバレッジの結果を [codecov.io](https://codecov.io) にアップロードしています。 とても簡単です!
### ユニットテスト結果のアップロード
ユニットテストが失敗したとしましょう。 ビルドログに戻って、どこで間違ってしまったのかを見つけ出すのは本当に面倒な作業ですが、有用なコンテキストが得られるかもしれません。 作業を楽にするために、jUnit 形式の結果をアップロードできるだけでなく、サードパーティのプログラムを実行して、見栄えの良い HTML レポートに変換することも可能です。
# Generate and Upload HTML xUnit report
- name: XUnit Viewer
id: xunit-viewer
uses: AutoModality/action-xunit-viewer@v1
if: always()
with:
# With -DUnitTest.FailuresAreFatal=1 a failed unit test will fail the build before this point.
# This action would otherwise misinterpret our xUnit style output and fail the build even if
# all tests passed.
fail: false
- name: Attach the report
uses: actions/upload-artifact@v1
if: always()
with:
name: ${{ steps.xunit-viewer.outputs.report-name }}
path: ${{ steps.xunit-viewer.outputs.report-dir }}
このほとんどは、 の Readme から拝借したものです。
## 最終結果
このワークフローの結果は、以下でご覧いただけます。
intersystems/apps-rest での CI ジョブのログ(ビルドアーティファクトを含む):
テストカバレッジレポート:
ご質問がございましたら、お知らせください!
記事
Shintaro Kaminaka · 2020年4月28日
CachéまたはEnsembleへの接続にStudio、ODBC、またはターミナルを使用している場合、その接続をどのように保護すれば良いのか疑問に思うかもしれません。 選択肢の一つに、TLS(別名SSL)を接続に追加することが挙げられます。 Cachéクライアントアプリケーション(TELNET、ODBC、Studio)にはすべて、TLSを接続に追加する機能があります。 あとは単純にその構成を行うだけです。
2015.1以降はこれらのクライアントを簡単に設定できるようになりました。 ここでは、その新しい方法について説明します。 既に古い方法を使用している場合も引き続き機能しますが、新しい方法への切り替えを検討することをお勧めします。
背景
これらのクライアントアプリケーションは、サーバーがインストールされていないマシンにインストールできます。 ただし、CACHESYSデータベースやcpfファイルなど、設定を保存する通常の場所へのアクセスに依存することはできません。 その代わり、受け付ける証明書やプロトコルの設定はテキストファイルに保存されます。 このファイルの設定の多くは、管理ポータルのSSL/TLS構成の設定に似ています。
設定ファイルはどこにありますか?
独自のファイルを作成する必要があります。 クライアントインストーラーは設定ファイルを作成しません。
設定ファイルはデフォルトでSSLDefs.iniという名前になっており、32ビット共通プログラムファイルのディレクトリ配下のInterSystems\Cacheディレクトリに配置する必要があります。 このディレクトリは、CommonProgramFiles(x86)(64ビット版Windowsの場合)またはCommonProgramFiles(32ビット版Windowsの場合)というWindows環境変数で確認できます。
例えばWindows 8.1の場合、デフォルトのファイルは次のようになります。
C:\Program Files (x86)\Common Files\InterSystems\Cache\SSLdefs.ini
設定ファイルの場所を変更する場合は、クライアントの実行可能ファイルに設定ファイルの場所を伝える必要があります。 そのためには、環境変数ISC_SSLconfigurationsを定義し、それを使用するファイルの完全なパスとファイル名に設定する必要があります。 この操作には管理者権限が必要な場合があります。
設定ファイルには何が記載されていますか?
ファイルには2つのセクションがあります。 最初のセクションは、接続名とTLS構成に関する設定です。 例えば、development.intersystems.com に接続する際に「DefaultSettings」というセクションを使用してTLSパラメーターを検出するようにStudioに指示します。
2番目のセクションは、接続に使用するTLS設定を定義するものです。 例えば、サーバーの証明書を署名する認証局を定義します。 これらのセクションの設定は、CachéまたはEnsembleサーバーのSSL/TLS構成の設定に非常に似ています。
最初のセクションは次のようになります。
[Development Server]
Address=10.100.0.17
Port=1972
TelnetPort=23
SSLConfig=DefaultSettings
カッコ内の名前は任意に設定できます。 この名前は、どの接続であるかを把握しやすくするためだけにあります。
Address、Port、およびTelnetPort設定を使用して、このセクションに一致する接続を決定します。 2016.1以降のクライアントのアドレスには、IPアドレスかDNS名を使用できます。 構成を使用するにはAddress、およびPortかTelnetPortの両方がクライアントアプリケーションの接続先と一致する必要があります。
最後のパラメーター(SSLConfig)は、TLS設定を取得する構成の名前です。 ファイル内の構成のいずれかの名前と一致する必要があります。
セクションの2番目のタイプは次のようになります。
[DefaultSettings]
VerifyPeer=2
VerifyHost=1
CAfile=c:\InterSystems\certificates\CAcert.pem
CertFile=c:\InterSystems\certificates\ClientCert.pem
KeyFile=c:\InterSystems\certificates\ClientKey.key
Password=
KeyType=2
Protocols=24
CipherList=ALL:!aNULL:!eNULL:!EXP:!SSLv2
セクションの名前は [DefaultSettings] のように最初の行に記述されており、上記の最初のセクションの例にあるSSLConfigパラメーターに記述されている名前と一致しています。 したがって、この構成はサーバー10.100.0.17のポート1972またはポート23への接続に使用されます。
上記の例でコピーアンドペーストを使用すると、多くの場合はテキストファイルに印刷不可能な文字が挿入されてしまいます。 ファイルをテキストのみで保存し、再度開くなどで余計な文字を確実に削除するようお願いします。
各パラメーターの意味は次のとおりです。
VerifyPeer
このオプションは、0=なし、1=要求、2=必須です。 必須(2)が推奨値です。 なし(0)を選択した場合、悪意のあるサーバーによって接続先サーバーが偽装される可能性があります。 要求(1)を選択した場合、信頼する認証局を入力してCAFileの値に指定された証明書を検証する必要があります。 これは、ポータルの「サーバー証明書の検証」に相当するものです。 (注意:要求はクライアント構成の場合は意味がありませんが、オプションが0と2である理由を理解していただくためにここに含めています。)
VerifyHost
このオプションは、0=なし、1=必須です。 このオプションは、サーバーの証明書のサブジェクトのコモンネームまたはsubjectAlternativeNameフィールドに、接続するように要求したホスト名またはIPがサーバーの証明書に記述されているかどうかをチェックします。 ポータルにはこのフィールドと同等のフィールドはありませんが、 %Net.HttpRequestクラスのSSLCheckServerIdentityプロパティと同じタイプのチェックを行います。 クライアントがCaché / Ensemble 2018.1以降、またはInterSystems IRIS Data Platformの任意のバージョンを使用している場合にのみ構成可能です。
CAfile
信頼できる認証局(CA)ファイルへのパスです。 自分が所有する証明書ではなく、相手側(サーバー)の証明書に署名したCAを指定しなければなりません。 VerifyPeerの値に2を選択した場合は値を入力しなければなりません。 これは、ポータルの「信頼できる認証局の証明書を含むファイル」に相当するものです。 証明書はPEM形式である必要があります。
CertFile
所有する証明書へのパスです。 クライアントが証明書を持たない場合は空白になります。 これは、ポータルの「クライアント証明書を含むファイル」に相当するものです。 証明書はPEM形式である必要があります。
KeyFile
CertFileに対応する秘密鍵へのパスです。 CertFileがある場合は入力し、ない場合は空白にする必要があります。 これは、ポータルの「関連する秘密鍵を含むファイル」に相当するものです。
Password
秘密鍵を復号化するために必要なパスワードです。 このクライアントに証明書を使用していない場合、または証明書の秘密鍵がディスク上で暗号化されていない場合は空白になります。
KeyType
秘密鍵はRSA (2) またはDSA (1) ですか? この値は、CertFileとKeyFileが設定されている構成にのみ関係します。 所有している鍵がどちらか分からない場合はRSAの可能性が高いと思われます。
Protocols
これは、サポートされているSSL/TLSバージョンのビット値を10進数で表した値です。 オプションは、1=SSLv2、2=SSLv3、4=TLSv1、8=TLSv1.1、16=TLSv1.2です。 SSLv2とSSLv3には既知の問題があるため、お勧めしません。 数字を足すと、複数のバージョンを指定できます。 例えば、24はTLSv1.1とTLSv1.2を表します。 これは、ポータルの「プロトコル」チェックボックスに相当するものです。 (注意:2015.1には8ビットと16ビットはありません。 これらを使用する場合は、2015.2以降にアップグレードする必要があります。)
CipherList
これは、ポータルの「有効な暗号スイート」に相当するものです。 このオプションは、このクライアントで受け入れられる暗号化とハッシュのタイプを正確に制御します。 ALL:!aNULL:!eNULL:!EXP:!SSLv2 が管理ポータルのこの設定のデフォルト値です。 接続に問題がある場合はおそらくこの値になっていません。 このオプションを変更すると、弱い暗号化が受け入れられて接続の安全性が低下する可能性があります。 この値に関する詳細は、OpenSSLのウェブサイトを参照してください。
最後の補足
やるべきことは以上です! ファイルを作成して既知の場所に配置すると、接続先の名前かIPアドレスとポートがファイルに記述されている接続のいずれかと一致する場合にそのファイルが自動的に使用されます。
サーバーのセットアップ
この記事ではクライアント側の接続でSSLを使用するように構成する方法について説明していますが、接続先のサーバーもSSLの受け入れ方法を理解している必要があることを忘れないでください。 SuperServerでSSLを使用する設定に関するドキュメントは次の場所にあります。
http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=...
また、Telnetサービスの構成に関するドキュメントは次の場所にあります。
http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=...
$SYSTEM.Security.Users.SetTelnetSSLSetting() メソッドを使用すると、TelnetサーバーがSSLの使用を許可または要求するかどうかを制御できます。 2016.1以降で使用可能です。
DSNの構成
設定ファイルに対応する接続先アドレスとポートが一致していれば、ODBC接続のDSNを変更する必要はありません。 SSLはDSNの認証方法にパスワードが選択されている場合でも使用されます。 パスワードとSSL/TLSおよびSSL/TLS Server Nameオプションは、ODBCにSSLを設定する2015.1以前のスタイル用のものでした。
ドキュメントのリンク
クライアントアプリケーション用のTLSに関するドキュメントは、IRISのドキュメントサイトから入手できます。
https://irisdocs.intersystems.com/irislatestj/csp/docbook/DocBook.UI.Page...
記事
Toshihiko Minamoto · 2020年10月14日
こんにちは!
この記事では、IRIS から Caché、Ensemble、HealthShare など、InterSystems の製品で使用されるクラスやその構造を理解するのに役立つツールの概要を簡単にまとめています。
つまり、そのツールはクラスやパッケージ全体を視覚化し、クラス間の相対関係を示し、ディベロッパーやチームリーダーに必要な情報をすべて提供してくれるので、わざわざ Studio に移動してコードを調べる必要が省けます。
InterSystems の製品について情報を集めている方からたくさんのプロジェクトをレビューしている方、または単純に InterSystems Technology ソリューションの新機能に興味がある方まで、ObjectScript Class Explorer の概要をぜひお読みください!
InterSystems 製品のご紹介
以前は Caché として知られた IRIS はマルチレベルの DBMS です。 SQL クエリを使ってアクセスしたり、さまざまなプログラミング言語のインターフェースを使い、保管されているオブジェクトやプロシージャを操作したりできます。 ですが、DBMS に組み込まれているネイティブ言語の ObjectScript (COS) を使ってアプリケーションを開発することが、常に最初の選択肢として選ばれます。
Caché は DBMS レベルのクラスに対応しています。 クラスには主に、Persistent(データベースに保管できる) と Registered(データベースに保管されないが、プログラムやハンドラーとしての役割を果たす)の2 種類があります。 また、Serial(アドレスなどの複雑なデータ型を作成するために Persistent クラスに統合して使えるクラス) 、DataType(ユーザー定義のデータ型を作成する際に使用される) 、Index、View、Stream などの特殊なタイプもいくつかあります。
Class Explorer の概要
Caché Class Explorer は、Caché クラスの構造をダイアグラムとして視覚化し、クラスやすべての関連情報 (メソッドのコード、クエリ、xData ブロック、コメント、ドキュメンテーション、さまざまなクラス要素のキーワードなど) の依存関係を示すツールです。
機能
Caché にはクエリ、xData ブロック、メソッドやプロパティの多数のキーワード (System、ZenMethod、Hidden、ProcedureBlock など)、親子関係、一対多関係、クラス型といった、スタンダードな UML ではサポートされていないが、Caché には重要な一連のエンティティが存在するため、Class Explorer は拡張バージョンの UML 表記を使って視覚化を実行します。
Caché Class Explorer (バージョン1.14.3) では、次のことができます。
パッケージの階層、クラスのダイアグラム、パッケージ全体を表示する。
表示されたダイアグラムの外観を編集する。
クラスのダイアグラムのその時点でのイメージを保存する。
ダイアグラムのその時点での外観を保存し、後で復元する。
ダイアグラムやクラスツリーに表示されるキーワードを使って検索を行う。
ツールヒントを使ってクラス、そのプロパティ、メソッド、パラメーター、クエリ、xData ブロックの完全な情報を確認する。
メソッドのコード、クエリ、または xData ブロックを表示する。
グラフィックアイコンを含むダイアグラム要素の表示を有効または無効にする。
この記事の残りの内容をよく理解していただけるよう、Class Explorer で視覚化されたクラスを見てみましょう。 それでは、例の 1 つとして、「SAMPLES」ネームスペースの「Cinema」パッケージを表示してみましょう。

詳細および機能の概要
左側のサイドバーにパッケージツリーがあります。 パッケージ名にカーソルを合わせると、その右側にボタンが表示されるので、それをクリックしてパッケージ全体を表示します。 パッケージツリーの中からクラスを選択し、リンクされているクラスと一緒にレンダリングします。
Class Explorer で表示できるクラス間の依存関係には種類がいくつかあります。

1. 継承。 継承先クラスを指す白い矢印で示されます。
2. アソシエーションまたはクラス同士の関係。クラスのフィールドに別クラスのタイプが含まれている場合、ダイアグラムビルダーはこれをアソシエーション関係として示します。
3. 親子関係と 一対多関係。データの整合性を維持するためのルール。
各関係にカーソルを合わせると、その関係を生み出すプロパティが強調表示されます。

Class Explorer は現在のパッケージの外に存在するクラス間の依存関係までは表示しません。 表示されるのは現在のパッケージ内のクラスのみです。また、Class Explorer によるクラス検索に制限を設定する場合は、「依存関係レベル」設定を使います。

クラスは長方形として表示され、以下の 6 つのセクションに分割されます。
1. クラス名:クラス名にカーソルを合わせると、作成日、変更日、コメント、クラスに割り当てられたすべてのキーワードが表示されます。 クラスヘッダーをダブルクリックすると、そのドキュメンテーションが表示されます。
2. クラスパラメーター: すべての割り当てられたパラメーターがタイプ、キーワード、コメントと共に表示されます。 斜体で表記されるパラメーターやすべてのプロパティは、カーソルを合わせるとツールヒントが表示されます。
3. クラスプロパティ:クラスプロパティはパラメーターに似ています。
4. メソッド:メソッドをクリックすれば、ソースコードが表示されます。 COS 構文は強調表示されます。
5. クエリ:メソッドと同様に、クリックすればソースコードが表示されます。
6. xData ブロック: 主に XML データで構成されるブロック クリックすると、フォーマットされたソースコードがブロックとして表示されます。
デフォルトで、各クラスは多数のグラフィックアイコンと一緒に表示されます。 各アイコンの意味は、画面の右上隅にある「ヘルプ」ボタンをクリックすれば分かります。 多少厳密な UML 表記をデフォルトで表示する必要がある場合や、クラスセクションを表示する場合は、グラフィックアイコンを設定セクションで無効にすることができます。
非常に大きなダイアグラムを使い慣れていない場合は、ダイアグラムのクイック検索機能を使うことができます。 入力したキーワードの一部を含むクラスが強調表示されます。 次のマッチにジャンプするには、Enter キーを押すか、検索ボタンをもう一度クリックします。

最後に、ダイアグラムの編集をすべて完了し、不要な関係をすべて削除し、各要素をそれぞれの適切な位置に配置して、希望通りの外観が出来上がれば、左下隅にある「ダウンロード」ボタンをクリックして保存します。
ピンボタン をアクティブにすると、クラス (またはパッケージ) の現在のセットのダイアグラムに配置されている要素の位置が保存されます。 例えば、クラス A と B を選択し、そのビューをピンボタンで保存すると、ブラウザーやマシンを再起動した後でも、クラス A と B を選択すれば完全に同じビューが表示されます。 しかし、クラス A だけを選択した場合は、デフォルトのレイアウトで表示されます。
インストール
Caché Class Explorer をインストールするには、[最新リリース版](https://github.com/intersystems-ru/UMLExplorer/releases) の XML パッケージだけをお好きなネームスペースにインポートしてください。 インポートが完了すると、「hostname / ClassExplorer /」という名前の新しい Web アプリ (最後のスラッシュは必須です) が表示されます。
インストールの詳しい手順
1. Caché Class Explorer の最新リリースを含むアーカイブをダウンロードします。
2. 「Cache/CacheClassExplorer-vX.X.X.xml」という名前の XML ファイルを抽出します。
3. 以下のいずれかの方法でパッケージをお好きなネームスペースにインポートします。
1. XML ファイルを Studio にドラッグする。
2. System Management Portal を使用する場合: System Explorer -> Classes -> Import と順に移動し、ローカルファイルへのパスを指定する。
3. ターミナルコマンドを使用する場合: do ##class(%Installer.Installer).InstallFromCommandLine(“Path/Installer.cls.xml”);
4. インポートログを読み、問題がなければ「http://hostname/ClassExplorer/」から Web アプリケーションを開くことができます。 問題が発生した場合は、以下を確認してください。
1. このネームスペースにクラスをインポートする権限があるか。
2. Web アプリケーションのユーザーは異なるネームスペースへのアクセス権を持っているか。
3. エラー 404 が表示される場合は、URL の最後に「/」を追加しているか。
他のスクリーンショット

[スクリーンショット 1] DSVRDemo パッケージ。クラス名にカーソルを合わせた状態。

[スクリーンショット 2] DataMining パッケージ。ダイアグラムでキーワード「TreeInput」を検索中。

[スクリーンショット 3] JavaDemo.JavaListSample クラスのメソッドコードを表示したビュー。

[スクリーンショット 4] ClassExplorer.Router クラスの XData ブロックのコンテンツを表示中。
Class Explorer の機能を標準の SAMPLES ネームスペース [デモ](http://37.139.4.54/ClassExplorer/)でお試しください。 プロジェクトのビデオレビューは [こちら](https://www.youtube.com/watch?v=j55fP2CnKpo) からご覧ください。
フィードバックやご提案、コメントはこちら、もしくは [GitHub リポジトリ](https://github.com/intersystems-ru/UMLExplorer)からお寄せください。 どうぞお楽しみください!
記事
Mihoko Iijima · 2021年2月21日
皆さんこんにちは!
VSCode の SQLTools エクステンションを使うと、VSCode から SQLTools に対応しているデータベースへ接続/クエリ実行が行えるようです。
1 つの IDE で 各種言語を操作でき、さらにクエリも発行できるなんて VSCode って便利ですね!👏👏
実は、まだプレビュー機能ではありますが、InterSystem IRIS も接続できます!🎊🎊
正式リリース前なのですが、どんな感じでご利用いただけるかをご紹介したいと思います。
解説ビデオ(4分ちょっと)もあります。ぜひご参照ください。
※ ObjectScript エクステンションの基本的な操作方法については、こちらの記事をぜひご参照ください。
手順1:SQLTools エクステンションをインストール
(ビデオでは、0:00~0:32 で解説しています)
図の手順でインストールします(右画面の SQLTools の説明文下の方に対応データベースリストがあり、「InterSystems IRIS」の文字も見えます!)。
手順2:SQLTools に対応するドライバをインストール(ここでは IRIS 用ドライバのインストール)
(ビデオでは、0:32~1:09 で解説しています)
SQLTools のインストールが終わると、VSCode の左端の黒いバーのところに アイコンが見えるのでクリックします。
ボタンが表示されるのでクリックすると、まだドライバがインストールされてませんよ、のメッセージが出るので、「Search VSCode marketplace」のリンクをクリックします。
IRIS 用ドライバをインストールしたら準備完了です。
手順3:接続定義の作成とテスト
(ビデオでは、1:15~2:19 で解説しています)
再度、VSCode の左端の黒いバーの アイコンをクリックし、「Add new connection」のボタンをクリックすると、以下のようにインストールしたドライが見えてきます。
IRIS のアイコンをクリックすると、接続情報入力欄が出てくるので、アクセスしたい IRIS の情報を入力し、で接続確認を行います。テスト接続が完了したら で設定を完了させます。
テスト接続時の画面は以下の通りです。
テスト接続が完了したら、忘れずに「SAVE CONNECTION」ボタンをクリックしてください。
手順4:データベースにアクセス!
(ビデオでは、2:19~ で解説しています)
「SAVE CONNECTION」ボタンをクリックすると、接続時の設定が表示されます。その下に「CONNECT NOW」ボタンが表示されるのでクリックします。
図の設定では、接続時にパスワード入力欄が表示される設定で作成しています。出てきたらパスワードを指定して Enter をクリックしてください。
(ビデオでは、2:25~2:49 で解説しています)
後は、好きなように SQL を実行するだけ!(ビデオでは、2:49~ で解説しています)
実行結果を CSV/JSON でエクスポートもできるようで、便利ですね!
正式リリースとなりましたら、またコミュニティでお知らせします! 私はいつもA5M2というツールを利用させて頂いています。
VSCodeのような統合環境で色々な事ができるのは便利ですし、今後、IRISでの開発にチャレンジされる方々にとっては朗報ですね。おじさんは時代の変化についてゆけず難儀しております。 ご覧いただきありがとうございます!
記事
Mihoko Iijima · 2021年8月11日
これは InterSystems FAQ サイトの記事です。
以下のような情報収集ツールがあります。
1) 性能評価の為のツール
GLOSTAT
グローバルアクセスのカウンター情報
mgstat
グローバルアクセスのカウンター情報を連続してファイルに記録する
JOBEXAM
問題のあるプロセスをモニターする
SystemCheck または Buttons
内部情報の収集
使用方法詳細は以下の記事もご参照ください。
【IRISベース】トラブル発生時の情報収集方法(IRIS / IRIS for Health / UCR 編)
【Caché ベース】トラブル発生時の情報収集方法(Caché / Ensemble / HealthConnect 編)
PERFMON
グローバル、ルーチン、プロセス毎のグローバルアクセスカウンタ情報
収集例は添付のPDFをご参照ください
PERFMON に用意された関数名を利用して、PERFMON で収集したデータをファイル出力するサンプルプログラムもご用意しています。 https://github.com/Intersystems-jp/FAQ-ZPERFMON
PROFILE
アプリケーションのルーチンおよびクラスのパフォーマンス解析(ルーチン単位に消費CPU、グローバル参照など取得可能)
%SYS.MONLBL
特定のルーチンを行単位でパフォーマンス解析(処理時間など行単位に計測)
詳細については、以下ドキュメントをご参照下さい。
^GLOSTAT を使用したグローバル動作の統計収集について【IRIS】
^GLOSTAT を使用したグローバル動作の統計収集について
^PERFMON を使用したシステム・パフォーマンスの監視について【IRIS】
^PERFMON を使用したシステム・パフォーマンスの監視について
^PROFILE を使用したルーチン・パフォーマンスの監視について【IRIS】
^PROFILE を使用したルーチン・パフォーマンスの監視について
※PROFILEは、Caché2009.1で追加されたシステムルーチンです。
^%SYS.MONLBL を使用したルーチン・パフォーマンスの検証について【IRIS】
^%SYS.MONLBL を使用したルーチン・パフォーマンスの検証について
^mgstat を使用したパフォーマンスの監視について【IRIS】
^mgstat を使用したパフォーマンスの監視について
2) Windowsのパフォーマンスモニター
インターシステムズのユーティリティでありませんが、CPU、メモリ、ディスクI/O のどれがパーフォマンスのボトルネックになっているのかを特定する為に使用します。
使用方法については、「パフォーマンス調査ガイド ~知っておこう システムの基準値~」の P35~38 をご参照ください。
3) 情報収集例
パフォーマンス低下時に、1) でご紹介した mgstat と 2) の情報収集を行います。
1) の mgstat により、データベースに対するアクセス量が取得でき、2) によりパフォーマンス低下時、コンピュータのどの資源が不足しているかの判別の材料になります。
さらに必要であれば、1) のPERFMONの情報収集を行い 、これによりアクセスの多いグローバル、ルーチンの情報が取得できます。
特定のルーチンに対するパフォーマンス解析では、以下2つのルーチンを利用します。
ルーチンのCPU使用率、グローバル参照数、処理時間など計測する場合は PROFILE
行単位でパフォーマンス解析(処理時間の計測など)を行う場合は %SYS.MONLBL
ご利用状況に合わせて、ご使用ください。
記事
Toshihiko Minamoto · 2022年4月12日
コミュニティの皆さん、こんにちは。お元気ですか?
皆さんは、創造性をどのようにして発揮していますか? 新しいアイデアはどのようにしてテストしていますか?
数年にもわたって、私はずっと新しいものを作り出し、既存のものを改良し、実験、テスト、破壊(いつも壊れてしまいます)を経て作り直し、そしてこのプロセスを繰り返してきました。
InterSystems が推進するコンテストは、モチベーションを大きく持ち上げてくれます。もちろん、賞品に目が行ってしまうことは否定できませんが。 しかし、賞品や報酬だけでなく、こういったコンテストでは自分の創造性が試されますし、作成、改良、テスト、実験の機会が得られます。 さらに、最も素晴らしいのは、何をやるのも自由であるということです!
私の場合、こういった機会は、独自の [ホワット・イフ...?](https://en.wikipedia.org/wiki/What_If...%3F_(TV_series))(マーベルが作家に自由にストーリーを改良させるシリーズ)を作成できるチャンスと見なしているため、これらのアイデアを私と一緒に受け入れてくれる人がいたのは幸運でした @José.Pereira に感謝です。
前回の相互運用性コンテストでは [Message Viewer](https://openexchange.intersystems.com/package/IRIS-Interoperability-Message-Viewer?tab=details) を作成したのですが、今回の相互運用性コンテストでも Message Viewer をもう一度取り上げました。_ただし_、**独自のビジュアルトレース機能**を追加して、です!
InterSystems テクノロジーを使用しており、統合機能の部分(Ensemble/Interoperability)をご存知の方であれば誰でも、ビジュアルトレース機能は長い間、同じ状態のまま、問題なく存在していたことをご存知でしょう。
確かに機能しますし、メッセージのシーケンス図や詳細を表示して情報や XML を引き出したりできますが、 機能するからと言って、改善しない理由はありませんよね? 新しい視点をもたらし、ちょっとした変化を促進してもよいのではないでしょうか?
例として、Steve Rogers がいます。マーベルの主人公の 1 人であるキャプテン・アメリカですが、ペギー・カーターをキャプテンとして再構想、制作、テストしました😂
それでは、私たちが作った新しい「ペギー・カーター」、つまりビジュアルトレースについて少しお話ししましょう!
古き良きビジュアルトレースを以下に示します。

さて、ここに数千件ものメッセージがあり、単純なメッセージを簡単に再送できない状態であることを想像してみてください。
メッセージビューア画面に戻り、メッセージを掘り起こしながら、検索して再送信する必要があるでしょう。

そこで、新しい外観で情報を集めて単純な機能を提供することで、これが可能であることを示すことを考えました。開発者の日常業務が少しでも楽になると思います。

**デモ**
このアプリを気に入ってもらえて、投票する価値があると思ってくれたなら、**IRIS Message Viewer** に投票してください!
記事
Megumi Kakechi · 2022年9月9日
これは InterSystems FAQ サイトの記事です。外部バックアップ機能と、SANソリューションが提供するスナップショット(スナップクローン、ミラークローンなど呼び方はベンダ毎に異なります)などのテクノロジを利用することで、バックアップ時のインスタンス停止時間を最短にすることができます。
操作手順概要は以下の通りです。
外部バックアップ用ユーティリティを利用して、データベースファイルへの書き込みを一時中断します(%SYSネームスペースで実行します)。
%SYS>set status=##class(Backup.General).ExternalFreeze()
外部のスナップショットユーティリティを使用して、ファイルシステムのスナップショットを作成します。
データベースファイルへの書き込みを再開するため、外部バックアップ用ユーティリティを使用します。
%SYS>set status=##class(Backup.General).ExternalThaw()
バックアップメディアにスナップショットをコピーします。
【ご参考】ExternalFreeze() の処理は以下のようになります。
1. ジャーナルファイルの切り替え 2. データベースバッファ上の書き込み待ちバッファをすべてデータベースファイルに書き出す 3. ライトデーモンをサスペンド状態にする
これらの処理の後、データベースファイルは静的な状態になり、外部のバックアップ処理によるバックアップが可能な状態(※)になります。※スナップショットコピーやミラーコピーの同期完了状態で切り離しが可能な状態。
この処理では、グローバルに対する書き込みを禁止していない為、データベースへの書き込みアクセスは、データベースキャッシュのバッファに余裕があれば可能です。ただし、ExternalFreeze() によるライトデーモンの不活動が長時間の場合、以下の条件で書き込みアクセスが待ち状態になります。
(1) 書き込み待ちのバッファ数が全バッファ数の70%以上になった場合 (2) ライトデーモンの不活動時間が10分以上(既定値)になった場合
(2)について、ライトデーモンの不活動時間のタイムアウト値は既定値で10分となっています。ExternalFreeze() が10分以上続く場合、ExternalThaw() が実施されるまで、書き込みアクセスが待ち状態になります。このライトデーモンの不活動時間のタイムアウト値は、ExternalFreeze() の第7パラメータにてsec単位で指定可能です。このタイムアウト値の範囲は、120秒~1200秒になります。
実行例:
%SYS>s x=##class(Backup.General).ExternalFreeze(,,,,,,1200) ;タイムアウト値 20分
外部バックアップについての詳細は、以下のドキュメントをご覧ください。外部バックアップについて
各バックアップ方法については、以下の関連トピックをご覧ください。
【関連トピック】データベースのバックアップ方法について累積バックアップと差分バックアップの違いについて稼働中のインスタンスを停止せずにバックアップを行う方法データベースのバックアップについて(InterSystems Symposia 2014)VM Backups and Caché freeze/thaw scripts
記事
Toshihiko Minamoto · 2021年6月3日
## コンテナ
[InterSystems IRIS Data Platformの公開](https://community.intersystems.com/post/intersystems-iris-data-platform-201810-release)により、Dockerコンテナでも製品を提供しています。 コンテナとは一体何でしょうか。
基本的なコンテナの定義は、プロセスのサンドボックスの定義です。
コンテナは、たとえば実行できるという点において、仮想マシン(VM)に似た部分を持つソフトウェア定義パッケージです。
コンテナは、完全なOSエミュレーションを使わずに分離することができるため、 VMよりもはるかに軽量です。
本質的に、コンテナは、どのようにアプリケーションをシステムから別のシステムに確実に移動し、それが動作することを保証できるのかという問題に対する答えと言えます。 アプリケーションのすべての依存関係をコンテナにカプセル化し、プロセス分離領域を作成することにより、アプリケーションソリューションがプラットフォーム間で移動した場合でも動作するという高い保証を得ることができます。
プロセスは、オペレーティングシステムによって実行が可能です。 これらのプロセスはアドレス領域、ネームスペース、cgroupなどを共有し、通常、OSの環境全体にアクセスすることができます。それらのスケジュールと管理は、OSが行います。 すべて良いことではありますが、特定のプロセスやいくつかのプロセスを分離して、特定のタスクや演算、またはサービスを実行したい場合はどうでしょうか。 手短に言えば、プロセスを分離できる機能こそ、コンテナが提供している機能なのです。 したがって、コンテナをプロセスのサンドボックスとして定義することができるでしょう。
では、サンドボックスとは何でしょうか。 サンドボックスは、コンテナがプロセスを持つ分離レベルです。 この機能は、ネットワークインターフェース、マウントポイント、インタープロセス通信(IPC)、ユニバーサルタイムシェアリング(UTS)といったシステムのほかの重要な部分もサンドボックス化することのできるネームスペースと呼ばれるLinuxのカーネル機能により実装されています()。
コンテナまたはサンドボックスは、制御グループまたはcgroupと呼ばれる別のカーネル機能によっても管理または制御することができます()。 コンテナがほかのコンテナやホストとリソースを共有する上で、ほかのネイバーに害を与えないように、コンテナにルールが適用されます。
コンテナとVMの違いを理解するには、VMを_家_に、そしてコンテナを_マンション_に例えることができます。

VMは、一軒家のように、自己完結型で独立しています。 それぞれの家には、配管、暖房、電気といった固有のインフラストラクチャが備わっており、 最低要件も与えられています(最低、寝室は1室、屋根は1つなど)。
一方のコンテナは、共有のインフラストラクチャを使用するように作られているため、マンションとして捉えることができます。 マンションの建物は、配管、暖房、電機システム、正面玄関、エレベーターなどを共有していますが、これと同様に、コンテナも、Linuxカーネルを通じてホストが提供しているリソースを使用します。 また、マンションの各居住戸のサイズや形には様々なものがあることも考えましょう。
コンテナには完全なOSはなく、/binの実行可能ファイルや /etcの構成ファイルと定義ファイルといった、最小限必要なLinux OSしか備わっていないため、サイズが非常に小さくなります。そのため、その場所を移動したり、スピンアップする場合に、一秒きっかりで敏速に行うことができます。 コンテナを構築した瞬間から、ソフトウェアファクトリーのプロビジョニングパイプラインを通じ、本番環境での最終実行に至るまで、アジリティを得られることになります。 ちなみに、コンテナはCI/CDマイクロサービスアーキテクチャのコンテキストにピッタリと収まりますが、これはまた別の機会にお話ししましょう。
コンテナ内のプロセスは、コンテナのライフサイクルと密接な関係があり、 コンテナを_起動_すれば、アプリのすべてのサービスも起動して実行し(たとえば、あるWebサーバーコンテナのポート80と、InterSystems IRISコンテナのポート57772と1972)、 コンテナを_停止_すれば、すべてのプロセスも停止します。
この記事では、コンテナのランタイムの基本的な概念について説明しました。コンテナは、プロセスをホストやその他のコンテナから分離するサンドボックスです。
コンテナを理解するには、その[イメージ](https://community.intersystems.com/post/container-what-container-image)に関する別の側面もあります。 これについては、第2部の記事で説明することにします。