%SYS.Journal.Record 类有一个查询(query), List, 可以列出Journal文件中记录的数据修改历史。例如,要查询谁对global节点^QP(1,2)做过修改,可以使用如下代码。它查询Journal文件(输入参数pFilePath)中的global节点(输入参数pSearchGlobal)的操作:
旨在统一软件开发 (Dev) 和软件运营 (Ops) 的软件工程实践。
%SYS.Journal.Record 类有一个查询(query), List, 可以列出Journal文件中记录的数据修改历史。例如,要查询谁对global节点^QP(1,2)做过修改,可以使用如下代码。它查询Journal文件(输入参数pFilePath)中的global节点(输入参数pSearchGlobal)的操作:
SQL Performance Analysis Toolkit,或者叫SQL性能分析工具,并不是给维护人员使用的。
在RIS文档里是这么说的: 这个工具包里的工具收集SQL执行的详细信息,用来找出一个查询计划的特殊问题。 使用这些信息,开发人员改善这个查询的效率。 它可以非常大的增加服务器的开销。..., 它不应该被持续执行。
要做分析,首先您需要打开一个采集“SQL runtime Statistics"的开关来收集详细信息,这个开关默认的状态是OFF。 文档里说: The SQL Performance Analysis Toolkit offers support specialists the ability to profile specific SQL statements or groups of statements.
这里的"support specialists"指的是厂家的技术支持人员。
因此,总结如下:
简单的介绍一下, 真正的使用需要参考在线文档: SQL性能分析工具(SQL Performance Analysis Toolkit)
进入*“系统资源管理器>工具>SQL性能工具>SQL运行时统计数据“*,您会看到在“setting"页面写明
当前 SQL 运行时统计数据设置为: 0 - SQL 运行时统计数据已关闭,查询代码生成中将不包含 stats-collection
下面是"更改设置"的按钮,点击后您会看到

这个工具私下被称为PTools, 当激活后,它会在SQL编译后的查询类里加入相应的代码,来跟踪Global Reference, 执行的SQL类编译的代码的行数,查询计划的每一个模块执行的时间等等。
无论您修改到什么级别的设置,1,2还是3, 您都会看到这样的提示
您正在将选项从 0 更改为 2,从先前在查询代码生成中不包括 Stats-collection 的环境启用 Stats-collection。保存更改后,您应该清除所有缓存查询,并重新编译包含嵌入式 SQL 的所有类和 routine。
也可以通过执行 %SYSTEM.SQL.PTools 命令行命令来执行。
%SYS.PTools.SQLStats在Cache 2008.1加入。它用来收集类和routine级别的metrics. 当激活后,它会在SQL编译后的查询类里加入相应的代码,来跟踪Global Reference, 执行的代码的行数,Time to Run and Number of Rows returned for the full query, or for each Module of a query.
您可以在管理门户查看查询的详细内容, 比如下面两个图, 第一个图给出了统计的3个查询,

第2个图是其中一个查询的详细数据,包括每个模块执行了多长时间:

如果使用SQL, 你可以查询视图%SYS_PTools.SQLStatsView , 比如下面这个例子:
SELECT RoutineName, ModuleName, AVG(ModuleCount) AS Mod_Count,
AVG(GlobalRefs) AS Global_Refs, AVG(LinesOfCode) AS Lines_of_Code, AVG(TotalTime) AS Total_Time
FROM %SYS_PTools.SQLStatsView
WHERE NameSpace = 'SAMPLES'
GROUP BY RoutineName, ModuleName
最近在多家现场都遇到了备机长时间宕机导致镜像日志写满磁盘的问题。在这里我将对这个问题发生的原因、发生后的处理、和如何预防这类问题发生进行一些讨论。
问题的发生一般始于一些原因导致的主机(如,01)宕机,进而触发镜像的主备切换。切换后备机(如,02)成为主机,并无缝接管业务。由于业务不受影响,如果不注意监控环境的话,很可能现场技术人员长时间都注意不到镜像的备机(01)是宕机状态。
备机长时间宕机会导致如下问题:
1. 这种情况下如果主机(02)再次遇到问题宕机,镜像将无法发挥其高可用性,无法保持业务稳定运行。
2. 主机(02)产生的镜像日志将无法同步到备机(01)。未同步的日志将一直被保存在主机(02)上不被删除。长此以往镜像日志磁盘将被写满,同样导致主机(02)宕机。
问题发现时切记不要手动从文件夹直接删除主机(02)上的镜像日志。未同步的日志一旦手动删除,镜像将无法自动同步,需要重做主备镜像。
问题发现时如果主机(02)还未宕机,此时尝试解决备机(01)问题,启动备机(01),等待镜像自动同步即可。同步完成之后镜像日志将可以被定时任务定时清除。如果遇到较为复杂的情况,现场请第一时间联系您的软件供应商,软件供应商将协同系联软件全球响应中心一起来解决您遇到的具体问题。
为了避免以上的问题发生,现场运维需要对镜像的状态和磁盘的状态配置监控。
在日常Cache运维过程中可能会由于数据或者程序等原因造成锁的异常增长,导致数据库性能受到影响会出现程序报错或卡顿无法正常运行的问题。遇到此类问题需查看数据库当前锁列表情况,找到出现次数最多关键锁,根据关键锁对应的进程来判断处理。总结有以下三种方式查看关键锁。
|
查看方式 |
优点 |
缺点 |
|
第一种 |
易操作、方式简便 |
慢、锁数量太多无法显示 |
|
第二种 |
快、不受网页限制 |
易忘、需要输入准确命令 |
|
第三种 |
快、灵活、直接显示关键锁信息 |
需定位准确命名空间 |
下面给出自定义程序实例,程序逻辑为按命名空间循环所有锁信息,通过计数器方式记录所有锁当中出现次数最多的一个,输出其信息。入参为数据库中不同命名空间,输出结果为锁名称及锁的所有者,所有者一般为进程ID或ECP。
生产环境下我们部署和使用IRiS引擎,往往采用其主备镜像模式,虽然此架构简单但是往往我们需要持续在电脑前点击或者操作1到2小时,如果中间有个环节出现了问题有时我们可能需要部署一天.
接下来我分享的是IRIS自带的一个功能帮助我们部署---manifest-安装清单。他的主要使用方式是提前通过配置约定好我们期望的安装设置,在安装的过程中由IRIS程序直接执行脚本,简化IRIS集群的部署,减少运维人员的操作步骤,让我们有更多的精力放在实际项目和业务上。
%Installer 实用程序允许您定义描述和配置特定 InterSystems IRIS 配置的安装清单,而不是分步安装过程。为此,我们需要创建一个类,其中包含描述所需配置的 XData 块,使用包含通常在安装期间提供的信息(超级服务器端口、操作系统等)的变量。我们还可以在类中包含一个使用 XData 块生成代码以配置实例的方法。本文提供了安装清单的示例,您可以复制和粘贴这个示例尝试使用。
定义清单后,可以在安装期间、从终端会话或代码调用它。注意:清单必须在 %SYS 命名空间中运行。
此成品展示的是一个一键安装主、备、仲裁的机器命令,此方法的使用可以便捷快速的安装主备环境,其基本每一行都有注释其说明:
本文讨论了在使用或维护InterSystems产品中遇到问题时,试图确定问题时可能用到的思路和工具。
确定问题发生的地点和时间
审查日志中的警告、错误和警报
以下日志可能包含有关该问题的有用信息。可以尝试在以下日志中寻找问题开始前后的警告或报错。
检查实例是否可以访问足够的存储空间
检查CPU活动
大家好!
这是关于使用 Docker 初始化 IRIS 实例的系列文章中的第三篇。 这次,我们将关注企业缓存协议(Enterprise Cache Protocol,ECP)。
ECP 允许以一种非常简单的方式将某些 IRIS 实例配置为应用程序服务器,将其他实例配置为数据服务器。 有关详细的技术信息,请参阅官方文档。
本文旨在介绍:
为此,我们通常使用我们在以前的 Web 网关中已经看到的一些工具,以及描述 OpenSSL、envsubst 和 Config-API 等工具的镜像文章。
ECP 不适用于 IRIS 社区版。 因此,需要访问全球响应中心才能下载容器许可证并连接到 containers.intersystems.com 注册表。
系统必须与容器共享一些本地文件。 需要创建特定用户和组来避免出现“访问被拒绝”错误。
“池大小”(PoolSize)设置的值决定了一个组件的作业的量和启动方式。在这篇文章中我们将具体讨论对于不同类型的组件来说“池大小”设置的可能值和这些值所代表的含义。
Pool Size = 1
对于所有的组件来说,运行池大小为1的含义都是一样的: 该组件有且只有一个作业,单独运行该组件的代码,顺序处理发送到该组件的消息(FIFO)。
Pool Size > 1
对于业务进程(BP)和业务操作(BO)来说,当运行池大小大于1时,该组件将运行多个作业(作业数=运行池大小设置数)。每个作业都只运行该组件的代码,但消息处理的顺序将被打乱。将运行池的大小设为大于1的值可以在一定程度上提升组件处理消息的性能,但是每个作业的性能还是受限于系统资源的,所以并不是说组件的性能可以随着运行池的大小增加而无限提升。
对于轮询类业务服务(Polling BS)来说,当运行池大小大于1时,该服务也将运行多个作业(作业数=运行池大小设置数)。但这种配置会导致多个进程对轮询结果产生竞争(race condition),所以一般情况下轮询服务不应将运行池大小设为大于1的数值。
上线一个新的集成平台production或者组件是需要很多精力的,用户常常需要对每一个组件所满足的需求和所能提供的功能,使用到的协议,以及组件对系统资源的调用有深入细致的了解。在配置好一个production之后,您可能需要将这个production推送到测试或者正式环境,或者需要将一个写好的组件代码应用到不同的项目上。这些时候,production的导出功能可以方便您传输production或组件的配置和代码。
导出
需要导出production时,您可以移步到管理门户 - Interoperability - 相应的命名空间 - 列表 - Production 页面,选择您需要导出的production,再点击页面上的导出键进行导出。如下图1所示:
在弹出的对话框中,您可以选择在导出文件中您想包括的内容。如下图2所示:
您也可以通过管理门户 - Interoperability - 相应的命名空间 - 配置 - Production 页面,点击“Production 设置” - “操作”选项卡 - “导出”键进行导出。弹出的对话框同样如图2所示,会自动包括大部分production及其组件所需要的类。如果需要添加或更改导出的类,可以在此对话框进行操作。
Cache锁的异常直接影响数据库进程运行,堆积的锁如果处理不及时会造成Cache性能异常,导致数据库访问受限或严重卡顿。本文主要以实例分析介绍Cache中常见锁的作用及其对应的处理方式,包括:系统锁、数据锁、Session锁、仪器锁、程序文件锁。其中数据锁异常需要及时处理。
查询Cache锁有两种方式:
1>可在System Management Protal的[Home]>[Locks]中查看;
2>可在terminal端使用Do ^LOCKTAB命令下查看,如下图所示,此方式适用于锁表量达到10000条以上,Protal页面HTTP响应超时无法显示锁表时使用。
一、【系统锁】
此类锁在数据库初次搭建时就存在,例如:
1>^%SYS("CSP","Daemon") ---调度锁
2>^TASKMGR ---守护进程
3>^DBACK ---数据库备份锁
4>^SYS("Task","TaskD",1058) ---执行系统任务锁
主要作用
cache数据库自身带有系统监控Portal界面,但需要运维人员定期主动查看才能获取监控信息。当系统故障发生时,容易出现由于没有及时获取故障信息而不能及时处理,从而导致造成的影响扩大。本文研究通过解析cache数据库控制台日志(cconsole.log)进行监控信息获取并主动推送微信或短信实现cache数据库主动实时监控。
cache数据库在运行时会将所有控制台消息包括一般消息、系统错误、某些操作系统错误和网络错误都会发送到控制台日志文件,通过操作员控制台工具从其他系统远程启动的作业的成功或失败等信息也会写入控制台日志,因此通过对控制台日志的解析即可获取所需要监控信息。具体步骤方法如下:
控制台日志默认存储在install-dir\mgr路径下。
根据cache版本不同,使用的读取方法也不同。对于cache2016版本以上,系统提供了EnsLib.SQL.Snapshot类,可以直接获取日志的行和列信息,非常方便。对于cache2010及以下版本则无此方法,需要使用%File文件读取方法。
在InterSystems IRIS医疗版里有一个文件压缩解压的适配器HS.Util.Zip.Adapter和对应的文件压缩解压业务操作HS.Util.Zip.Operations。集成产品可以使用它们进行文件的压缩和解压操作。这2个类的联机文档说明较少,这里介绍它们的使用方法。
InterSystems IRIS使用操作系统的压缩和解压缩能力,因此需要注册操作系统执行压缩解压的命令。
在管理门户的Health标签页下,选中配置注册(Configuration Registry):
在其中增加2个注册项目:
\ZipUtility\UnZipCommand 和\ZipUtility\ZipCommand,分别代表解压和压缩命令。适配器HS.Util.Zip.Adapter会检查这2个注册项并得到相应的命令。各个操作系统的命令并不一样,示例如下:
\ZipUtility\UnZipCommand 解压缩命令
| Windows | "c:\program files\7-zip\7z" x %1 -o. -r |
| 非Windows | unzip %1 -d . |
\ZipUtility\ZipCommand 压缩命令
| Windows | "c:\program files\7-zip\7z" a %1 . -r |
| 非Windows | zip -rm %1 . |
在生产环境中IRIS通常以故障转移集群的形态被部署,而集群中各故障转移成员的镜像状态将决定该集群在故障发生时是否能够顺利切换保障业务不中断。因此,成员状态通常也是运维团队需要巡检或监控的目标。
尽管IRIS内部API提供了丰富的集群配置、成员状态监控等一系列接口,但除Portal上的镜像监视器外,并没有特定的接口便于从外部系统访问(如进行企业级监控集成时),也没有整合好的监控接口可用与获取镜像的健康状态。但在IRIS上开发一个REST接口暴露镜像状态数据并不困难,如下所示:
最近一些用户问到监控集成平台业务行为查询的问题,例如如何查询服务的平均耗时、发生错误的服务数量...
业务行为监控对于集成平台来说非常重要,可以帮助我们:
仅提供这些查询是很容易的,但要更好地监控集成平台的业务行为,需要更深入的了解InterSystems集成架构。
无论Ensemble、Health Connect还是InterSystems IRIS,它们都具有下面的集成架构:
通过业务服务向外发布服务、通过业务操作连接第三方接口、通过业务流程协同业务操作,它们统称为集成业务组件。可以简单理解为业务行为是由这些业务组件完成的:
要监控业务行为,服务、接口和流程都需要监控。
这种情况先抽查这些消息所处的会话中是否有未完成操作周期的消息(状态为除“Completed”“Error”“Discarded”之外的状态)。如有,且定期清除任务配置了“KeepIntegrity”,且该环境并不需要保留这些消息,可通过关闭清除任务中的“KeepIntegrity”配置清除这些会话和包含的消息。如果有这类消息,但是定期清除任务未配置“KeepIntegrity”,可能是定期清除任务的逻辑或消息数据问题导致清楚任务查找的时候没有覆盖这些消息,请联系WRC帮助排查具体原因。
有关定期清除任务的更多信息请参见文档
Purging Production Data | Managing Productions | InterSystems IRIS for Health 2022.1
这种情况需要具体排查每个较大的global。可能有以下原因:
所有源代码均在: https://github.com/antonum/ha-iris-k8s
在上一篇文章中,我们讨论了如何在k8s集群上建立具有高可用性的IRIS,基于分布式存储,而不是传统的镜像。作为一个例子,那篇文章使用了Azure AKS集群。在这一篇中,我们将继续探讨k8s上的高可用配置。这一次,基于Amazon EKS(AWS管理的Kubernetes服务),并将包括一个基于Kubernetes 快照进行数据库备份和恢复的选项。
开始干活. 首先需要一个AWS账户,安装 AWS CLI,kubectl 和 eksctl 工具. 要创建新的集群,请运行以下命令:
eksctl create cluster \ --name my-cluster \ --node-type m5.2xlarge \ --nodes 3 \ --node-volume-size 500 \ --region us-east-1
这个命令需要大约15分钟,部署EKS集群并使其成为你的kubectl工具的默认集群。你可以通过运行以下代码来验证你的部署:
Hi 社区
在本文中,我们将基于Docker程序化地配置一个Apache Web Gateway,使用。:

我们将使用两个镜像:一个用于Web网关,第二个用于IRIS实例。
所有必需的文件都在这 GitHub repository.
我们从git clone开始:
git clone https://github.com/lscalese/docker-webgateway-sample.git
cd docker-webgateway-sample
为了避免权限方面的问题,你的系统需要一个用户和一个组:
需要与容器共享证书文件。 如果你的系统中不存在这些文件,只需执行:
sudo useradd --uid 51773 --user-group irisowner
sudo groupmod --gid 51773 irisowner
sudo useradd –user-group www-data
在这个示例中,我们使用以下三个证书:
有一个随时可用的脚本来生成它们。.
然而,你应该自定义证书的主题;只需编辑这个文件 gen-certificates.sh .
这是 OpenSSL subj argument的结构:
可以随意改动这些值.
# sudo is needed due chown, chgrp, chmod ...
sudo ./gen-certificates.sh
如果一切都OK,应该能看到两个带证书的新目录 ./certificates/ and ~/webgateway-apache-certificates/ with certificates:
| File | Container | Description |
|---|---|---|
| ./certificates/CA_Server.cer | webgateway,iris | Authority server certificate |
| ./certificates/iris_server.cer | iris | Certificate for IRIS instance (used for mirror and wegateway communication encryption) |
| ./certificates/iris_server.key | iris | Related private key |
| ~/webgateway-apache-certificates/apache_webgateway.cer | webgateway | Certificate for apache webserver |
| ~/webgateway-apache-certificates/apache_webgateway.key | webgateway | Related private key |
| ./certificates/webgateway_client.cer | webgateway | Certificate to encrypt communication between webgateway and IRIS |
| ./certificates/webgateway_client.key | webgateway | Related private key |
请记住,如果有自签名的证书,浏览器会显示安全警报。 显然,如果你有一个由认证机构交付的证书,你可以用它来代替自签的证书(尤其是Apache服务器证书)
让我们来看看配置文件.
你能看到在 webgateway-config-files 目录下 CSP.INI 文件.
将被推到镜像里, 但内容可以在runtime被修改.
可以把这个文件作为模版.
在这个示例中,以下参数将在容器启动时被覆盖:
更多细节请参考 startUpScript.sh . 大致上,替换是通过sed命令行进行的.
同时, 这个文件包含 SSL\TLS 配置来确保与 IRIS 实例的通信:
SSLCC_Certificate_File=/opt/webgateway/bin/webgateway_client.cer
SSLCC_Certificate_Key_File=/opt/webgateway/bin/webgateway_client.key
SSLCC_CA_Certificate_File=/opt/webgateway/bin/CA_Server.cer
这些语句都比较重要. 我们必需确保证书文件可用.
我们稍后将在docker-compose文件中用一个卷来做这件事.
这是一个Apache 配置文件. 允许使用HTTPS协议并将HTTP请求重定向到HTTPS.
证书和私钥文件在这个文件里设置:
SSLCertificateFile /etc/apache2/certificate/apache_webgateway.cer
SSLCertificateKeyFile /etc/apache2/certificate/apache_webgateway.key
对我们 IRIS实例, 我们仅仅配置最低要求来允许SSL\TLS 和Web Gateway 之间的通信; 这涉及到:
%SuperServer SSL Config.为简化配置, config-api 用一个简单的JSON 配置文件.
{
"Security.SSLConfigs": {
"%SuperServer": {
"CAFile": "/usr/irissys/mgr/CA_Server.cer",
"CertificateFile": "/usr/irissys/mgr/iris_server.cer",
"Name": "%SuperServer",
"PrivateKeyFile": "/usr/irissys/mgr/iris_server.key",
"Type": "1",
"VerifyPeer": 3
}
},
"Security.System": {
"SSLSuperServer":1
},
"Security.Services": {
"%Service_WebGateway": {
"ClientSystems": "172.16.238.50;127.0.0.1;172.16.238.20"
}
}
}
不需要做任何动作. 在容器启动时这个配置会自动加载.
ARG IMAGEWEBGTW=containers.intersystems.com/intersystems/webgateway:2021.1.0.215.0
FROM ${IMAGEWEBGTW}
ADD webgateway-config-files /webgateway-config-files
ADD buildWebGateway.sh /
ADD startUpScript.sh /
RUN chmod +x buildWebGateway.sh startUpScript.sh && /buildWebGateway.sh
ENTRYPOINT ["/startUpScript.sh"]
默认的 entry point是 /startWebGateway, 但是在启动webserver前需要执行一些操作. 记住我们的 CSP.ini 文件只是个 模版, 并且我们需要在启动时改变一些参数 (IP, port, system manager) . startUpScript.sh 将执行这些变化并启动初始 entry point 脚本 /startWebGateway.
启动容器之前, 必须修改好docker-compose.yml 文件:
**SYSTEM_MANAGER** 必须配好授权的IP来访问 Web Gateway Managementhttps://localhost/csp/bin/Systems/Module.cxw
基本就是你自己的IP地址 (可以是一个用逗号分开的列表).
**IRIS_WEBAPPS** 必须配好 CSP 应用列表. 这个表用空格隔开, 例如: IRIS_WEBAPPS=/csp/sys /swagger-ui. 默认, 只有 /csp/sys 被暴露.
80和 443 端口映射好. 如果你的系统中已经使用了这些端口,请将调整为其他端口.
version: '3.6'
services:
webgateway:
image: tls-ssl-webgateway
container_name: tls-ssl-webgateway
networks:
app_net:
ipv4_address: 172.16.238.50
ports:
# change the local port already used on your system.
- "80:80"
- "443:443"
environment:
- IRIS_HOST=172.16.238.20
- IRIS_PORT=1972
# Replace by the list of ip address allowed to open the CSP system manager
# https://localhost/csp/bin/Systems/Module.cxw
# see .env file to set environement variable.
- "SYSTEM_MANAGER=${LOCAL_IP}"
# the list of web apps
# /csp allow to the webgateway to redirect all request starting by /csp to the iris instance
# You can specify a list separate by a space : "IRIS_WEBAPPS=/csp /api /isc /swagger-ui"
- "IRIS_WEBAPPS=/csp/sys"
volumes:
# Mount certificates files.
- ./volume-apache/webgateway_client.cer:/opt/webgateway/bin/webgateway_client.cer
- ./volume-apache/webgateway_client.key:/opt/webgateway/bin/webgateway_client.key
- ./volume-apache/CA_Server.cer:/opt/webgateway/bin/CA_Server.cer
- ./volume-apache/apache_webgateway.cer:/etc/apache2/certificate/apache_webgateway.cer
- ./volume-apache/apache_webgateway.key:/etc/apache2/certificate/apache_webgateway.key
hostname: webgateway
command: ["--ssl"]
iris:
image: intersystemsdc/iris-community:latest
container_name: tls-ssl-iris
networks:
app_net:
ipv4_address: 172.16.238.20
volumes:
- ./iris-config-files:/opt/config-files
# Mount certificates files.
- ./volume-iris/CA_Server.cer:/usr/irissys/mgr/CA_Server.cer
- ./volume-iris/iris_server.cer:/usr/irissys/mgr/iris_server.cer
- ./volume-iris/iris_server.key:/usr/irissys/mgr/iris_server.key
hostname: iris
# Load the IRIS configuration file ./iris-config-files/iris-config.json
command: ["-a","sh /opt/config-files/configureIris.sh"]
networks:
app_net:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
Build and start:
docker-compose up -d --build
tls-ssl-iris 和 tls-ssl-webgateway 容器应该启动好了.
打开网页 http://localhost.
你将自动被重定向到https://localhost.
浏览器显示安全警告. 如果是自签署的证书,这是正常的,接受并继续.

打开 https://localhost/csp/bin/Systems/Module.cxw 并测试服务器连接.

打开 https://localhost/csp/sys/utilhome.csp

赞! Web Gateway 例子跑起来了!
在上一篇文章中,我们建立了一个镜像环境,但网络网关是一个缺失的部分。 现在,我们可以改进这一点。 一个包括Web Gateway和一些更多改进的资源库就可以用了 iris-miroring-with-webgateway :
查看 repository文件 README.md 来运行以下环境:

设置可重复的开发环境的最简单的方法之一是使用容器。我发现在快速迭代时,在我的开发环境容器里托管一个vscode实例是非常方便的。因此,我创建了一个快速的容器脚本,将一个基于浏览器的vscode添加到IRIS容器中。这应该适用于大多数2021.1以上的容器。我的代码库可以在这里找到
带VSCode 且预连接好的InterSystems IRIS 容器
| Cred | Value |
|---|---|
| User | _SYSTEM |
| Password | SYS |

这个项目创建了一个IRIS容器,在同一个IRIS容器中提供了vscode的托管(web-based)版本。这提供了:
git clone https://github.com/nickmitchko/Hosting-vscode-in-a-container.gitdocker build . -t vscode-irishealth-ml:latest --no-cachedocker-compose up# New folder for project
mkdir vscode-iris
cd vscode-iris
# Clone repo here
git clone https://github.com/nickmitchko/Hosting-vscode-in-a-container.git .
# Build image
docker build . -t vscode-irishealth-ml:latest --no-cache
# Only Run (A) or (B)
#
# (A) Run compose file
docker-compose up
# OR (B) if you want a daemon
docker-compose up -d
如果想要一个持久化IRIS实例, 去掉docker-compose.yml 文件中16-20行里的注释 . 这样就在容器上增加了一个持久化存储的挂载。
volumes:
- "./durable/:/durable/"
environment:
- ISC_DATA_DIRECTORY=/durable/iconfig
这个镜像是建立在 InterSystems 开发者社区 zpm 镜像上 (看这里). 这些镜像包括了让我们从package repo 安装的zpm命令,只是仅有一个90天的社区版 license。
用于这个builds上的镜像标签image tag:
FROM intersystemsdc/irishealth-ml-community:latest
如果你想改变镜像, 把docker 文件里的第一行改成你想要的镜像标签image tag (可以是一个自定义的IRIS instance 或者 官方支持的). 例如:
FROM containers.intersystems.com/intersystems/irishealth-community:2021.2.0.651.0
如果你没有用 docker compose, 你仍然可以如下运行容器:
# After building the container
# --after command is required
docker run --name vscode -d \
--publish 1972:1972 \
--publish 52773:52773 \
--publish 51773:51773 \
--publish 53773:53773 \
--publish 8080:8080 \
--publish 8888:8888 \
vscode-irishealth-ml:latest \
--after "/bin/bash /install/boot.sh"
各位好,
你曾建立过一个镜像环境吗?它是否有一个私有网络、虚拟IP地址和SSL配置? 在做了几次之后,我意识到这是一个漫长的过程,而且需要很多手动操作来生成证书和配置每个IRIS实例。 对于经常要做这件事的人来说,这是一个痛苦的过程。
例如,质量保证团队可能需要为每个新的应用程序版本创建一个新的镜像环境来测试。支持团队可能需要创建一个镜像环境来重现一个复杂的问题。
我们肯定需要工具来快速创建这些镜像环境。
在这篇文章中,我们将用如下环境创建一个镜像样例:

乍一看,它似乎有点复杂,看起来需要大量的代码,但不要担心。 在OpenExchange上有一些库,可以轻松地执行大多数操作。
本文的目的是提供一个例子,说明如何根据你的需要调整这个过程,但在安全问题上,它不是一个最佳实践指南。 现在,让我们来创建我们的样本。
PKI-script: 公钥基础设施(PKI)是一个与IRIS集成的功能,它允许你生成一个自签名的证书并拥有你的授权服务器。在伟大的Pete Greskoff的文章之后,PKI-script的目标是以编程方式执行所有操作,避免在管理门户中进行任何手动操作。 该库包括用于镜像的实用方法。 然而,如果你已经有了证书,你可以用它们来代替PKI-Script。
config-api: 这个库将被用来配置IRIS。它从1.1.0版本开始支持镜像配置。我们将不对如何使用这个库进行详细描述。 这里 已经有一组文章。简而言之,config-api将被用来创建IRIS模板配置文件(JSON格式)并轻松加载。
ZPM.
Docker.
你可以在iris-mirroring-samples repository上找到所有必要的资源文件。
克隆现有的资源库:
git clone https://github.com/lscalese/iris-mirroring-samples
cd iris-mirroring-samples
如果你喜欢从头开始创建一个样本,而不是克隆资源库,只需创建一个带有子目录的新目录: backup 和 config-files. 下载 irissession.sh :
mkdir -p iris-mirroring-samples/backup iris-mirroring-samples/config-files
cd iris-mirroring-samples
wget -O session.sh https://raw.githubusercontent.com/lscalese/iris-mirroring-samples/master/session.sh
为了避免以后出现 "权限拒绝 "的问题,我们需要创建irisowner组,irisowner用户,并将备份目录的组改为irisowner。
sudo useradd --uid 51773 --user-group irisowner
sudo groupmod --gid 51773 irisowner
sudo chgrp irisowner ./backup
这个目录将被用作卷,在与其他节点建立第一个镜像成员后共享数据库备份。
镜像在IRIS社区版中不可用。
如果你还没有有效的IRIS容器许可证,请用你的账户连接到
全球响应中心(WRC)。
点击 "Actions" --> "SW distribtion", 然后点击 "Evaluations" 按钮并选择"Evaluation License"; 填写表单。
把你的许可证文件iris.key复制到这个目录。
###登录Intersystems 容器注册中心(Containers Registry)
为了方便起见,我们使用Intersystems Containers Registry(ICR)来提取docker镜像。如果你不知道你的docker登录名/密码,只要用你的WRC账户连接到SSO.UI.User.ApplicationTokens.cls 就可以检索到你的ICR Token。
docker login -u="YourWRCLogin" -p="YourICRToken" containers.intersystems.com
myappdata数据库和global我们现在并没有真正创建myappdata数据库,而是准备一个配置,在docker构建时创建它。
为此,我们只是用JSON格式创建一个简单的文件。
config-api库将被用来在IRIS实例中加载它。
为此,我们只是用JSON格式创建一个简单的文件。
config-api库将被用来在IRIS实例中加载它。
创建文件config-files/simple-config.json
{
"Defaults":{
"DBDATADIR" : "${MGRDIR}myappdata/",
"DBDATANAME" : "MYAPPDATA"
},
"SYS.Databases":{
"${DBDATADIR}" : {}
},
"Databases":{
"${DBDATANAME}" : {
"Directory" : "${DBDATADIR}"
}
},
"MapGlobals":{
"USER": [{
"Name" : "demo.*",
"Database" : "${DBDATANAME}"
}]
},
"Security.Services" : {
"%Service_Mirror" : { /* Enable the mirror service on this instance */
"Enabled" : true
}
}
}
这个配置文件允许你用默认设置创建一个新的数据库,并在USER命名空间做global映射demo.*。
关于config-api 配置文件功能的更多信息请参考相关的文章 或github页
Docker文件是基于现有的 docker模板的,但我们需要做一些修改,以创建一个工作目录,安装使用虚拟IP的工具,安装ZPM等等。
我们的IRIS image对每个镜像成员都是一样的。镜像将根据其角色The mirroring will be set up on the container starting with the correct configuration depending on its role (第一成员,故障转移备份成员,或读写报告成员) 在容器上以正确的配置开始设置。 请看下面Dockerfile上的注释:
ARG IMAGE=containers.intersystems.com/intersystems/iris:2021.1.0.215.0
# 不需要从WRC下载image。它将在构建时从ICR中提取。
FROM $IMAGE
USER root
#
COPY session.sh /
COPY iris.key /usr/irissys/mgr/iris.key
# /opt/demo 将是我们的工作目录,用于存储我们的配置文件和其他安装文件。
# 安装iputils-arping 以得到一个arping 命令。这在配置虚拟IP时会用到。
# 下载最新ZPM 版本 (ZPM 仅包含在社区版中)。
RUN mkdir /opt/demo && \
chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/demo && \
chmod 666 /usr/irissys/mgr/iris.key && \
apt-get update && apt-get install iputils-arping && \
wget -O /opt/demo/zpm.xml https://pm.community.intersystems.com/packages/zpm/latest/installer
USER ${ISC_PACKAGE_MGRUSER}
WORKDIR /opt/demo
# 设置默认镜像(Default Mirror)角色为主控(master)
# 它将在运行时被重写在docker-compose文件上(第一个实例的主文件、备份和报告)。
ARG IRIS_MIRROR_ROLE=master
# 将config-files目录的内容复制到/opt/demo。
# 目前我们只创建了一个simple-config来设置我们的数据库和global映射。
# 在本文的后面,我们将添加其他配置文件来设置镜像。
ADD config-files .
SHELL [ "/session.sh" ]
# 安装 ZPM
# 用 ZPM 安装config-api 和 pki-script
# 用config-api加载simple-config.json文件,用以:
# - 创建"myappdata" 数据库,
# - 为 "myappdata "数据库中global "demo.*"在命名空间 "USER "中添加一个global映射。
# 基本上,安装ObjectScript应用程序的入口在这里。
# 对于这个例子,我们将加载simple-config.json来创建一个简单的数据库和一个global映射。
RUN \
Do $SYSTEM.OBJ.Load("/opt/demo/zpm.xml", "ck") \
zpm "install config-api" \
zpm "install pki-script" \
Set sc = ##class(Api.Config.Services.Loader).Load("/opt/demo/simple-config.json")
# 复制镜像初始化脚本。
COPY init_mirror.sh /
# 执行一个启动后的脚本,配置镜像。
# init_mirror.sh的内容将在本文后面描述。
CMD ["-a", "/init_mirror.sh"]
Docker文件已经准备好了;我们可以制作image了。:
docker build --no-cache --tag mirror-demo:latest .
这个image将会运行 将被用于运行主节点、备份节点和报告节点。
config-api库允许配置一个镜像,所以我们必须为第一个镜像成员创建一个专门的配置文件config-files/mirror-master.json
为方便起见,注释直接位于JSON中。你可以下载 没有注释的mirror-master.json. 所有的IP地址将通过Docker-compose文件分配给每个节点。
{
"Defaults":{ /* Section contains all variables */
"MirrorName" : "Demo", /* The name of our mirror */
"ArbiterNode" : "172.16.238.10|2188", /* IP Address and port of the arbiter node */
"VirtualAddress" : "172.16.238.100/24", /* Virtual IP Address */
"VirtualAddressInterface" : "eth0", /* Network interface used for the Virtual IP Address. */
"MirrorAddress" : "172.16.220.20", /* IP Address of this node in the private mirror network */
"AgentAddress" : "172.16.238.20", /* IP Address of this node (Agent is installed on the same machine) */
"SystemName" : "master", /* This instance name in the mirror */
"DBDir" : "${MGRDIR}myappdata/", /* Database directory to add to the Demo mirror */
"DBName" : "MYAPPDATA" /* Database name in the mirror */
},
"SYS.MirrorMaster" : {
"${MirrorName}" : {
"Config" : {
"Name" : "${MirrorName}",
"SystemName" : "${SystemName}",
"UseSSL" : true,
"ArbiterNode" : "${ArbiterNode}",
"VirtualAddress" : "${VirtualAddress}",
"VirtualAddressInterface" : "${VirtualAddressInterface}",
"MirrorAddress": "${MirrorAddress}",
"AgentAddress": "${AgentAddress}"
},
"Databases" : [{ /* List of databases to add to the mirror */
"Directory" : "${DBDir}",
"MirrorDBName" : "${DBName}"
}],
"SSLInfo" : { /* SSL Configuration, certificates are generated by PKI */
"CAFile" : "/usr/irissys/mgr/CAServer/CA_Server.cer",
"CertificateFile" : "/usr/irissys/mgr/master_client.cer",
"PrivateKeyFile" : "/usr/irissys/mgr/master_client.key",
"PrivateKeyPassword" : "",
"PrivateKeyType" : "2"
}
}
}
}
创建一个配置文件,故障转移备份成员config-files/mirror-backup.json.
它看起来像第一个成员。
{
"Defaults":{ /* Section contains all variables */
"MirrorName" : "Demo", /* Mirror to join */
"AgentAddress" : "172.16.238.20", /* Agent IP Address of the first mirror member */
"SystemName" : "backup", /* This instance name in the mirror */
"PrimaryInstanceName" : "IRIS", /* IRIS Instance name of the first mirror member */
"VirtualAddressInterface" : "eth0", /* Network interface used for the Virtual IP Address. */
"DBDir" : "${MGRDIR}myappdata/", /* DB in mirror */
"MirrorAddress" : "172.16.220.30" /* IP Address of this node in the private mirror network */
},
"SYS.MirrorFailOver" : {
"${MirrorName}" : {
"Config": {
"Name" : "${MirrorName}",
"SystemName" : "${SystemName}",
"InstanceName" : "${PrimaryInstanceName}",
"AgentAddress" : "${AgentAddress}",
"AgentPort" : "2188",
"AsyncMember" : false,
"AsyncMemberType" : ""
},
"Databases" : [{
"Directory" : "${DBDir}"
}],
"LocalInfo" : {
"VirtualAddressInterface" : "${VirtualAddressInterface}",
"MirrorAddress": "${MirrorAddress}"
},
"SSLInfo" : {
"CAFile" : "/usr/irissys/mgr/CA_Server.cer",
"CertificateFile" : "/usr/irissys/mgr/backup_client.cer",
"PrivateKeyFile" : "/usr/irissys/mgr/backup_client.key",
"PrivateKeyPassword" : "",
"PrivateKeyType" : "2"
}
}
}
}
它与故障转移配置文件非常相似。 不同之处在于AsyncMember、AsyncMemberType和MirrorAddress的值。
创建文件./config-files/mirror-report.json:
{
"Defaults":{
"MirrorName" : "Demo",
"AgentAddress" : "172.16.238.20",
"SystemName" : "report",
"PrimaryInstanceName" : "IRIS",
"VirtualAddressInterface" : "eth0",
"DBDir" : "${MGRDIR}myappdata/",
"MirrorAddress" : "172.16.220.40"
},
"SYS.MirrorFailOver" : {
"${MirrorName}" : {
"Config": {
"Name" : "${MirrorName}",
"SystemName" : "${SystemName}",
"InstanceName" : "${PrimaryInstanceName}",
"AgentAddress" : "${AgentAddress}",
"AgentPort" : "2188",
"AsyncMember" : true,
"AsyncMemberType" : "rw"
},
"Databases" : [{
"Directory" : "${DBDir}"
}],
"LocalInfo" : {
"VirtualAddressInterface" : "${VirtualAddressInterface}",
"MirrorAddress": "${MirrorAddress}"
},
"SSLInfo" : {
"CAFile" : "/usr/irissys/mgr/CA_Server.cer",
"CertificateFile" : "/usr/irissys/mgr/report_client.cer",
"PrivateKeyFile" : "/usr/irissys/mgr/report_client.key",
"PrivateKeyPassword" : "",
"PrivateKeyType" : "2"
}
}
}
}
所有的配置文件都准备好了!
我们的Dockerfile的最后一行是CMD ["-a", "/init_mirror.sh"]。 现在我们要写这个脚本来生成证书,并用相关的配置文件来设置每个IRIS节点。
正如你在这个脚本中看到的那样,生成证书的代码非常简单:
Do ##class(lscalese.pki.Utils).MirrorMaster(,"",,,,"backup,report") -主控节点。
它配置了PKI服务器,PKI客户端,请求证书;等待验证,获得证书,自动接受验证节点的进一步请求,持续5分钟。自动接受的请求只限于故障转移备份主机 和 报告异步成员主机。Do ##class(lscalese.pki.Utils).MirrorBackup("${PKISERVER}","") -备份节点和报告节点。
配置 PKI 客户端,请求证书,等待验证,获得证书。#!/bin/bash
# 用来测试镜像的数据库
DATABASE=/usr/irissys/mgr/myappdata
# 目录包含由主控节点备份的myappdata,以便在其他节点上恢复。
BACKUP_FOLDER=/opt/backup
# 主控节点的json config-api格式的镜像配置文件。
MASTER_CONFIG=/opt/demo/mirror-master.json
# json config-api格式的镜像配置文件,用于故障转移备份节点。
BACKUP_CONFIG=/opt/demo/mirror-backup.json
# 报告异步节点的json config-api格式的镜像配置文件。
REPORT_CONFIG=/opt/demo/mirror-report.json
# 镜像名字...
MIRROR_NAME=DEMO
# 镜像成员清单
MIRROR_MEMBERS=BACKUP,REPORT
# PKI服务器主机:端口(PKI服务器安装在主实例上)。
PKISERVER=master:52773
# 在主控节点上操作。
# 在这个实例上配置公钥基础设施服务器,并生成证书以配置使用SSL的镜像。
# 请参见文章https://community.intersystems.com/post/creating-ssl-enabled-mirror-intersystems-iris-using-public-key-infrastructure-pki。
# 和相关的工具https://openexchange.intersystems.com/package/PKI-Script。
# 使用config-api加载镜像配置与/opt/demo/simple-config.json文件。
# 启动一个作业,自动接受其他名为 "备份 (backup)"和 "报告 (report)"的成员加入镜像(避免在门户管理中进行手动验证,最大延迟为600秒)。
master() {
rm -rf $BACKUP_FOLDER/IRIS.DAT
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS <<- END
Do ##class(lscalese.pki.Utils).MirrorMaster(,"")
Set sc = ##class(Api.Config.Services.Loader).Load("${MASTER_CONFIG}")
Set ^log.mirrorconfig(\$i(^log.mirrorconfig)) = \$SYSTEM.Status.GetOneErrorText(sc)
Job ##class(Api.Config.Services.SYS.MirrorMaster).AuthorizeNewMembers("${MIRROR_MEMBERS}","${MIRROR_NAME}",600)
Hang 2
Halt
END
}
# 由主控节点运行,对myappdata 数据库镜像备份
make_backup() {
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).DismountDatabase(\"${DATABASE}\")"
md5sum ${DATABASE}/IRIS.DAT
cp ${DATABASE}/IRIS.DAT ${BACKUP_FOLDER}/IRIS.TMP
mv ${BACKUP_FOLDER}/IRIS.TMP ${BACKUP_FOLDER}/IRIS.DAT
# 备份被储存在容器外
# chmod 777 可避免我们需要从主机删除这个文件时碰到拒绝权限问题
chmod 777 ${BACKUP_FOLDER}/IRIS.DAT
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).MountDatabase(\"${DATABASE}\")"
}
# 恢复镜像数据库 "myappdata"。 这个恢复过程是在故障转移 "备份 "节点和 "报告 "节点上进行的。
restore_backup() {
sleep 5
while [ ! -f $BACKUP_FOLDER/IRIS.DAT ]; do sleep 1; done
sleep 2
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).DismountDatabase(\"${DATABASE}\")"
cp $BACKUP_FOLDER/IRIS.DAT $DATABASE/IRIS.DAT
md5sum $DATABASE/IRIS.DAT
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS "##class(SYS.Database).MountDatabase(\"${DATABASE}\")"
}
# 配置“备份”成员
# - 配置公钥基础设施客户端以安装证书并使用镜像的SSL。
# - 如果这个实例是备份,加载配置文件/opt/demo/mirror-backup.json,或
# 如果这个实例是报告(即异步读写镜像节点),加载配置文件/opt/demo/mirror-report.json
other_node() {
sleep 5
iris session $ISC_PACKAGE_INSTANCENAME -U %SYS <<- END
Do ##class(lscalese.pki.Utils).MirrorBackup("${PKISERVER}","")
Set sc = ##class(Api.Config.Services.Loader).Load("$1")
Halt
END
}
if [ "$IRIS_MIRROR_ROLE" == "master" ]
then
master
make_backup
elif [ "$IRIS_MIRROR_ROLE" == "backup" ]
then
restore_backup
other_node $BACKUP_CONFIG
else
restore_backup
other_node $REPORT_CONFIG
fi
exit 0
我们有四个容器可以启动。一个Docker-compose文件是一个完美的文件,可以协调我们的样本。
version: '3.7'
services:
arbiter:
image: containers.intersystems.com/intersystems/arbiter:2021.1.0.215.0
init: true
container_name: mirror-demo-arbiter
command:
- /usr/local/etc/irissys/startISCAgent.sh 2188
networks:
app_net:
ipv4_address: 172.16.238.10
extra_hosts:
- "master:172.16.238.20"
- "backup:172.16.238.30"
- "report:172.16.238.40"
cap_add:
- NET_ADMIN
master:
build: .
image: mirror-demo
container_name: mirror-demo-master
networks:
app_net:
ipv4_address: 172.16.238.20
mirror_net:
ipv4_address: 172.16.220.20
environment:
- IRIS_MIRROR_ROLE=master
ports:
- 81:52773
volumes:
- ./backup:/opt/backup
hostname: master
extra_hosts:
- "backup:172.16.238.30"
- "report:172.16.238.40"
cap_add:
- NET_ADMIN
backup:
image: mirror-demo
container_name: mirror-demo-backup
networks:
app_net:
ipv4_address: 172.16.238.30
mirror_net:
ipv4_address: 172.16.220.30
ports:
- 82:52773
environment:
- IRIS_MIRROR_ROLE=backup
volumes:
- ./backup:/opt/backup
hostname: backup
extra_hosts:
- "master:172.16.238.20"
- "report:172.16.238.40"
cap_add:
- NET_ADMIN
report:
image: mirror-demo
container_name: mirror-demo-report
networks:
app_net:
ipv4_address: 172.16.238.40
mirror_net:
ipv4_address: 172.16.220.40
ports:
- 83:52773
environment:
- IRIS_MIRROR_ROLE=report
volumes:
- ./backup:/opt/backup
hostname: report
extra_hosts:
- "master:172.16.238.20"
- "report:172.16.238.40"
cap_add:
- NET_ADMIN
networks:
app_net:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
# 镜像私有网络
mirror_net:
ipam:
driver: default
config:
- subnet: "172.16.220.0/24"
docker-compose up
等待每个实例有一个良好的镜像状态:
Primary.Backup.Connected.这需要一些时间,因为系统在获取虚拟IP方面有一些问题。
将进行许多尝试,并在messages.log中写上AddVirtualAddress failed。
最后,你应该在docker日志中看到这些信息:
mirror-demo-master | 01/09/22-11:02:08:227 (684) 1 [Utility.Event] Becoming primary mirror server
...
mirror-demo-backup | 01/09/22-11:03:06:398 (801) 0 [Utility.Event] Found MASTER as primary, becoming backup
...
mirror-demo-report | 01/09/22-11:03:10:745 (736) 0 [Generic.Event] MirrorClient: Connected to primary: MASTER (ver 4)
你也可以直接通过门户网站 http://localhost:81/csp/sys/utilhome.csp 检查镜像状态。

在Docker-compose中,我们对端口81、82和83进行了映射,使其可以访问每个管理门户。 这就是所有实例的默认登录名和密码:
检查镜像监视器( mirror monitor) (在管理门户management portal中;这是默认用户名和密码): http://localhost:81/csp/sys/op/%25CSP.UI.Portal.Mirror.Monitor.zen
验证镜像设置: http://localhost:81/csp/sys/mgr/%25CSP.UI.Portal.Mirror.EditFailover.zen?$NAMESPACE=%25SYS

我们可以通过简单地设置一个以demo.开始的global来启动一个测试。
记住,我们已经在命名空间USER上配置了一个global映射demo.*。
在主服务器上打开一个终端会话:
docker exec -it mirror-demo-master irissession iris
Set ^demo.test = $zdt($h,3,1)
检查备份节点上的数据是否可用:
docker exec -it mirror-demo-backup irissession iris
Write ^demo.test
检查报告节点上的数据是否可用:
docker exec -it mirror-demo-report irissession iris
Write ^demo.test
好了! 我们已经准备好了一个镜像环境,完全以自动化方式/编程方式创建。 为了更完整一些,我们应该在网络网关和IRIS之间添加一个带https和加密的网络网关,但我们将把它留给下一篇文章。
如果你决定创建自己的脚本,希望这篇文章对你有用。
本文内容的灵感来自于以下内容:
生产环境中会定时生成备份(全备,增备),因为服务器空间有限,所以需要定时删除。
请问:IRIS2021 是否有工具或者代码可以实现定时删除3周前备份文件的功能。如果是代码实现,思路是什么,能否给个Demo。
背景:在实际场景中,处理历史数据问题会出现数据暴增的情况,在此情景下journal文件会暴增从而出现磁盘被沾满的风险,因此需要对journal进行删除。
步骤:
1.点击【系统操作】->【任务管理器】->【新任务】创建定时任务。
2.按下图输入参数
重要参数:
任务运行所在的 命名空间:%SYS
任务类型:运行传统任务
执行代码:do ##Class(%SYS.Journal.File).PurgeAll()
4.点击【完成】
备注:此任务在数据暴增情况结束后应挂起。
问题:
1、EnableVSSBackup这个参数在哪里设置?
2、Cache是否有自己的writer,如果有,怎样查到,叫什么名?
3、实现Cache的全量增量备份,使用VSS是否是最佳实践?
4、是否有Cache全量增量备份的实践案例,以供参考?
————————————————————————————————————————————————————————————————————————————————
我参考这篇官方文档,在启动应用时EnableVSSBackup会默认设置为1,但是我在配置或者应用界面中并没有看到这参数。
https://docs.intersystems.com/latest/csp/docbook/Doc.View.cls?KEY=GCDI_…
在 Cache启动的时候,我在日志中并没有收到”Caché VSS Writer started“的信息;而且我在cache.cpf里添加EnableVSSBackup 字段为1,再启动cache会得到下面的乱码信息。
SAM(系统警报和监视)以“功能齐全”的 docker-compose 容器集的形式提供,只要启动就可以开始以默认的仪表板监视 IRIS 实例。 使用初始配置就可以很好地了解 SAM 功能并开始对 IRIS 系统进行基本监视。 但是,当开始监视多个系统并收集大量指标数据时,需要更改一些默认设置。 为了从 SAM 获取更多价值,您还会想要添加来自其他数据源(目标)的指标。 以下技巧将帮助您在生产环境中部署 SAM,从多个目标收集指标并将这些指标组合到您自己的仪表板和图表中。 此外,您还将看到一些可能有助于探索 SAM 容器和应用程序的命令。
*注意:*我应该指出,其中一些技巧和提示可能不是最佳做法;这更像是一个日志,记录了我第一次如何配置 SAM 来监视相同系统上的多个服务器和非 IRIS 目标的基准。 如果您有建议,请在评论中指教 ;) 所以,记住本帖可能会随着时间的推移而有所变化,让我们开始吧;
在下面的技巧中,有重启 docker 以及启动和停止 SAM 的操作。 请通读这些技巧,确定哪些适合您,然后按照下面的相同顺序执行。
默认情况下,docker 容器将文件存储在根 (/) 文件系统。 SAM 不需要很多 CPU 或内存资源;但是,指标收集将占用空间。
指标需要的存储容量“视情况而定”。 虽然在开始监视之前可能无法明确数据库大小,但大致上,在抓取周期为 15 秒的情况下,监视 10 个 IRIS 虚拟机以及操作系统指标大约消耗 50GB 存储。
策略包括:增加监视实例的根存储,或更改数据库的卷位置。 我使用了以下命令来更改运行 docker 的虚拟机上的 docker 目录。 也许是杀鸡用了牛刀,但很管用。
[root@mysamserver lib]# sudo systemctl stop docker
[root@mysamserver lib]# pwd
/var/lib
[root@mysamserver lib]# cp -rp docker /data/docker/data
[root@mysamserver lib]#
[root@mysamserver lib]# rm -rf docker
cat /etc/docker/daemon.json
{
"data-root": "/data/docker/data",
"bip": "192.168.0.1/24"
}
sudo systemctl daemon-reload
sudo systemctl restart docker
systemctl status docker.service
我假定您已在测试系统上设置 SAM,并熟悉它的基本操作:添加集群和实例,以及查看系统指标。 建议您花 20 分钟时间查看我在虚拟全球峰会 2020 上的展示,以了解安装步骤的概述,以及添加多个目标的运行指标时 SAM 的外观。 要观看此会议,请使用以下链接(您需要使用您的电子邮件注册):
登录到 SAM 门户并配置一些 IRIS 实例。 这会填充配置文件并提供向导。
http://mysamserver:8080/api/sam/app/index.csp#/
注意:如果要添加多个实例,或者希望用脚本执行此步骤,可以通过 API 添加实例。 请参见文档。
SAM 随附了一个 IRIS 社区版许可证。 有几个限制,包括 IRIS.DAT 限制为 10GB。 10GB 不足以长时间从多个目标收集数据。 请联系您的 InterSystems 联系人以获取生产许可证。 在没有编辑器的情况下,在精简的容器中更新许可证可能很棘手,我只是在 IRIS 容器上登录一个交互式会话,然后使用以下命令更新许可证密钥:
docker exec -it sam_iris_1 bash
cd /dur/iconfig/mgr
cat <<EOF >iris.key
>
[ConfigFile]
FileType=InterSystems License Rev-A.1
LicenseID=999999
[License]
LicenseCapacity=InterSystems IRIS 2020.2 Server for SAM:etc etc, the key you were sent by your InterSystems contact.
>EOF
exit
./stop.sh
./start.sh
docker exec -it sam_iris_1 bash
cd /dur/iconfig/mgr
cat messages.log
例如,prometheus 节点导出程序可显示各种硬件和内核相关的指标。
通过请求(抓取)实例端点的指标,测试节点导出程序是否正常工作:
curl my_target_server_name:9100/metrics
您应该看到类似下面的信息:
mylaptop:~ mo$ my_target_server_name:9100/metrics | more
HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 4.8862e-05
go_gc_duration_seconds{quantile="0.25"} 7.5898e-05
go_gc_duration_seconds{quantile="0.5"} 9.2974e-05
go_gc_duration_seconds{quantile="0.75"} 0.000130664
go_gc_duration_seconds{quantile="1"} 0.000358762
go_gc_duration_seconds_sum 303.291715258
go_gc_duration_seconds_count 2.572586e+06
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 9
:
: many many metrics will be displayed
注意您可以对您的 IRIS 实例执行同样操作:
mylaptop:~ mo$ curl my_target_server_name:52776/api/monitor/metrics | more
iris_cpu_pct{id="AUXWD"} 0
iris_cpu_pct{id="CSPDMN"} 0
iris_cpu_pct{id="CSPSRV"} 0
iris_cpu_pct{id="ECPCliR"} 0
iris_cpu_pct{id="ECPCliW"} 0
iris_cpu_pct{id="ECPSrvR"} 0
iris_cpu_pct{id="ECPSrvW"} 0
:
: many many metrics will be displayed
例如,前一个技巧中的 node-exporter 实例。 配置文件将位于 SAM 的安装位置。 如下所示,可以看到 grafana 和 prometheus yml 配置文件。
[root@mysamserver sam-1.0.0.115-unix]# ls
config docker-compose.yml readme.txt start.sh stop.sh
[root@mysamserver sam-1.0.0.115-unix]# tree -x config
config
├── alertmanager
│ └── isc_alertmanager.yml
├── grafana
│ ├── dashboard.json
│ ├── dashboard-provider.yml
│ ├── datasource.yml
│ └── grafana.ini
├── nginx
│ └── nginx.conf
└── prometheus
├── isc_alert_rules.yml
└── isc_prometheus.yml
4 directories, 8 files
以下示例是使用 SAM 中的配置 GUI 屏幕创建的 isc_prometheus.yml 文件。 该文件包含两个集群。 一个集群监视 sam 实例本身,另一个集群监视五个 IRIS 实例。
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
global:
evaluation_interval: 15s
scrape_interval: 15s
remote_read:
- url: http://iris:52773/api/sam/private/db/read
remote_write:
- url: http://iris:52773/api/sam/private/db/write
rule_files:
- ./isc_alert_rules.yml
scrape_configs:
- job_name: SAM
metrics_path: /api/monitor/metrics
scheme: http
static_configs:
- labels:
cluster: "1"
targets:
- mysaminstance.mycompany.com:8080
- labels:
cluster: "2"
targets:
- myiristarget1:52776
- myiristarget2:52776
- myiristarget3:52776
- myiristarget4:52776
- myiristarget5:52776
isc_prometheus.yml 文件的底部。 注意 API metrics_path 与 IRIS 不同。alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
global:
evaluation_interval: 15s
scrape_interval: 15s
remote_read:
- url: http://iris:52773/api/sam/private/db/read
remote_write:
- url: http://iris:52773/api/sam/private/db/write
rule_files:
- ./isc_alert_rules.yml
scrape_configs:
- job_name: SAM
metrics_path: /api/monitor/metrics
scheme: http
static_configs:
- labels:
cluster: "1"
targets:
- iscsydsam.iscinternal.com:8080
- labels:
cluster: "2"
targets:
- myiristarget1:52776
- myiristarget2:52776
- myiristarget3:52776
- myiristarget4:52776
- myiristarget5:52776
- job_name: node_shard1
metrics_path: /metrics
scheme: http
static_configs:
- labels:
cluster: "2"
group: node
targets:
- myiristarget1:9100
- job_name: node_shard2
metrics_path: /metrics
scheme: http
static_configs:
- labels:
cluster: "2"
group: node
targets:
- myiristarget2:9100
- job_name: node_shard3
metrics_path: /metrics
scheme: http
static_configs:
- labels:
cluster: "2"
group: node
targets:
- myiristarget3:9100
- job_name: node_shard4
metrics_path: /metrics
scheme: http
static_configs:
- labels:
cluster: "2"
group: node
targets:
- myiristarget4:9100
- job_name: node_shard5
metrics_path: /metrics
scheme: http
static_configs:
- labels:
cluster: "2"
group: node
targets:
- myiristarget5:9100
./stop.sh
./start.sh
SAM 现在从您通过 GUI 添加的 IRIS 实例以及相同实例上的 node-exporter 中收集指标。
在 SAM 的第一版中,您可以在 GUI 中更改收集指标的天数。 但是,我在显示所有指标时遇到一个问题。 在我弄清楚发生了什么之前,我更改了 Prometheus 中的保留天数,否则 SAM 将收集数据,但是您在 Grafana 的 Prometheus 查询中看不到指标。
在文件 docker-compose.yml 中用来安装 SAM 的层,更改 Prometheus 启动时设置的保留天数,例如在 prometheus 部分中,更新 storage.tsdb.retention.time 参数以匹配所需的保留天数:
prometheus:
command:
- --web.enable-lifecycle
- --config.file=/config/isc_prometheus.yml
- --storage.tsdb.retention.time=30d
注意:在 SAM 的第一版中,最长保留天数为 30 天。 然后使用提供的 docker-compose shell 脚本停止再启动 SAM:
./stop.sh
./start.sh
您可以向现有仪表板添加面板,也可以创建新的仪表板以满足您的监视需求。 这是一个很大的主题,所以留到下一个帖子再说。 不过,这里先帮助您上手。
在 SAM 屏幕上使用 View in Grafana(在 Grafana 中查看)按钮切换到 Grafana。
打开 Grafana 后,可以创建或编辑仪表板;
网上有许多查询导出程序(如 node-exporter)的示例。
当可以显示 IRIS 系统指标(SAM 中的默认设置)、IRIS 应用程序指标(您需要将这些指标构建到应用程序中)以及其他指标(如 node-exporter 或由供应商创建的任何数量的指标)时,真正强大的功能才体现出来。 例如,使用 SAM 和 cAdvisor 监视 Docker 容器
如果一张图片胜过千言万语,那么一段视频又价值几何? 当然胜过敲一个帖子。
请在 InterSystems Developers YouTube 观看我的“Coding talks”:
1. 使用 Yape 分析 InterSystems IRIS 系统性能。 第 1 部分:安装 Yape
在容器中运行 Yape。
2. Yape 容器 SQLite iostat InterSystems
提取和绘制 pButtons 数据,包括时间范围和 iostat。
如果您需要一个简单的方法来捕获和查看 Caché 和 IRIS 以及系统性能指标,可以安排每天运行 pButtons 来轻松实现。 我之前写过这方面的文章。
我经常需要查看客户系统以进行容量规划和性能检查,这就是我编写 Yape 并在 GitHub 上提供它的原因。 我的 InterSystems 同事 Fabian 将 Yape 的内部结构带入了新方向,并使其正式在容器中运行。 Fabian 已经离开 InterSystems,但我继续在 GitHub 上进行开源开发。 在过去一个月左右的时间里,我修复了一些操作系统命令格式错误,使日期处理更智能,在 vmstat 中添加了“Total CPU”图表(倒着看“id”导致我的脖子拉伤),以及其他修饰性更改。
如果您想为 Yape 做出贡献,它在 GitHub 上是开源的。 如果您有功能要求,请通过建议页面告诉我。
另外,请查看 Open Exchange 上的 Yape 应用程序。
在接下来的几个月,我将分享工作流程中的其他一些技巧,并期望继续开发以使呈现的数据更加有用。 Yape 非常适合检查和查看昨天或过去一周发生的事件的趋势,但是您还需要实时监视和警报... 这里我也对将来的一些帖子做个预告 ;)
服务器操作系统频繁产生错误日志“生成了一个严重警告并将其发送到远程终结点。这会导致连接终止。TLS 协议所定义的严重错误代码是 10。Windows SChannel 错误状态是 10。” 想请问一下,这个错误信息是我们产品导致产生的问题吗?
我们不必等待SAM发布才开始规划和试用该API来监控IRIS实例。在以后的文章中,我将更深入地探讨可用的指标及其意义,并提供一些交互式仪表板的示例。首先,我将介绍一下相关背景和一些问题及答案。
IRIS(和Caché)一直在收集自身及其运行平台的数十个指标。收集这些指标来监控Caché和IRIS的方法向来有很多。我发现,很少有安装软件使用IRIS和Caché的内置解决方案。譬如,History Monitor作为性能和系统使用指标的历史数据库,已经推出很长时间了,但它没有简便方法可实时显示这些指标和仪表系统。
IRIS平台解决方案(以及整个业界)正在从仅在一些本地实例上运行的单体式应用程序过渡到“随处”部署的分布式解决方案。在许多用例中,原有的IRIS监控方案并不适用于这些新的模式。InterSystems没有做重复工作,而是将目光投向当前流行的、经过验证的监控和告警开源解决方案。
众所周知,InterSystems IRIS 提供了很多的工具来提升应用系统可伸缩性。尤其在提升数据并行处理能力方面,InterSystems 做了很多努力,例如在 SQL 查询中使用并行处理,以及在 IRIS中引入最具吸引力的特征:分片(sharding)。然而,许多成熟的开发成果最初是在 Caché中完成的,而且已经迁移到 IRIS 中。这些成熟的开发成果大都使用 DBMS(数据库管理系统)的多模型功能,实现在单独的数据库中共存不同的数据模型。例如, HIS qMS 数据库同时包含语义关系(电子病历)、传统关系(与 PACS 的交互)和层次数据模型(实验室数据以及与其他系统的集成)。这些数据模型大多是通过 SP.ARM 的 qWORD 工具(一种直接访问 Global的小型数据库管理系统)实现的。遗憾的是,由于查询未使用 IRIS SQL,无法利用并行查询处理的新功能进行扩展。
而且,随着数据库规模的不断增长,大型关系型数据库所固有的大多数问题开始出现在非关系型数据库中。这就是我们关注可用于扩展的并行数据处理技术的一个主要原因。
在本文中,我将围绕多年来在解决任务时用到的并行数据处理展开多方位讨论,而这些是我在大数据问题探讨中很少提到的。我将重点讨论数据库的技术改造,或者更确切地说,是数据库转换技术。
众所周知,在系统开发的早期阶段(通常远远早于项目完成的时间)就已经选择好了数据模型、存储架构以及软件和硬件平台。但是在系统完成部署几年后,通常会因为这样或那样的原因需要对数据进行迁移。下面是一些常见的任务(所有示例均为真实案例):
你可能会问,这些方案有那么难吗?只需要停止旧系统,导出数据,然后导入到新系统中就可以了。但是,如果你正在处理的是几百 GB(甚至几 TB)的数据库,而且系统在 7x24 运行,那么就无法使用标准的 IRIS 工具解决上述这些任务了。
假设可以将一个任务分解成几个组件。幸运的话,你会发现可以将其中一些并行解决。例如:
可以让多个报告同时执行所有操作:一个报告正处在准备阶段,同时另一个报告已经开始打印,等等。这种方法并不新鲜。早在 60 年前批量数据处理技术出现时,它就开始发挥作用了。虽然这不是一个新的概念,但是非常有用。然而,只有当所有子任务的执行时间具有可比性时,才会实现显著的加速效果,实际情况却并非总是如此。
当任务的操作顺序可以按任意顺序执行并迭代时,它们可以同时执行。例如:
这些任务具有以下共同特点:
这些简单的示例表明,水平并行在数据转换任务中是常用到的,事实也的确如此。在接下来的内容中,我们将重点关注此类并行处理。
MapReduce 是由谷歌引入的一种分布式计算模型。它在处理大量信息的同时也会执行此类操作。目前流行的开源项目构建在 Apache Hadoop和[Mahout](https://ru.bmstu.wiki/index.php?title=Map&action=edit&redlink=1.bmstu.wiki/index.php?title=Map&action=edit&redlink=1)(在处理程序之间分配任务)、实际处理和归约(合并处理结果)。
对此感兴趣的读者如果想了解更多信息,我推荐 Timur Safin 的系列文章,他在《Caché MapReduce——大数据和 MapReduce 概念简介》(第一部分)中介绍了在 IRIS/Caché中创建MapReduce 工具的方法。
请注意,因为 IRIS 具有将数据快速写入数据库的"先天能力",所以归约这一步通常是微不足道的,类似 WordCount 分布式版本中的情况。在处理数据库转换任务时,可能完全没有必要进行这一步。例如,使用并行处理程序将一个大型的 Global 移动到单独的数据库,则不需要任何其他操作。
并行计算模型的创建者(例如 MapReduce)通常将其扩展到多个服务器,即所谓的数据处理节点,但是在数据库转换任务中,通常一个这样的节点就足够了。事实上,连接多个处理节点(例如,通过企业缓存协议(ECP))是没有意义的,因为数据转换所需的 CPU 负载相对较小——这里不用考虑处理过程中的数据量。在这种情况下,初始数据仅使用一次,也就意味着无法通过分布式缓存带来任何性能提升。
经验表明,比较方便的做法是使用两个角色不对称的服务器。下面稍微进行一下简化:
可以说,这种分配任务的方法结合了水平并行(用于在主服务器内分配负载)和垂直并行(用于在主服务器和从属服务器之间分配“职责”)。
让我们思考一下最普通的数据库转换任务:将全部或部分数据从源数据库传输到目标数据库,同时可能对 Global 执行某种重新编码(可以是编码更改、排序规则的更改等等)。在这种情况下,新旧数据库是保存在本地的不同数据库服务器上的。下面列出的是架构师和开发人员需要解决的子任务:
接下来我们逐个进行分析。
众所周知,即使 IRIS 以 Unicode 方式安装,它也可以挂载 8 位数据库(本地和远程)。但反之则不行:8 位版本的 IRIS 无法支持 Unicode 数据库,否则会出现<WIDE CHAR>错误。在决定将哪个服务器(源服务器或目标服务器)作为主服务器时,必须考虑到数据转换过程中字符编码是否发生了更改。然而,想要决定最终的解决方案,还需要考虑下一个任务,那就是:
你有以下几个选项:
在选择方法时,我的优先级非常明确:如果 ECP 可用,并且在传输期间源数据库保持静态,则选择方法 1;如果 ECP 不可用,但数据库保持静态,则选择方法 2;如果修改了源数据库,则选择方法 3。结合这些情况及主服务器的选择条件,我们可以生成如下可能性矩阵:
| 传输期间源数据库是静态的吗? | ECP 协议是否可用? | 源数据库的位置 | 主系统 |
|---|---|---|---|
| 是 | 是 | 目标系统远程 | 目标 |
| 是 | 否 | 目标系统本地(副本) | 目标 |
| 否 | 不重要,因为我们将使用TCP 套接字机制传输数据. | 源系统本地(原始) | 源 |
乍一看,似乎可以简单地通过读取全局目录逐个传递 Global。但是,同一个数据库中的Global 的大小可能相差很大:我最近遇到的一个生产数据库中的 Global 的大小范围在 1MB -600GB 之间。假设我们有多工作进程(nWorkers)可供使用,并且至少有一个 Global(Globals)^Big 符合下面条件:
^Big 的大小 >(所有^ Globals 的大小)/ nWorkers
然后,无论分布式 Global 转移过程中的其他任务完成的多么顺利,最终分配给^Big 的处理任务将一直保持忙碌,并且可能在其他进程完成之后很久才能完成其任务。如果想要改善这种情况,你可以预先按照大小对 Global 进行排序,并从最大的 Global 开始处理。但是如果^Big的大小明显偏离所有 Global 的平均值(这是 MIS qMS 数据库的典型情况):
^Big 的大小 >>(所有^ Globals 的大小)/ nWorkers
这个策略不会提供太大的帮助,因为它必定会产生好几个小时的延迟。因此,需要将大型Global 拆分成多个部分,通过多个并行进程对其进行处理。我想强调的是,这个任务(列表中的第 3 项任务)是本文讨论的最难的任务,而且花费了我(而不是 CPU!)很多时间。
与并行处理机制进行交互的方式如下:
幸运的是,IRIS 提供了一个非常适合该方案的、出色的并行处理引擎(可以通过%SYSTEM.WorkMgr 类实现)。我们将在运行的实例中应用改引擎,并在计划发表的系列文章中进行深入探讨。
在下一篇文章中,我将更加详细地阐述任务 3 的解决方案。
在第三篇文章中(如果大家对我的文章感兴趣的话),我将讨论任务 4 中的细微差别,包括%SYSTEM.WorkMgr 的局限性及其解决方案。
假设你想了解 InterSystems 在数据分析方面能提供什么。 你研究了理论,现在想要进行一些实践。 幸运的是,InterSystems 提供了一个项目:Samples BI,其中包含了一些很好的示例。 从 README 文件开始,跳过任何与 Docker 相关的内容,直接进行分步安装。 启动虚拟实例 安装 IRIS,按照说明安装 Samples BI,然后用漂亮的图表和表格让老板眼前一亮。 到目前为止还不错。
但是不可避免地,你需要进行更改。
事实证明,自己保留虚拟机存在一些缺点,交给云服务商保管是更好的选择。 Amazon 看起来很可靠,你只需创建一个 AWS 帐户(入门免费),了解到使用 root 用户身份执行日常任务是有害的,然后创建一个常规的具有管理员权限的 IAM 用户。
点击几下鼠标,就可以创建自己的 VPC 网络、子网和虚拟 EC2 实例,还可以添加安全组来为自己开放 IRIS Web端口 (52773) 和 ssh 端口 (22)。 重复 IRIS 和 Samples BI 的安装。 这次使用 Bash 脚本,如果你喜欢,也可以使用 Python。 再一次让老板刮目相看。
但是无处不在的 DevOps 运动让你开始了解基础架构即代码,并且你想要实现它。 你选择了 Terraform,因为它是众所周知的,而且它的方法非常通用,只需微小调整即可适合各种云提供商。 使用 HCL 语言描述基础架构,并将 IRIS 和 Samples BI 的安装步骤转换到 Ansible。 然后再创建一个 IAM 用户使 Terraform 正常工作。 全部运行一遍。 获得工作奖励。
渐渐地你会得出结论,在我们这个微服务时代,不使用 Docker 就太可惜了,尤其是 InterSystems 还会告诉你怎么做。 返回到 Samples BI 安装指南并阅读关于 Docker 的几行内容,似乎并不复杂:
将浏览器定向到 http://localhost:52773/csp/user/_DeepSee.UserPortal.Home.zen?$NAMESPACE=USER 后,再次去老板那里,因为做得好而获得一天假期。
然后你开始明白,“docker run”只是开始,至少需要使用 docker-compose。 没问题:
这样你使用 Ansible 安装了 Docker 和 docker-compose,然后运行了容器,如果机器上还没有映像,则会下载一个映像。 最后安装了 Samples BI。
你一定喜欢 Docker,因为它是各种内核素材的又酷又简单的接口。 你开始在其他地方使用 Docker,并且经常启动多个容器。 还发现容器必须经常互相通信,这就需要了解如何管理多个容器。
终于,你发现了 Kubernetes。
从 docker-compose 快速切换到 Kubernetes 的一个方法是使用 kompose。 我个人更喜欢简单地从手册中复制 Kubernetes 清单,然后自己编辑,但是 kompose 在完成小任务方面做得很好:
现在你有了可以发送到某个 Kubernetes 集群的部署和服务文件。 你发现可以安装 minikube,它允许你运行一个单节点 Kubernetes 集群,这正是你现阶段所需要的。 在摆弄一两天 minikube 沙盒之后,你已经准备好在 AWS 云中的某处使用真实的 Kubernetes 部署。
设置
我们一起来进行吧。 此时,我们做以下几个假设:
首先,我们假设你有一个 AWS 帐户,你知道其 ID,并且未使用 root 凭据。 你创建了一个具有管理员权限且只能以编程方式访问的 IAM 用户(我们称之为“my-user”),并存储了其凭据。 你还创建了另一个具有相同权限的 IAM 用户,名为“terraform”:

Terraform 将以它的名义进入你的 AWS 帐户,并创建和删除必要资源。 这两个用户的广泛权限将通过演示来说明。 你在本地保存了这两个 IAM 用户的凭据:
注意:不要复制和粘贴上面的凭据。 它们在这里作为示例提供,不再存在。 请编辑 ~/.aws/credentials 文件并引入你自己的记录。
其次,我们将在文中使用虚拟的 AWS 帐户 ID (01234567890) 和 AWS 区域“eu-west-1”。 可以随意使用其他区域。
第三,我们假设你知道 AWS 不是免费的,你需要为使用的资源付费。
接下来,您已经安装了 AWS CLI 实用程序,以便与 AWS 进行命令行通信。 你可以尝试使用 aws2,但你需要在 kube 配置文件中特别设置 aws2 的用法,如这里所述。
你还安装了 kubectl 实用程序来与 AWS Kubernetes 进行命令行通信。
并且你也针对 docker-compose.yml 安装了 kompose 实用程序,来转换 Kubernetes 清单。
最后,你创建了一个空的 GitHub 仓库,并将其克隆到主机上。 我们将其根目录引用为
请注意,所有相关代码都在 github-eks-samples-bi 仓库中复制,以简化拷贝和粘贴。
我们继续。
AWS EKS 预置
我们已经在文章使用 Amazon EKS 部署简单的基于 IRIS 的 Web 应用程序中知道了 EKS。 那时,我们以半自动方式创建了一个集群。 即,我们在一个文件中描述集群,然后从本地机器手动启动 eksctl 实用程序,该实用程序根据我们的描述创建集群。
eksctl 是为创建 EKS 集群而开发的,它非常适合概念验证实现,但对于日常使用来说,最好使用更通用的工具,例如 Terraform。 AWS EKS 简介是一个非常好的资源,其中介绍了创建 EKS 集群所需的 Terraform 配置。 花一两个小时熟悉一下,决不会是浪费时间。
你可以在本地操作 Terraform。 为此,你需要一个二进制文件(在撰写本文时,我们使用最新的 Linux 版本 0.12.20),并且 IAM 用户“terraform”需要有足够的权限才能让 Terraform 进入 AWS。 创建目录
你可以创建一个或多个 .tf 文件(它们会在启动时合并)。 只需复制并粘贴 AWS EKS 简介中的代码示例,然后运行如下命令:
你可能会遇到一些错误。 如果遇到的话,可以在调试模式下操作,但记得稍后关闭该模式:
这个经验会很有用,你很可能会启动一个 EKS 集群(使用“terraform apply”进行该操作)。 在 AWS 控制台中查看:

觉得厌烦时就清理掉:
然后进入下一阶段,开始使用 Terraform EKS 模块,尤其它也基于同一 EKS 简介。 在 examples/ 目录中,你将看到如何使用它。 你还会在那里找到其他示例。
我们对示例进行了一定的简化。 以下是主文件,其中调用了 VPC 创建和 EKS 创建模块:
provider "kubernetes" {
host = data.aws_eks_cluster.cluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data)
token = data.aws_eks_cluster_auth.cluster.token
load_config_file = false
version = "1.10.0"
}
locals {
vpc_name = "dev-vpc"
vpc_cidr = "10.42.0.0/16"
private_subnets = ["10.42.1.0/24", "10.42.2.0/24"]
public_subnets = ["10.42.11.0/24", "10.42.12.0/24"]
cluster_name = "dev-cluster"
cluster_version = "1.14"
worker_group_name = "worker-group-1"
instance_type = "t2.medium"
asg_desired_capacity = 1
}
data "aws_eks_cluster" "cluster" {
name = module.eks.cluster_id
}
data "aws_eks_cluster_auth" "cluster" {
name = module.eks.cluster_id
}
data "aws_availability_zones" "available" {
}
module "vpc" {
source = "git::https://github.com/terraform-aws-modules/terraform-aws-vpc?ref=master"
name = local.vpc_name
cidr = local.vpc_cidr
azs = data.aws_availability_zones.available.names
private_subnets = local.private_subnets
public_subnets = local.public_subnets
enable_nat_gateway = true
single_nat_gateway = true
enable_dns_hostnames = true
tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
}
public_subnet_tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"kubernetes.io/role/elb" = "1"
}
private_subnet_tags = {
"kubernetes.io/cluster/${local.cluster_name}" = "shared"
"kubernetes.io/role/internal-elb" = "1"
}
}
module "eks" {
source = "git::https://github.com/terraform-aws-modules/terraform-aws-eks?ref=master"
cluster_name = local.cluster_name
cluster_version = local.cluster_version
vpc_id = module.vpc.vpc_id
subnets = module.vpc.private_subnets
write_kubeconfig = false
worker_groups = [
{
name = local.worker_group_name
instance_type = local.instance_type
asg_desired_capacity = local.asg_desired_capacity
}
]
map_accounts = var.map_accounts
map_roles = var.map_roles
map_users = var.map_users
}
我们再仔细看一下 main.tf 中的“terraform”块:
这里需要指出,我们将遵守不低于 Terraform 0.12 的语法(与早期版本相比有了很大变化),同时,Terraform 不应该将其状态存储在本地,而是远程存储在 S3 存储桶中。
不同的人可以从不同的地方更新 terraform 代码确实很方便,这意味着我们需要能够锁定用户的状态,因此我们使用 dynamodb 表添加了一个锁。 有关锁定的更多信息,请参见状态锁定页面。
由于存储桶的名称在整个 AWS 中应该是唯一的,因此你不能再使用名称“eks-github-actions-terraform”。 请想一个你自己的名称,并确保它没有被占用(应该收到 NoSuchBucket 错误):
想好一个名称,创建存储桶(我们这里使用 IAM 用户“terraform”。 它拥有管理员权限,因此可以创建存储桶),并为其启用版本管理(这在配置出错时能让你省心):
对于 DynamoDB,不需要唯一性,但你需要先创建一个表:

注意,如果 Terraform 操作失败,你可能需要从 AWS 控制台手动删除锁。 但这样做时要小心。
对于 main.tf 中的 eks/vpc 模块,引用 GitHub 上提供的模块很简单:
现在看一下另外两个 Terraform 文件(variables.tf 和 outputs.tf)。 第一个文件保存了 Terraform 变量:
variable "map_accounts" {
description = "Additional AWS account numbers to add to the aws-auth configmap. See examples/basic/variables.tf for example format."
type = list(string)
default = []
}
variable "map_roles" {
description = "Additional IAM roles to add to the aws-auth configmap."
type = list(object({
rolearn = string
username = string
groups = list(string)
}))
default = []
}
variable "map_users" {
description = "Additional IAM users to add to the aws-auth configmap."
type = list(object({
userarn = string
username = string
groups = list(string)
}))
default = [
{
userarn = "arn:aws:iam::01234567890:user/my-user"
username = "my-user"
groups = ["system:masters"]
}
]
}
这里最重要的部分是将 IAM 用户“my-user”添加到 map_users 变量中,但你应该使用自己的帐户 ID 替换 01234567890。
这有什么用? 当通过本地 kubectl 客户端与 EKS 通信时,它会向 Kubernetes API 服务器发送请求,每个请求都要经过身份验证和授权过程,这样 Kubernetes 就可以知道谁发送了请求,以及它们可以做什么。 因此 Kubernetes 的 EKS 版本会要求 AWS IAM 帮助进行用户身份验证。 如果发送请求的用户列在 AWS IAM 中(这里我们指向其 ARN),请求将进入授权阶段,该阶段将由 EKS 自己处理,但要依据我们的设置。 这里要指出的是,IAM 用户“my-user”非常酷(组“system: masters”)。
最后,output.tf 文件描述了 Terraform 在完成工作后应该打印的内容:
output "cluster_security_group_id" {
description = "Security group ids attached to the cluster control plane."
value = module.eks.cluster_security_group_id
}
output "config_map_aws_auth" {
description = "A kubernetes configuration to authenticate to this EKS cluster."
value = module.eks.config_map_aws_auth
}
Terraform 部分的描述完成。 我们很快就会回来,看看如何启动这些文件。
Kubernetes 清单
到目前为止,我们已经解决了在哪里启动应用程序的问题。 现在我们来看看要运行什么。
回想一下 /k8s/ 目录中的 docker-compose.yml(我们重命名了服务,添加了几个不久就会被 kompose 用到的标签)
运行 kompose,然后添加下面突出显示的内容。 删除注释(使内容更容易理解):
我们使用 Recreate 更新策略,这意味着先删除 pod,然后重新创建。 这对于演示目的是允许的,让我们可以使用更少的资源。
我们还添加了 postStart 挂钩,该挂钩在 pod 启动后立即触发。 我们等待至 IRIS 启动,然后从默认的 zpm-repository 安装 samples-bi 包。
现在我们添加 Kubernetes 服务(同样没有注释):
是的,我们将在“默认”命名空间中部署,该命名空间适合演示。
好了,现在我们知道了运行_位置_和_内容_。 还剩下_方式_需要了解。
GitHub Actions 工作流程
我们不需要每件事都从头开始做,而是创建一个工作流程,类似于使用 GitHub Actions 在 GKE 上部署 InterSystems IRIS 解决方案中所述的工作流程。 这次,我们不必担心构建容器。 GKE 特定的部分已替换为特定于 EKS。 粗体部分与接收提交消息和在条件步骤中使用它有关:
# Environment variables.
# ${{ secrets }} are taken from GitHub -> Settings -> Secrets
# ${{ github.sha }} is the commit hash
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}
CLUSTER_NAME: dev-cluster
DEPLOYMENT_NAME: samples-bi
jobs:
eks-provisioner:
# Inspired by:
## https://www.terraform.io/docs/github-actions/getting-started.html
## https://github.com/hashicorp/terraform-github-actions
name: Provision EKS cluster
runs-on: ubuntu-18.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Get commit message
run: |
echo ::set-env name=commit_msg::$(git log --format=%B -n 1 ${{ github.event.after }})
- name: Show commit message
run: echo $commit_msg
- name: Terraform init
uses: hashicorp/terraform-github-actions@master
with:
tf_actions_version: 0.12.20
tf_actions_subcommand: 'init'
tf_actions_working_dir: 'terraform'
- name: Terraform validate
uses: hashicorp/terraform-github-actions@master
with:
tf_actions_version: 0.12.20
tf_actions_subcommand: 'validate'
tf_actions_working_dir: 'terraform'
- name: Terraform plan
if: "!contains(env.commit_msg, '[destroy eks]')"
uses: hashicorp/terraform-github-actions@master
with:
tf_actions_version: 0.12.20
tf_actions_subcommand: 'plan'
tf_actions_working_dir: 'terraform'
- name: Terraform plan for destroy
if: "contains(env.commit_msg, '[destroy eks]')"
uses: hashicorp/terraform-github-actions@master
with:
tf_actions_version: 0.12.20
tf_actions_subcommand: 'plan'
args: '-destroy -out=./destroy-plan'
tf_actions_working_dir: 'terraform'
- name: Terraform apply
if: "!contains(env.commit_msg, '[destroy eks]')"
uses: hashicorp/terraform-github-actions@master
with:
tf_actions_version: 0.12.20
tf_actions_subcommand: 'apply'
tf_actions_working_dir: 'terraform'
- name: Terraform apply for destroy
if: "contains(env.commit_msg, '[destroy eks]')"
uses: hashicorp/terraform-github-actions@master
with:
tf_actions_version: 0.12.20
tf_actions_subcommand: 'apply'
args: './destroy-plan'
tf_actions_working_dir: 'terraform'
kubernetes-deploy:
name: Deploy Kubernetes manifests to EKS
needs:
- eks-provisioner
runs-on: ubuntu-18.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Get commit message
run: |
echo ::set-env name=commit_msg::$(git log --format=%B -n 1 ${{ github.event.after }})
- name: Show commit message
run: echo $commit_msg
- name: Configure AWS Credentials
if: "!contains(env.commit_msg, '[destroy eks]')"
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Apply Kubernetes manifests
if: "!contains(env.commit_msg, '[destroy eks]')"
working-directory: ./k8s/
run: |
aws eks update-kubeconfig --name ${CLUSTER_NAME}
kubectl apply -f samples-bi-service.yaml
kubectl apply -f samples-bi-deployment.yaml
kubectl rollout status deployment/${DEPLOYMENT_NAME}
当然,我们需要设置“terraform”用户的凭据(从 ~/.aws/credentials 文件中获取),让 Github 使用它的机密:

注意工作流程的突出显示部分。 我们可以通过推送包含短语“[destroy eks]”的提交消息来销毁 EKS 集群。 请注意,我们不会使用这样的提交消息来运行“kubernetes apply”。
运行管道,但首先要创建一个 .gitignore 文件:
在 GitHub 仓库页面的“Actions”选项卡上监视部署过程。 请等待成功完成。
第一次运行工作流程时,“Terraform apply”步骤需要 15 分钟左右,大约与创建集群的时间一样长。 下次启动时(如果未删除集群),工作流程会快很多。 你可以将此签出:
当然,最好检查一下我们做了什么。 这次可以在你的笔记本电脑上使用 IAM“my-user”的凭据:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-42-1-125.eu-west-1.compute.internal Ready
$ kubectl get po
NAME READY STATUS RESTARTS AGE
samples-bi-756dddffdb-zd9nw 1/1 Running 0 6m16s
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.20.0.1
samples-bi LoadBalancer 172.20.33.235 a2c6f6733557511eab3c302618b2fae2-622862917.eu-west-1.elb.amazonaws.com 52773:31047/TCP 6m33s
访问 _http://a2c6f6733557511eab3c302618b2fae2-622862917.eu-west-1.elb.amazonaws.com:52773/csp/user/_DeepSee.UserPortal.Home.zen?$NAMESPACE=USER _(将链接替换为你的外部 IP),然后输入“_system”、“SYS”并更改默认密码。 您应该看到一系列 BI 仪表板:

点击每个仪表板的箭头可以深入了解:

记住,如果重启 samples-bi pod,所有更改都将丢失。 这是有意的行为,因为这是演示。 如果你需要保留更改,我在 github-gke-zpm-registry/k8s/statefulset.tpl 仓库中创建了一个示例。
完成后,删除你创建的所有内容:
结论
在本文中,我们将 eksctl 实用程序替换成 Terraform 来创建 EKS 集群。 这是向“编纂”您的所有 AWS 基础架构迈出的一步。
我们展示了如何使用 Github Actions 和 Terraform 通过 git push 轻松部署演示应用程序。
我们还向工具箱中添加了 kompose 和 pod 的 postStart 挂钩。
这次我们没有展示 TLS 启用。 我们将在不久的将来完成这项任务。
我非常高兴地宣布,InterSystems 容器注册表现在可以使用了。 这为客户访问基于容器的版本及预览提供了新的渠道。 所有的社区版镜像都可在公共存储库中找到,且无需登录。 所有完整发布的镜像(IRIS、IRIS for Health、Health Connect、System Alerting and Monitoring、InterSystems Cloud Manager)和实用程序镜像(例如,仲裁器、Web 网关和 PasswordHash)都需要登录令牌,该令牌从 WRC 帐户生成。WRC 发布网站暂时将继续以 tarball 方式提供已发布镜像。 不过,您现在可以配置 CI/CD 管道以直接从 InterSystems 容器注册表“docker pull”镜像。
可通过 https://containers.intersystems.com 访问该注册表。 有关完整的使用说明,请参阅下文或参阅文档(使用 InterSystems 容器注册表)。如果您遇到任何问题或有任何反馈要分享,请在下面的评论中告知我们,或联系 support@intersystems.com。
--------------------------------------------------------------
本文档列出了 InterSystems 容器注册表 (ICR) 中可用的镜像,并提供了使用说明。该注册表位于 containers.intersystems.com 上。
可以使用 docker pull 命令下载 ICR 中的镜像,例如:
本文档包含以下部分:
以下 ICR 镜像是公开可用的,无需身份验证即可拉取:
InterSystems IRIS | IntegratedML | 2020.3 | containers.intersystems.com/intersystems/iris-ml-community:2020.3.0.302.0 |
| Community Edition | 2020.3 | containers.intersystems.com/intersystems/iris-community:2020.3.0.221.0 | |
2020.3 ARM64 | containers.intersystems.com/intersystems/iris-community-arm64:2020.3.0.221.0 | ||
InterSystems IRIS for Health | IntegratedML | 2020.3 | containers.intersystems.com/intersystems/irishealth-ml-community:2020.3.0.302.0 |
| Community Edition | 2020.3 | containers.intersystems.com/intersystems/irishealth-community:2020.3.0.221.0 | |
2020.3 ARM64 | containers.intersystems.com/intersystems/irishealth-community-arm64:2020.3.0.221.0 | ||
System Alerting and Monitoring |
| 1.0 | containers.intersystems.com/intersystems/sam:1.0.0.115 |
Arbiter | 2020.1 | containers.intersystems.com/intersystems/arbiter:2020.1.0.215.0 |
2020.2 | containers.intersystems.com/intersystems/arbiter:2020.2.0.211.0 | |
2020.3 | containers.intersystems.com/intersystems/arbiter:2020.3.0.210.0 | |
Health Connect | 2020.1 | containers.intersystems.com/intersystems/healthconnect:2020.1.0.215.0 |
InterSystems Cloud Manager (ICM) | 2020.1 | containers.intersystems.com/intersystems/icm:2020.1.0.215.0 |
2020.2 | containers.intersystems.com/intersystems/icm:2020.2.0.211.0 | |
2020.3 | containers.intersystems.com/intersystems/icm:2020.3.0.221 | |
InterSystems IRIS | 2020.1 | containers.intersystems.com/intersystems/iris:2020.1.0.215.0 |
2020.2 | containers.intersystems.com/intersystems/iris:2020.2.0.211.0 | |
2020.3 | containers.intersystems.com/intersystems/iris:2020.3.0.221.0 | |
2020.1 ARM64 | containers.intersystems.com/intersystems/iris-arm64:2020.1.0.215.0 | |
2020.2 ARM64 | containers.intersystems.com/intersystems/iris-arm64:2020.2.0.211.0 | |
2020.3 ARM64 | containers.intersystems.com/intersystems/iris-arm64:2020.3.0.221.0 | |
| 2020.3 IntegratedML | containers.intersystems.com/intersystems/iris-ml:2020.3.0.302.0 | |
InterSystems IRIS for Health | 2020.1 | containers.intersystems.com/intersystems/irishealth:2020.1.0.217.1 |
2020.2 | containers.intersystems.com/intersystems/irishealth:2020.2.0.211.0 | |
2020.3 | containers.intersystems.com/intersystems/irishealth:2020.3.0.221.0 | |
2020.1 ARM64 | containers.intersystems.com/intersystems/irishealth-arm64:2020.1.0.217.1 | |
2020.2 ARM64 | containers.intersystems.com/intersystems/irishealth-arm64:2020.2.0.211.0 | |
2020.3 ARM64 | containers.intersystems.com/intersystems/irishealth-arm64:2020.3.0.221.0 | |
| 2020.3 IntegratedML | containers.intersystems.com/intersystems/irishealth-ml:2020.3.0.302.0 | |
PasswordHash | 1.0 | containers.intersystems.com/intersystems/passwordhash:1.0 |
Web Gateway | 2020.2 | containers.intersystems.com/intersystems/webgateway:2020.2.0.211.0 |
2020.3 | containers.intersystems.com/intersystems/webgateway:2020.3.0.221.0 |
但是,出于安全原因,您可能想要输入命令 docker login container.intersystems.com,然后在 Username 提示符下输入用户名并将密码粘贴到 Password: 提示符下。
注意:如果您登录到另一个 Docker 注册表,则 docker login 命令可能会导致错误;登录到 container.intersystems.com 之前,请先注销其他注册表。
API 可用于列出 Docker 注册表中的镜像和标签。 可用于列出注册表清单的开源第三方实用程序的一个示例是 docker-ls ,其可从 https://github.com/mayflower/docker-ls 获取。
获取此实用程序的方法有几种。 你可以:
安装 docker-ls 后,您可以使用以下命令列出 ICR 中的存储库:
注意:使用 --interactive-password 选项提示输入密码,不要在命令行中输入密码。
要仅列出公开可用的镜像,请为 -user 和 --password 选项提供空字符串 ("") 作为参数, 例如,以下仅列出了公共 InterSystems IRIS for Health 镜像的标签:
如果希望看到非公共镜像的完整列表,则无论是否登录 container.intersystems.com,都需要向该实用程序提供用户名和密码。
可访问 https://github.com/mayflower/docker-ls 了解其他示例。