最近发现随着使用时间变长,Orthanc 的性能下降变得十分明显,且越来越无法忍受,表现为从 PACS 系统上查询缓慢,通常需要10秒 +,下载也缓慢,内网千兆空闲,极端情况下,传输速度甚至会掉到 300 KiB/s ,并且经测试不是本地硬盘的读写瓶颈(队列、4K)
因为之前是基本默认配置部署的,想着是不是有什么更优配置需要修改下
查了下官方社区文档资料
https://orthanc.uclouvain.be/book/faq/troubleshooting.html
提到其默认部署的数据库引擎是 SQLite,这里已经蚌埠住了,应该是这个问题没跑了,继续往下看看到
From a performance point of view, you may stick with SQLite if you do not plan to store more than 25.000 - 50.000 instances.
从性能角度看,如果你不打算存储超过 25,000 到 50,000 个实例,可以选择 SQLite。
看到这句话,我立刻检查了当前本地 Orthanc PACS 系统的存储实例数量
# Patients 1490
# 研究 1644
# 系列 8324
# 实例 674946
存储大小 322.06 GB
好家伙,67 万+ 已经远远超出默认 SQLite 数据库引擎索引的推荐范围了
检查本地文件系统上面的 Orthanc 所使用的默认 SQLite 索引文件大小
D:\OrthancStorage\index 显示为1.05 GiB,才 1 GiB 就已经无法忍受了,很难想象现在不解决后面数据量继续增加再解决,会是什么表情,全是技术债啊
那么开干,尝试从默认的 SQLite 索引迁移到的 PostgreSQL,这里 PostgreSQL 只做 Index,因为我这里不是使用了 对象存储 / HA / 云场景
对于本地单机实例来说,Storage 继续用 本地文件系统 NTFS,不让 PostgreSQL 成为 DICOM 文件的存储后端,官方备注 You likely don't need to enable this option
环境
- Windows 11 24H2 Tiny
- Orthanc 1.12.7、1.12.10
- 希捷银河 X16 氦气机械硬盘
- 330 GiB 数据量,67 万+ 实例(Instances)
- 去官网获取最新版本的 PostgreSQL 相关插件
默认安装时是有自带的 PostgreSQL相关插件,我看了下我的自带插件版本为 v7.2
C:\Program Files\Orthanc Server\Plugins 下面的 2 个插件:OrthancPostgreSQLIndex.dll、OrthancPostgreSQLStorage.dll
去官网下载最新版 https://orthanc.uclouvain.be/downloads/windows-64/orthanc-postgresql/index.html
此时此刻最新版为 v10.0
把下载回来的 OrthancPostgreSQLStorage-10.0.dll 和 OrthancPostgreSQLIndex-10.0.dll 重命名,去掉后缀的 -10
备份原本的自带插件版本,直接在原本的插件上重命名附带 _bak 后缀,完成备份,把新版的插件放到插件目录
启动失败,日志输出二进制不兼容,无奈只能回滚到自带的插件版本 - 安装 PostgreSQL 数据库
到官网下载最新版,此时最新版为 v18.1.2
https://www.postgresql.org/download/
安装完之后,使用超级管理员权限给 Orthanc 分配一个专用数据库,将 PostgreSQL 的相关路径添加到系统的环境变量
如我这里是 D:\PostgreSQL\18\bin
打开终端,登录 PostgreSQL CLI
psql -U postgres
创建 orthanc 用户和数据库,这里用户名数据库密码全部为 orthanc
CREATE USER orthanc WITH PASSWORD 'secret';
CREATE DATABASE orthanc
WITH OWNER = orthanc
ENCODING = 'UTF8';
GRANT ALL PRIVILEGES ON DATABASE orthanc TO orthanc;
- 查询迁移相关资料
经过长达一天的各种尝试,在当前版本 (2025-05-22) 最新发布的 v1.12.7 情况下,无法只迁移 SQLite 索引到 PostgreSQL
相关资料
https://discourse.orthanc-server.org/t/help-with-index-migration-from-sqlite-to-postgresql-using-python-orthanc-tools/5930/1
https://orthanc.uclouvain.be/book/users/replication.html
https://orthanc.uclouvain.be/book/plugins/advanced-storage.html
都是必须对原有数据存储目录进行复制,相当于重新导入
最后还是发现了一个官方的方案
有一个 Advanced Storage Plugin 插件可以处理这种数据库索引迁移的情况
但是对版本有要求,要求是 ≥ v1.12.8 ,我这是 v1.12.7,有点尴尬,此时最新版为 2025-12-15 发布的 v1.12.10
好在升级很简单
停止运行旧版本 Ortahnc,然后使用自带的卸载程序卸载,会保留所有数据和配置,仅是卸载自身,放心卸载
之后下载最新版安装程序,运行安装,安装时,注意存储目录和安装目录要跟卸载前的一致,即可无损平滑升级
之后顺利启动 使用高级存储插件来实现 SQLite 索引迁移到 PostgreSQL
文档:
https://orthanc.uclouvain.be/book/plugins/advanced-storage.html
https://github.com/orthanc-server/orthanc-setup-samples/tree/master/docker/sqlite-to-postgresql
https://github.com/orthanc-server/orthanc-advanced-storage/blob/master/Plugin/Configuration.json
这也是官方例子里面的一个典型场景,原话 Note: The plugin should never be configured to index its own Orthanc storage! However, the plugin might be used to index another Orthanc storage, e.g., to perform a migration from SQLite to PostgreSQL.最后根据文档,迁移配置如下
编辑 Orthanc 的配置文件 "C:\Program Files\Orthanc Server\Configuration\orthanc.json"添加如下字段
"AdvancedStorage": { "Enable": true, "Indexer": { "Enable": true, // Interval (in seconds) between the end of a scan and the start of the next scan. "Interval": 10, // Interval (in milliseconds) between the handling of 2 scanned files. This reduces the // workload on Orthanc while scanning files. "ThrottleDelayMs": 5, // The list of file extensions to parse while indexing. Any extension not in this list will not be parsed. // This option can not be used together with "SkippedExtensions". "ParsedExtensions": [], // The list of file extensions to skip from indexing. Any file ending with one of these extensions will not be parsed. // This option can not be used together with "ParsedExtensions" "SkippedExtensions": [], "Folders": ["D:\\OrthancStorage"], "TakeOwnership": true }, // This is the Delayed Deletion mode configuration. On some file systems, file deletions might // be slow. When the delayed deletion moe is enabled, when Orthanc needs to delete a file, // the file is scheduled for later deletion and the delete operation seems fast from the user point of view. // Orthanc will then delete all scheduled files asynchronously. // This replaces the former delayed-deletion plugin. "DelayedDeletion": { // Set "Enable" to true to enable the delayed deletion moe "Enable": true, // Interval (in milliseconds) between the deletion of 2 scheduled files. This reduces the // workload on the disk while deleting files. "ThrottleDelayMs": 5 } }, "PostgreSQL": { "EnableIndex": true, "EnableStorage": false, "Host": "127.0.0.1", "Port": 5432, "Database": "orthanc", "Username": "orthanc", "Password": "orthanc", "Lock": false, "EnableSsl": false, "MaximumConnectionRetries": 10, "ConnectionRetryInterval": 5, "IndexConnectionsCount": 50, "TransactionMode": "ReadCommitted", "EnableVerboseLogs": false, "HousekeepingInterval": 1, "AllowInconsistentChildCounts": false, "UseDynamicConnectionPool": false, "Schema": "public", "ApplicationName": "Orthanc" },
以上配置中,其他正常配置没什么说的,有一个特性可以开启,开启 DelayedDeletion 延迟删除功能,可以把删除的文件移到异步处理队列来处理文件删除
开始测试,为了便于观察,使用终端启动 Orthanc,并添加 Debug 标志输出详细日志信息
Orthanc.exe "C:\Program Files\Orthanc Server\Configuration\orthanc.json" --trace

可以看到已经生效了,扫描本地的存储后端的数据,读取每个 DICOM 文件的元信息,重建索引写入 PostgreSQL,并且无需停机
期间可以继续接受新的检查推送,平滑升级
就是本地的这个希捷银河 X16 氦气硬盘在发出吱吱喳喳的炒豆子声音
访问 Orthanc Explorer 2 WebUI :http://127.0.0.1:8042/ui/app/index.html#/settings
根据观察,大概 1 分钟能识别添加重建索引的数据量为 0.5 - 1 GiB 的样子
10 分钟的时候,识别添加纳入索引的实例数量为 7867,1454 个研究,速度还是很快的
升级期间,就进行效果测试,然后也是给了我一个大大的惊喜
从 Orthanc PACS 查询检索,一个月的数据量,千条级别的量级检索,0.5 秒立刻返回了数据,经过多次测试,就是这么快,我嘞个豆啊
下载速度从 300 ~ 1000 KiB/s 提升到 22.5 MiB/s(因为网络构架没跑满,使用的无线网卡速率瓶颈)
对于一年的数据量规模,也是没有任何压力,至多 3 秒钟给我返回了 上万+ 数据
以前过得都是什么苦日子,查个 1 天范围的数据,几条数据,都是需要十几秒的查询耗时,经常还无响应
PostgreSQL 永远的神!