大家好,我是帥氣小伙。前段時(shí)間忙于實(shí)施醫(yī)療集團(tuán)信息化的事情,太久沒(méi)更文了,剛好今天更個(gè)文章梳理一下前段時(shí)間關(guān)于影像中心建設(shè)的一些感悟。很歡迎大家一同探討。
為什么選擇orthanc?
orthanc是一款能夠提供RESTful API 的迷你影像服務(wù)器,orthanc提供了數(shù)據(jù)庫(kù)存儲(chǔ)dicom索引的插件(Postgresql,Mysql,SQLlite),它大大降低了技術(shù)開(kāi)發(fā)的難度,開(kāi)發(fā)者并不需要了解太多的dicom協(xié)議的知識(shí),便能輕松應(yīng)對(duì)dicom的圖像的檢索,dicom圖像的存儲(chǔ),dicom圖像的壓縮,dicom圖像的轉(zhuǎn)發(fā)。因?yàn)樗麄兠鎸?duì)的都是他們熟悉的東西,Http接口和關(guān)系型數(shù)據(jù)庫(kù);另外一方面,從軟件實(shí)施的難度來(lái)看,orthanc提供了windows安裝包,在應(yīng)對(duì)醫(yī)院前置機(jī)配置也是游刃有余(最糟糕的XP系統(tǒng)同樣能兼容)
Dicom存儲(chǔ)的難度
1.dicom圖像的大小直接導(dǎo)致了存儲(chǔ)成本的提高,雖然硬盤(pán)不貴
2.dicom如果使用分布式存儲(chǔ)將提高檢索難度。
3.dicom圖像的管理如果采用分布式存儲(chǔ)將會(huì)變得困難,假如要?jiǎng)h除一次檢查圖像。
4.如果采用傳統(tǒng)的HDFS這樣的存儲(chǔ)方式,開(kāi)發(fā)接口將面對(duì)的是一堆未可知的問(wèn)題,這并不是一堆簡(jiǎn)單的文件,需要從里面提取圖像信息(根據(jù)檢查號(hào)查詢(xún)圖像)。
5.dicom存儲(chǔ)同樣也存在網(wǎng)絡(luò)帶寬問(wèn)題,影像中心到底需要多大的帶寬?
問(wèn)題分析
1.dicom文件的分布式存儲(chǔ)是必然的,一組dicom圖像可以把它看成是數(shù)據(jù)塊(study),存儲(chǔ)的時(shí)候不需要將它拆分,因?yàn)橐坏┎鸱至耍瑱z索的時(shí)候很可能是大海撈針一般。
2.dicom圖像的接收可以理解為點(diǎn)對(duì)點(diǎn)的傳輸,如果是相對(duì)于影像中心的概念,很可能是一點(diǎn)對(duì)多點(diǎn)的模式,因此對(duì)于接收節(jié)點(diǎn)的壓力是很大的(在自動(dòng)傳輸?shù)那闆r下),并且接收節(jié)點(diǎn)同樣也面臨了磁盤(pán)使用率過(guò)高的情況,很容易造成磁盤(pán)壞道的情況。
云存儲(chǔ)技術(shù)方案設(shè)想
1.影像中心層級(jí)結(jié)構(gòu)

1.采集層:部署在院內(nèi),負(fù)責(zé)影像的采集,圖像來(lái)源可以來(lái)自設(shè)備和pacs系統(tǒng)
2.存儲(chǔ)層:部署在云服務(wù)器上,負(fù)責(zé)影像圖像的接收和存儲(chǔ)
3.查詢(xún)層:部署在云服務(wù)器上,負(fù)責(zé)開(kāi)放對(duì)外接口(檢索圖像,查看圖像...)
2.dicom圖像分布式存儲(chǔ)設(shè)計(jì)

采集層
自動(dòng)轉(zhuǎn)發(fā):在接收到設(shè)備或pacs轉(zhuǎn)發(fā)圖像后,馬上向影像中心轉(zhuǎn)發(fā)。orthanc的技術(shù)實(shí)現(xiàn)是基于lua腳本。例如
function OnStoredInstance(instanceId, tags, metadata)
-- Ignore the instances that result from a modification to avoid
-- infinite loops
if (metadata['ModifiedFrom'] == nil and
metadata['AnonymizedFrom'] == nil) then
-- The tags to be replaced
local replace = {}
replace['StationName'] = 'My Medical Device'
-- 可以在此設(shè)置一些自定義的Tag,例如醫(yī)院標(biāo)識(shí)號(hào)等等
-- The tags to be removed
local remove = { 'MilitaryRank' }
-- Modify the instance, send it, then delete the modified instance
Delete(SendToModality(ModifyInstance(instanceId, replace, remove, true), 'sample'))
-- Delete the original instance
Delete(instanceId)
end
end
手動(dòng)轉(zhuǎn)發(fā):基于orthanc的RESTful API 可以實(shí)現(xiàn)手動(dòng)轉(zhuǎn)發(fā)
orthanc RESTful API
存儲(chǔ)層
基于docker容器技術(shù),快速實(shí)施部署和節(jié)點(diǎn)監(jiān)控,目前的k8s技術(shù)已經(jīng)相當(dāng)成熟了,無(wú)論是節(jié)點(diǎn)的存儲(chǔ),節(jié)點(diǎn)的網(wǎng)絡(luò)拓?fù)錁?gòu)建是相當(dāng)?shù)某錾恕?br> orthanc dockerfile
環(huán)式節(jié)點(diǎn)轉(zhuǎn)發(fā)存儲(chǔ)
這個(gè)設(shè)想主要是考慮到,將接收節(jié)點(diǎn)的壓力分發(fā)到各個(gè)節(jié)點(diǎn),但是如果鏈太長(zhǎng),很容易圖像在數(shù)據(jù)鏈路中丟失,這里可能會(huì)有更好的設(shè)計(jì)思路。


技術(shù)可行性

lua腳本可以通過(guò)命令行調(diào)用python腳本實(shí)現(xiàn)對(duì)于業(yè)務(wù)系統(tǒng)的對(duì)接。例如節(jié)點(diǎn)注冊(cè),節(jié)點(diǎn)銷(xiāo)毀。
dicom圖像連續(xù)性保證,在圖像傳輸?shù)那闆r下,假設(shè)有一個(gè)18張圖像的檢查,A節(jié)點(diǎn)已經(jīng)存儲(chǔ)了17張,但是磁盤(pán)使用超過(guò)了80%,按照我設(shè)計(jì)的鏈?zhǔn)睫D(zhuǎn)發(fā)規(guī)則,它應(yīng)該存儲(chǔ)到下一個(gè)節(jié)點(diǎn)。在轉(zhuǎn)發(fā)之前,我們只需要知道當(dāng)前節(jié)點(diǎn)是否存在與這張圖像的檢查號(hào)(studyid)相同的圖像,再確認(rèn)轉(zhuǎn)發(fā)即可保證圖像的連續(xù)性。這里預(yù)留了10%的磁盤(pán)空間就是為了應(yīng)對(duì)這種情況。
dicom存儲(chǔ)服務(wù)擴(kuò)容,存儲(chǔ)始終都會(huì)有溢出的一天,我們的運(yùn)維要及時(shí)發(fā)現(xiàn),快速解決,采用鏈?zhǔn)酱鎯?chǔ),最終由溢出節(jié)點(diǎn)回到原點(diǎn)并觸發(fā)接收節(jié)點(diǎn)溢出告警,由于一開(kāi)始轉(zhuǎn)發(fā)節(jié)點(diǎn)不存儲(chǔ)圖像,有足夠的緩存時(shí)間去擴(kuò)容。采用鏈?zhǔn)酱鎯?chǔ)的擴(kuò)容其實(shí)很簡(jiǎn)單,再啟動(dòng)一個(gè)轉(zhuǎn)發(fā)節(jié)點(diǎn),配置它的轉(zhuǎn)發(fā)節(jié)點(diǎn)即可,然后再把這個(gè)新啟動(dòng)的轉(zhuǎn)發(fā)節(jié)點(diǎn)的ip更改即可。
查詢(xún)層
經(jīng)過(guò)了存儲(chǔ)層和采集層的搭建,這里已經(jīng)初步解決了dicom圖像存儲(chǔ)問(wèn)題,下一步就是對(duì)dicom圖像的檢索了。其實(shí)這就是一個(gè)分布式數(shù)據(jù)源查詢(xún)的問(wèn)題。

開(kāi)發(fā)影像接口從此回到了關(guān)系數(shù)據(jù)庫(kù)接口開(kāi)發(fā)。

總結(jié)
這是一個(gè)設(shè)想,沒(méi)有真正實(shí)施過(guò),希望有這一方面使用的朋友,批評(píng)指正,我也希望這個(gè)方案能夠真正的實(shí)施落地。