搜索​​​​

清除过滤器
文章
Nicky Zhu · 十一月 2, 2021

IRIS 2021 技术文档 First Look 32 -- InterSystems 云管理器(Cloud Manager)

目录 技术概要:InterSystems 云管理器(Cloud Manager) 1 ICM 能为您做什么? 1 ICM 是如何工作的? 1 试一试!使用 ICM 在云中部署 InterSystems IRIS 2 安装 Docker 3 下载 ICM 映像 3 启动 ICM 3 获取云供应商帐户和证书 3 生成安全密钥 4 自定义示例配置文件 4 配置基础设施 9 部署 InterSystems IRIS 10 尝试 ICM 管理命令 11 取消配置基础设施 12 ICM 能做的远不止这些! 13 了解有关 ICM 的更多信息 13 插图目录 图 1: ICM 让一切变得简单 2 图 2: 云供应商的 ICM 默认文件示例 8 图 3: 交互式 ICM 命令 11 技术概要:InterSystems 云管理器(Cloud Manager) 本文向您介绍了 InterSystems 云管理器(InterSystems Cloud Manager,ICM),这是基于 InterSystems IRIS®数据平台的应用程序的端到端云配置和部署解决方案。 作为本指南的一部分,您将使用 ICM 在公共云中配置基础设施,并在该基础设施上部署 InterSystems IRIS。 要浏览所有的技术概要(First Looks),包括那些可以在免费的云实例或 web 实例上执行的技术概要(First Looks),请参见 InterSystems First Looks(《InterSystems 技术概要》)。 ICM 能为您做什么? 欢迎来到云时代(Cloud Age)! 您是否对它的机会虎视眈眈,但又对它的挑战保持警惕?具体来说, 您是否渴望利用云,但又犹豫是否要投入资源进行复杂的迁移? 您是否已经在云中,但还在努力寻找一种方法,以便在各种软件环境中管理部署和版本化您的应用程序? 您是否希望将持续集成和交付引入您的软件工厂,并将 DevOps 方法引入您的部署过程?也就是说,您想把自己从传统实践、库依赖、系统漂移、手动升级和其他开销的限制和风险中解放出来吗? ICM 可以提供帮助! ICM 为您提供了一种简单、直观的方法来配置云基础设施并在其上部署服务,帮助您现在就进入云,而无需进行重大开发或重组。基础设施即代码 (infrastructure as code,IaC) 和容器化部署的优势使得在 Google、Amazon 和 Azure 等公共云平台或私有 VMware vSphere 云上部署基于 InterSystems IRIS 的应用程序变得容易。定义您想要的内容,发布一些命令,剩下的工作由 ICM 来完成。 即使您已经在使用云基础设施、容器,或者同时使用两者,ICM 也可以通过自动化大量手动步骤,极大地减少配置和部署应用程序所需的时间和精力。 ICM 是如何工作的? 在您输入的纯文本配置文件的指导下,ICM 使用 Hashicorp 流行的 Terraform IaC 工具配置您的基础设施,并根据需要配置的主机节点。在下一阶段,ICM 将 InterSystems IRIS 和您的应用程序部署在 Docker 容器中,如果需要,还可以部署其他服务。您想要的部署所需的所有 InterSystems IRIS 配置都是自动执行的。ICM 还可以在现有的虚拟和物理集群上部署容器化服务。 ICM 本身带有一个容器映像,其中包含您所需要的一切。从 InterSystems 的 ICM 映像下载并运行容器,打开命令行,您就可以开始了。ICM 通过组合这些元素,使一切变得简单: 可以用作模板以快速定义所需部署的示例配置文件。 可以向其中添加应用程序的 InterSystems IRIS 映像。 试一试! 使用 ICM 在云中部署 InterSystems IRIS 每个任务的用户友好命令。 管理已配置节点和部署在其上的服务并与之交互的多种方法。 图 1: ICM 让一切变得简单 试一试!使用 ICM 在云中部署 InterSystems IRIS ICM 为您执行许多任务,并为您提供许多选项,以帮助您准确地部署您所需要的内容,所以在生产中使用它需要一定的计划和准备(尽管比手动方法要少得多!)。但配置和部署过程很简单,ICM 可以为您做出许多决定。这一探索旨在让您亲眼看到 ICM 是如何工作的,以及使用 ICM 在亚马逊网络服务(Amazon Web Services,AWS)上部署 InterSystems IRIS 配置是多么容易。虽然这不是一时的工作,但这种探索不应该占用您太多的时间,您可以在机会出现时分阶段进行。 为了让您体验 ICM 而又不至于在细节上陷入困境,我们保持了简单的探索;例如,我们让您尽可能多地使用默认设置。但是,当您把 ICM 引入您的生产系统时,您需要做很多不同的事情,特别是(但不限于)安全方面。所以请确保不要把这种对 ICM 的探索与真实的情况相混淆! 本文档末尾提供的参考资料将使您对在生产中使用 ICM 的情况有一个很好的了解。ICM Guide(《ICM 指南》)提供了使用 ICM 的完整信息和程序,并在适当的地方提供了链接。 这些说明假定您具备以下条件: 特定于容器的 InterSystems IRIS 分片(sharding)许可证并可以访问 InterSystems 软件下载。 亚马逊网络服务(Amazon Web Services,AWS)、谷歌云平台(Google Cloud Platform,GCP)、微软云(Azure)或腾讯云(Tencent)上的帐户。 在配置文件中指定的许多属性在这些云平台上是通用的,但其他属性是特定于平台的。有关这些差异的详细信息可在 ICM Guide(《ICM 指南》)的"ICM Reference(《ICM 参考资料》)"一章中的"Provider-Specific Parameters(特定于供应商的参数)"部分找到。 试一试! 使用 ICM 在云中部署 InterSystems IRIS 安装 Docker ICM 是作为容器映像提供的,它包含您需要的所有内容。因此,对启动 ICM 的 Linux、macOS 或 Microsoft Windows 系统的唯一要求是安装 Docker,并运行 Docker 守护进程,以及系统连接到 Internet。有关在您的平台上安装 Docker 的信息,请参见 Docker 文档中的 Install Docker(《安装 Docker》)。 重要提示: Docker 企业版(Enterprise Edition)和社区版(Community Edition)18.09 及更高版本支持 ICM;企业版(Enterprise Edition)仅支持生产环境。 下载 ICM 映像(Image) 要使用 ICM,您需要将 ICM 映像下载到您正在工作的系统中;这要求您识别将从其中下载它的注册表和访问所需的凭证。同样,对于 ICM 部署 InterSystems IRIS 和其他 InterSystems 组件,它需要相关映像的此信息。ICM 下载映像的注册表必须能被您使用的云供应商访问(也就是说,不能在防火墙后面),而且为了安全起见,必须要求 ICM 使用您提供给它的凭证进行身份验证。有关识别所涉及的注册表和下载 ICM 映像的详细信息,请参见 InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)中的 Downloading the ICM Image(下载 ICM 映像)。 注意: 启动 ICM 的映像的主要版本和部署的 InterSystems 映像必须匹配。例如,您不能使用 2019.3 版本的 ICM 部署 2019.4 版本的 InterSystems IRIS。 有关在容器中使用 InterSystems IRIS 的简要介绍,包括实际操作经验, 请参见 First Look: InterSystems Products in Containers(《技术概要:容器中的 InterSystems 产品》);有关使用 ICM 以外的方法在容器中部署 InterSystems IRIS 和基于 InterSystems IRIS 的应用程序的详细信息,请参见 Running InterSystems IRIS in Containers(《在容器中运行 InterSystems IRIS》)。 启动 ICM 要在命令行上启动 ICM,使用下面的 docker run 命令,从注册表中拉出(下载)ICM 映像,从中创建一个容器,并启动该容器,例如: docker run --name icm -it --cap-add SYS_TIME containers.intersystems.com/intersystems/icm:2021.1.0.205.0 ICM 容器中的 /Samples 目录,每个供应商都有一个(/AWS,/GCP,等等),旨在使您能够轻松地使用开箱即用的 ICM 进行配置和部署;您可以使用这些目录之一中的示例配置文件 ,也可以从该目录进行配置和部署。然而,由于这些目录在 ICM 容器内,当容器被删除时,其中的数据就会丢失,包括您的配置文件和 ICM 创建并用于管理配置的基础设施的状态目录。在生产中,最好的做法是在启动 ICM 时通过挂载外部卷使用容器外的位置来存储这些数据(请参见 Docker 文档中的 Manage data in Docker(在 Docker 中管理数据))。 获取云供应商帐户和证书 ICM 可以在四个公共云平台上进行配置和部署:亚马逊网络服务(Amazon Web Services,AWS)、谷歌云平台(Google Cloud Platform,GCP)、微软云(Azure)和腾讯云(Tencent)。 登录您的 AWS、GCP、Azure 或 Tencent 帐户。如果您和您的雇主都还没有帐户,您可以进入AWS、GCP、Azure或Tencent 门户页面,快速创建一个免费帐户。 有关获取 ICM 需要向每个云供应商进行身份验证的帐户凭证的信息,请参见 ICM Guide(《ICM 指南》)的 "ICM Reference(《ICM 参考资料》) "一章中的 Security- Related Parameters(安全相关的参数)。 试一试! 使用 ICM 在云中部署 InterSystems IRIS 生成安全密钥 ICM 与配置基础设施的云供应商、配置的节点上的 Docker 以及容器部署后的若干 InterSystems IRIS 服务进行安全的通信。您已经下载或识别了您的云证书;您还需要其他文件来启用安全的 SSH 和 TLS 通信。 您可以使用 ICM 提供的两个脚本来创建您需要的文件,keygenSSH.sh 脚本创建所需的 SSH 文件并将它们放在 ICM 容器的 /Samples/ssh 目录中。keygenTLS.sh 脚本创建所需的 TLS 文件,并将它们放在 /Samples/tls 中。 要在 ICM 命令行上运行这些脚本,请输入以下内容: # keygenSSH.sh Generating keys for SSH authentication. ... # keygenTLS.sh Generating keys for TLS authentication. ... 有关这些脚本生成的文件的更多信息,请参见 ICM Guide(《ICM指南》)中的 Obtain Security-Related Files(获取安全相关的文件)、ICM Security(ICM 安全)和 Security-Related Parameters(安全相关的参数)。 重要提示: 这些生成的密钥是为了方便您在本文体验和其他测试中使用;在生产中,您应该根据您公司的安全策略来生成或获取所需的密钥。这些脚本生成的密钥以及您的云供应商凭证必须完全安全,因为它们提供了对使用它们的任何 ICM 部署的完全访问权限。 自定义示例配置文件 要定义您希望 ICM 部署的配置,您在两个 JSON 格式的配置文件中包含所需的设置:默认文件和定义文件。前者(defaults.json)包含应用于整个部署的设置 --- 例如,您对云供应商的选择 ------而后者(definitions.json)定义了您想要的节点类型以及每种节点的数量,从而决定了您是部署一个分片集群、一个独立的 IRIS 实例,还是其他配置。 ICM 容器中的 /Samples 目录为所有四个云供应商提供示例配置文件。例如,AWS 的示例配置文件位于 /Samples/AWS 目录中。要自定义这些文件,请选择您要使用的供应商,然后按照下面的表格描述,为该供应商修改示例默认值和定义文件。要做到这一点,您可以使用 vi 等编辑器直接在容器内编辑它们,或者在本地命令行上使用 docker cp 命令将它们从容器复制到本地文件系统,然后在您编辑它们后再次返回,例如: docker cp icm:/Samples/AWS/defaults.json . docker cp icm:/Samples/AWS/definitions.json . ... docker cp defaults.json icm:/Samples/AWS docker cp definitions.json icm:/Samples/AWS 重要提示: 字段名和值都是区分大小写的;例如,要选择 AWS 作为云供应商,您必须在默认文件中包含 "Provider":"AWS" ,而不是 "provider": "AWS"、"Provider": "aws"等等。 自定义 defaults.json 下表详细说明了 /Samples 文件中提供的默认文件所需的最小自定义,以及对可选更改的建议。这里没有涉及到的任何设置都可以在示例文件中保持原样。 试一试! 使用 ICM 在云中部署 InterSystems IRIS 每个设置都连接到 ICM Guide(《ICM 指南》)的 "ICM Reference(《ICM 参考资料》)"一章中的 ICM Configuration Parameters(ICM 配置参数)部分中的相关表格,在那里您可以找到更详细的说明;在那里,搜索您想要的参数。最右边的列显示了在示例默认文件中出现的每个参数或参数集。 要查看所有供应商通用的所有设置,请参见该部分的 General Parameters(常规参数) ;要查看特定于特定供应商的所有设置,请参见 Provider-Specific Parameters(特定于供应商的参数)。 下图显示了 AWS、GCP、Azure 和 Tencent 的示例 defaults.json 文件的内容: 设置 说明 示例 defaults.json 文件中的条目 Provider 识别云基础设施供应商;保留示例 defaults.json 中的值。 “Provider”:[”AWS”|"GCP"|"Azure"|"Tencent"], Label 配置节点的命名方案中的字段, Label-Role-Tag-NNNN (请参见下面的 Role);更新以识别部署的所有者和目的, 例如,使用您的公司名称和“TEST”来创建节点名称,如 Acme-DATA-TEST-0001。 "Label": "Sample", Tag (请参见上面的 Label ) "Tag": "TEST", DataVolumeSize 为每个节点配置的持久化数据卷的大小,这可以在 definitions.json 文件中的各个节点定义中被覆盖;接受示例 defaults.json 中的值,除非您在 Tencent 上配置,在这种情况下,将其改为 60。 "DataVolumeSize": "10", SSHUser 在配置节点上具有 sudo 访问权限的非根帐户,用于 ICM 访问; 您可以保留示例 defaults.json 中的默认值, 但如果您在 AWS 或 Tencent 上更改了机器映像(如下),则可能需要更新此条目。 "SSHUser": "ubuntu",(AWS & Tencent) "SSHUser": "sample",(GCP & Azure) SSHPublicKey SSH 公钥的位置。如果您使用了 Generate Security Keys(生成安全密钥)中讨论的密钥生成脚本, 则密钥位于示例文件指定的目录中,因此无需更改;如果您提供了自己的密钥, 请使用 docker cp 将它们从本地文件系统复制到这些位置。 "SSHPublicKey": "/Samples/ssh/insecure-ssh2.pub", SSHPrivateKey SSH 私钥的位置;请参见上面的 SSHPublicKey。 "SSHPrivateKey": "/Samples/ssh/insecure", TLSKeyDir TILS 文件的位置;请参见上面的 SSHPublicKey 。 "TLSKeyDir": "/Samples/tls/", 设置 说明 示例 defaults.json 文件中的条目 DockerVersion 要安装在已配置节点上的 Docker 版本;保持默认值。 "DockerVersion": "5:19.03.8~3-0~ubuntu-bionic", DockerImage 要部署在已配置节点上的映像;更新以反映您在 Identify Docker Repository and Credentials(识别 Docker 存储库和凭证)中识别的存储库和映像信息。 "DockerImage": "containers.intersystems.con/intersystems/iris:2021.1.0.205.0", DockerUser- name Docker- Password 如果在私有存储库中,则下载 DockerImage 指定的映像所需的凭证;请更新以反映您在 Identify Docker Repository and Credentials(识别 Docker 存储库和凭证)中识别的存储库信息和凭证。 "DockerUsername": "xxxxxxxxxxxx", "DockerPassword": "xxxxxxxxxxxx", LicenseDir InterSystems IRIS 许可证的暂存目录;将您的特定于容器的 InterSystems IRIS 分片(sharding)许可证放在这个目录中。 “LicenseDir”: “/Samples/Licenses”, Region, Location (Azure) 供应商用于配置基础设施的计算资源的地理区域;接受示例 defaults.json 中的默认值,或者从供应商那里选择 region 和 zone 的另一个组合(如下)。 "Region": "us-west-1",(AWS) "Region": "us-east1",(GCP) "Location": "Central US",(Azure) "Region": "na-siliconvalley", (Tencent) Zone 所选区域内的可用区(如上);接受示例 defaults.json 中的默认值,或者从供应商那里选择 region 和 zone 的另一个组合。 "Zone": "us-west-1c",(AWS) "Zone": "us-east1-b",(GCP) "Zone": "1",(Azure) "Zone": "na-siliconvalley-1", (Tencent) Machine image (特定于供应商) 配置节点的平台和 OS 模板;接受示例 defaults.json 中的默认值,或者从供应商那里选择 machine image 和 instance type 的不同组合(如下)。 "AMI": "ami-c509eda6",(AWS) "Image": "ubuntu-os-cloud/ubuntu-1804-bionic-v20180617", (GCP) "PublisherName": "Canonical",(Azure) "Offer": "UbuntuServer",(Azure) "Sku": "18.04-LTS",(Azure) "Version": "18.04.201804262",(Azure) "ImageID": "img-pi0ii46r",(Tencent) 设置 说明 示例 defaults.json 文件中的条目 Instance type (特定于供应商) 配置节点的计算资源模板;接受示例 defaults.json 中的值,或者从供应商那里选择 machine image 和 instance type 的不同组合(如上)。 "InstanceType": "m4.large",(AWS) "MachineType": "n1-standard-1",(GCP) "Size": "Standard_DS2_v2",(Azure) "InstanceType": "S2.MEDIUM4",(Tencent) Credentials and account settings (特定于供应商) ICM 向供应商进行身份验证所需的文件或 ID,因供应商而异;更新以指定您的帐户所需的文件位置或 ID(有关说明,请点击供应商链接)。 “Credentials”:”/Samples/AWS/credentials”, (AWS) "Credentials": "/Samples/GCP/sample.credentials",(GCP) "Project": "dp-icmdevelopment",(GCP) "SubscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",(Azure) "ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",(Azure) "ClientSecret": "xxxxxxxxxxxx/xxxxxxxxxxxxxxx/xxxxxxxxxxxxxx=", (Azure) "TenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",(Azure) "SecretID": "xxxxxxxxxxxx",(Tencent) "SecretKey": "xxxxxxxxxxxx",(Tencent) ISCPassword 已部署的 InterSystems IRIS 映像中预定义帐户的密码;要在部署阶段以交互方式提供带有屏蔽输入的密码(为安全起见建议这样做),请删除此字段,否则更改为您的首选密码。 "ISCPassword": "", Mirror 确定部署在 DATA、DM 和 DS 节点上的 InterSystems IRIS 实例是否被配置为镜像;保留默认值。 “Mirror”: “false” 设置 说明 示例 defaults.json 文件中的条目 UserCPF 指定用于覆盖已部署实例的初始 CPF 设置的配置合并文件。(如果您不熟悉配置合并功能或 CPF,请删除此条目;有关配置合并的信息,请参见 ICM Guide(《ICM**指南》)的 "ICM Reference(《ICM 参考资料》)"一章中的 Deploying with Customized InterSystems IRIS Configurations(使用自定义的 InterSystems IRIS 配置进行部署)。) "UserCPF": "/Samples/cpf/iris.cpf" 下图显示了 AWS、GCP、Azure 和 Tencent 的示例 defaults.json 文件的内容: 图 2: 云供应商的 ICM 默认文件示例 自定义 definitions.json 在 /Samples 目录中的示例 definitions.json 文件(对所有供应商来说都是一样的),定义了一个有两个数据节点和两个计算节点的分片集群,如下所示: 试一试! 使用 ICM 在云中部署 InterSystems IRIS [ { "Role": "DATA", "Count": "2", "LicenseKey": "ubuntu-sharding-iris.key" }, { "Role": "COMPUTE", "Count": "2", "StartCount": "3", "LicenseKey": "ubuntu-sharding-iris.key" } ] Role 字段标识正在配置的节点类型,在这种情况下是 DATA 和 COMPUTE。Count 字段表示要配置多少个该类型的节点;对于 COMPUTE 节点,StartCount 从 0003 开始编号。LicenseKey 字段表示 InterSystems IRIS 许可证文件的名称,该文件位于默认文件中由 LicenseDir 字段指定的目录中。 在这个练习中,删除 COMPUTE 定义,只保留 DATA 定义,如下所示: [ { "Role": "DATA", "Count": "2", "LicenseKey": "ubuntu-sharding-iris.key" } ] 部署分片集群时,所有节点必须有分片(sharding)许可证。使用 docker cp 将分片(sharding)许可证复制到 LicenseDir 指定的容器内的位置,如 /Samples/Licenses,并更新 DATA 节点定义中的 LicenseKey 设置,以指定要使用的许可证密钥。 这些是配置基本分片集群所需的唯一 definitions.json 更改。要配置一个独立的 InterSystems IRIS 实例,请使用此定义: [ { "Role": "DM", "Count": "1", "LicenseKey": "standard-iris.key"" }, ] 配置基础设施 默认情况下,ICM 从当前目录中的配置文件中获取输入,因此您需要做的就是将配置基础设施更改为您选择的供应商的 /Samples 目录,例如 /Samples/AWS,并发出这个命令: icm provision icm provision 命令在您选择的平台上分配和配置主机节点。在配置操作期间,ICM 在状态子目录中创建或更新状态和日志文件,完成后创建 instances.json 文件,作为后续部署和管理命令的输入。 因为 ICM 同时运行多个任务,所以这些步骤(Terraform 计划和应用、复制文件、挂载卷等等)可能不会以相同的顺序在节点上启动和完成。完成后,ICM 提供了一个已经配置好的主机节点的摘要,并输出一个命令行,可以在以后用来删除基础设施,如下所示: Machine IP Address DNS Name Region Zone Acme-DATA-TEST-0001 00.53.183.209 ec2-00-53-183-209.us-west-1.compute.amazonaws.com us-west-1 c Acme-DATA-TEST-0002 00.53.183.185 ec2-00-53-183-185.us-west-1.compute.amazonaws.com us-west-1 c To destroy: icm unprovision [-cleanUp] [-force] 试一试! 使用 ICM 在云中部署 InterSystems IRIS 重要提示: 复制输出中提供的 icm unprovision 命令行,并保存此信息,这样您就可以在取消配置时轻松地复制它。这个输出也出现在 icm.log 文件中。 管理和取消配置您的基础设施所需的文件和目录都在 ICM 容器中,因此当您删除它时就会丢失。因此,在完成基础设施并成功地取消配置之前,您不能删除 ICM 容器。(在生产中,最好的做法是在启动 ICM 时通过挂载外部卷使用容器外的位置来存储这些数据(请参见 Docker 文档中的 Manage data in Docker(在 Docker 中管理数据))。 在配置和部署阶段发生的错误的详细信息写入状态目录子目录中的 terraform.err 文件;当发生错误时,ICM 会将您指向适当的文件,该文件可以帮助您识别问题的原因。 如果 icm provision 由于超时和供应商方面的内部错误,或者配置文件中的错误而没有成功完成,您可以根据需要再次发出该命令,直到 ICM 为所有指定的节点完成所有需要的任务而没有错误。更多信息,请参见 ICM Guide(《ICM 指南》)的 "Using ICM(《使用 ICM》) "一章中的 "Reprovisioning the Infrastructure(重新配置基础设施)"。 有关 icm provision 的更多信息,请参见 ICM Guide(《ICM 指南》)中的 The icm provision Command (icm 配置命令)。 部署 InterSystems IRIS 除了在提供的主机节点上下载映像(Image)并将它们作为容器运行外,ICM 还执行特定于 InterSystems IRIS 的配置和其他任务。要在您已配置的节点上部署 InterSystems IRIS,请留在 /Samples 目录,您在其中自定义了配置文件并配置了基础设施,然后发出以下命令: icm run 默认情况下,icm run 下载并运行配置文件中 DockerImage 字段指定的映像,在这种情况下,是来自 InterSystems 存储库的 InterSystems IRIS 映像;每个容器都被命名为 iris。在实践中,在定义文件中的节点定义中使用不同的 DockerImage 字段(而不是对默认文件中的所有节点使用一次,如此处),可以让您在不同的节点类型上运行不同的映像,除此之外,您还可以使用某些选项多次执行 icm run 命令,以便在每个配置的节点上或只在指定节点上部署具有唯一名称的多个容器。 InterSystems IRIS 在每个节点上启动后,ICM 会执行实例所需的任何配置 --- 例如,重置密码、配置分片(sharding)等。因为 ICM 同时运行多个任务,因此部署过程中的步骤可能不会以相同的顺序在节点上启动和完成。 完成后,ICM 输出一个链接到相应的 InterSystems IRIS 实例的管理门户(Management Portal): $ icm run -definitions definitions_cluster.json Executing command 'docker login' on ACME-DATA-TEST-0001... ...output in /Samples/AWS/state/ACME-DATA-TEST/ACME-DATA-TEST-0001/docker.out ... Pulling image intersystems/iris:2021.1.0.205.0 on ACME-DATA-TEST-0001... ...pulled ACME-DATA-TEST-0001 image intersystems/iris:2021.1.0.205.0 ... Creating container iris on ACME-DATA-TEST-0002... ... Management Portal available at: http://ec2-00-53-183-209.us-west-1.compute.amazonaws.com:52773/csp/sys/UtilHome.csp 在这种情况下,所提供的链接用于数据节点 1,或者用于独立的实例(如果这是您选择的配置)。在浏览器中打开链接,并使用管理门户(Management Portal)探索 InterSystems IRIS。 与 icm provision 一样,如果 icm run 由于超时和供应商方面的内部错误而没有成功完成,您可以再次发出命令;在大多数情况下,反复尝试,部署就会成功。但是,如果错误仍然存在,并且需要手动干预 --- 例如,如果它是由某个配置文件中的错误引起的 --- 在修复问题后,您可能需要删除受影响的一个或多个节点上的持久化 %SYS 数据, 试一试! 使用 ICM 在云中部署 InterSystems IRIS 在重新发布 icm run 命令之前,如 ICM Guide(《ICM 指南》)的 "Using ICM(《使用 ICM》)"一章中的 Redeploying Services(重新部署服务)所述。在出现错误的情况下,请参见 ICM 指向您访问的日志文件,以获得有助于您确定问题原因的信息。 有关 icm run 命令及其选项的更多信息,请参见 ICM Guide(《ICM 指南》)中的 The icm run Command(icm run 命令)。 尝试 ICM 管理命令 ICM 提供了一系列的命令用于 管理配置的基础设施。 管理部署的容器。 与运行在部署的容器中的服务交互,包括 InterSystems IRIS。 这些命令在 ICM Guide(《ICM 指南》)的 Infrastructure Management Commands(基础设施管理命令)、Container Management Commands(容器管理命令)和 Service Management Commands(服务管理命令)小节中有详细的讨论,并在 ICM Commands and Options(ICM 命令和选项)中全面列出。这里提供了一些示例,供您在部署时试用。特别要注意的是,有三个命令(icm ssh、icm exec 和 icm session)可以让您在多个层次上与您部署的节点交互 --- 与节点本身、与部署在它上面的容器以及与容器内运行的 InterSystems IRIS 实例,如下所示: 图 3: 交互式 ICM 命令 在您新部署的 InterSystems IRIS 配置上试试这些命令吧! 列出配置的主机节点: 试一试! 使用 ICM 在云中部署 InterSystems IRIS icm inventory 在每个主机节点上运行 shell 命令: icm ssh -command "df -k" 当一个命令在多个节点上执行时,输出被写入文件,并提供一个输出文件的列表。例如,在这种情况下,如果您部署了分片集群,三个节点各有一个输出文件。 在特定的主机节点上打开交互式 shell: icm ssh -role DATA -interactive 要做到交互,命令必须使用 -interactive 选项并指定单个节点。例如,虽然 icm ssh 可以在多个节点上执行命令,如前面的示例所示,但它只能使用 -interactive 选项在一个节点上打开交互式 shell,如本例所示。代替 -role DM 选项将命令限制在该类型的节点上(在您的部署中只有一个节点),您也可以使用-machine 选项来指定一个特定节点的名称,例如: icm ssh -machine Acme-DATA-TEST-0001 -interactive 显示部署的 InterSystems IRIS 容器的状态: icm ps 当在节点上部署了多个容器时,这个命令会将它们全部列出。 将本地文件复制到 InterSystems IRIS 容器或其中一个容器: icm cp -localPath /Samples/ssh/ssh_notes -remotePath /home/sshuser icm cp -localPath /Samples/ssh/ssh_notes -remotePath /home/sshuser -role DM 在每个 InterSystems IRIS 容器中运行 shell 命令: icm exec -command "ls /irissys/" 在特定的 InterSystems IRIS 容器中打开一个交互式 shell(或运行任何 shell 命令): icm exec -command "bash" -role DATA -interactive 为 InterSystems IRIS 实例打开一个终端(Terminal)窗口(对于单个实例,总是交互式的): icm session -machine Acme-DATA-TEST-0001 针对 InterSystems IRIS 的每个实例,或针对特定的实例,运行 SQL 命令: icm sql -command "SELECT Name FROM Security.Users" icm sql -command "SELECT Name FROM Security.Users" -machine Acme-DATA-TEST-0002 取消配置基础设施 因为 AWS 和其他公共云平台实例会不断产生费用,所以在完成这一体验后,立即取消配置基础设施是很重要的。 要做到这一点,把您从 icm provision 的输出中保存的 icm unprovision 命令复制到 ICM 命令行,例如: $ icm unprovision -cleanUp ICM 能做的远不止这些! 如果您没有从配置输出中保存命令,您可以在工作目录的 icm.log 文件中找到它(例如,/Samples/AWS/icm.log)。-cleanUp 选项在取消配置后会删除状态目录;如果没有这个选项,状态目录会被保留下来。 ICM 能做的远不止这些! 尽管您刚刚完成的 ICM 探索是刻意简化的,但它仍包含了现实世界的基础设施配置和服务部署。添加到您刚刚完成的只是在配置文件中扩展您的部署定义并利用大量命令行选项的问题。例如,您可以 通过定义 AM 节点和 DM 节点,部署应用服务器和数据服务器的分布式缓存集群,或通过仅定义 DM 节点部署独立的 InterSystems IRIS 实例。 部署镜像(mirror) DATA 节点或镜像 DM 节点,只需在默认文件中包含"Mirror":"True",并在定义文件中定义偶数个 DATA 节点或两个 DM 节点和一个 AR(仲裁器)节点。 部署一个包含 COMPUTE 节点的分片集群,以分离查询和数据摄取工作量,同时保持并行处理和分布式缓存的优势,提高两者的性能。 在定义文件中添加 web 服务器(WS)和负载均衡器(LB 或自动)。 通过在定义文件中为不同的节点指定不同的 DockerImage 值,并多次执行 icm run 命令,在不同的节点上部署不同的服务。 通过多次执行 icm run ,同时在命令行中使用 -container 和 -image 选项指定不同的容器名称和映像(包括自定义和第三方映像),在一些或所有节点上部署多个服务。 通过使用第三方工具和内部脚本扩展 ICM 的功能,进一步提高自动化程度,减少工作量。 在已有的虚拟和物理集群上部署服务。 在不部署服务的情况下配置基础设施,只需使用 ICM provision 命令停止。 所有这些可能性以及更多的可能性都在 ICM Guide(《ICM 指南》)中有所涉及。 了解有关 ICM 的更多信息 要了解有关 ICM 和在容器中使用 InterSystems IRIS 的更多信息,请参见 InterSystems Cloud Manager Introduction(《InterSystems 云管理器简介》) (视频) The Benefits of InterSystems Cloud Manager(《InterSystems 云管理器的优势》) (视频) Experience InterSystems IRIS in the Cloud(在云中体验 InterSystems IRIS) (在线体验) InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》) First Look:InterSystems Products in Containers(《技术概要:容器中的 InterSystems 产品》) Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)
文章
Nicky Zhu · 九月 9, 2021

IRIS 2021 技术文档 First Look 22 -- 技术概要:部署 InterSystems 分片集群

本文档将您介绍InterSystems IRIS®数据平台的分片(sharding)功能,以及它在分片集群中的使用,以水平扩展 InterSystems IRIS 的数据量。 作为本指南的一部分,您将使用 ICM 在公共云中提供的分片集群,并了解分片表(sharding a table)如何在集群中的分片之间分布其行。 分片(Sharding)如何帮助您? 您感受到大数据(Big Data)的热度了吗? 无论是否准备好了,我们都在管理比以往任何时候都多的数据,并被要求用这些数据做更多的事情——所需的响应时间也越来越短。无论您是照顾一千万名患者、每天处理数十亿的金融订单,追踪一个星系的恒星,还是监控一千个工厂的引擎,数据平台不仅要支持您目前的数据工作量,而且还必须在保持性能的同时进行扩展(Scale),以满足不断增长的需求,避免业务中断。每个特定业务的工作量对其运行的数据平台提出了不同的挑战 — 而随着工作量的增加,这些挑战将变得更加严峻。 InterSystems IRIS 包含一套全面的功能来扩展(Scale)您的应用程序,这些功能可以单独或组合应用,这取决于您的工作量的性质和它所面临的特定性能挑战。其中之一是分片(sharding),它在多个服务器上对数据及其相关缓存进行分区,为查询和数据摄取提供灵活、价优的性能扩展,同时通过高效的资源利用使基础设施价值最大化。InterSystems IRIS 分片集群(sharded cluster) 可以为各种应用程序提供显著的性能优势,特别是对于那些工作量包括以下一项或多项的应用程序: 高容量或高速数据摄入,或组合。 相对较大的数据集,返回大量数据的查询,或两者兼有。 执行大量数据处理的复杂查询,例如扫描磁盘上的大量数据或涉及大量计算工作的查询。 这些因素各自都会影响分片(sharding)的潜在收益,但如果将它们结合起来,收益可能会得到增强。例如,所有这三个因素的组合——快速摄入的大量数据、大型数据集以及检索和处理大量数据的复杂查询——使得如今的许多分析工作量非常适合进行分片(sharding)。 请注意,这些特征都与数据有关;InterSystems IRIS 分片(sharding)的主要功能是扩展数据量(sharded cluster)。但是,当涉及部分或所有这些数据相关因素的工作量也经历了来自大量用户的非常高的查询量时,分片集群也可以包括扩展用户量(scale for user volume)功能。分片(sharding)也可以与垂直扩展相结合。通过 InterSystems IRIS,您可以为工作量的性能挑战创建恰到好处的整体扩展解决方案。 分片(Sharding)是如何工作的? 分片架构的核心是跨多个系统对数据及其相关缓存进行分区。分片集群将大型数据库表水平(即按行)划分为多个 InterSystems IRIS 实例,称为数据节点(data node),同时允许应用程序通过这些实例中的任何一个访问这些表。每个数据节点在集群分片数据中的份额被称为分片(shard)。这种架构有三个优势: 并行处理(Parallel processing) 查询在数据节点上并行运行,合并查询结果,并作为完整的查询结果返回给应用程序,在许多情况下显著提高了执行速度。 分区缓存(Partitioned caching) 每个数据节点都有自己的专用缓存,而不是由单个实例的缓存为整个数据集服务,这大大降低了缓存溢出和强制降低性能的磁盘读取的风险。 并行加载(Parallel loading) 数据可以并行加载到数据节点上,从而减少摄取工作量和查询工作量之间的缓存和磁盘争夺,提高两者的性能。 一个被称为分片管理器(sharding manager)的联合软件组件会跟踪哪些数据位于哪些数据节点上,并相应地指导查询。非分片数据存储在配置的第一个数据节点上,称为数据节点 1 (它也存储代码和元数据)。从应用程序 SQL 的角度来看,分片表(sharded table)和非分片表(nonsharded table)之间的区别是完全透明的。 图 1: 一个基本的分片集群 试一试!部署和演示 InterSystems IRIS 分片集群 在这次探索中,您将 使用 InterSystems 云管理器(InterSystems Cloud Manager,ICM)在公共云中部署基本的分片集群。 ICM 是一个自动化的命令行工具,可以轻松地在云中配置基础设施,并在提供的节点上部署 InterSystems IRIS 和其他服务。ICM 负责所有需要的 InterSystems IRIS 配置,所以如果您指定了一个分片集群,该集群在部署完成后就可以使用了。 使用不同的分片键(shard key)从相同的数据中创建三个分片表(sharded table),并观察数据节点上跨分片的行的不同分布。 分片键是用来确定分片表的哪些行存储在哪些分片上的一个或多个字段。默认情况下,RowID 被用作分片键,这种分布对于大多数分片表来说是最有效的方法,因为它提供了数据均匀分布的最佳保证,并允许最有效的并行数据加载。然而,在一种情况下,用户定义的键可能是有益的。当您对在字段或用于连接它们的字段上的查询中经常连接的两个大表进行分片时,要连接的行被存储在相同的分片上,并且连接可以在每个分片上本地执行,而不是跨分片执行(across the shard),从而提供显著的性能提升。这被称为 cosharded 连接(cosharded join)。 在所有三个分片表上运行相同的查询,以证明跨分片的行分布对查询是完全透明。 为了向您介绍分片(sharding),而又不至于让您在细节上陷入困境,我们保持了简单的探索。生产中的分片集群需要计划和许多决策,所以确保不要把对分片(sharding)的探索和真实情况相混淆!例如,在设计一个生产集群时,您将检查您的架构和表,以决定哪些表将被分片,然后根据分片数据的预期工作集和服务器上数据库缓存的可用内存量,决定部署多少个数据节点(通常为 4 到 16 个)。然而,在本次探索中,您将部署一个由两个数据节点组成的基本集群。本文档末尾列出的参考资料将使您对生产中使用分片(sharding )的情况有一个很好的了解。Scalability Guide(《可扩展性指南》)中的 "Horizontally Scaling for Data Volume Sharding(《水平扩展数据卷分片[Sharding]》)"一章提供了有关分片(sharding)和分片集群的详细信息。 这些说明假定您有 InterSystems IRIS 分片(sharding)许可证并可以访问 InterSystems 软件下载。 使用 ICM 部署集群 您可以在 First Look:InterSystems Cloud Manager(《技术概要:InterSystems 云管理器》)中找到使用 ICM 在亚马逊网络服务(Amazon Web Services)公共云平台上部署分片集群的程序;特别是在 Try It!Deploy InterSystems IRIS in the Cloud with ICM(试一试!使用 ICM 在云中部署 InterSystems IRIS)部分。您可以使用此处显示的整个程序。当您进入自定义定义.json(Customize definitions.json)时,验证每个 LicenseKey 字段的值是否是 defaults.json 文件中 LicenseDir 字段指定的暂存位置中的 InterSystems IRIS 分片(sharding)许可证的文件名。当您完成了部署阶段(部署 InterSystems IRIS[Deploy InterSystems IRIS])后,留在 ICM 容器中。 注意: 正如 Scalability Guide(《可扩展性指南》)中的 Deploying the Sharded Cluster(部署分片集群) 所描述的那样,您也可以在现有的物理、虚拟或云机器上安装 InterSystems IRIS 实例,并使用分片 API(Sharding API) 或管理门户(Management Portal)部署分片集群,或使用多种方法之一自动化部署分片集群。 使用不同的分片键以不同的方式分布行,然后查询分片表 为了了解分片集群如何根据您使用的分片键(shard key)在数据节点上的分片上对分片表(sharded table)进行分区,您将连接到集群并执行以下步骤: 创建并填充一个小型的非分片表。 使用三个不同的分片键,创建三个与非分片表具有相同字段的分片表 。 从非分片表中填充分片表。 从分片表中选择行,以查看在每种情况下,行在分片(数据节点)上的分布情况。 当一个表被分片时,RowID 值被从每个分片的不同范围分配,从相隔甚远的范围开始;相同范围的行在同一个分片上。当处理一个小表时,就像本例一样,分片的 RowID 很容易区分,清楚地告诉您哪些行在一个分片上,哪些在另一个分片上(尽管您无法分辨哪个分片是哪个)。在 RowID 上分片的表的行的分布方式与行中的数据没有关系,如果您清空并重新加载一个表,可能会有所不同。另一方面,用户定义的分片键,根据键中一个或多个字段的值来分配行,因此当您清空并重新加载表(假设值和分片数没有改变)时将是相同的。 查询所有三个表以获得其中一个字段的最大长度,来显示跨分片(across shards)的行的分布对查询是透明的。 对于这部分探索,请使用以下程序: 为任意一个数据节点实例打开终端(Terminal)窗口。 在 ICM 命令行上, 发出命令 icm session 命令,使用 -machine 选项指定一个数据节点的名称,使用 - namespace 选项指定集群命名空间 IRISCLUSTER (或者使用默认文件中的 Namespace 字段指定的命名空间,如果不同的话)。 如果您不确定节点的名称,可以使用 icm inventory 命令来显示节点名称: $ icm inventory Machine IP Address DNS Name Region Zone Acme-DATA-TEST-0001 00.53.183.209 ec2-00-53-183-209.us-west-1.compute.amazonaws.com us-west-1 c Acme-DATA-TEST-0002 00.53.183.185 ec2-00-53-183-185.us-west-1.compute.amazonaws.com us-west-1 c 选择一个节点(哪个节点并不重要)并发出命令: icm session -machine Acme-DATA-TEST-0002 -namespace IRISCLUSTER icm session 命令为指定节点上的 InterSystems IRIS 实例打开一个终端(Terminal)窗口。 如果您使用 %SYSTEM.Cluster.Sharding API 手动部署您的集群,使用 InterSystems IRIS Basics:Connecting an IDE(《技术概要:连接一个 IDE》)中的procedure described for your instance(为您的实例描述的程序),在任一实例上打开一个终端(Terminal)窗口,然后切换到 IRISCLUSTER 命名空间 (或者初始化集群时指定的命名空间,如果不同的话)。 Node: Acme-DATA-TEST-0002, Instance: IRIS USER>set $namespace="IRISCLUSTER" IRISCLUSTER> 打开终端(Terminal)SQL shell:IRISCLUSTER>do $SYSTEM.SQL.Shell() [SQL]IRISCLUSTER>> 使用以下 SQL 语句,创建并填充非分片表 test.nonsharded。 CREATE TABLE test.nonsharded (field1 CHAR(5), field2 CHAR(5)) INSERT INTO test.nonsharded (field1,field2) VALUES ('one','one') INSERT INTO test.nonsharded (field1,field2) VALUES ('one','two') INSERT INTO test.nonsharded (field1,field2) VALUES ('one','three') INSERT INTO test.nonsharded (field1,field2) VALUES ('two','one') INSERT INTO test.nonsharded (field1,field2) VALUES ('two','two') INSERT INTO test.nonsharded (field1,field2) VALUES ('two','three') INSERT INTO test.nonsharded (field1,field2) VALUES ('three','one') INSERT INTO test.nonsharded (field1,field2) VALUES ('three','two') INSERT INTO test.nonsharded (field1,field2) VALUES ('three','three') 使用 SELECT 来查看表的内容: SELECT * FROM test.nonsharded field1 field2 one one one two one three two one two two two three three one three two three three 使用 test.nonsharded 中的相同字段创建三个分片表,在第一个表中使用默认的分片键(RowID),在第二个表中使用 field1 字段,在第三个表中使用 field2 字段,并使用从 test.nonsharded 中选择的 INSERT INTO 语句填充每一个: CREATE TABLE test.rowid (field1 CHAR(5), field2 CHAR(5), SHARD) INSERT INTO test.rowid (field1,field2) SELECT field1,field2 FROM test.nonsharded CREATE TABLE test.field1 (field1 CHAR(5), field2 CHAR(5), SHARD KEY (field1)) INSERT INTO test.field1 (field1,field2) SELECT field1,field2 FROM test.nonsharded CREATE TABLE test.field2 (field1 CHAR(5), field2 CHAR(5), SHARD KEY (field2)) INSERT INTO test.field2 (field1,field2) SELECT field1,field2 FROM test.nonsharded 使用 SELECT *,%ID 来显示每个分片表的内容和它在分片上的 RowID。 SELECT *,%ID FROM test.rowid ORDER BY %ID field1 field2 ID one one 1 one two 2 two one 3 two two 4 three three 5 one three 256000 two three 256001 three one 256002 three two 256003 这个分布并不反映 field1 或 field2 的值(具有各自全部三个值的行位于两个分片上)。如果您删除、重新创建并重新加载 test.rowid,分布可能会有所不同。 SELECT *,%ID FROM test.field1 ORDER BY %ID field1 one one one field2 one 1 two 2 three 3 ID two one 256000 two two 256001 two three 256002 three one 256003 three two 256004 three three 256005 在 field1 字段上分片(sharding)会分布行,使那些具有相同 field1 值的行被放在同一个分片上。在这种情况下,值为 1 的行在一个分片上,值为 2 和 3 的行在另一个分片上,但是哪个数值最终在哪个分片上取决于有多少个分片和多少个数值。 SELECT *,%ID FROM test.field2 ORDER BY %ID field1 field2 ID one one 1 two one 2 three one 3 one two 256000 one three 256001 two two 256002 two three 256003 three two 256004 three three 256005 这里,分布是由 field2 字段的值决定的。 最后,作为分片如何将工作分配到数据节点的示例,对所有三个分片表使用以下 SELECT 语句: SELECT MAX(LENGTH(field2)) FROM <table> 在每种情况下,结果都是 5,即最长值的长度是 3,因为跨分片的行分布对查询来说是完全透明的。 MAX(LENGTH(field2)) 表达式在每个分片上独立计算,分片管理器选择它们返回结果的 MAX()。例如,当查询在 test.field2 表上运行时,一个分片返回 3,因为它在 field2 字段中只有值 1 ,而另一个分片返回 5;然后分片管理器选择 5 作为两个结果中较大的那个。 如果您愿意,可以使用 EXPLAIN 来显示查询计划,明确指出如何将工作发送到分片上: EXPLAIN SELECT MAX(LENGTH(field2)) FROM <table> 更多分片集群选项 分片集群的其他选项包括如下内容: 您可以随时添加数据节点,并跨扩展的数据节点集重新平衡现有的分片数据。重新平衡(Rebal ancing)不能与查询和更新同时进行,因此只有在分片集群离线并且没有其他分片操作的情况下才能进行。( Scalability Guide[《可扩展性指南》]中的 Add Nodes and Rebalance Data[添加节点和重新平衡数据] ) 要为集群上的数据添加高可用性,您可以将数据节点部署为镜像故障转移对。( Scalability Guide[《可扩展性指南》]中的 Mirror for High Availability[高可用性镜像])。 对于需要极低查询延迟的高级用例(可能与不断涌入的数据相冲突),可以添加计算节点 ,为查询服务提供一个透明的缓存层。当集群包含计算节点时,只读的查询会自动在计算节点上并行执行,而不是在数据节点上执行;所有写入操作(插入、更新、删除和 DDL 操作)继续在数据节点上执行。这种分工将查询和数据摄取工作量分开,同时保持并行处理和分布式缓存的优势,提高两者的性能。(Scalability Guide[《可扩展性指南》]中的 Deploy Compute Nodes[部署计算节点]) 了解有关分片(Sharding)的更多信息 要了解有关分片的更多信息,请参见 Data Platform Scalability Technology Overview(《数据平台可扩展性技术概要》) (视频) Introduction to Sharding(《分片简介》) (在线课程) Sharding Basics(《分片基础》) (在线课程) Experience InterSystems IRIS in the Cloud(在云中体验 InterSystems IRIS) (在线体验) Scalability Guide(《可扩展性指南》) First Look:InterSystems Cloud Manager(《技术概要:InterSystems 云管理器》)
文章
jieliang liu · 十月 26, 2021

IRIS 2021 技术文档 First Look 24 技术概要:容器中的 InterSystems 产品

本技术概要(First Look)通过重点概述和基本的实践示例,向您介绍在 InterSystems IRIS®数据平台上使用容器(Container)的基本原理。您将了解容器的目的、重要性和好处,以及 InterSystems 如何实现它们的具体细节。 有关 Docker 容器和 InterSystems IRIS 的完整文档,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》),以及 InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)的 ICM Overview(ICM 概述)章节。Learn More About InterSystems IRIS in Containers(了解容器中的 InterSystems IRIS 的更多信息)部分提供了到其他参考资料的链接。 要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 为什么是容器(Container)? 容器(Container)将应用程序打包成独立于平台、完全可移植的运行时解决方案(runtime solution),满足所有需求,但却隔离于任何依赖项(dependency)。具体来说,Docker 容器无处不在。因为所有主要的公共云基础设施即服务(Infrastructure as a Service,IaaS)供应商都支持 Docker,企业可以通过使用容器并让云供应商处理基础设施来降低成本和复杂性。 容器带来了以下所有的好处: 容器干净地划分代码和数据,提供完全分离的关注点,应用程序可轻松部署和升级。 容器是非常高效的;容器中的应用程序只包含运行它所需的元素(element),并使其能够访问所需的连接、服务和接口,而且容器作为单个进程运行,所占用的内存并不比任何其他可执行文件多。 容器支持应用程序在不同环境之间的清洁移动(clean movement)——例如,从开发到测试,再到生产——从而减少具有不同目标的部门之间的典型过程和管理冲突。开发人员可以专注于最新的代码和库(library),质量开发人员(quality developers)专注于测试和缺陷描述,运营工程师专注于整体解决方案的基础设施,包括网络、高可用性、数据持久性(data durability)等等。 容器提供了企业对业务和技术进行变革所需的敏捷性、灵活性和可重复性。容器将应用供应过程(包括构建阶段)与运行过程明确分开,企业可以采用统一的应用程序交付方法,包括更敏捷的交付方法(DevOps)和架构(微服务)。 这些优势使容器成为应用程序的天然构件块,推动应用程序交付和部署方法变得更简单、更快速、更可重复、更强大。 容器中的 InterSystems IRIS 因为容器只打包运行容器化应用程序所需的元素,并在本地执行应用程序,所以它提供标准的、易于理解的应用程序配置、行为和访问。如果您对在 Linux 上运行的 InterSystems IRIS 有经验,那么基于 Linux 的 InterSystems IRIS 容器在什么物理、虚拟或云系统和操作系统平台上运行并不重要;您以相同的方式与它们进行交互,就像在 Linux 系统上运行传统的 InterSystems IRIS 实例一样。 下面介绍 InterSystems IRIS 在如何使用容器方面的不同。 InterSystems 提供的映像(InterSystems-provided images)——容器映像(container image)是可执行包,而容器是映像(image)的运行时实例 (runtime instance)——即映像(image)在执行时在内存中变成的实例。InterSystems 提供包含完整安装的 InterSystems IRIS 实例的映像(image),以及其他相关映像(image)。有关 InterSystems 映像(image)的更多信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 Using InterSystems IRIS Images(使用 InterSystems IRIS 映像)。 在本文档的实践体验中,您将从 InterSystems 提供的 InterSystems IRIS 映像(image)中创建并启动一个容器。 Iris-main 程序(iris-main program)——iris-main 程序使 InterSystems IRIS 和其他产品能够满足在 Docker 容器中运行的应用程序的要求。入口点应用程序(entrypoint application),即容器启动时启动的主进程,需要阻塞(block)——即等待(wait),直到其工作完成,但启动 InterSystems IRIS 的命令并不作为一个阻塞进程(blocking process)运行。iris-main 程序通过启动 InterSystems IRIS 来解决这个问题,然后继续作为阻塞入口点应用程序(blocking entrypoint application)运行。有关 iris-main 的更多信息,请参见在 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 The iris-main Program(iris-main 程序)。 该程序还提供了许多选项,以帮助调整 InterSystems IRIS 在容器中的行为;您将在本文档的实践体验中使用一些 iris-main 选项。 持久化 %SYS 功能(durable %SYS feature)——因为容器化的应用程序与主机环境隔离,所以它不会写入持久化数据(persist data);当容器被移除并被新的容器取代时,它在容器内写入的任何内容都会丢失。因此,容器化应用部署的一个重要方面是安排数据存储在容器之外,并提供给其他和未来的容器使用。 当 InterSystems IRIS 在容器中运行时,持久化 %SYS 功能(The durable %SYS feature)能够持久地存储特定于实例的数据——如用户定义、审计记录以及日志、日记和 WIJ 文件——允许一个实例跨越多个容器。例如,如果您使用持久化 %SYS 运行 InterSystems IRIS 容器,您可以通过停止原始容器(the original container)并运行使用旧容器创建的特定于实例的数据(instance-specific data)的新容器来升级实例。 您将在本文档的实践体验中探索持久化 %SYS (durable %SYS)功能。有关持久化 %SYS(durable %SYS) 的详细信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 Durable %SYS for Persistent Instance Data(持久化 %SYS 的持久化实例数据)。 重要提示: InterSystems 的容器映像符合开放容器标准(Open Container Initiative,OCI)规范,并在 Docker 企业版(Enterprise Edition)引擎上使用广泛流行的容器 Ubuntu 操作系统构建,该引擎完全支持 OCI 标准,并允许映像在 Docker Hub 注册表中认证和展示。因此,InterSystems 映像在任何基于 Linux 操作系统的符合 OCI 标准的运行时引擎上都得到支持,无论是在自有云还是在公共云中。 InterSystems 云管理器(InterSystems Cloud Manager,ICM)在其提供的云基础设施以及现有的虚拟和物理基础设施上提供 InterSystems IRIS 容器和其他容器的自动部署。有关使用 ICM 部署容器化的 InterSystems IRIS 实例的更多信息,请参见 First Look:InterSystems Cloud Manager(《技术概要:InterSystems 云管理器》) 和 InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)。 3. 下载 InterSystems IRIS 映像(Image) 要使来自 InterSystemsInterSystems IRIS 映像(image)可用于本实践,您必须将映像(image)下载到您正在使用的系统中。以下替代方案描述了您可以或可能可以使用的 InterSystems IRIS 映像(image)。 您可以使用来自 InterSystems 容器注册表(InterSystems Container Registry,ICR)的 InterSystems IRIS 社区版(Community Edition)映像(image),该映像(image)包含可从 InterSystems 获得的所有映像(image)的存储库,如 Using the InterSystems Container Registry(《使用 InterSystems 容器注册表》)中所述。您也可以从 Docker Store 的 InterSystems IRIS 数据平台页面下载社区版(Community Edition)映像(image)。 InterSystems IRIS 社区版(Community Edition)有一个免费的内置 13个月的许可证(和一些功能限制);如果您在这次实践中使用社区版(Community Edition),您就不需要提供下一步(Add the License Key to the External Storage Location(添加许可证密钥到外部存储位置))中所述的许可证密钥。更多信息,请参见 Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》)中的 Deploy InterSystems IRIS Community Edition on Your Own System(在您自己的系统上部署 InterSystems IRIS 社区版)。 注意: 另一个选择是在 GCP、AWS 或 Azure 上提供一个承载运行中的 InterSystems IRIS 社区版(Community Edition)容器的云节点;更多信息,请参见 Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》)中的 Deploy InterSystems IRIS Community Edition on a Cloud Node(在云节点上部署 InterSystems IRIS 社区版)。如果您在这个练习中使用社区版(Community Edition)的云节点,您可以跳过接下来的两个步骤,并跳转到 Change the Instance and Commit the Container as a New Image(更改实例并将容器作为新映像提交)。 如果您是 InterSystems 客户,您可以使用 InterSystems 容器注册表(InterSystems Container Registry,ICR)发布的 InterSystems IRIS 映像(image)。Using the InterSystems Container Registry(使用 InterSystems 容器注册表)列出了 IRC 提供的 InterSystems IRIS 映像(image),并解释了如何使用您的 WRC 凭证对注册表进行身份验证,以便您下载。 您的企业可能有一个私有映像(image)注册表,其中包括一个或多个 InterSystems IRIS 映像(image)。如果是这样,请获取您需要的映像(image)的注册表、存储库和标签的位置,以及访问所需的凭证。 当您确定了要下载的注册表和需要的凭证(如果有)后,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品 》)中的 Downloadingthe InterSystems IRIS Image(下载 InterSystems IRIS 映像),了解下载 InterSystems IRIS 映像(image)的说明。 为了简单起见,这些说明假定您正在使用的映像(image)是 intersystems/iris:2021.1.0.205.0。 4. 添加许可证密钥到外部存储位置 与任何 InterSystems IRIS 实例一样,在容器中运行的实例需要一个许可证密钥(通常称为 iris.key)。 从 Docker Store 获得的 InterSystems IRIS 社区版(Community Edition)映像(在上一节中进行了描述)带有一个免费的内置临时许可证。然而,一般来说,许可证密钥没有也不能包含在 InterSystems IRIS 容器映像(container image)中,而是必须在容器启动后复制到容器中,以便激活运行在其中的 InterSystems IRIS 实例。iris-main 程序为此提供了一个选项,但它要求您把许可证密钥放在一个作为外部 volume 挂载的存储位置;下一节提供了使用说明。要了解有关 InterSystems IRIS 容器的许可证密钥的更多信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 License Keys for InterSystems IRIS Containers(InterSystems IRIS 容器的许可证密钥)。 将您的 InterSystems IRIS 许可证密钥文件 iris.key 复制到外部存储位置。 5. 从 InterSystems IRIS 映像(Image)运行容器 一旦您在本地机器上使 InterSystems IRIS 映像(image)可用,确定了外部存储位置并在其上放置了许可证密钥,您就可以使用 docker run 命令来创建和启动容器了。Docker run 命令实际上结合了三个独立的命令,如下所示: docker pull — 如果本地不存在映像(image),则下载一个。 docker create — 从映像(image)中创建一个容器。 docker start — 启动容器。 这些命令中的每一个都是单独有用的,在不同的背景下有不同的用途。更多信息,请参见 Docker 文档中的Docker run reference(Docker 运行参考资料) 。 下面是一个 docker run 命令的示例;所附文本对所有选项都作了解释。请注意,docker run 命令的选项出现在命令行中映像(image)规范之前,而 InterSystems iris-main 程序的选项(请参见 InterSystems IRIS in Containers(《容器中的 InterSystems IRIS》))出现在之后。在这种情况下,作为 docker run 一部分的 pull 命令不需要运行,因为您已经下载了您想使用的 iris 映像(image)。 docker run --name iris --detach --publish 52773:52773 --volume /nethome/pmartinez/iris_external:/external intersystems/iris:2021.1.0.205.0 --key /external/iris.key --name 容器名称(container name) 指定容器的名称,您可以在其他 Docker 命令中用它来引用该容器,例如,当您想停止该容器时,使用 docker stop container name 。 --detach 在后台运行容器(并显示容器的唯一 ID)。 --Publish 主机端口:容器端口(host_port:container_port) 将容器内的端口发布到主机上的端口,这样容器外(在主机上或其他机器上)的实体就可以与容器内的程序联系。例如,InterSystems IRIS 实例的管理门户(Management Portal)是通过实例的 Web 服务器端口(默认为 52773)访问的。如果容器内的这个端口发布到主机上的端口,那么可以使用主机的端口将实例的管理门户(Management Portal)加载到浏览器中。 --volume 外部存储路径:内部 volume(external_storage_path:internal_volume) 挂载容器可访问的外部存储位置作为容器内部的存储 volume。有关哪些存储位置可以以这种方式挂载以及可能需要的 Docker 配置的信息,请参见 Docker 文档中的 Use Volumes(使用 Volumes ) 。 重要提示: InterSystems 不支持在 InterSystems IRIS 容器中把 NFS 位置作为外部 volume 挂载。 存储库/映像:标签(repository/image:tag) 指定要提取并用于创建容器的映像(请参见 Download the InterSystems IRIS Image(下载 InterSystems IRIS 映像))。使用 docker images 命令来列出可用的映像(image),并确保您指定的是正确的映像(image)。 --Key 许可证密钥路径(license_key_path) iris-main 选项,它标识了要安装在容器实例中的 InterSystems IRIS 许可证密钥;这个位置必须是在一个挂载的 volume 上。 使用前面的示例和说明来构建您自己的 docker run 命令,并在命令行上执行。当命令完成后,使用 docker ps 命令可以在列表中看到您的容器,状态为 Up。 试一试! 创建您自己的基于 InterSystems IRIS 的容器 $ docker run --name iris --detach --publish 52773:52773 --volume /nethome/pmartinez/iris_external:/external intersystems/iris:2021.1.0.205.0 --key /external/iris.key 426d4a511d6746d89ec2a24cf93b29aa546ea696b479a52210d37da4c6d04883 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS 426d4a511d67 intersystems/iris:2021.1.0.205.0 "/iris-main --key ..." 5 seconds ago Up 3 seconds PORTS NAMES 0.0.0.0:52773->52773/tcp iris 注意: InterSystems IRIS 社区版(Community Edition)映像(请参见 Download the InterSystems IRIS Image(下载 InterSystems IRIS 映像))不需要--key 选项 ,该映像附带一个免费的内置许可证。 如果映像尚未在本地存在,但在您组织的存储库中——请参见 Download the InterSystems IRIS Image(下载 InterSystems IRIS 映像),Docker 会在创建和启动容器之前拉取(下载)该映像(image)。 如示例所示,创建容器后,Docker 输出 UUID 长标识符(long identifier); 前 12 个字符组成 UUID 短标识符(short identifier),用于标识其他输出中的容器,例如来自 docker ps 命令的容器。 6.更改实例并将容器作为新映像(Image)提交 当您更改容器内运行的程序时,您可以使用 docker commit 命令从容器中创建一个新映像(image)。这个新映像(image)与您创建容器的原始映像(image)相同,但包括您对容器所作的更改。要了解其工作原理,请遵循以下步骤: 打开容器中 InterSystems IRIS 实例的管理门户(Management Portal)。实例的管理门户(Management Portal)的 URL 包含了实例的主机标识符和 web 服务器端口号 。 主机标识符是运行容器的系统的主机名或 IP 地址;如果您的浏览器与容器运行在同一个系统上,则可以使用 localhost。 Web 服务器端口号是您在使用 docker run 启动容器时发布的实例的 web 服务器端口号,即 52773 的主机端口号。假设您包含了--publish 52773:52773,正如上一节末尾的示例命令中提供的那样,web 服务器端口号是 52773。 例如,在容器主机上,Web 服务器端口为 52773,管理门户(Management Portal)的 URL 将是 http://localhost:52773/csp/sys/%25CSP.Portal.Home.zen。 使用预定义用户帐户之一登录,例如 _SYSTEM,其默认密码是 SYS(请参见 Predefined User Accounts(预定义用户账户))。出于安全考虑,在第一次登录(使用管理门户(Management Portal)或 iris terminal 命令)到容器化的 InterSystems IRIS 实例上的任何预定义账户时,系统会立即提示您更改密码。 注意: 有关更改预定义帐户(强烈建议在生产中这样做)的默认密码(包括在脚本和自动部署中)的更多信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 Authentication and Passwords (身份验证和密码)。 从主页上,选择 System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Namespaces(命名空间) 来显示 Namespaces(名称空间) 页面,然后点击 Create New Namespace(创建新的命名空间) 按钮来显示 New Namespace(新的命名空间) 页面。 创建名为 USER2 的命名空间,方法是在 Name of the namespace box(命名空间框的名称)中输入 USER2,从 Copy from 下拉菜单中选择 USER,清除 Enable namespace for interoperability productions(为互操作性产品启用命名空间) 复选框并确认,点击 Save(保存) 按钮,最后确认您想要复制所有属性和映射。 然后点击 Copy Namespace Mappings(复制命名空间映射) 页面上的 Close(关闭) ,返回到 Namespaces(命名空间) 页面,在该页面上列出了 USER2 命名空间。 您现在已经改变了容器中的实例。 接下来,停止该容器并将其作为名为 iris2 的新映像(image)提交,然后列出可用的映像。 $ docker stop iris $ docker commit iris acme/iris2:test sha256:7b4adb9f7abf1490a39086665ccd3d255c05163c25cb9a3de8e9421f6ca16b40 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE acme/iris2 test 421f6ca16b40 8 seconds ago 1.40GB intersystems/iris 2020.3.0.221.0 15627fb5cb76 1 hour ago 1.39GB centos 7.3.1611 262f7381844c 2 weeks ago 192MB hello-world latest 05a3bd381fc2 7 months ag 1.84kB 最后,删除从原始 iris 映像创建的容器。 $ docker rm iris iris 7.运行和调查第二个基于 InterSystems IRIS 的容器 为了总结这一体验,您将使用 docker run 命令从您刚刚提交的基于 InterSystems-IRIS 的映像中创建并启动一个容器,包括用于持久化特定于实例的数据的持久化 %SYS 功能(durable %SYS feature)。持久化 %SYS (durable %SYS)是保存特定于实例的数据以及您对它所做的任何更改的一种更有用的方法。因为这些数据被保存在容器之外,它可以成为新的 InterSystems IRIS 容器的数据,允许您通过运行后面的映像(image)的容器来升级 IRIS 实例,同时保留以前的容器的数据;当内部容器更改提交到新映像时,这是不可能的。有关持久化 %SYS (durable %SYS)的详细信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 Durable %SYS for Persistent Instance Data(持久化实例数据的持久化 %SYS )。当您启动新容器后,将执行以下操作: 确认在作为一个新映像(image)提交的容器中创建的命名空间(请参见 Change the Instance and Commit the Container as a New Image(更改实例并将容器作为新映像提交))存在于新容器中的 InterSystems IRIS 实例中。 在容器中更改 InterSystems IRIS 实例的设置,并查看它反映在容器外持久化 %SYS (durable %SYS)数据中。 确认您添加的演示文件在容器内存在。 要做到这一点,请遵循以下步骤: 为这个容器确定一个外部存储位置。您可以使用在 Add the License Key to the External Storage Location(添加许可证密钥到外部存储位置)中为前一个容器选择的许可证密钥,也可以选择一个新的。许可证密钥应该仍然在以前的位置。(如果您使用一个新的位置,请确保许可证密钥已经到位)。 创建一个 docker run 命令,类似您在 Run a Container from the InterSystems IRIS Image(从 InterSystems IRIS 映像运行容器)中执行的命令, 基于那里的指令,但有两个更改。 添加选项 --env ISC_DATA_DIRECTORY=pathname 标识持久化 %SYS(durable %SYS) 目录,即写入 InterSystems IRIS 实例的持久化数据(persistent data)的位置。持久化 %SYS目录(durable %SYS directory)必须在一个挂载的 volume 上(请参见--volume 选项和 Add the License Key to the External Storage Location(添加许可证密钥到外部存储位置))。 注意: InterSystems 建议指定挂载 volume 的子目录为持久化 %SYS 的位置。下面的 docker ps 示例显示了这一点。 使用映像:标签(image:tag) 指定新映像 之前,您从 intersystems/iris:2021.1.0.205.0 (即 InterSystems 提供的映像)创建了容器;这次,您使用的是 acme/iris2:test,这是您通过提交更改过的 iris 容器创建的。 调用容器 iris2。当 docker run 命令完成后,使用 docker ps 命令来列出容器并查看其状态。例如: $ docker run --name iris2 --detach --publish 52773:52773--volume /nethome/pmartinez/iris_external:/external --env ISC_DATA_DIRECTORY=/external/durable acme/iris2:test --key /external/iris.key bdfe214ef76a34290a8308cddce92162aae14df1ba1bc244e692af3c8d911a3e $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS af3c8d911a3e acme/iris2:test "/iris-main --key ..." 5 seconds ago Up 3 seconds PORTS NAMES 0.0.0.0:52773->52773/tcp iris2 注意: InterSystems IRIS 社区版(Community Edition)映像(请参见 Download the InterSystems IRIS Image(下载 InterSystems IRIS 映像))不需要--key 选项,该映像附带一个免费的内置许可证。 Docker Compose 是一个用于定义和运行多容器应用程序的工具,为 Docker 命令行交互提供了替代方案。要使用 Compose,您需要创建 docker-compose.yml ,其中包含您想要创建、启动和管理的容器的规范,然后使用 docker-compose 命令。更多信息,请参见 Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》)中的 Running an InterSystems IRIS Container:Docker Compose Example(运行 InterSystems IRIS 容器:Docker Compose 示例),和 Docker 文档中的 Overview of Docker Compose(Docker Compose 概述)。 确认从已更改的 InterSystems 容器提交的更改 在 Change the Instance and Commit the Container as a New Image(更改实例并将容器作为新映像提交)中,您在从 InterSystems 提供的映像 intersystems/iris:2021.1.0.205.0 创建的容器中为 InterSystems IRIS 实例添加了一个命名空间,然后将该容器作为一个新映像 acme/iris2:test 提交。因此,您添加的命名空间应该存在于运行在 iris2 容器内的 InterSystems IRIS 实例中,该容器是从 acme/iris2:test 创建的。 要确认这一点,请执行以下操作: 打开管理门户(Management Portal)并登录,如 Change the Instance and Commit the Container as a New Image(更改实例并将容器作为新映像提交)中所述。 从主页上,选择 System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Namespaces(命名空间),来显示命名空间(Namespaces)页面;在 iris 容器中创建的 USER2 命名空间被列出。 探索和更改持久化 %SYS 目录 要探索 InterSystems IRIS 容器的持久化 %SYS 功能,请执行以下操作: 要查看 InterSystems IRIS 在容器外写入的特定于实例的数据,因为您在 docker run 命令中包含了持久化 %SYS 环境变量,显示您在该变量中指定的目录的内容,该目录在您使用--volume 选项指定的存储位置,作为要挂载的外部 volume。例如,如果该目录被指定为 /nethome/pmartinez/iris_external/durable,如示例 docker run 中所示,您会做如下操作 $ cd /nethome/pmartinez/iris_external $ ls durable iris.key $ ls durable csp dist httpd iris.cpf iris.cpf_20180417 _LastGood_.cpf mgr $ ls durable/mgr alerts.log irisaudit iris.ids irislocaldata iristemp IRIS.WIJ journal.log startup.last SystemMonitor.log user ilock IRIS.DAT iris.lck iris.shid iris.use journal messages.log stream Temp 返回容器中 InterSystems IRIS 实例的管理门户(Management Portal),选择 System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Journal Settings(日志设置) 以显示日志设置(Journal Settings)页面。 Secondary journal directory(二级日志目录)设置从 /external/durable/mgr/journal/ 更改为 /external/durable/mgr/journal2/,并点击 Save(保存)。 返回到命令行,再次列出持久化 %SYS 目录的 mgr 子目录: $ ls /nethome/pmartinez/iris_external/durable/mgr alerts.log irisaudit iris.ids iris.lck iris.shid iris.use journal journal.log messages.log stream Temp ilock IRIS.DAT iris.key irislocaldata iristemp IRIS.WIJ journal2 licmanager.port startup.last SystemMonitor.log user 由于您对容器内的 InterSystems IRIS 实例进行了更改,所以 journal2 子目录被添加到容器外 。 这个示例显示了持久化 %SYS (durable %SYS)如何使您通过从新映像(image)创建容器来升级容器化的 InterSystems IRIS 实例。您对实例所做的所有持久化更改都存储在容器外的持久化 %SYS 目录(durable %SYS directory);如果您使用所需的选项从任何 InterSystems IRIS 映像(image)创建并启动一个新容器 — 即--volume 选项为持久化 %SYS (durable %SYS)挂载外部存储位置,以及--env ISC_DATA_DIRECTORY 选项指定该挂载 volume 上持久化 %SYS(durable %SYS) 位置,该位置必须存在,并且包含一个 /mgr 子目录 — 这些更改由实例继承,因为它使用与前一个容器中的实例相同的数据。 4.了解有关容器中的 InterSystems IRIS 的更多信息 此时,您已经准备好继续探索容器和 InterSystems IRIS 必须提供的东西。使用下面的文档和参考资料来深入了解容器和 InterSystems IRIS。 Docker Containers and InterSystems IRIS(《Docker 容器和 InterSystems IRIS》) (视频) Running InterSystems Products in Containers(《在容器中运行 InterSystems 产品》) 来自 InterSystems 开发者社区(Developer Community)的文章: What is a Container?(《什么是容器?》) What is a Container Image?(《什么是容器映像?》) Using InterSystems IRIS Containers with Docker for Windows(《使用 InterSystems IRIS 容器与 Docker for Windows》) Docker Documentation(《Docker 文档》) InterSystems Cloud Manager Guide(《InterSystems 云管理器指南》)——使用 InterSystems 云管理器(InterSystems Cloud Manager,ICM)可以轻松直观地配置基础设施,并以各种方式在上面部署容器。ICM 为 InterSystems IRIS 带来了基础设施即代码(Infrastructure as Code,IaC)和容器化部署的好处,而不需要在新技术、培训、配置和管理方面进行重大投资。本指南包含有关 ICM 和使用 InterSystems IRIS 与 Docker 容器的文档。 First Look:InterSystems Cloud Manager(《技术概要:InterSystems 云管理器》)
公告
Claire Zheng · 七月 30, 2021

Online Meetup:InterSystems 开发者竞赛(人工智能与机器学习)

亲爱的社区开发者们,大家好! 我们真诚邀请您参加 Online Meetup:InterSystems 开发者竞赛(人工智能与机器学习)! 时间: 2021年7月30日(周五) 11:00 AM (美东时间)23:00 (北京时间) 在这场在线Meetup,您将了解到: 此次优胜者的个人履历; 获奖Application的简短Demo; 有关应用技术的开放探讨、问答,以及下次竞赛的一些计划。 我们的发言人名单: @José.Pereira, BI开发者,Shift Consultoria e Sistemas Ltda @Henrique.GonçalvesDias, 系统管理专员/数据库管理员, Sao Paulo Federal Court @Oleh.Dontsov, 全栈开发工程,Tax Sketches SRO @Aleksandr.Kalinin6636, 工程师, LLC "Escape" @Renato.Banzai, 机器学习工程师,Itaú Unibanco @Evgeny.Shvarov, InterSystems 开发者生态经理(Developer Ecosystem Manager) @Thomas.Dyar, InterSystems 产品专家(机器学习) @Raj.Singh5479, InterSystems 产品经理( 开发者体验) @Robert.Kuszewski, InterSystems 产品经理( 开发者体验) 欢迎您在这个特别的会议上与我们的开发人员沟通、交流! ➡️ 注册参会!
公告
Michael Lei · 十二月 30, 2021

第三方合作伙伴产品展示:InterSystems IRIS的“新”监控工具

亲爱的女士们和先生们,在上个月,我改进了我的工具Caché监视器......但首先:名字 选择Caché Monitor这个名字是为了反映该工具与Caché数据库的紧密结合。我想,在可预见的未来,Intersystems Caché这个既定名称很可能会被InterSystems IRIS数据平台完全取代。因此,重塑品牌的步骤成为必要。为了在未来不那么紧密地与一个产品名称联系在一起,我们选择了一个更加中立的新名字: SQL Data Lens 不管叫什么名字,实现与Intersystems产品最紧密的整合仍然是我们的目标。持续的发展也反映在版本号的延续上。上一个版本是Caché Monitor 2.96,下一个版本是SQL Data Lens 3.0。 但这不仅仅是重新命名,而且还集成了许多新的功能,例如 一个很大的进步是,SQL Data Lens现在是基于Java Runtime Environment 11的,有了它,就可以改善对HiDPI的支持。在操作系统层面上配置了系统规模因素,支持每台显示器的DPI! 但也集成了一个新的现代的Flat 外观和Feel 集成,在亮Light和暗Dark两种模式下。 SQL DataLens带有一个最小化的私有JRE(基于JetBrains JDK 11)。 ...等等 请随时从以下网站下载并测试SQL Data Lens,无需任何注册: https://sqldatalens.com/ 我期待着你的经验,建议和想法,这些都非常欢迎。 谢谢您的关注! Andreas https://sqldatalens.com/从链接进去下载不了 我刚试了一下是可以的,而且不用翻墙,看看是否本地浏览器或者其他问题?谢谢! https://sqldatalens.com/download/ 点击download之后,会跳到https://sqldatalens.com/sqldl_files/latest/SQLDataLens_308_20220508.zip这个链接,提示“ Server Error 403 Forbidden ” 那可能得麻烦您到英文社区下面问下,这是我们德国合作伙伴做的:https://community.intersystems.com/post/new-tool-intersystems-iris, 谢谢!
文章
姚 鑫 · 一月 19, 2023

第五十章 使用 ^SystemPerformance 监视性能 - Microsoft Windows 平台的 InterSystems IRIS 性能数据报告

# 第五十章 使用 ^SystemPerformance 监视性能 - Microsoft Windows 平台的 InterSystems IRIS 性能数据报告 #### Microsoft Windows 平台的 IRIS 性能数据报告 - `%SS` - 使用 `ALL^%SS` 命令在运行过程中采集了四个样本。 - `Configuration *` - 来自服务器的 `IRIS` 实例名称和主机名、完整的 `IRIS` 版本字符串、许可客户名称和许可订单号。 - `cpf file *` - 当前活动配置文件的副本。 - `irisstat -c` - 使用命令 `.\bin\irisstat -s -p-1 -c-1 -e1 -m8 -n2 -N127` 在运行过程中以均匀间隔采集四个样本。以下是对每个参数的简要说明: - `-p-1`: 对进程表进行采样以包括进程和全局状态信息。 - `-c-1`: 对共享内存的计数器部分进行采样以显示日志、锁、磁盘和资源使用统计信息。 - `-e1`: `SYSLOG` 错误表。 - `-m8`: 文件表,其中包括所有 `IRIS.DAT` 文件及其属性。 - `-n2`: 网络结构表,包括本地到远程数据库的映射。 - `-N127`: 客户端和服务器连接的 `ECP` 统计信息。 - `irisstat -D` - 使用命令 `irisstat cache --f1 -D10,100` 在运行过程中以均匀的间隔采集八个样本。以下是对每个参数的简要说明: - `-fl`: 基本标志。 - `-D10,100`: 在 `10` 秒的总采样周期内,每 `100` 毫秒对块碰撞进行采样。 - `license *` - 使用 `Decode^%LICENSE` 和 `counts^%LICENSE` 的 `IRIS` 许可使用信息。 - `mgstat` - 使用 `^mgstat` 实用程序在运行过程中获取 `IRIS` 特定数据。 - `perfmon` - `Microsoft Windows perfmon` 实用程序的输出。 `Microsoft Windows perfmon` 数据的默认呈现方式是原始格式。可以将格式切换为已处理,这会删除重复的服务器名称并将日期时间列拆分为单独的列,以提高可读性。以下函数允许查询和更新确定 `perfmon` 数据是否被操作的标志:`set rc=$$setperfmonpostproc^SystemPerformance(`) 其中 `onoroff` 可以是 `1`(开)或 `0`(关),或者不区分大小写的单词`“on”`或`“off”`。返回码 `1` 表示标志更新成功,`0` 表示更新失败,`-1` 表示非 `Windows` 平台。要确定当前格式(原始格式或已处理格式):`set status=$$getperfmonpostproc^SystemPerformance()` 返回代码 `1` 表示已处理格式,`0` 表示原始格式。此外,在 `^SystemPerformance` 的交互式运行中,在配置文件菜单显示之前报告标志的当前状态。默认情况下,`perfmon` 监视默认 `pbctrs.txt` 文件中指定的计数器定义。要监视先前定义的性能计数器,请使用以下命令将定义导入 `^SystemPerformance`:写入 `$$importctrs^SystemPerformance(WindowsCtrName [,SystemPerformanceCtrName [,SystemPerformanceFileName]])` 返回代码 `0` 表示成功,负数后跟原因字符串表示失败.不允许重复的 `SystemPerformance` 计数器名称。如有必要,`^SystemPerformance` 会生成内部计数器名称和文件名。要将默认的 `SystemPerformance` 计数器定义更改为现有定义,请使用:`write $$setctrddefault(SystemPerformanceCtrName)` 返回代码 `1` 表示成功,后跟原因字符串的 `0` 表示失败。如果指定了无效计数器,则会设置内置默认值。要重置默认的 `SystemPerformance` 计数器定义,请使用:`do clrctrdefault^SystemPerformance()` 要将特定的 `SystemPerformance` 计数器定义与现有配置文件相关联,请使用:`write $$addctrtoprofile(ProfileName,SystemPerformanceCtrName)` 返回码 `1` 表示成功,`0` 后跟一个原因字符串表示失败。如果配置文件或计数器定义不存在,则不会运行该命令。 - `Profile *` - 有关创建此日志的 `^SystemPerformance` 配置文件的信息。 - `tasklist` - `tasklist -V` 命令的四个输出,在运行过程中以均匀的间隔获取。 `tasklist -V` 命令提供系统上运行的所有进程的列表。 - `Windows info *` - `systeminfo` 命令的输出,包括 `Windows` 版本(不包括修补程序信息)和硬件信息;例如,处理器数量、安装的内存和使用的内存。
文章
姚 鑫 · 一月 21, 2023

第五十二章 使用 ^SystemPerformance 监视性能 - IBM AIX® 平台的 InterSystems IRIS 性能数据报告

# 第五十二章 使用 ^SystemPerformance 监视性能 - IBM AIX® 平台的 InterSystems IRIS 性能数据报告 - `%SS` - 使用 `ALL^%SS` 命令在运行过程中采集了四个样本。 - `AIX info *` - `oslevel` 的输出。 `uname -a`、`prtconf` 和 `lspv `命令 - `Configuration *` - 来自服务器的 `IRIS` 实例名称和主机名、完整的 `IRIS` 版本字符串、许可客户名称和许可订单号。 - `cpf file *` - 当前活动配置文件的副本。 - `cpu type *` - 有关安装的处理器以及是否启用 `SMT` 的信息; `lsattr -El proc0` 的输出。 - `irisstat -c` - 使用命令 `irisstat cache -p-1 -c-1 -e1 -m8 -n2 -N127` 在运行过程中以均匀的间隔采集四个样本。以下是对每个参数的简要说明: - `-p-1`: 对进程表进行采样以包括进程和全局状态信息。 - `-c-1`: 对共享内存的计数器部分进行采样以显示日志、锁、磁盘和资源使用统计信息。 - `-e1`: `SYSLOG` 错误表。 - `-m8`: 文件表,其中包括所有 `IRIS.DAT` 文件及其属性。 - `-n2`: 网络结构表,包括本地到远程数据库的映射。 - `-N127`: 客户端和服务器连接的 `ECP` 统计信息。 - `irisstat -D` - 使用命令 `irisstat cache --f1 -D10,100` 在运行过程中以均匀的间隔采集八个样本。以下是对每个参数的简要说明: - `-fl`: 基本标志。 - -`D10,100`: 在 `10` 秒的总采样周期内,每 `100` 毫秒对块碰撞进行采样。 - `df -k *` - 有关挂载文件系统的信息,包括挂载点、逻辑卷和可用空间; `df -k` 命令的输出。 - `filesystems *` - 当前 `/etc/filesystems` 文件。 - `ioo -a *` - `I/O`可调参数的当前值; `ioo -a` 命令的输出。仅当启动 `^SystemPerformance` 配置文件运行的用户具有 `root` 访问权限时才包括在内。 - `iostat -DIT` - 带有 `IBM AIX® 5.3` 及更新版本采样时间的扩展磁盘/设备统计信息的长列表; `iostat -DIT` 命令的输出。信息因 `IBM AIX® 5.3` 之前的发行版而异。 - `ipcs *` - 进程间通信配置信息,包括共享内存、信号量和消息队列; `ipcs -a` 命令的输出。 - `license *` - 使用 `Decode^%LICENSE` 和 `counts^%LICENSE` 的 `IRIS` 许可使用信息。 - `mount *` - 有关所有文件系统及其挂载选项的信息。 - `mgstat` - 使用 `^mgstat` 实用程序在运行过程中获取 `IRIS` 特定数据。请参阅 `Monitoring Guide` 的 `Monitoring Performance Using ^mgstat` 部分。 - `Profile *` - 有关创建此日志的 `^SystemPerformance` 配置文件的信息。 - `ps:` - 使用命令 `ps aux` 在运行过程中以均匀的间隔采集四个样本。 - `sar -d` - 仅当启动 `^SystemPerformance` 配置文件运行的用户具有 `root` 访问权限并且 `/usr/sbin/sar` 存在时才包括在内。 - `sar -r` - 仅当启动 `^SystemPerformance` 配置文件运行的用户具有 `root` 访问权限并且 `/usr/sbin/sar` 存在时才包括在内。 - `sar -u` - 包括微分区信息(如果使用)的 `CPU` 统计信息。仅当启动 `^SystemPerformance` 配置文件运行的用户具有 `root` 访问权限并且 `/usr/sbin/sar` 存在时才包括在内。 - `vmo –a` - 虚拟内存可调参数的当前值; `vmo -a` 命令的输出。仅当启动 `^SystemPerformance` 配置文件运行的用户具有 `root` 访问权限时才包括在内。 - `vmstat -s *` - 虚拟内存统计的绝对计数,包括总页入和页出。 - `vmstat -t` - 带有时间戳的虚拟内存和 `CPU`(分页、排队和 CPU)统计信息。 - `vmstat -v *` - 示例虚拟内存统计信息,包括可用页面、`pbuf` 使用情况和 `fsbuf` 使用情况。
文章
jieliang liu · 九月 23, 2021

IRIS 2021 技术文档 First Look 19 使用 InterSystems 产品优化 SQL 性能

html {overflow-x: initial !important;}:root { --bg-color: #ffffff; --text-color: #333333; --select-text-bg-color: #B5D6FC; --select-text-font-color: auto; --monospace: "Lucida Console",Consolas,"Courier",monospace; --title-bar-height: 20px; } .mac-os-11 { --title-bar-height: 28px; } html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; } body { margin: 0px; padding: 0px; height: auto; inset: 0px; font-size: 1rem; line-height: 1.42857143; overflow-x: hidden; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; tab-size: 4; background-position: inherit; background-repeat: inherit; } iframe { margin: auto; } a.url { word-break: break-all; } a:active, a:hover { outline: 0px; } .in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); } #write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 36px; } #write.first-line-indent p { text-indent: 2em; } #write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; } #write.first-line-indent li { margin-left: 2em; } .for-image #write { padding-left: 8px; padding-right: 8px; } body.typora-export { padding-left: 30px; padding-right: 30px; } .typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; } .typora-export .task-list-item input { pointer-events: none; } @media screen and (max-width: 500px) { body.typora-export { padding-left: 0px; padding-right: 0px; } #write { padding-left: 20px; padding-right: 20px; } .CodeMirror-sizer { margin-left: 0px !important; } .CodeMirror-gutters { display: none !important; } } #write li > figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max-width: 100%; vertical-align: middle; image-orientation: from-image; } button, input, select, textarea { color: inherit; font-family: inherit; font-size: inherit; font-style: inherit; font-variant-caps: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; } input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; } *, ::after, ::before { box-sizing: border-box; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; } #write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; } p { line-height: inherit; } h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 4; } p { orphans: 4; } h1 { font-size: 2rem; } h2 { font-size: 1.8rem; } h3 { font-size: 1.6rem; } h4 { font-size: 1.4rem; } h5 { font-size: 1.2rem; } h6 { font-size: 1rem; } .md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; } .hidden { display: none; } .md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; } a { cursor: pointer; } sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; } sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; } #write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; } figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; } figure > table { margin: 0px; } tr { break-inside: avoid; break-after: auto; } thead { display: table-header-group; } table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; } table.md-table td { min-width: 32px; } .CodeMirror-gutters { border-right-width: 0px; background-color: inherit; } .CodeMirror-linenumber { } .CodeMirror { text-align: left; } .CodeMirror-placeholder { opacity: 0.3; } .CodeMirror pre { padding: 0px 4px; } .CodeMirror-lines { padding: 0px; } div.hr:focus { cursor: none; } #write pre { white-space: pre-wrap; } #write.fences-no-line-wrapping pre { white-space: pre; } #write pre.ty-contain-cm { white-space: normal; } .CodeMirror-gutters { margin-right: 4px; } .md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; position: relative !important; background-position: inherit; background-repeat: inherit; } .md-fences-adv-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; } #write .md-fences.mock-cm { white-space: pre-wrap; } .md-fences.md-fences-with-lineno { padding-left: 0px; } #write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; } .md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; } .CodeMirror-line, twitterwidget { break-inside: avoid; } .footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; } .footnotes + .footnotes { margin-top: 0px; } .md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; background-position: 0px 0px; } li div { padding-top: 0px; } blockquote { margin: 1rem 0px; } li .mathjax-block, li p { margin: 0.5rem 0px; } li blockquote { margin: 1rem 0px; } li { margin: 0px; position: relative; } blockquote > :last-child { margin-bottom: 0px; } blockquote > :first-child, li > :first-child { margin-top: 0px; } .footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; } #write .footnote-line { white-space: pre-wrap; } @media print { body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; font-variant-ligatures: no-common-ligatures; } #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; } .typora-export * { -webkit-print-color-adjust: exact; } .typora-export #write { break-after: avoid; } .typora-export #write::after { height: 0px; } .is-mac table { break-inside: avoid; } .typora-export-show-outline .typora-export-sidebar { display: none; } } .footnote-line { margin-top: 0.714em; font-size: 0.7em; } a img, img a { cursor: pointer; } pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background-color: rgb(204, 204, 204); display: block; overflow-x: hidden; } p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; } #write.first-line-indent p > .md-image:only-child:not(.md-img-error) img { left: -2em; position: relative; } p > .md-image:only-child { display: inline-block; width: 100%; } #write .MathJax_Display { margin: 0.8em 0px 0px; } .md-math-block { width: 100%; } .md-math-block:not(:empty)::after { display: none; } .MathJax_ref { fill: currentcolor; } [contenteditable="true"]:active, [contenteditable="true"]:focus, [contenteditable="false"]:active, [contenteditable="false"]:focus { outline: 0px; box-shadow: none; } .md-task-list-item { position: relative; list-style-type: none; } .task-list-item.md-task-list-item { padding-left: 0px; } .md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; } .math { font-size: 1rem; } .md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-top-left-radius: 10px; border-top-right-radius: 10px; border-bottom-right-radius: 10px; border-bottom-left-radius: 10px; } .md-toc-content { position: relative; margin-left: 0px; } .md-toc-content::after, .md-toc::after { display: none; } .md-toc-item { display: block; color: rgb(65, 131, 196); } .md-toc-item a { text-decoration: none; } .md-toc-inner:hover { text-decoration: underline; } .md-toc-inner { display: inline-block; cursor: pointer; } .md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; } .md-toc-h2 .md-toc-inner { margin-left: 2em; } .md-toc-h3 .md-toc-inner { margin-left: 4em; } .md-toc-h4 .md-toc-inner { margin-left: 6em; } .md-toc-h5 .md-toc-inner { margin-left: 8em; } .md-toc-h6 .md-toc-inner { margin-left: 10em; } @media screen and (max-width: 48em) { .md-toc-h3 .md-toc-inner { margin-left: 3.5em; } .md-toc-h4 .md-toc-inner { margin-left: 5em; } .md-toc-h5 .md-toc-inner { margin-left: 6.5em; } .md-toc-h6 .md-toc-inner { margin-left: 8em; } } a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; } .footnote-line a:not(.reversefootnote) { color: inherit; } .md-attr { display: none; } .md-fn-count::after { content: "."; } code, pre, samp, tt { font-family: var(--monospace); } kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background-color: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; } .md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); } code { text-align: left; } a.md-print-anchor { white-space: pre !important; border: none !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; text-shadow: initial !important; background-position: 0px 0px !important; } .os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; } .md-diagram-panel > svg { max-width: 100%; } [lang="flow"] svg, [lang="mermaid"] svg { max-width: 100%; height: auto; } [lang="mermaid"] .node text { font-size: 1rem; } table tr th { border-bottom-width: 0px; } video { max-width: 100%; display: block; margin: 0px auto; } iframe { max-width: 100%; width: 100%; border: none; } .highlight td, .highlight tr { border: 0px; } mark { background-color: rgb(255, 255, 0); color: rgb(0, 0, 0); } .md-html-inline .md-plain, .md-html-inline strong, mark .md-inline-math, mark strong { color: inherit; } .md-expand mark .md-meta { opacity: 0.3 !important; } mark .md-meta { color: rgb(0, 0, 0); } @media print { .typora-export h1, .typora-export h2, .typora-export h3, .typora-export h4, .typora-export h5, .typora-export h6 { break-inside: avoid; } } .md-diagram-panel .messageText { stroke: none !important; } .md-diagram-panel .start-state { fill: var(--node-fill); } .md-diagram-panel .edgeLabel rect { opacity: 1 !important; } .md-require-zoom-fix { height: auto; margin-top: 16px; margin-bottom: 16px; } .md-require-zoom-fix foreignObject { font-size: var(--mermaid-font-zoom); } .md-fences.md-fences-math { font-size: 1em; } .md-fences-advanced:not(.md-focus) { padding: 0px; white-space: nowrap; border: 0px; } .md-fences-advanced:not(.md-focus) { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .typora-export-show-outline .typora-export-content { max-width: 1440px; margin: auto; display: flex; flex-direction: row; } .typora-export-sidebar { width: 300px; font-size: 0.8rem; margin-top: 80px; margin-right: 18px; } .typora-export-show-outline #write { --webkit-flex: 2; flex: 2 1 0%; } .typora-export-sidebar .outline-content { position: fixed; top: 0px; max-height: 100%; overflow: hidden auto; padding-bottom: 30px; padding-top: 60px; width: 300px; } @media screen and (max-width: 1024px) { .typora-export-sidebar, .typora-export-sidebar .outline-content { width: 240px; } } @media screen and (max-width: 800px) { .typora-export-sidebar { display: none; } } .outline-content li, .outline-content ul { margin-left: 0px; margin-right: 0px; padding-left: 0px; padding-right: 0px; list-style: none; } .outline-content ul { margin-top: 0px; margin-bottom: 0px; } .outline-content strong { font-weight: 400; } .outline-expander { width: 1rem; height: 1.428571429rem; position: relative; display: table-cell; vertical-align: middle; cursor: pointer; padding-left: 4px; } .outline-expander::before { content: ''; position: relative; font-family: Ionicons; display: inline-block; font-size: 8px; vertical-align: middle; } .outline-item { padding-top: 3px; padding-bottom: 3px; cursor: pointer; } .outline-expander:hover::before { content: ''; } .outline-h1 > .outline-item { padding-left: 0px; } .outline-h2 > .outline-item { padding-left: 1em; } .outline-h3 > .outline-item { padding-left: 2em; } .outline-h4 > .outline-item { padding-left: 3em; } .outline-h5 > .outline-item { padding-left: 4em; } .outline-h6 > .outline-item { padding-left: 5em; } .outline-label { cursor: pointer; display: table-cell; vertical-align: middle; text-decoration: none; color: inherit; } .outline-label:hover { text-decoration: underline; } .outline-item:hover { border-color: rgb(245, 245, 245); background-color: var(--item-hover-bg-color); } .outline-item:hover { margin-left: -28px; margin-right: -28px; border-left-width: 28px; border-left-style: solid; border-left-color: transparent; border-right-width: 28px; border-right-style: solid; border-right-color: transparent; } .outline-item-single .outline-expander::before, .outline-item-single .outline-expander:hover::before { display: none; } .outline-item-open > .outline-item > .outline-expander::before { content: ''; } .outline-children { display: none; } .info-panel-tab-wrapper { display: none; } .outline-item-open > .outline-children { display: block; } .typora-export .outline-item { padding-top: 1px; padding-bottom: 1px; } .typora-export .outline-item:hover { margin-right: -8px; border-right-width: 8px; border-right-style: solid; border-right-color: transparent; } .typora-export .outline-expander::before { content: "+"; font-family: inherit; top: -1px; } .typora-export .outline-expander:hover::before, .typora-export .outline-item-open > .outline-item > .outline-expander::before { content: '−'; } .typora-export-collapse-outline .outline-children { display: none; } .typora-export-collapse-outline .outline-item-open > .outline-children, .typora-export-no-collapse-outline .outline-children { display: block; } .typora-export-no-collapse-outline .outline-expander::before { content: "" !important; } .typora-export-show-outline .outline-item-active > .outline-item .outline-label { font-weight: 700; } .md-inline-math-container mjx-container { zoom: 0.95; } .CodeMirror { height: auto; } .CodeMirror.cm-s-inner { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror-scroll { overflow: auto hidden; z-index: 3; } .CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); } .CodeMirror-gutters { border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; white-space: nowrap; background-position: inherit; background-repeat: inherit; } .CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); } .cm-s-inner .cm-keyword { color: rgb(119, 0, 136); } .cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); } .cm-s-inner .cm-number { color: rgb(17, 102, 68); } .cm-s-inner .cm-def { color: rgb(0, 0, 255); } .cm-s-inner .cm-variable { color: rgb(0, 0, 0); } .cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); } .cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); } .cm-s-inner .cm-string { color: rgb(170, 17, 17); } .cm-s-inner .cm-property { color: rgb(0, 0, 0); } .cm-s-inner .cm-operator { color: rgb(152, 26, 26); } .cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); } .cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); } .cm-s-inner .cm-meta { color: rgb(85, 85, 85); } .cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); } .cm-s-inner .cm-builtin { color: rgb(51, 0, 170); } .cm-s-inner .cm-bracket { color: rgb(153, 153, 119); } .cm-s-inner .cm-tag { color: rgb(17, 119, 0); } .cm-s-inner .cm-attribute { color: rgb(0, 0, 204); } .cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); } .cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); } .cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); } .cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); } .cm-negative { color: rgb(221, 68, 68); } .cm-positive { color: rgb(34, 153, 34); } .cm-header, .cm-strong { font-weight: 700; } .cm-del { text-decoration: line-through; } .cm-em { font-style: italic; } .cm-link { text-decoration: underline; } .cm-error { color: red; } .cm-invalidchar { color: red; } .cm-constant { color: rgb(38, 139, 210); } .cm-defined { color: rgb(181, 137, 0); } div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); } div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); } .cm-s-inner .CodeMirror-activeline-background { background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror { position: relative; overflow: hidden; } .CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: inherit; background-position: inherit; background-repeat: inherit; } .CodeMirror-sizer { position: relative; } .CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; outline: 0px; } .CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; } .CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: auto hidden; } .CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; } .CodeMirror-gutter-filler { left: 0px; bottom: 0px; } .CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 10px; z-index: 3; overflow-y: hidden; } .CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; } .CodeMirror-gutter-wrapper { position: absolute; z-index: 4; border: none !important; background-position: 0px 0px !important; } .CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; } .CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; } .CodeMirror-lines { cursor: text; } .CodeMirror pre { border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; border-width: 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; word-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; background-position: 0px 0px; } .CodeMirror-wrap pre { word-wrap: break-word; white-space: pre-wrap; word-break: normal; } .CodeMirror-code pre { border-right-width: 30px; border-right-style: solid; border-right-color: transparent; width: fit-content; } .CodeMirror-wrap .CodeMirror-code pre { border-right-style: none; width: auto; } .CodeMirror-linebackground { position: absolute; inset: 0px; z-index: 0; } .CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; } .CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; } .CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; } .CodeMirror-measure pre { position: static; } .CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right-style: none; width: 0px; } .CodeMirror div.CodeMirror-cursor { visibility: hidden; } .CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; } .cm-searching { background-color: rgba(255, 255, 0, 0.4); } span.cm-underlined { text-decoration: underline; } span.cm-strikethrough { text-decoration: line-through; } .cm-tw-syntaxerror { color: rgb(255, 255, 255); background-color: rgb(153, 0, 0); } .cm-tw-deleted { text-decoration: line-through; } .cm-tw-header5 { font-weight: 700; } .cm-tw-listitem:first-child { padding-left: 10px; } .cm-tw-box { border-style: solid; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-color: inherit; border-top-width: 0px !important; } .cm-tw-underline { text-decoration: underline; } @media print { .CodeMirror div.CodeMirror-cursor { visibility: hidden; } } :root { --side-bar-bg-color: #fafafa; --control-text-color: #777; } @include-when-export url(https://fonts.loli.net/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext); /* open-sans-regular - latin-ext_latin */ /* open-sans-italic - latin-ext_latin */ /* open-sans-700 - latin-ext_latin */ /* open-sans-700italic - latin-ext_latin */ html { font-size: 16px; -webkit-font-smoothing: antialiased; } body { font-family: "Open Sans","Clear Sans", "Helvetica Neue", Helvetica, Arial, 'Segoe UI Emoji', sans-serif; color: rgb(51, 51, 51); line-height: 1.6; } #write { max-width: 860px; margin: 0 auto; padding: 30px; padding-bottom: 100px; } @media only screen and (min-width: 1400px) { #write { max-width: 1024px; } } @media only screen and (min-width: 1800px) { #write { max-width: 1200px; } } #write > ul:first-child, #write > ol:first-child{ margin-top: 30px; } a { color: #4183C4; } h1, h2, h3, h4, h5, h6 { position: relative; margin-top: 1rem; margin-bottom: 1rem; font-weight: bold; line-height: 1.4; cursor: text; } h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { text-decoration: none; } h1 tt, h1 code { font-size: inherit; } h2 tt, h2 code { font-size: inherit; } h3 tt, h3 code { font-size: inherit; } h4 tt, h4 code { font-size: inherit; } h5 tt, h5 code { font-size: inherit; } h6 tt, h6 code { font-size: inherit; } h1 { font-size: 2.25em; line-height: 1.2; border-bottom: 1px solid #eee; } h2 { font-size: 1.75em; line-height: 1.225; border-bottom: 1px solid #eee; } /*@media print { .typora-export h1, .typora-export h2 { border-bottom: none; padding-bottom: initial; } .typora-export h1::after, .typora-export h2::after { content: ""; display: block; height: 100px; margin-top: -96px; border-top: 1px solid #eee; } }*/ h3 { font-size: 1.5em; line-height: 1.43; } h4 { font-size: 1.25em; } h5 { font-size: 1em; } h6 { font-size: 1em; color: #777; } p, blockquote, ul, ol, dl, table{ margin: 0.8em 0; } li>ol, li>ul { margin: 0 0; } hr { height: 2px; padding: 0; margin: 16px 0; background-color: #e7e7e7; border: 0 none; overflow: hidden; box-sizing: content-box; } li p.first { display: inline-block; } ul, ol { padding-left: 30px; } ul:first-child, ol:first-child { margin-top: 0; } ul:last-child, ol:last-child { margin-bottom: 0; } blockquote { border-left: 4px solid #dfe2e5; padding: 0 15px; color: #777777; } blockquote blockquote { padding-right: 0; } table { padding: 0; word-break: initial; } table tr { border: 1px solid #dfe2e5; margin: 0; padding: 0; } table tr:nth-child(2n), thead { background-color: #f8f8f8; } table th { font-weight: bold; border: 1px solid #dfe2e5; border-bottom: 0; margin: 0; padding: 6px 13px; } table td { border: 1px solid #dfe2e5; margin: 0; padding: 6px 13px; } table th:first-child, table td:first-child { margin-top: 0; } table th:last-child, table td:last-child { margin-bottom: 0; } .CodeMirror-lines { padding-left: 4px; } .code-tooltip { box-shadow: 0 1px 1px 0 rgba(0,28,36,.3); border-top: 1px solid #eef2f2; } .md-fences, code, tt { border: 1px solid #e7eaed; background-color: #f8f8f8; border-radius: 3px; padding: 0; padding: 2px 4px 0px 4px; font-size: 0.9em; } code { background-color: #f3f4f4; padding: 0 2px 0 2px; } .md-fences { margin-bottom: 15px; margin-top: 15px; padding-top: 8px; padding-bottom: 6px; } .md-task-list-item > input { margin-left: -1.3em; } @media print { html { font-size: 13px; } table, pre { page-break-inside: avoid; } pre { word-wrap: break-word; } } .md-fences { background-color: #f8f8f8; } #write pre.md-meta-block { padding: 1rem; font-size: 85%; line-height: 1.45; background-color: #f7f7f7; border: 0; border-radius: 3px; color: #777777; margin-top: 0 !important; } .mathjax-block>.code-tooltip { bottom: .375rem; } .md-mathjax-midline { background: #fafafa; } #write>h3.md-focus:before{ left: -1.5625rem; top: .375rem; } #write>h4.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h5.md-focus:before{ left: -1.5625rem; top: .285714286rem; } #write>h6.md-focus:before{ left: -1.5625rem; top: .285714286rem; } .md-image>.md-meta { /*border: 1px solid #ddd;*/ border-radius: 3px; padding: 2px 0px 0px 4px; font-size: 0.9em; color: inherit; } .md-tag { color: #a7a7a7; opacity: 1; } .md-toc { margin-top:20px; padding-bottom:20px; } .sidebar-tabs { border-bottom: none; } #typora-quick-open { border: 1px solid #ddd; background-color: #f8f8f8; } #typora-quick-open-item { background-color: #FAFAFA; border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee; border-style: solid; border-width: 1px; } /** focus mode */ .on-focus-mode blockquote { border-left-color: rgba(85, 85, 85, 0.12); } header, .context-menu, .megamenu-content, footer{ font-family: "Segoe UI", "Arial", sans-serif; } .file-node-content:hover .file-node-icon, .file-node-content:hover .file-node-open-state{ visibility: visible; } .mac-seamless-mode #typora-sidebar { background-color: #fafafa; background-color: var(--side-bar-bg-color); } .md-lang { color: #b4654d; } /*.html-for-mac { --item-hover-bg-color: #E6F0FE; }*/ #md-notification .btn { border: 0; } .dropdown-menu .divider { border-color: #e5e5e5; opacity: 0.4; } .ty-preferences .window-content { background-color: #fafafa; } .ty-preferences .nav-group-item.active { color: white; background: #999; } .menu-item-container a.menu-style-btn { background-color: #f5f8fa; background-image: linear-gradient( 180deg , hsla(0, 0%, 100%, 0.8), hsla(0, 0%, 100%, 0)); } :root {--mermaid-font-zoom:1em ;} @media print { @page {margin: 0 0 0 0;} body.typora-export {padding-left: 0; padding-right: 0;} #write {padding:0;}} 技术概要:使用 InterSystems 产品优化 SQL 性能使用 InterSystems SQL 优化查询使用 EXPLAIN 关键字显示查询计划在管理门户(Management Portal)中使用 SQL 查询接口显示查询计划发现查询计划结果中潜在的性能问题测试查询执行测试位片索引(Bitslice Index)的效果向交易类型字段(TransactionType Field)添加位图索引(Bitmap Index)重新测试查询性能查看随时间变化的查询性能了解有关 InterSystems SQL 的更多信息介绍材料 技术概要:使用 InterSystems 产品优化 SQL 性能 技术概要:使用 InterSystems 产品优化 SQL 性能 本技术概要(First Look)指南向您介绍了 InterSystems SQL 查询优化,包括查询分析工具的使用,几种索引方法以及随着时间的变化查看运行时统计数据的能力。 要浏览所有的技术概要(First Look),包括其他可以在免费的云实例或 web 实例上执行的技术概要(First Look),请参见 InterSystems First Looks(《InterSystems 技术概要》)。 使用 InterSystems SQL 优化查询 InterSystems IRIS®数据平台为 SQL 查询性能调整提供全套工具: 查询计划分析的图形化显示 如位图和位片索引(bitslice index)等索引策略结构紧凑,可由矢量化 CPU 指令有效处理。每种索引类型都为某些查询类型(如逻辑条件、计数和聚合函数)提供了好处。通过索引,您可以在一个核心上实现每秒多达数十亿行的查询性能结果。 随时间变化的 SQL 查询性能指标 重要提示: 下面演示中显示的查询性能数字代表了在一台 Windows 10 笔记本电脑上进行的多次演示试验。根据您的环境,您可能会看到不同的查询性能数字。 想查看 InterSystems IRIS SQL 功能快速演示吗?请查看 SQL QuickStart(SQL 快速入门)! 用前须知 阅读本文之前,建议阅读并完成 First Look:InterSystems SQL(《技术概要:InterSystems SQL》)。在这里,您将再次使用 InterSystems IRIS SQL Shell;您将使用的数据来自您在技术概要:InterSystems SQL的演示时创建的百万记录股票交易数据表。 您还将运行 TuneTableutility,它检查表中的数据并创建 InterSystems SQL 查询优化器(决定如何最好地运行任何查询的引擎)使用的统计数据。这些统计数据包括表的大小(区段大小)和每列唯一值的数量(选择性)。优化器在决定连接顺序等情况下使用表大小,其中最好从较小的表开始。在表有多个索引的情况下,选择性有助于优化器选择最佳索引。在产品实例中,您通常只运行一次 TuneTable:在数据被加载到表中之后和运行之前。 演示:显示和解释优化前的查询计划 First Look:InterSystems SQL (《技术概要:InterSystems SQL》)解释了如何执行在技术概要(First Look)和此处运行演示所需的以下步骤: 选择一个 InterSystems IRIS 实例。您的选择包括多种类型的已授权的和免费的评估实例;关于如何部署每种类型的信息,请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。 打开 InterSystems 终端(Terminal)(简称终端(Terminal))来运行 SQL Shell。 从 GitHub repo https://github.com/intersystems/FirstLook-SQLBasics 获取本指南的实用程序文件和数据,包括 stock_table_demo_two.csv,其中包含一百万行股票表数据 Loader.xml,是一个包含实用程序方法的类文件,用于将 Stock_table_demo_two.csv 中的数据加载到InterSystems IRIS 表中。 运行 TuneTable 实用程序 如果您的 InterSystems IRIS 实例不再包含 StockTableDemoTwotable,请按照 Demo:Using Bitmap Indexing To Maximize Query Performance(《演示:使用位图索引最大化查询性能》)(在执行 SELECT DISTINCT 查询之前停止)的前四个步骤重新创建并加载它。 在 SQL Shell 中,在 FirstLook.StockTableDemoTwo 上运行 TuneTable 实用程序,如下所示: OBJ DO $SYSTEM.SQL.TuneTable("FirstLook.StockTableDemoTwo") 该命令在 SQL Shell 中不会生成可见的输出。 使用 EXPLAIN 关键字显示查询计划 这个演示假设您想获得所有"SELL"交易的平均价格。鉴于该表包含一百万条记录,所需的查询有可能非常慢。 虽然您可能已经想在 Price 和 TransactionType 字段上创建索引,但在开始优化工作之前,查看查询计划将具有指导意义。在 SQL Shell 中,您可以通过在查询前添加 EXPLAIN 关键字来显示查询计划。查询计划显示 SQL 查询优化器将如何使用索引(如果有索引的话),或者是否将直接读取表数据来执行语句。 要使用 EXPLAIN 关键字来显示查询计划,在 SQL Shell 中执行以下语句: EXPLAIN SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' 这将返回格式为 XML 的查询计划: xxxxxxxxxx Plan "<plans> <plan> <sql> SELECT AVG ( Price ) AS AveragePrice FROM FirstLook . StockTableDemoTwo WHERE TransactionType = ? /*#OPTIONS {""DynamicSQLTypeList"":""1""} */ </sql> <cost value=""1827000""/> Call module B. Output the row. <module name=""B"" top=""1""> Process query in parallel, partitioning master map FirstLook.StockTableDemoTwo.IDKEY into subranges of T1.ID values, piping results to temp-file A: SELECT count(T1.Price),sum(T1.Price) FROM %NOPARALLEL FirstLook.StockTableDemoTwo T1 where ((%SQLUPPER(T1.TransactionType) = %SQLUPPER(?))) Read temp-file A, looping on a counter. For each row: Accumulate the count([value]). Accumulate the sum([value]). </module> 演示:显示和解释优化前的查询计划 </plan> <plan> <sql> SELECT COUNT ( T1 . Price ) , SUM ( T1 . Price ) FROM %NOPARALLEL FirstLook . StockTableDemoTwo T1 WHERE ( ( %SQLUPPER ( T1 . TransactionType ) = %SQLUPPER ( ? ) ) ) %PARTITION BY T1 . ID > ? AND T1 . ID <= ? </sql> <cost value=""1827000""/> Call module B. Output the row. <module name=""B"" top=""1""> Read master map FirstLook.StockTableDemoTwo.IDKEY, looping on ID (with a range condition). For each row: Accumulate the count(Price). Accumulate the sum(Price). </module> </plan> </plans>" 您将看到为执行 SQL 查询而生成的查询计划可以分为多个模块,每个模块都执行计划的不同部分,例如评估子查询。 实际上,这个查询计划被分为两个独立的计划。顶部计划用于初始查询。它调用一个模块 B,在这个模块中,其中"主映射"被分区,并在每个分区上并行执行子查询。子查询的计划遵循初始查询的计划。 在 "Spotting Potential Performance Issues in Query Plan Results(在查询计划结果中发现潜在的性能问题)"中,您将学习如何识别这个查询的问题。 在管理门户(Management Portal)中使用 SQL 查询接口显示查询计划 InterSystems IRIS 在管理门户(Management Portal)中提供了一个基于 web 的接口,用于 SQL 查询执行和计划分析。要使用管理门户(Management Portal)中的 SQL 查询接口显示查询计划: 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中URL described for your instance(为您的实例描述的 URL),在浏览器中打开您的实例的管理门户(Management Portal)。 请确保您是在 USER 命名空间。 如果您还没有找到,可以: 在屏幕的顶部面板中,点击当前命名空间名称右侧的 SWITCH(交换)。 在弹出的窗口中,选择 USER(用户) 并点击 OK(确定)。 导航到 SQL 页面(System Explorer(系统资源管理器) > SQL)。 省略 EXPLAIN 关键字,将"Using the EXPLAIN Keyword to Show a Query Plan(使用 EXPLAIN 关键字显示查询计划)中的查询粘贴到 Execute Query(执行查询) 标签的文本字段中。 点击 Show Plan(显示计划) 来显示查询计划。 结果将如下所示: 解释这些结果是下一节的主题。 发现查询计划结果中潜在的性能问题 查看查询计划结果,您可以看到这个查询存在一些严重的潜在性能问题。如果您查看子查询的计划,也就是实际工作完成的地方,您可以看到第一个任务是 "读取主映射"。这意味着 InterSystems SQL 查询优化器不会使用任何索引来运行查询; 演示:测试查询优化 相反,查询将遍历表中的所有 ID。特别是在大表的情况下,这表明查询将不能很好地执行。 当您优化查询时,您会看到它的执行时间减少,查询计划也会有明显的变化。 注意: 相对成本可以很好地预测性能,但只是相对于某个特定的查询而言。如果您在表中添加了一个索引,并且看到相对成本下降了,那么很可能这个查询现在会运行得更快。然而,相对成本并不是为了比较两个不同查询的性能。 测试查询执行 要获取有关未优化查询将如何执行的一些实际数据,请在 SQL Shell 中运行它: SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' GO 输出将如下所示: xxxxxxxxxx AveragePrice 266.1595139195757844 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0009s/6/1246/0ms execute time(s)/globals/cmds/disk: 0.2599s/1000075/8502571/0ms cached query class: %sqlcq.USER.cls5 语句准备和执行指标分别列出。特别注意以下两项: 执行时间为 0.2599 秒。虽然这个时间看起来并不算长,但可以通过使用索引大大改善。 在执行步骤中读取的 globals 数量为 1,000,075。(Globals 是 InterSystems IRIS 用来存储数据的多维稀疏数组(multidimensional sparse arrays);更多信息,请参见 Introduction to InterSystems IRIS Programming(《InterSystems IRIS 编程简介》)中的Introduction to Globals(Globals 简介)一章。为了提高查询性能,应该减少这个数字。您会在下一节看到这种情况。 重要提示: 准备工作只需一次:第一次重新规划查询。如果修改了相关表或添加或删除了索引,查询将自动重新规划。大多数应用程序只准备一次查询,但会多次执行。因此,在这个演示中,我们的重点将是调整执行性能。 演示:测试查询优化 向价格字段添加位片索引(Bitslice Index) 如果您的查询将包含一个或多个字段上的聚合函数,那么为这些字段中的一个或多个字段添加位片索引(bitslice index)可能会提高性能。 位片索引(bitslice index)将字段中的每个数字数据值表示为二进制位字符串,二进制值中的每个数字都有一个位图,以记录哪些行的二进制数字为 1。 因为我们想要获得所有"SELL"交易的平均价格,所以在 Price 字段中添加一个位片索引(bitslice index)是有意义的。要在 Price 字段上创建位片索引(bitslice index) PriceIdx,请在 SQL Shell 中执行以下语句: 演示:测试查询优化 CREATE BITSLICE INDEX PriceIdx ON TABLE FirstLook.StockTableDemoTwo (Price) CREATE BITSLICE INDEX PriceIdx ON TABLE FirstLook.StockTableDemoTwo (Price) xxxxxxxxxx 0 Rows Affected statement prepare time(s)/globals/cmds/disk: 0.0091s/2000/13151/0ms execute time(s)/globals/cmds/disk: 1.4268s/2087789/55765062/1ms cached query class: %sqlcq.USER.cls7 但是,正如您将在下面看到的,仅仅因为您创建了索引并不一定意味着 InterSystems SQL 查询优化器会使用它 。 测试位片索引(Bitslice Index)的效果 要查看新的位片索引(bitslice index)是否会对查询的执行方式或运行速度产生任何影响,请使用上述任何一种方法(SQL Shell 或管理门户(Management Portal))来显示查询计划。 正如您将看到的,查询计划仍然与以前相同。InterSystems SQL 查询优化器将不会使用新的索引。 运行查询产生的性能统计数据与您创建位片索引(bitslice index)之前几乎相同(0.2559 秒的执行时间与 0.2599 秒相比)。InterSystems IRIS 智能地缓存查询计划和数据,因此同一查询的后续运行可能会提高性能,鉴于查询性能时间略有不同,这里可能就是这种情况。 在机器上运行的其他应用程序也会影响性能。 SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' GO SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' xxxxxxxxxx AveragePrice 266.1595139195757844 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0569s/35431/227191/0ms execute time(s)/globals/cmds/disk: 0.2559s/1000075/8502571/0ms cached query class: %sqlcq.USER.cls8 如果从查询中删除 WHERE 子句,当您显示查询计划时,将会看到完全不同的结果: 如您所见,读取位片索引(bitslice index)是查询计划的第一步。在这个计划中没有读取到"总映射"。 SQL 查询优化器也使用第二个索引 FirstLook.StockTableDemoTwo.$StockTableDemoTwo。这是位图范围索引, 在执行 CREATE TABLESQL 语句时自动创建。它是表中所有行的位图索引(bitmap index),而不仅仅是一个字段,每个位的值反映了该行是否实际存在。 演示:测试查询优化 然而,我们真正想要运行的查询包含一个 WHERE 子句。因此,我们必须找到一种方法,让 SQL 查询优化器在 WHERE 子句存在时使用索引。 向交易类型字段(TransactionType Field)添加位图索引(Bitmap Index) 如果您阅读了 InterSystems SQL Optimization Guide(《InterSystems SQL 优化指南》),您会发现 InterSystems SQL 查询优化器在与 WHERE 子句字段上的位图索引(bitmap index)结合使用时,通常会使用位片索引(bitslice index)。 这是因为没有 WHERE 子句的聚合查询可以简单地聚合索引中的所有数据。然而,为了只聚合满足 WHERE 条件的行,查询必须掩码那些不满足条件的行的位片索引(bitslice index)的位。在 WHERE 子句中的字段上有一个位图索引(bitmap index),允许有效地构建这个掩码。 幸运的是,查询中的另一个字段 TransactionType 是位图索引(bitmap index)的一个很好的候选者,因为它的可能值计数是两个("SELL"和"BUY")。 要向 TransactionType 字段添加位图索引(bitmap index),请在 SQL Shell 中执行以下语句: CREATE BITMAP INDEX TransactionTypeIdx ON TABLE FirstLook.StockTableDemoTwo (TransactionType) CREATE BITMAP INDEX TransactionTypeIdx ON TABLE FirstLook.StockTableDemoTwo (TransactionType) xxxxxxxxxx 0 Rows Affected statement prepare time(s)/globals/cmds/disk: 0.0069s/2001/13291/0ms execute time(s)/globals/cmds/disk: 1.1046s/2088960/19771584/0ms cached query class: %sqlcq.USER.cls7 重新测试查询性能 现在,您已经添加了位片索引(bitslice index)和位图索引(bitmap index):如果您显示的查询计划 SELECT AVG(Price) as AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' 在 SQL Shell 或管理门户(Management Portal)中,您会看到查询优化器使用您创建的两个索引来获得最佳性能。 还请注意,18742 的相对成本只是未优化查询的一小部分,其成本为 1827000。 演示:测试查询优化 最后,如果您在 SQL Shell 中运行这个查询,您会看到对 globals 的更有效使用(594 而不是 1000075)。 最关键的是,有索引的查询运行速度比无索引的查询快了近 85 倍(执行时间为 0.0031 秒,而非 0.2599)。 查看随时间变化的查询性能 SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' GO SELECT AVG(Price) As AveragePrice FROM FirstLook.StockTableDemoTwo WHERE TransactionType = 'SELL' xxxxxxxxxx AveragePrice 266.1595139195757844 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0554s/34877/186130/0ms execute time(s)/globals/cmds/disk: 0.0031s/594/2878/0ms cached query class: %sqlcq.USER.cls8 为了随时间跟踪查询的性能,InterSystems IRIS 提供了查询统计数据,您将在下一节了解如何查看这些数据。 查看随时间变化的查询性能 要跟踪运行缓慢的查询或查看新查询在产品中的运行情况,您可以使用管理门户(Management Portal)中的 SQL Statements(SQL 语句)视图。要导航到这个视图,在管理门户(Management Portal)中打开 SQL 查询接口,并点击 SQL Statements(SQL语句)。 例如,如果您上面调整的查询在其原始(未优化的)计划下运行了 9 次,您可能会看到类似这样的结果: 点击 SQL Statement Text column(SQL 语句文本列)中的语句链接, 允许您以 SQL 形式查看查询: 您还可以使用缓存查询类的名称将 SQL 语句执行与 SQL Statements(SQL 语句)视图联系起来,该名称是 SQL Shell 中输出的最后一行,并列在 SQL Statements(SQL 语句) 的 Location(s)(位置)列中。 在您优化查询并运行几次后,您可以期望看到 Total time(总时间)和 Average time(平均时间)的改善列。 了解有关 InterSystems SQL 的更多信息 请注意,Count(计数)的值已经下降。这是因为位图和位片索引(bitslice index)的添加引起了查询计划的改变,这反过来又触发了对相关类的缓存查询的删除。该查询在新查询计划下总共运行了 8 次,平均每天 4 次。 了解有关 InterSystems SQL 的更多信息 要了解更多有关 SQL 和 InterSystems IRIS 的信息,请参见: 介绍材料 First Look:InterSystems SQL(《技术概要:InterSystems SQL》) Using InterSystems SQL(《使用 InterSystems SQL》) InterSystems SQL Reference(《InterSystems SQL 参考书目》) InterSystems SQL Overview(《InterSystems SQL 概述》) SQL 开发 SQL -- Things You Should Know(《SQL -- 您应该知道的事情》) Developing with InterSystems Objects and SQL(《使用 InterSystems Objects 和 SQL 开发》) 查询优化 InterSystems SQL Optimization Guide(《InterSystems SQL 优化指南》) Optimizing SQL Queries(《优化 SQL 查询》) 分片和可扩展性 First Look:Scaling for Data Volume with Sharding(《技术概要:带分片的数据卷扩展》) Scalability Guide(《可扩展性指南》) SQL 搜索 First Look:SQL Search with InterSystems IRIS(《技术概要:使用 InterSystems IRIS 进行 SQL 搜索》) Using InterSystems SQL Search(《使用 InterSystems SQL 搜索》) Creating iFind Indices for Searching Text Fields(《创建用于搜索文本字段的 iFind 索引》) JDBC First Look:JDBC and InterSystems IRIS (《技术概要:JDBC 和 InterSystems IRIS》) Using Java JDBC with InterSystems IRIS(《在 InterSystems IRIS 中使用 Java JDBC》)<文档> Java Overview (《Java 概述》) 了解有关 InterSystems SQL 的更多信息 Using JDBC with InterSystems IRIS(《在 InterSystems IRIS 中使用 JDBC》) <在线学习>
文章
jieliang liu · 九月 22, 2021

IRIS 2021 技术文档 First Look 9--ADO.NET 和 InterSystems 产品

技术概要:ADO.NET 和 InterSystems 产品 本技术概要(First Look)解释了如何通过 InterSystems ADO.NET Managed Provider 连接到 InterSystems IRIS®数据平台。一旦根据本指南完成操作,就意味着您已经配置了一个 Visual Studio 项目来使用 InterSystems.Data.IRISClient.dll 程序集,建立了到 InterSystems IRIS 的 ADO.NET 连接,从您的 .NET 应用程序运行多个 SQL 语句,并在 InterSystems IRIS 系统管理门户(InterSystems IRIS System Management Portal)中确认这些语句的效果。 为了让您体验一下 ADO.NET Managed Provider,而又不陷入细节的困境,我们会确保这一探索简洁可行。这些活动被设计成只使用默认设置和功能,这样您就可以熟悉功能的基本原理,而不必处理那些离题或过于复杂的细节。当您将 ADO.NET 引入您的生产系统时,您可能需要做一些不同的事情。请确保不要把这种对 ADO.NET 的探索与真实的东西混淆起来! 本文档末尾提供的参考资料将使您对在生产中使用 ADO.NET 所涉及的内容有一个很好的了解。 有关 ADO.NET 的更多文档,请参见结尾处的 Learn More About ADO.NET(了解更多有关 ADO.NET 的信息)。 要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 为什么 ADO.NET 很重要 ADO.NET 是来自 Microsoft .NET Framework 的数据访问技术,提供对数据源的访问。它用于建立数据库连接,并为 .NET Framework 程序员提供一种标准、可靠的方式,来连接到多种类型的数据源或使用 SQL 对它们进行操作。通过 ADO.NET Managed Provider 连接到 InterSystems IRIS 很简单,特别是如果您以前使用过 ADO.NET。从 .NET 应用程序建立到 InterSystems IRIS 的 ADO.NET 连接,允许您从 .NET 应用程序对 InterSystems IRIS 数据库运行 SQL 命令。 如果您是 InterSystems IRIS 的新手,但熟悉 .NET 和 SQL,您可以立即使用现有的专业知识来帮助您熟悉数据库平台。您可以在开发环境中测试 ADO.NET 连接和 SQL 命令,只需几行代码。 ADO.NET 和 InterSystems IRIS InterSystems IRIS 是完全符合 ADO.NET 规范的实现。InterSystems ADO.NET Managed Provider 提供对数据的简单关系访问。它处理来自应用程序的 ADO.NET 方法调用,并向 InterSystems IRIS 提交 SQL 请求。然后将结果返回给调用的应用程序------在本例中,就是您的 .NET 应用程序。 通过 ADO.NET 连接到 InterSystems IRIS 是一个非常简单的过程。 为了使用 InterSystems IRIS ADO.NET 功能,您必须首先将 InterSystems.Data.IRISClient.dll 程序集作为依赖项添加到 Visual Studio 项目中。确认一些设置后,使用我们的示例代码建立到 InterSystems IRIS 的 ADO.NET 探索 ADO.NET 连接,并执行 SQL 查询。请注意,InterSystems.Data.IRISClient.dll 程序集自始至终都是使用 .NET 管理代码实现的,这使得在 .NET 环境中部署它很容易。它是线程安全(thread-safe)的 ,可以在多线程的 .NET 应用程序中使用。 探索 ADO.NET 我们开发了一个简短的演示,向您展示如何使用 ADO.NET 和 InterSystems IRIS。(想试试 InterSystems IRIS .NET 开发和互操作性功能的在线视频演示?请看.NET QuickStart(.NET 快速入门)!) 用前须知 要使用这个程序,您需要一个安装了 .NET 框架和 Visual Studio 的 Windows 系统,以及一个运行中的 InterSystems IRIS 实例来连接。您对 InterSystems IRIS 的选择包括多种类型的已授权的和免费的评估实例;实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。有关如何部署每种类型的实例的信息(如果您还没有可使用的实例) ,请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。使用同一文档中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)和 .Net IDE 中的信息将 Visual Studio 连接到您的 InterSystems IRIS 实例。 配置 Visual Studio 项目 在 Visual Studio 主菜单中,通过选择 File(文件) > New (新的)> Project(项目)创建一个新项目。在出现的对话框中,点击 Visual C# 选项,并选择 Console App (.NET Framework)(控制台应用程序(.NET 框架))。对于 Name(名称) 字段,输入 ADONET。点击 OK(確定)。这将使用 .NET Framework 创建一个新的控制台(console)应用程序。 下一步,在 Visual Studio 主菜单中,选择 Project(项目) > ADONET Properties(ADONET 属性)。在 Target framework(目标框架)下,选择 .NET Framework 4.5(.NET 框架 4.5)。 添加程序集引用 InterSystems.Data.IRISClient.dll 程序集必须安装在您的本地系统上。您可以通过克隆 repo https://github.com/intersystems/quickstarts-dotnet/tree/master/EFPlay/bin/Debug 或从该 repo 下载文件来获取它。如果 InterSystems IRIS 安装在您的本地系统或您可以访问的另一个系统上,则该程序集已经安装在子目录 install-dirdevdotnetbinv4.5 中,其中 install-dir 是该实例的安装目录。 要将 InterSystems.Data.IRISClient.dll 的程序集引用添加到项目: 从 Visual Studio 主菜单中,选择 Project(项目) > Add Reference(添加引用)... 在出现的窗口中,点击 Browse(浏览).... 浏览到 InterSystems.Data.IRISClient.dll 文件的位置。 选择文件并点击 Add(添加)。 点击 OK(確定)。 在 Visual Studio Solution Explorer 中, InterSystems.Data.IRISClient.dll 程序集现在应该列在 Reference(引用)下。 探索 ADO.NET 通过 ADO.NET 连接 现在,您可以从 .NET 应用程序连接到 InterSystems IRIS 了。InterSystems ADO.NET Managed Provider 的连接字符串是由定义连接属性的键/值对组成的。连接字符串的语法是: Server=host_IP; Port=superserverPort; Namespace=namespace; Password=password; User ID=username; 其中的变量表示 InterSystems IRIS 实例主机的 IP 地址、实例的超级服务器端口、实例上的命名空间和实例的凭据(credentials)。这与您在连接 Visual Studio 到您的实例时使用的信息相同,如用前须知中所述。 将其粘贴到 Visual Studio 后,在随后的代码中更新该信息。您可以将命名空间设置为预定义的命名空间 USER,如所示,或者设置为您在已安装的实例上创建的另一个命名空间。 using System; ​ using InterSystems.Data.IRISClient; ​ namespace ADONET ​ { ​ class Program ​ { ​ static void Main(string[] args) ​ { ​ String host = "<host>"; String port = "<port>"; ​ String username = "<username>"; String password = "<password>"; String Namespace = "USER"; ​ IRISConnection IRISConnect = new IRISConnection(); IRISConnect.ConnectionString = "Server = " + host ​ + "; Port = " + port + "; Namespace = " + Namespace ​ + "; Password = " + password + "; User ID = " + username; ​ IRISConnect.Open(); ​ String sqlStatement1 = "CREATE TABLE People(ID int, FirstName varchar(255), LastName varchar(255))"; ​ String sqlStatement2 = "INSERT INTO People VALUES (1, 'John', 'Smith')"; String sqlStatement3 = "INSERT INTO People VALUES (2, 'Jane', 'Doe')"; String queryString = "SELECT * FROM People"; ​ IRISCommand cmd1 = new IRISCommand(sqlStatement1, IRISConnect); IRISCommand cmd2 = new IRISCommand(sqlStatement2, IRISConnect); IRISCommand cmd3 = new IRISCommand(sqlStatement3, IRISConnect); IRISCommand cmd4 = new IRISCommand(queryString, IRISConnect); ​ //ExecuteNonQuery() is used for CREATE, INSERT, UPDATE, and DELETE SQL Statements cmd1.ExecuteNonQuery(); ​ cmd2.ExecuteNonQuery(); cmd3.ExecuteNonQuery(); ​ //ExecuteReader() is used for SELECT IRISDataReader Reader = cmd4.ExecuteReader(); ​ Console.WriteLine("Printing out contents of SELECT query: "); while (Reader.Read()) ​ { ​ + ", " ​ Console.WriteLine(Reader.GetValue(0).ToString() + ", " + Reader.GetValue(1).ToString() ​ + Reader.GetValue(2).ToString()); ​ } ​ Reader.Close(); cmd1.Dispose(); cmd2.Dispose(); cmd3.Dispose(); cmd4.Dispose(); IRISConnect.Close(); ​ Console.WriteLine("Press any key to continue..."); ​ Console.ReadKey(); ​ } ​ } ​ } 通过点击 Start(开始)按钮,或按 F5 键来运行代码。 如果连接和查询已经成功完成,您应该会看到一个控制台(console)窗口,其中包含 SELECT 查询的结果。 确认管理门户(Management Portal)的变更 接下来,使用以下程序在管理门户(Management Portal)中确认您的结果: 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中为您的实例描述的 URL ,在浏览器中打开您的实例的管理门户(Management Portal)。 如果您不在代码指定的命名空间中,请切换到该命名空间(点击页面顶部 Namespace(命名空间):指示器旁边的 Switch(切换))。 导航到 SQL 页面(System Explorer(系统资源管理器) > SQL),然后点击 Execute Query(执行查询)标签,并粘贴以下 SQL 查询: SELECT ID, FirstName, LastName FROM SQLUser.People 点击 Execute(执行)。该页面应该显示在示例代码中创建的 People 表的内容。 了解更多有关 ADO.NET 的信息 要了解更多有关 ADO.NET、SQL 和 InterSystems IRIS 的信息请参见: Using the InterSystems Managed Provider for .NET(《使用 .NET 的 InterSystems Managed Provider》) Using InterSystems SQL(《使用 InterSystems SQL》) ADO.NET Overview(《ADO.NET 概述》)
文章
Hao Ma · 十一月 2, 2021

IRIS 2021 技术文档 First Look 13 - InterSystems IRIS Native API for Java

本文档解释了如何使用 InterSystems IRIS Native 功能从 Java 应用程序中访问 InterSystems IRIS®数据平台的 globals。在本文中,您将首先连接到 InterSystems IRIS。然后您将在 InterSystems IRIS 中设置和检索一个 global 节点的值,并在另一个 global 节点上进行迭代。您还将调用 InterSystems IRIS 类方法。所有这些活动都将在 Java 应用程序中执行。为了让您体验 IRIS Native,而又不陷入细节困境,本次探索特意设计得很简单。这些活动被设计成只使用默认设置和功能,这样您就可以熟悉功能的基本原理,而不必处理那些离题或过于复杂的细节。当您把 IRIS Native 引入您的生产系统时,您可能需要做一些不同的事情。请确保不要把这种对 IRIS Native 的探索与真实的情况相混淆! 本文档末尾提供的参考资料将使您对在生产中使用 IRIS Native 的情况有一个很好的了解。要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 1 Globals 简介Globals 提供了一种易于使用的方式,来存储持久化多维数组中的数据。Global 是存储在 InterSystems IRIS 物理数据库中的命名多维数组。在应用程序中,globals 到物理数据库的映射基于当前命名空间,命名空间提供一个或多个物理数据库的逻辑统一视图。例如,要使用一个名为 ^Settings 的 global 将值 "Red"与键 "Color"关联起来,请使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础: 连接一个 IDE》)中的procedure described for your instance(为您的实例描述的程序),打开 InterSystems 终端(InterSystems Terminal),并输入以下代码:set ^Settings("Color")="Red" 您可以利用 globals 的多维特性来定义一个更复杂的结构: set ^Settings("Auto1","Properties","Color") = "Red" set ^Settings("Auto1","Properties","Model") = "SUV" set ^Settings("Auto2","Owner") = "Mo"set ^Settings("Auto2","Properties","Color") = "Green" 有关 globals 的更多信息,请参见 Using Globals(《使用 globals》)。 2 为什么 IRIS Native 很重要?IRIS Native 是建立在 InterSystems IRIS JDBC 功能之上的一项功能,它允许您执行核心类 ObjectScript 命令的有限子集,并使用 globals 访问 InterSystems IRIS 数据,类似于在 InterSystems 终端(InterSystems Terminal)中使用的方式。该功能利用 JDBC 连接(JDBC connection)在 Java 应用程序中暴露(expose)核心 ObjectScript 功能。重要的是,由于 IRIS Native 使用与 JDBC 相同的连接,因此 InterSystems IRIS 数据通过 JDBC 作为关系表暴露(expose)给 Java 应用程序,通过 IRIS Native 作为 globals 暴露(expose)给 Java 应用程序。 探索 IRIS Native InterSystems IRIS 提供了一组独特的功能,可以使用相同的物理连接和事务环境来使用多个范例(本机、关系和面向对象)操作数据。 3 探索 IRIS Native以下向您简短演示如何在 Java 应用程序中使用 IRIS Native。(想试试 InterSystems IRIS Java 开发和互操作性功能的在线视频演示吗?请看 Java QuickStart(Java快速入门)!) 3.1 用前须知要使用该程序,您需要在一个系统上工作,安装 JDK 1.8 版本和您选择的 Java IDE,并连接一个正在运行的 InterSystems IRIS 实例。您对 InterSystems IRIS 的选择包括多种已授权的和免费的评估实例;实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。使用同一文档中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)和 Java IDE 中的信息,将 IDE 连接到您的 InterSystems IRIS 实例。您还需要将 InterSystems IRIS JDBC 驱动程序 intersystems-jdbc-3.0.0.jar 添加到您的本地 CLASSPATH。您可以从https://github.com/intersystems/quickstarts-java/tree/master/lib下载这个文件。如果您已经在本地系统或您能访问的另一个系统上安装了 InterSystems IRIS,您可以在 install-dir\dev\java\lib\JDK18 中找到该文件,其中 install-dir 是 InterSystems IRIS 的安装目录。3.2 连接 InterSystems IRIS InterSystems IRIS 连接字符串的语法是:jdbc:IRIS://host_IP:superserverPort/namespace,username,password其中的变量表示在 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中connection settings described for your instance(为您的实例描述的连接设置)——这与您将 IDE 连接到实例时使用的信息相同。将命名空间设置为预定义的命名空间 USER,如下面的代码所示,或者设置为您在安装的实例中创建的另一个命名空间(只要您更新代码)。如果您连接到本地 Windows 系统上的实例(使用主机名 localhost 或 IP 地址 127.0.0.1),该连接会自动使用一种特殊的、高性能的本地连接,称为shared memory connection(共享内存连接),它为 IRIS Native 提供了更好的性能。有关更多信息,请参见 First Look:JDBC and InterSystems IRIS(技术概要: JDBC 和 InterSystems IRIS)。3.3 使用 IRIS Native现在,您已经准备好试验 IRIS Native 了。在您已连接的 IDE 中(请参见 “用前须知”),创建一个名为 IRISNative 的新 Java 项目,并粘贴以下代码。确保编辑变量superserverPort(超级服务端口)、username(用户名)、namespace(命名空间)和password(密码),以反映您实例的正确值。import java.sql.DriverManager;import com.intersystems.jdbc.IRISConnection; import com.intersystems.jdbc.IRIS;import com.intersystems.jdbc.IRISIterator; public class IRISNative {protected static int superserverPort = 00000; // YOUR PORT HERE protected static String namespace = "USER"; 探索 IRIS Native protected static String username = "_SYSTEM"; protected static String password = "SYS";public static void main(String[] args) { try {// open connection to InterSystems IRIS instance using connection string IRISConnection conn = (IRISConnection) DriverManager.getConnection("jdbc:IRIS://localhost:"+superserverPort+"/"+namespace,username,password);// create IRIS Native objectIRIS iris = IRIS.createIRIS(conn); System.out.println("[1. Setting and getting a global]");// setting and getting a global// ObjectScript equivalent: set ^testglobal("1") = 8888 iris.set(8888,"^testglobal","1");// ObjectScript equivalent: set globalValue = $get(^testglobal("1")) Integer globalValue = iris.getInteger("^testglobal","1");System.out.println("The value of ^testglobal(1) is " + globalValue); System.out.println(); System.out.println("[2. Iterating over a global]");// modify global to iterate over// ObjectScript equivalent: set ^testglobal("1") = 8888// ObjectScript equivalent: set ^testglobal("2") = 9999 iris.set(8888,"^testglobal","1");iris.set(9999,"^testglobal","2");// iterate over all nodes forwardsIRISIterator subscriptIter = iris.getIRISIterator("^testglobal"); System.out.println("walk forwards");while (subscriptIter.hasNext()) {String subscript = subscriptIter.next(); System.out.println("subscript="+subscript+", value="+subscriptIter.getValue());}System.out.println();System.out.println("[3. Calling a class method]");// calling a class method// ObjectScript equivalent: set returnValue = ##class(%Library.Utility).Date(5) String returnValue = iris.classMethodString("%Library.Utility","Date",5); System.out.println(returnValue);System.out.println();// close connection and IRIS object iris.close();conn.close();} catch (Exception ex) { System.out.println(ex.getMessage());}}} 示例代码分为三个部分:1. 第一部分展示了如何设置一个 global 值以及稍后如何检索它。这部分里面执行的命令等同于 ObjectScript 的 SET 和 GET 命令。2. 第二部分展示了如何迭代 global 的子节点(subnode),类似于 $ORDER ObjectScript 函数。3. 第三部分展示了如何使用 IRIS Native 从您的 Java 应用程序调用 ObjectScript 类方法(class method)。 如果示例执行成功,您应该会看到带有示例代码结果的输出: 了解有关 IRIS Native 的更多信息 [1.Setting and getting a global] The value of ^testglobal(1) is 8888[2.Iterating over a global] walk forwardssubscript=1, value=8888 subscript=2, value=9999[3.Calling a class method] Jan 30, 2018 3.4 确认管理门户(Management Portal)的变更接下来,使用以下程序在管理门户(Management Portal)中确认您的结果。1. 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中URL described for your instance(为您的实例描述的 URL),在浏览器中打开您实例的管理门户(Management Portal)。2. 如果您不在代码指定的命名空间中,请切换到该命名空间。3. 导航到 Globals 页面(System Explorer(系统资源管理器) > Globals)。您应该会看到在示例代码中创建的 testglobal。点击 View(查看) 来查看其内容。 您应该会看到 global 的两个节点:^testglobal(1) = 8888 和^testglobal(2) = 9999。 4 了解有关 IRIS Native 的更多信息有关 IRIS Native、globals 和 InterSystems IRIS 的更多信息,请参见:First Look:JDBC and InterSystems IRIS(《技术概要:JDBC 和 InterSystems IRIS》)Using Globals(《使用 Globals》)Using the Native API for Java(《使用 Native API for Java》)
文章
Hao Ma · 十一月 2, 2021

IRIS 2021 技术文档 First Look 18 - 在 InterSystems 产品中开发 REST 接口

本文档将向您展示如何开发 REST 接口。您可以将这些 REST 接口与 UI 工具(如 Angular)一起使用,以提供对数据库和互操作性产品的访问。您也可以使用它们支持外部系统访问 InterSystems IRIS®数据平台应用程序。要浏览所有的技术概要(First Look),包括可以在 InterSystems IRIS 免费的评估实例上执行的那些,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 1 为什么提供 REST 接口如果您需要从外部系统访问 InterSystems IRIS 数据库中的数据,或者想为这些数据提供用户界面,您可以通过定义 REST 接口来实现。REST——REpresentational State Transfer——是一种使用公开的 URL 从另一个系统检索、添加、更新或删除数据的方法。REST 基于 HTTP,并使用 HTTP 动词 POST、GET、PUT 和 DELETE 映射到数据库应用程序常见的创建、读取、更新和删除 (CRUD)功能。您还可以在 REST 中使用其他 HTTP 动词,如 HEAD、PATCH 和 OPTIONS。REST 是在应用程序之间共享数据的众多方式之一,因此,如果您选择直接使用其他协议,如 TCP、SOAP 或 FTP 进行通信,则您可能并不总是需要设置 REST 服务。但是使用 REST 有以下优点:• REST 通常只有一个很小的开销(overhead)。它通常使用 JSON,这是一个轻量级的数据包装器。JSON 使用标签标识数据,但标签未在正式模式定义中指定,也没有显式的数据类型。REST 通常比 SOAP 更易于使用,SOAP 使用 XML 且开销(overhead)更大。• 通过在 REST 中定义一个接口,可以很容易地将客户端和数据库服务器之间的依赖关系降到最低。这使您可以在不影响数据库实现的情况下更新用户界面。您还可以在不影响用户界面或访问 REST API 任何外部应用程序的情况下更新数据库实现(database implementation)。 2 对 InterSystems IRIS 的 REST 调用 在定义 REST 接口之前,您应该了解 REST 调用如何流经 InterSystems IRIS。首先,考虑 REST 调用的部分,如:GET http://localhost:52773/rest/coffeemakerapp/coffeemakers 这由以下部分组成:• GET——这是 http 动词。• http:——这指定了通信协议。• //localhost:52773——这指定了托管 REST 接口的 InterSystems IRIS 实例的服务器和端口号。 如何在 InterSystems IRIS 中定义 REST 接口 • /rest/coffeemakerapp/coffeemakers——这是 URL 的主要部分,标识了 REST 调用所指向的资源。在下面的讨论中,URL 指的是 REST 调用的这一部分。 注意: 尽管这个技术概要(First Look)使用安装了 InterSystems IRIS 的 Web 服务器(在本例中是在本地系统的端口 52773 上),但对于部署的任何代码,您都应该使用一个商业 Web 服务器来替换它。安装 InterSystems IRIS 的 web 服务器仅供开发代码时临时使用,并不具备商业 web 服务器的强大功能。 当客户端应用程序进行 REST 调用时:1. InterSystems IRIS 将它指向与 URL 对应的 web 应用程序。例如,以 /coffeemakerapp 开头的 URL 将被发送到处理咖啡机的应用程序,以 /api/docdb 开头的 URL 将被发送到处理文档数据模型(Document Data Model)的 web 应用程序。2. Web 应用程序根据 HTTP 动词(verb)和 URL 中标识 web 应用程序的部分之后的任何部分,将调用指向一个方法。它通过将动词(verb)和 URL 与称为 URLMap 的结构进行比较来实现这一点。3. 该方法使用 URL 来标识 REST 调用所指定的资源,并根据动词(verb)来执行操作。例如,如果动词(verb)是 GET,该方法返回关于资源的一些信息;如果动词(verb)是 POST,该方法创建一个新的资源实例;如果动词(verb)是 DELETE,该方法删除指定资源。对于 POST 和 PUT 动词(verb),通常有一个提供更多信息的数据包。4. 该方法执行所请求的操作,并向客户端应用程序返回一个响应信息。 REST 调用需要执行方法和访问数据所需的任何权限。用户或 web 应用程序都可以拥有这些权限。您可以把这些权限分配给角色,然后把角色分配给用户或 web 应用程序。在这个示例中,%All 角色被分配给 web 应用程序。这允许未知用户(未经身份认证)访问 coffeemakerapp 数据。如果您没有把这个角色分配给 web 应用程序,未知用户将收到 401 未经授权的错误。您必须在 REST 身份认证调用中指定一个有足够权限的用户。详情请参见 "Securing REST Services(《确保 REST 服务》)"。 3 如何在 InterSystems IRIS 中定义 REST 接口在 InterSystems IRIS 中,有两种方法来定义 REST 接口:• 定义 OpenAPI 2.0 规范,然后使用 API 管理(API Management)工具来生成 REST 接口的代码。• 手动编码 REST 接口,然后在管理门户(Management Portal)中定义一个 web 应用程序。 本技术概要(First Look) 展示了如何手动编码 REST 接口,包括开发一个调度类(dispatch class)。如果您更喜欢使用规范优先的方法,这些调度类(dispatch class)是自动生成的,不应该被编辑。使用规范优先定义的优点包括能够从规范自动生成文档和客户端代码,但您可以使用任何一种方式来定义 REST 接口。有关使用规范定义 REST 接口的更多信息,请参见 Creating Rest Services(《创建 REST 服务》)。 4 手动编码 REST 接口 手动编码 REST 接口包括以下步骤:• 创建 %CSP.REST 的子类并定义 UrlMap。 手动编码 REST 接口 • 对处理 REST 调用的方法进行编码。• 定义 web 应用程序——您通常使用管理门户(Management Portal)来执行此操作。 本技术概要(First Look)使用了一个访问咖啡机数据库的示例应用程序 coffeemakerapp 来演示如何手动编码 REST 接口。Coffeemakerapp 提供 REST 接口来获取咖啡机的信息、在数据库中创建新的记录、更新现有的记录或删除记录。以下几节通过注释探讨了此示例应用程序的类定义和一些方法,以增强您对代码的理解。您将在完成本技术概要(First Look) 的练习部分后,从 GitHub 下载整个应用程序的代码。 4.1 创建 %CSP.REST 的子类并定义 URLMap 这是 demo.CoffeeMakerRESTServer 类定义的第一部分。它扩展了 %CSP.REST 类。 Class Demo.CoffeeMakerRESTServer Extends %CSP.REST{Parameter HandleCorsRequest = 1;XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]{<Routes><Route Url="/test" Method="GET" Call="test"/><Route Url="/coffeemakers" Method="GET" Call="GetAll" /><Route Url="/coffeemaker/:id" Method="GET" Call="GetCoffeeMakerInfo" /><Route Url="/newcoffeemaker" Method="POST" Call="NewMaker" /><Route Url="/coffeemaker/:id" Method="PUT" Call="EditMaker" /><Route Url="/coffeemaker/:id" Method="DELETE" Call="RemoveCoffeemaker"/></Routes>} 查看路由(Route)要素。每个都有三个属性:• Url——这标识了可由该路由(Route)处理的 REST URL。由于 IRIS 指向以 /rest/coffeemakerapp 开头的 URL,因此这个属性指定了紧随其后的 URL 部分。如果 Url 属性是 /cof- feemakers,则此路由( Route)处理以 /rest/coffeemakerapp/coffeemakers 开头的 URL。• Method(方法)——这标识了路由(Route)处理的动词。请注意,最后两行的 Url 值相同,/coffeemaker/:id。有 PUT 方法的路由(Route)将处理以 /rest/coffeemaker- app/coffeemaker/:id 开头的 URL 的 PUT 动词,有 DELETE 方法的路由(Route)将处理具有相同开头的 URL 的 DELETE 动词。• Call(调用)——指定要调用的方法来处理这个 REST 调用。该方法会被传递完整的 URL 和任何数据,以便它可以根据 URL 做出响应。 Url 值中以 : 开头的部分表示通配符。也就是说,/coffeemaker/:id 将匹配 /coffeemaker/5,/coffeemaker/200,甚至是 /coffeemaker/XYZ。被调用的方法将在参数中获得 :id 的值。在这种情况下,它标识了要更新(使用 PUT)或删除的咖啡机的 ID。Url 值有额外的选项,允许您将 REST URL 转发到 %CSP.REST 子类的另一个实例,但您不需要在这个技术概要(First Look)中处理它。HandleCorsRequest 参数指定浏览器是否应该允许跨源资源共享(Cross-origin Resource Sharing,CORS),即在一个域中运行的脚本试图访问在另一个域中运行的 REST 服务,但这也是一个高级主题。 4.2 编码方法 GetAll 方法检索有关所有咖啡机的信息。以下是其代码: 手动编码 REST 接口 ClassMethod GetAll() As %Status{Set tArr = []Set rs = ##class(%SQL.Statement).%ExecDirect(,"SELECT * FROM demo.coffeemaker") While rs.%Next() {Do tArr.%Push({"img": (rs.%Get("Img")), "coffeemakerID": (rs.%Get("CoffeemakerID")), "name": (rs.%Get("Name")),"brand": (rs.%Get("Brand")),"color": (rs.%Get("Color")),"numcups": (rs.%Get("NumCups")),"price": (rs.%Get("Price"))})}Write tArr.%ToJSON() Quit $$$OK} 此方法的注意事项:• 没有任何参数。每当这个方法被调用时,它就会执行一个 SQL 语句,从 demo.coffeemaker 数据库中选择所有记录。• 对于数据库中的每条记录,它都会将这些值作为名称、值对附加到数组中。• 它将数组转换为 JSON,并通过将 JSON 编写到 stdout 来将 JSON 返回给调用的应用程序。• 最后,它成功退出。 NewMaker() 方法没有参数,但有一个 JSON 有效负荷,用于指定要创建的咖啡机。以下是其代码:ClassMethod NewMaker() As %Status{If '..GetJSONFromRequest(.obj) {Set %response.Status = ..#HTTP400BADREQUEST Set error = {"errormessage": "JSON not found"} Write error.%ToJSON()Quit $$$OK}If '..ValidateJSON(obj,.error) {Set %response.Status = ..#HTTP400BADREQUEST Write error.%ToJSON()Quit $$$OK}Set cm = ##class(demo.coffeemaker).%New() Do ..CopyToCoffeemakerFromJSON(.cm,obj)Set sc = cm.%Save() Set result={}do result.%Set("Status",$s($$$ISERR(sc):$system.Status.GetOneErrorText(sc),1:"OK")) write result.%ToJSON()Quit sc} 此方法的注意事项:• 首先,它通过调用类中稍后定义的 GetJSONFromRequest() 和 ValidateJSON() 方法,测试有效负荷是否包含有效的 JSON 对象。• 然后它使用 JSON 对象创建一个新的 demo.coffeemaker,将记录保存在数据库中。• 它通过将状态写入 stdout 来返回状态。 最后,RemoveCoffeemaker() 方法展示了 Url 的:id部分是如何作为参数传递给该方法的: 为自己定义 REST 接口 ClassMethod RemoveCoffeemaker(id As %String) As %Status{Set result={}Set sc=0if id'="",##class(demo.coffeemaker).%ExistsId(id) { Set sc=##class(demo.coffeemaker).%DeleteId(id)do result.%Set("Status",$s($$$ISERR(sc):$system.Status.GetOneErrorText(sc),1:"OK"))}else {do result.%Set("Status","")}write result.%ToJSON() quit sc} 总之,由路由调用(Route Call)属性指定的方法通过以下方式处理 REST 调用:• 获得任何参数作为调用参数。• 通过 obj 值访问有效负荷。• 通过将响应写入 stdout,将其返回给客户端应用程序。 5 为自己定义 REST 接口本节逐步向您展示如何使用咖啡机应用程序来处理 REST 调用。与其让您编写 REST 接口的代码,不如从 GitHub 下载完成的应用程序。构建应用程序后,您将定义 Web 应用程序,然后通过 REST 调用测试应用程序。 5.1 用前须知要使用这个程序,您需要在一个系统上工作,安装一个 REST API 应用程序(如 Postman、Chrome 高级 REST 客户端(Chrome Advanced REST Client)或 cURL),并连接一个正在运行的 InterSystems IRIS 实例。您对 InterSystems IRIS 的选择包括多种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的 系统托管(尽管它们必须相互具有网络访问权限)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。有关将 REST API 应用程序连接到您的 InterSystems IRIS 实例所需的信息,请参见同一文档中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)。 5.2 下载示例应用程序通过克隆或下载已完成的 coffeemakerapp 应用程序来开始这个练习,该应用程序包括测试对 InterSystems IRIS 的 REST 调用所需的所有 REST 接口。这个技术概要-REST(FirstLook-REST)示例代码可以在以下网站获得:https://github.com/intersystems/FirstLook-REST。从 GitHub 下载的内容必须能从您的 InterSystems IRIS 实例访问。下载文件的程序取决于您所使用的实例类型,如下所示:• 如果您使用的是 ICM 部署的实例:1. 使用带有 -machine 和 -interactive 选项的 icm ssh 命令,在托管实例的节点上打开默认 shell,例如:icm ssh -machine MYIRIS-AM-TEST-0004 -interactive 为自己定义 REST 接口 2. 在 Linux 命令行上,使用以下命令之一将 repo 克隆到实例的数据存储卷(data storage volume)。例如,对于部署在 Azure 上的配置,数据卷的默认挂载点(default mount point)是 /dev/sdd,因此您可以使用如下命令: $ git clone https://github.com/intersystems/FirstLook-REST /dev/sdd/FirstLook-REST OR$ wget -qO- https://github.com/intersystems/FirstLook-REST/archive/master.tar.gz | tar xvz -C/dev/sdd 这些文件现在对容器文件系统上 /irissys/data/FirstLook-REST 中的 InterSystems IRIS 可用。 • 如果您正在使用通过其他方式部署的容器化实例(授权版或社区版(Community Edition)):1. 在主机上打开 Linux 命令行。(如果您在云节点上使用社区版(Community Edition),请使用 SSH 连接该节点,如在 Deploy and Explore InterSystems IRIS(《部署和探索 InterSystems IRIS》) 中所述。)2. 在 Linux 命令行上,使用 git clone 或 wget 命令,如上所述,将 repo 克隆到容器中挂载为卷的存储位置。– 对于社区版(Community Edition)实例,您可以克隆到实例的持久化 %SYS 目录 (存储指定于实例的配置数据的目录)。在 Linux 文件系统中,这个目录是 /opt/ISC/dur。这使得文件对容器文件系统上 /ISC/dur/FirstLook-REST 中的 InterSystems IRIS 可用。 – 对于已授权的容器化实例(containerized instance),选择容器中作为卷挂载的任何存储位置(如果使用它,包括持久化 %SYS 目录)。例如, 如果您的 docker run 命令包含选项 -v /home/user1:/external,并且您将 repo 克隆到 /home/user1,则文件对容器文件系统上 /external/FirstLook-REST 中的 InterSystems IRIS 可用。 • 如果您使用的是 InterSystems 学习实验室(Learning Labs)实例:1. 在集成 IDE 中打开命令行终端。2. 将目录更改为 /home/project/shared 并使用 git clone 命令克隆 repo: $ git clone https://github.com/intersystems/FirstLook-REST 该文件夹被添加到左边资源管理器(Explorer)面板的 Shared (共享)下,并且该目录对 /home/project/shared 中的 InterSystems IRIS 可用。• 如果您使用的是已安装的实例:– 如果实例的主机是安装了 GitHub 桌面(GitHub Desktop)和 GitHub 大文件存储(GitHub Large File Storage)的 Windows 系统:1. 在主机的 web 浏览器中进入 https://github.com/intersystems/FirstLook-REST。2. 选择 Clone or download(克隆或下载) 然后选择 Open in Desktop(在桌面上打开)。 这些文件对您的 GitHub 目录中的 InterSystems IRIS 可用,例如在 C:\Users\User1\Documents\GitHub\FirstLook-REST 中。– 如果主机是 Linux 系统,只需在 Linux 命令行上使用 git clone 命令或 wget 命令,就可以将 repo 克隆到您所选择的位置。 5.3 创建一个支持互操作性的命名空间如果您已经有了一个互操作性命名空间,就可以使用它。否则,创建一个命名空间:1. 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中为您的实例描述的 URL,在浏览器中打开您的实例的管理门户(Management Portal)。 为自己定义 REST 接口 2. 通过导航到命名空间(Namespaces)页面(System Administration(系统管理) > Configuration(配置) > System Configuration(系统配置) > Namespaces(命名空间)), 并按照 System Administration Guide(《系统管理指南》)的“Configuring InterSystems IRIS(《配置 InterSystems IRIS》)”一章中创建/修改命名空间中的使用新命名空间(New Namespace)页面的说明,点击 Create New Namespace(创建新命名空间)按钮,创建一个支持互操作性的命名空间。 5.4 构建示例代码 要构建示例代码,请按照以下步骤操作1. 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中为您的实例描述的程序,打开 InterSystems 终端(Terminal)。2. 将命名空间设置为您将使用的互操作性命名空间。输入以下命令,替换 <Namespace-name> 与您所使用的命名空间。set $namespace = "<namespace-name>" 3. 输入以下命令,替换 <path> 与您下载示例的路径。 该目录包含许可证(License)和 Readme 文件以及 buildsample 目录:do $system.OBJ.Load("<path>/buildsample/Build.RESTSample.cls","ck") do ##class(Build.RESTSample).Build()4. 当出现提示时,输入下载此示例的目录的完整路径。然后,该方法加载和编译代码,并执行其他需要的设置步骤。注意: FirstLook-REST / README.md 文件包含这些说明的一个版本。5.5 定义一个 web 应用程序 现在您已经使用 REST 接口构建了示例应用程序,您需要定义一个 web 应用程序:1. 使用 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中为您的实例描述的 URL,在浏览器中打开您的实例的管理门户(Management Portal)。2. 选择 System Administration(系统管理) > Security(安全) > Applications(应用程序) > Web Applications(web 应用程序)。3. 选择 Create New Web Application(创建新的 web 应用程序) 并输入以下设置• Name(名称): /Rest/coffeemakerapp——它指定了将由这个 web 应用程序处理的 URL。InterSystems IRIS 会将所有以 /rest/coffeemakerapp 开头的 URL 定向到这个 web 应用程序。• Namespace(命名空间): 您创建的支持互操作性的名称空间的名称。• Enable(支持): 选择 REST。• Dispatch Class(调度类): Demo.CoffeeMakerRESTServer——这是定义了 URLMap 的类。• Security Settings/Allowed Authentication Methods(安全设置/允许的身份认证方法): 同时选择 Unauthenticated(未经身份认证) 和 Password(密码) 复选框。4. 选择 Save(保存)。5. 要允许此示例的未经身份认证的访问,必须赋予 web 应用程序 %All 角色。要执行此操作:a. 选择 Save(保存)后,选择 Application Roles(应用程序角色)标签。b. 从 Available(可用的)角色中选择 %All 角色。c. 点击右箭头(选择)按钮,将 %All 角色移动到 Selected(选定的) 角色。 为自己定义 REST 接口 d. 点击 Assign(分配) 按钮。e. %All 角色现在被列为 Application Role(应用程序角色)。这确保了来自未经身份认证用户的 REST 调用将拥有访问 coffeemakerapp 数据所需的权限。如果没有这个角色,REST 调用将必须为拥有足够权限的用户指定身份认证。 5.6 访问 REST 接口 CoffeeMaker REST 应用程序现在可以工作了。您将输入 REST 命令来访问咖啡机数据库。在您的 REST API 工具(如 Postman)中,按照以下步骤操作:1. 指定 REST POST 请求来添加新的咖啡机,必要时使用您的 InterSystems IRIS 实例的指定信息• HTTP 操作: POST• URL: http://server:port/rest/coffeemakerapp/newcoffeemaker,其中服务器和端口是您的实例的主机标识符和 web 服务器端口。• 您的实例的登录凭证。• 输入数据: {"img":"img/coffee3.png","coffeemakerID":"99","name":"Double Dip","brand":"Coffee+", "color":"Blue","numcups":2,"price":71.73} 尽管数据包含一个 coffeemakerID 的值,但这是一个计算字段,并且在添加记录时会分配一个新值。该调用返回成功状态:{"Status":"OK"} 2. 重复上一步骤两次,添加以下两个咖啡机: {"img":"img/coffee4.png","coffeemakerID":"99","name":"French Press","brand":"Coffee For You", "color":"Blue","numcups":4,"price":50.00}{"img":"img/coffee9.png","coffeemakerID":"99","name":"XPress","brand":"Shiny Appliances", "color":"Green","numcups":1,"price":95.00} 3. 使用相同的实例指定信息,指定一个 REST GET 请求,以获得数据库中的咖啡机列表:• HTTP 操作: GET• URL: http://server:port/rest/coffeemakerapp/coffeemakers• 您的实例的登录凭证。 该调用返回一个咖啡机列表,如: [{"img":"img/coffee3.png","coffeemakerID":"1","name":"Double Dip","brand":"Coffee+", "color":"Blue","numcups":2,"price":71.73},{"img":"img/coffee4.png","coffeemakerID":"2","name":"French Press","brand":"Coffee For You", "color":"Blue","numcups":4,"price":50},{"img":"img/coffee9.png","coffeemakerID":"3","name":"XPress","brand":"shiny Appliances", "color":"Green","numcups":1,"price":95}] 4. 指定以下 REST 调用,删除 ID=2 的咖啡机:• HTTP 操作:DELETE• URL: http://server:port/rest/coffeemakerapp/coffeemaker/2• 您的实例的登录凭证。 为自己定义 REST 接口 该调用返回成功状态: {"Status":"OK"} 5. 重复 REST GET 请求。该调用返回一个咖啡机列表,如: [{"img":"img/coffee3.png","coffeemakerID":"1","name":"Double Dip","brand":"Coffee+", "color":"Blue","numcups":2,"price":71.73},{"img":"img/coffee9.png","coffeemakerID":"3","name":"XPress","brand":"Shiny Appliances", "color":"Green","numcups":1,"price":95}] 5.7 记录 REST 接口 当您向开发者提供 REST 接口时,您应该提供文档,以便他们知道如何调用接口。您可以使用 Open API Spec 来记录 REST 接口,并使用工具,如 Swagger 来编辑和格式化文档。InterSystems 正在开发一项功能来支持这个文档。这个版本包含了 API 管理(API Management)中的一个功能,它可以为您的 REST API 生成文档框架。您仍然需要编辑生成的文档,以添加注释和额外的信息,例如参数和 HTTP 返回值的内容。要为 CoffeeMakerApp REST 示例生成文档,请输入以下 REST 调用,使用您的 InterSystems IRIS 实例的指定信息和您创建的命名空间的名称:• HTTP 操作:GET• URL: http://server:port/api/mgmnt/v1/namespace/spec/rest/coffeemakerapp/• 您的 InterSystems IRIS 实例的登录凭证。 您可以把这个调用的输出粘贴到 swagger 编辑器中。它将 JSON 转换为 YAML(另一种标记语言(Yet Another Markup Language))并显示文档。您可以使用 swagger 编辑器向文档中添加更多信息。Swagger 编辑器显示的文档如下所示: 有关 InterSystems IRIS 和 REST 的更多信息 6 有关 InterSystems IRIS 和 REST 的更多信息 有关在 InterSystems IRIS 中创建 REST 服务的更多信息,请参见以下内容:• Setting Up RESTful Services(设置 RESTful 服务) 是 InterSystems 的在线课程,它使用与本文档相同的咖啡机应用程序,但更详细。 您需要登录 learning.intersystems.com 才能参加这个课程。如果您没有账户,可以创建一个。• Creating REST Services(《创建 REST 服务》)• Using REST Services and Operations in Productions(《在产品中使用 REST 服务和操作》)
文章
jieliang liu · 十月 26, 2021

IRIS 2021 技术文档 First Look 29 技术概要:LDAP 和 InterSystems 产品

技术概要:LDAP 和 InterSystems 产品 目录 技术概要: LDAP 和 InterSystems 产品 1 设置 LDAP 身份验证 1 选择 InterSystems IRIS 实例 1 定义 LDAP 配置 1 选择新的 LDAP 域作为默认值 2 启用 LDAP 身份验证 2 为 LDAP 服务器安装安全证书 3 探索 LDAP 用户和组 4 User1: 操作员 4 User2: 管理者 5 User3: 开发者 5 自动创建用户 6 了解有关 LDAP 和安全的更多信息 6 技术概要:LDAP 和 InterSystems 产品 InterSystems IRIS®数据平台可以与 LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)服务器集成,从而可以无缝地使用这种流行技术对用户进行身份验证。通过 LDAP 提供授权也很容易。 当用户尝试登录 InterSystems IRIS 时,用户名和密码会被发送到 LDAP 服务器,以验证该用户是否存在。一旦用户的身份得到验证,LDAP 服务器就会向 InterSystems IRIS 发送关于用户属于哪些组的信息。这些组与 InterSystems IRIS 中的角色相对应,这些角色控制用户被授权执行什么操作,以及是否可以读取或写入内容。通过这种方式,InterSystems IRIS 在其安全策略的身份验证和授权方面都使用了 LDAP 技术。 按照本指南中的步骤,您可以连接到 LDAP 服务器,并探索它如何影响 InterSystems IRIS 中的安全。在这些练习中,您将配置 InterSystems IRIS 以与 Windows 活动目录(Active Directory)服务器集成。虽然也支持其他的 LDAP 服务器,但本文主要介绍如何使用活动目录(Active Directory)进行 LDAP 身份验证和授权。 要浏览所有的技术概要(First Look),包括下面描述的可以在免费的社区版(Community Edition)实例上执行的其他内容,请参见 InterSystems First Looks(《InterSystems 技术概要》)。 设置 LDAP 身份验证 在以 LDAP 用户登录并在 InterSystems IRIS 中探索基于 LDAP 的安全之前,需要完成以下操作: 选择 InterSystems IRIS 实例 定义 LDAP 配置 选择 LDAP 域作为默认值 在 InterSystems IRIS 中启用 LDAP 身份验证 为 LDAP 服务器安装安全证书 选择 InterSystems IRIS 实例 要使用该程序,您需要一个正在运行的 InterSystems IRIS 实例。您的选择包括多种类型的已授权的和免费的评估实例;该实例不需要由您正在工作的系统托管(尽管它们必须相互具有网络访问权限)。关于如何部署每种类型的实例的信息(如果您还没有可使用的实例),请参见 InterSystems IRIS Basics: Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 Deploying InterSystems IRIS(部署 InterSystems IRIS)。 定义 LDAP 配置 InterSystems IRIS 使用 LDAP 配置来定义连接到 LDAP 服务器和搜索用户所需的信息。要创建和定义新的 LDAP 配置: 设置 LDAP 身份验证 在浏览器中打开您的实例的管理门户(Management Portal)。要使用的 URL 取决于您选择的实例类型;有关确定正确的 URL 的信息,请参见 InterSystems IRIS Basics:Connecting an IDE(《InterSystems IRIS 基础:连接一个 IDE》)中的 InterSystems IRIS Connection Information(InterSystems IRIS 连接信息)。 进入 Security LDAP Configurations(安全 LDAP 配置) 页面 (System Administration(系统管理) > Security(安全) > System Security(系统安全) > LDAP Configurations(LDAP 配置))。 点击 Create New LDAP configuration(创建新 LDAP 配置)。 在 Name(名称)字段中,输入 irisldap.com。 选择 Enabled(已启用) 复选框。 选择 LDAP server is a Windows Active Directory server(LDAP 服务器是一个 Windows 活动目录(Active Directory) 服务器) 复选框。 定义以下字段: +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | 字段 | > 内容 | +=================================================================+===========================================================================+ | LDAP domain name(LDAP 域名) (仅限 Windows) | > irisldap.intersystems.com | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | LDAP host names(LDAP 主机名) | > irisldapdc1.irisldap.intersystems.com | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | LDAP username to use for searches(用于搜索的 LDAP 用户名) | - (Windows) sidLDAPQuery | | | | | | - (UNIX®) | | | | | | > CN=sidLDAPQuery,CN=Users,DC=irisldap,DC=intersystems,DC=com | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | LDAP username password(LDAP 用户名密码) | > 选择 Enter New Password(输入新密码), 然后输入密码为 Cach3L3arning | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | LDAP Base DN to use for searches(用于搜索的 LDAP 基础 DN) | > DC=irisldap,DC=intersystems,DC=com | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ | LDAP Unique search attribute(LDAP 独特的搜索属性) | > sAMAccountName | +-----------------------------------------------------------------+---------------------------------------------------------------------------+ 选择 Use TLS/SSL encryption for LDAP sessions(将 TLS/SSL 加密用于 LDAP 会话)复选框。 选择 Use LDAP Groups for Roles/Routine/Namespace(将 LDAP 组用于角色/路由/命名空间)复选框。 选择 Allow Universal group Authorization(允许通用组授权)复选框。 点击 Save(保存)。 选择新的 LDAP 域作为默认值 一旦定义了 LDAP 服务器的 LDAP 配置,您需要将新的 LDAP 配置设置为默认的 LDAP 域。要将 LDAP 服务器设置为默认服务器: 从管理门户(Management Portal)主页,进入 System-wide Security Parameters(全系统安全参数) 页面 (System Administration(系统管理) >**Security(安全) > System Security(系统安全) > System-wide Security Parameters(全系统安全参数)**)。 从 Default security domain(默认安全域)下拉列表中选择 irisldap.com。 点击 Save(保存)。 启用 LDAP 身份验证 使用 LDAP 服务器只是 InterSystems IRIS 中可用的一种身份验证方法。不仅必须为 InterSystems IRIS 的整个实例启用 LDAP 身份验证,而且需要由 LDAP 用户访问的 InterSystems IRIS 的每个组件也必须启用 LDAP 身份验证。以下程序为实例和 InterSystems IRIS 安全所需的那些组件启用 LDAP 身份验证: 设置 LDAP 身份验证 从管理门户(Management Portal)主页,进入 Authentication/Web Session Options(身份验证/Web 会话选项) 页面(System Administration(系统管理)> Security(安全) > System Security(系统安全) > Authentication/Web Session Options(身份验证/Web 会话选项))。 选择 Allow LDAP authentication(允许 LDAP 身份验证)复选框。 点击 Save(保存)。 从管理门户(Management Portal)主页,进入 Web Applications(Web 应用程序)页面 (System Administration(系统管理) > Security(安全) > Applications(应用程序) > Web Applications(Web 应用程序))。 在这个页面上,您将为您在 InterSystems IRIS 中将要访问的管理门户(Management Portal)部分启用 LDAP 授权。因为管理门户(Management Portal)的其他部分没有启用 LDAP 授权,如果您试图探索这些其他部分,可能会被要求登录。 点击 /csp/sys 来显示用于配置 web 应用程序的页面。 在 Security Settings(安全设置) 部分,在 Allowed Authentication Methods(允许的身份验证方法)字段中选择 LDAP 复选框。 点击 Save(保存)。 一旦设置被保存,点击 Cancel(取消)以返回到 Web Applications(Web 应用程序)页面。 点击 /csp/sys/sec。这个 web 应用程序包含管理门户(Management Portal)的安全页面。 在 Security Settings(安全设置)部分,在 Allowed Authentication Methods(允许的身份验证方法)字段中选择 LDAP 复选框。 点击 Save(保存)。 一旦设置被保存,点击 Cancel(取消)以返回到 Web Applications(Web 应用程序) 页面。 点击 /csp/sys/op。这个 web 应用程序包含管理门户(Management Portal)的操作页面。 <span id="1.5_Installing_a_Security_Certificate_fo" class="anchor"></span>在 Security Settings(安全设置) 部分,在 Allowed Authentication Methods(允许的身份验证方法)字段中选择 LDAP 复选框。 点击 Save(保存)。 为 LDAP 服务器安装安全证书 LDAP 服务器采用 TLS 进行安全保护,因此您需要安装安全证书才能成功访问服务器。在将其标识为安全证书之前,您将创建一个包含所需证书内容的 .cer 文件。 创建 .cer 文件 要创建将作为安全证书安装的文件: 打开一个文本编辑器,如记事本,并创建一个新文件。 复制以下所有内容并将其粘贴到文本编辑器中的新文件中。新文件应该以 -----BEGIN CERTIFICATE-----开头,并以-----END CERTIFICATE-----结尾。 -----BEGIN CERTIFICATE----- MIIDuTCCAqGgAwIBAgIQO5hG2uC7G7ZBxcXt/J+z3TANBgkqhkiG9w0BAQsFADBv MRMwEQYKCZImiZPyLGQBGRYDY29tMRwwGgYKCZImiZPyLGQBGRYMaW50ZXJzeXN0 ZW1zMRgwFgYKCZImiZPyLGQBGRYIaXJpc2xkYXAxIDAeBgNVBAMTF2lyaXNsZGFw LUlSSVNMREFQREMxLUNBMB4XDTE4MDQwOTE0MDUzMloXDTIzMDQwOTE0MTUzMlow bzETMBEGCgmSJomT8ixkARkWA2NvbTEcMBoGCgmSJomT8ixkARkWDGludGVyc3lz dGVtczEYMBYGCgmSJomT8ixkARkWCGlyaXNsZGFwMSAwHgYDVQQDExdpcmlzbGRh cC1JUklTTERBUERDMS1DQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB AL/aNDJJNbzGh6tXG8+hmEEplb80UQMcIhLvoanz/RKKZXBBY68rO5pkYUwn/24g pryGy0OUjA997KKol5rdbXWzK7vUMuVSp0atw1m4vF9hmp1bpKBC60OXmV39Fqar ej1dkRl0ZXOmCexP8JqTyNwhpOLXvazzzvsNRr4ts9u1m6y9kFYecu4PRqtFCgoC T6rbgqz1Ew3VrhQHi0HWvq1sR2CngxdyG8AnlSo6nz3X/IrTwrw5lauNLfpsRda5 D5YfUpxYeqpONSUB650u9bC0l5eRWe8kS33Xr+u5Odkhy087I/zN+GK7xMGzxYMR OWNINIGRvlLuDRshKQl4gP0CAwEAAaNRME8wCwYDVR0PBAQDAgGGMA8GA1UdEwEB /wQFMAMBAf8wHQYDVR0OBBYEFM3Ofv4R/zkEgHkp4ayvTkAvxJikMBAGCSsGAQQB gjcVAQQDAgEAMA0GCSqGSIb3DQEBCwUAA4IBAQC8hhvc/+WsDeipNezBo+ovum2z 7q0fStr73Tj84cDGSyCmT2Q/h0qFvkfjtRd8AUBdG0qjhIB4VLVyWmrWDl1jAUcr 3AzygfO6UZjNRT+4c8r8R2xOhE3wJEJWibzXD9bPCtCkhYNJT6bi5PSRgUq+r9GU 探索 LDAP 用户和组 IHnAUmaQa+K+kNEpAvBfIeQ2ox9NPbtUfj/fswKpubWzZZc2udeU8SQLacl6tZMA tXgZPT6lQfoZU2WmDG1EnoC4Ji1++Sf6Ho2i6kxg1m6geyOPSsGPdsAVjYCqCjuZ pxjAsfZXV2juLyTBM51rrmV/Rqfougnikh4zhFRBrOHtMP71ZxCptMVz3RHe -----END CERTIFICATE----- 在您可以访问的目录中将该文件另存为 irisldap.cer。 在 Windows 上安装安全证书 如果您在 Windows 上运行 InterSystems IRIS,请完成以下步骤来完成安装您所创建的安全证书的过程。 使用 Windows 资源管理器(Explorer),双击在您保存文件的目录中的安全文件 irisldap.cer。 点击 Install Certificate(安装证书)。 选择 Local Machine(本地机器) 并点击 Next(下一步)。 点击 Yes(是) 以允许对您的设备进行更改。 选择 Place all certificates in the following store(将所有证书放入以下存储区)并点击 Browse(浏览)。 选择 Trusted Root Certification Authorities(受信任的根证书颁发机构)并点击 OK(确定)。 点击 Next(下一步)。 点击 Finish(完成)。 在 UNIX®上安装安全证书 如果您在 UNIX®上运行 InterSystems IRIS,请完成以下步骤来完成安装您所创建的安全证书的过程。 以 _system 用户身份登录管理门户(Management Portal)时,进入 Security LDAP Configurations(安全 LDAP 配置) 页面 (System Administration(系统管理) > Security(安全) > System Security(系统安全) > LDAP Configurations(LDAP 配置))。 从 LDAP 配置的列表中点击 irisldap.com。 在 TLS/SSL certificate file(TLS/SSL 证书文件)字段中,输入 irisldap.cer 的路径和文件名,这是您创建并保存的文件。 探索 LDAP 用户和组 现在您已经配置了您的 LDAP 连接并启用了 LDAP 身份验证,您可以使用 LDAP 服务器来登录 InterSystems IRIS。LDAP 服务器包含三个用户:user1、user2 和 user3。user1 属于 intersystems-Role-%Operator 组,user2 属于 intersystems-Role-%Manager 组,user3 属于 intersystems-Role-%Developer 组。每个组都授予属于 InterSystems IRIS 中相应角色的权限。例如,当 user1 通过 LDAP 服务器的身份验证成功时,将为其分配 %Operator 角色。 在本教程中,您将以所有三个用户的身份登录到 InterSystems IRIS,并根据与用户关联的角色探索可用的操作。当您作为一个有效的 LDAP 用户登录到 InterSystems IRIS 时,InterSystems IRIS 会自动创建用户,而不需要您事先手动添加用户。 User1: 操作员 要以 user1 的身份登录并探索 InterSystems IRIS: 如果您目前已登录到 InterSystems IRIS,请点击管理门户(Management Portal)左上角的 Logout(退出) 链接。 探索 LDAP 用户和组 使用以下凭证登录 InterSystems IRIS: 用户名:user1 密码:Password1 user1 是 intersystems-Role-%Operator 组的成员。基于这个组,当 user1 通过身份验证时,他们会被自动授予与 InterSystems IRIS 中 %Operator 角色相关的权限。 从管理门户(Management Portal)主页,进入 Databases(数据库) 页面 (System Operation(系统操作) > Databases(数据库))。user1 可以访问这个页面,因为他们已经被 LDAP 服务器授权,可以和与 %Operator 角色关联的页面进行交互。 在管理门户(Management Portal)主页上,请注意 System Administration(系统管理) 菜单已被禁用。 user1 不能访问此菜单,因为 %Operator 角色不包含适当的权限。 User2: 管理者 要以 user2 的身份登录并探索 InterSystems IRIS: 点击管理门户(Management Portal)左上角的 Logout(退出) 链接。 使用以下凭证登录 InterSystems IRIS: 用户名:user2 密码:Password2 user2 是 intersystems-Role-%Manager 组的成员。基于这个组,当 user2 通过身份验证时,他们会被自动授予与 %Manager 角色相关的权限。正如您将看到的,这些权限包括访问 user1 无法看到的页面。 从管理门户(Management Portal)主页,进入 Users(用户) 页面 (System Administration(系统管理) > Security(安全) > Users(用户))。请记住,user1 不能访问 System Administration(系统管理) 菜单。 从用户列表中点击 user1。 点击 Roles(角色) 标签。 请注意,%Operator 是分配给 user1 的唯一角色。 点击 Cancel(取消) 以返回到 Users(用户) 页面。 请注意,在用户列表中没有 user3 的条目。该用户将在 user3 登录时自动创建,此时 InterSystems IRIS 使用 LDAP 服务器对用户进行身份验证。 User3: 开发者 要以 user3 的身份登录并探索 InterSystems IRIS: 点击管理门户(Management Portal)左上角的 Logout(退出)链接。 使用以下凭证登录 InterSystems IRIS: 用户名:user3 密码:Password3 user3 是 intersystems-Role-%Developer 组的成员。基于这个组,当 user3 通过身份验证时,他们会被自动授予与 %Developer 角色相关的权限。 请注意,该用户可以访问 System Explorer(系统资源管理器)菜单,而不是 System Operation(系统操作)和 System Administration(系统管理)菜单。您可以看出,分配给 user3 的 %Developer 角色与分配给 了解有关 LDAP 和安全的更多信息 user1 和 user2 的角色具有不同的权限。这可以防止 user3 看到自己的用户配置文件,因为 Users(用户)页面是在 System Administration(系统管理)菜单下。 自动创建用户 您已经登录到 InterSystems IRIS,但没有先创建新用户。当在 LDAP 服务器上发现这些用户时,InterSystems IRIS 会自动创建这些用户。下面的程序演示了这个过程: 点击管理门户(Management Portal)左上角的 Logout(退出)链接。 使用以下凭证登录 InterSystems IRIS: 用户名:user2 密码:Password2 请记住,user2 拥有 %Manager 角色。 从管理门户(Management Portal)主页,进入 Users(用户) 页面 (System Administration(系统管理) > Security(安全) > Users(用户))。 在列表中找到 user3 并点击行中的 Delete(删除)。 此时,拥有 %Developer 角色的 user3 在 InterSystems IRIS 中不复存在。 点击管理门户(Management Portal)左上角的 Logout(退出)链接。 使用以下凭证登录 InterSystems IRIS: 用户名:user3 密码:Password3 因为 user3 仍然存在于 LDAP 服务器上,所以即使您刚刚在 InterSystems IRIS 中删除了用户帐户,您也能够以 user3 的身份重新登录到 InterSystems IRIS。 如果需要,您可以重新登录 InterSystems IRIS,以确认 user3 现在是一个用户。 a. 点击管理门户(Management Portal)左上角的 Logout(退出)链接。 b. 使用以下凭证登录 InterSystems IRIS: 用户名:user2 密码:Password2 c. 从管理门户(Management Portal)主页,进入 System Administration(系统管理) > Security(安全) > Users(用户)。user3 现在在列表中,尽管您之前删除了该用户账户。 了解有关 LDAP 和安全的更多信息 您可以使用以下参考资料来了解有关 LDAP 和其他安全概念的更多信息。 有关在 InterSystems IRIS 中使用 LDAP 的详细信息,请参见 LDAP Guide(《LDAP 指南》)。 有关 InterSystems IRIS 中基于角色的安全的介绍,请参见 First Look:Role-Based Access Control(《技术概要:基于角色的访问控制》)。
文章
Claire Zheng · 一月 20, 2021

使用内置的REST API监控InterSystems IRIS

我们不必等待SAM发布才开始规划和试用该API来监控IRIS实例。在以后的文章中,我将更深入地探讨可用的指标及其意义,并提供一些交互式仪表板的示例。首先,我将介绍一下相关背景和一些问题及答案。 IRIS(和Caché)一直在收集自身及其运行平台的数十个指标。收集这些指标来监控Caché和IRIS的方法向来有很多。我发现,很少有安装软件使用IRIS和Caché的内置解决方案。譬如,History Monitor作为性能和系统使用指标的历史数据库,已经推出很长时间了,但它没有简便方法可实时显示这些指标和仪表系统。 IRIS平台解决方案(以及整个业界)正在从仅在一些本地实例上运行的单体式应用程序过渡到“随处”部署的分布式解决方案。在许多用例中,原有的IRIS监控方案并不适用于这些新的模式。InterSystems没有做重复工作,而是将目光投向当前流行的、经过验证的监控和告警开源解决方案。 Prometheus? Prometheus是一个基于成熟技术、应用广泛的著名开源监控系统,具有多种多样的插件。Prometheus的设计目的是在云环境中很好地运行,但它同样适用于本地环境。Prometheus的插件包括操作系统、web服务器(如Apache)和许多其他的应用程序。Prometheus通常与前端客户端(如Grafana)一起使用,后者可提供极具定制性的一流UI/UX体验。 Grafana? Grafana也是开源平台。随着本系列文章的深入,我将提供常见场景监控仪表板的示例模板。在这些示例模板的基础上,你可以进一步设计自己想要的各种仪表板。将IRIS指标与你的整个解决方案堆栈的各项指标适当结合,就可以发挥真正的威力;各项指标来自于平台组件、操作系统、IRIS,尤其是当你在应用程序中添加仪表功能的时候。 我以前见过这种方法吗? 使用Prometheus和Grafana监控IRIS与Caché并不是新出现的方法。几年来,我一直使用这些应用程序监控我的开发和测试系统。在开发者社区中搜索“Prometheus”,就可以找到一些其它文章,这些文章讲述了如何显示Caché指标,以供Prometheus使用。 跟过去不同的是,现在的/api/monitor API是内置的,而且默认启用。用户无需为显示指标而自己编写类。 Prometheus入门 在这里简单介绍一下Prometheus和一些术语。希望读者能够深入学习并打下一定基础,这将有助于你思考如何运用IRIS或其他来源提供的各项指标或将其可视化。 Prometheus的工作方式是抓取或提取由作为HTTP端点的应用程序(IRIS /api/monitor等API)所公开的时间序列数据。现有的导出器和客户端库适用于多种语言、框架、开源应用程序(例如Apache等web服务器)、操作系统、docker、Kubernetes、数据库和现在的IRIS。 导出器用于将应用程序和服务仪表化,并公开端点上的相关指标以进行抓取。核心导出器支持各种标准组件,例如web服务器、数据库等。其他多种开源导出器可从Prometheus社区获取。 Prometheus术语 有几个关键术语需要了解: ·目标 是指你关心的服务所处的位置,例如主机、应用程序或服务(如:Apache、IRIS或你自己的应用程序)。 ·Prometheus 通过HTTP抓取目标,以收集指标作为时间序列数据。 ·时间序列数据 是通过应用程序(如IRIS)或导出器公开的。 ·导出器 可用于你无法控制的数据,譬如Linux内核指标。 ·生成的时间序列数据 存储在本地Prometheus服务器上的一个数据库中**。 ·这个时间序列数据库 可以使用优化的查询语言(PromQL)进行查询,以便创建警报或者由客户端应用程序(如Grafana)在仪表板中显示指标等。 **剧透警告:出于安全性、扩展性、高可用性及运营效率方面的考虑,在新的SAM解决方案中,Prometheus时间序列数据所使用的数据库是IRIS数据库!但对IRIS平台的Prometheus数据库的访问是透明的,而应用程序(如Grafana)对这些访问既不知道也不关心。 Prometheus数据模型 该API返回的指标是Prometheus格式的。Prometheus采用基于文本的简单指标格式,每行一个指标,格式如下: [ (timen, valuen), ....] 指标可将标签作为(键,值)对,而标签是将指标作为维度过滤的强大方法。例如,检验IRIS /api/monitor返回的一个指标──日志可存储空间: iris_jrn_free_space{id="WIJ",dir=”/fast/wij/"} 401562.83 标识符反映了指标的含义和来源: iris_jrn_free_space 多个标签可用于修饰指标,然后用来过滤和查询。在这个例子中,可以看到WIJ及其存储目录: id="WIJ",dir="/fast/wij/" 此外,还有一个值:401562.83(MB)。 有哪些IRIS指标可供使用? 预览版文档资料中含有一个指标列表。但要注意,其中的内容可能会有所调整。你也可以查询/api/monitor/metrics端点以查看列表。我使用的是Postman,关于这一点,我将在下一篇文章中进行阐述。 我应该监控什么? 考虑怎样监控你的系统和应用程序时,请记住以下要点: 1. 尽可能将影响用户的关键指标仪表化 o用户并不关心你的某台机器是否缺少CPU。 o用户关心的服务是否缓慢或出错。 o你的主仪表板应显示那些直接影响用户的高级指标。 2. 仪表板应避免显示大量图表 o人无法一次性处理太多数据。 o例如:每项服务都有一个仪表板。 3. 关注服务,而不是机器 o将问题定位到某项服务之后,你就可以接着往下找原因,看看是否是哪台机器出了问题。 参考资料 文档资料和下载 Prometheus:https://prometheus.io/ Grafana:https://grafana.com/ 在InterSystems 2019年全球峰会上,我简要介绍了预发布版SAM(包括Prometheus和Grafana);你可以在InterSystems学习服务网站上找到相关链接。如果此链接无效,请访问InterSystems学习服务网站,并搜索:“System Alerting and Monitoring Made Easy”。 你也可以在社区中搜索“Prometheus”和“Grafana”。 注:本文为译文,欢迎点击阅读原文,原文由Murray Oldfield撰写
公告
Claire Zheng · 二月 1, 2021

InterSystems多模型数据库竞赛优胜者已产生!

亲爱的社区用户,大家好! InterSystems多模型数据库竞赛 已圆满结束,感谢大家积极参加这次编程马拉松! 现在,我们来宣布此次竞赛优胜者! 下面这些开发者及其开发的应用值得拥有雷鸣般的掌声!!! 🏆专家提名奖(Experts Nomination) - 获奖者由我们特别挑选的专家团选出: 🥇 第一名,$2,000 的获奖者 @José.Pereira ,提交项目为:iris-image-index-demo 🥈 第二名,$1,000 的获奖者@MikhailenkoSergey ,提交的项目为: zapm 🥉 第三名, $500 的获奖者 @Renato.Banzai ,提交的项目为: iris-multimodel-suite 🏆 社区提名奖(Community Nomination) - 获得总投票数最多的应用: 🥇 第一名,$1,000的获奖者@Botai.Zhang ,提交的项目为: HealthInfoQueryLayer 🥈 第二名,$500 的获奖者 @Henrique.GonçalvesDias ,提交的项目为: iris-vaccine-tracker 🥉 第三名,$250 的获奖者@José.Pereira ,提交的项目为: iris-image-index-demo 恭喜所有获奖用户! 感谢您对本次大赛的关注,感谢您在这场令人兴奋的编程大赛中付出的努力! 接下来呢? 我们的 InterSystems 编程大奖赛! 已经开始了 奖金总额: $16,000 加入大奖赛,不见不散哦😉 热烈恭喜@Botai Zhang!
公告
Claire Zheng · 三月 8, 2021

InterSystems中文社区编程大奖赛获奖项目简介

InterSystems编程大奖赛取得圆满成功,来自中文社区的两位参赛者获得项目奖励,项目简介如下。 获奖者@Botai Zhang 获奖情况:获得专家提名奖(Experts Nomination)第三名和社区提名奖(Community Nomination)第一名 提交项目:HealthInfoQueryLayer(基于Intersystems IRIS平台整合医院信息查询业务解决方案) 项目简介:随着医院信息化建设的逐步完善,医院子系统越来越多,系统间接口越来越多,同时接口费用不断增加,管理工作变得越来越复杂。其中,查询类业务接口根据业务类型分化,数量也是逐步递增,带来接口量大、开发工作繁重、代码冗余、维护困难等等问题。针对这一困境,我们基于Intersystems IRIS数据平台整合医院信息查询业务解决方案。该应用程序可通过配置完成查询业务接口实现,大大缩小开发、维护、实施等项目关键运转周期。 欢迎移步项目链接了解更多详情: HealthInfoQueryLayer 获奖者@Weiwei Yang获奖情况:社区提名奖(Community Nomination)第二名提交项目:Dictionary comparison scheme of cache database项目简介(应用场景):现场需要将各个科室部门内的数据统一汇总到医院总部,但是汇总后发现各个科室使用的字典并不统一,需要将表中的现存的字典统一更换为医院制定字典。例如:A科室中人员的性别字典使用0/1/2表示各种性别,B科室中性别字典使用F/M/O表示各种性别,但是现在医院要求所有性别字典保存Female/Male/Other性别信息,此时就需要替换原有的性别字典为新用字典。当初,此处只是列举了一个使用场景,未来有多个需要对照字典的工作都可以考虑此项目的设计和实现思想。欢迎移步项目链接了解更多详情:Dictionary comparison scheme of cache database