本頁面說明將資料匯入 Cloud Healthcare API 時,如何最佳化資料傳輸量的最佳做法。這些最佳化建議適用於具備管理大型系統資料傳輸量經驗的技術人員。
資料處理量
資料傳輸量是指 Cloud Healthcare API 每秒處理的資源數量 (例如 FHIR 資源或 DICOM 例項),或位元組。
資料傳輸速率限制
以下列出資料傳輸量可能受限的原因:
- 您沒有為大量要求做好準備,導致流量激增。
- 頻寬限制會導致在短時間內傳送大量資料時,擷取資料的速度變慢。
- 多個並行交易會變更相同的 Cloud Healthcare API 資源,導致資料爭用。
- 傳送太多小型要求。詳情請參閱「避免傳送小型匯入和匯出要求」。
- 同時執行的長時間執行作業 (LROs) 過多,且頻寬有限。
- 同時排定太多 LRO 會導致失敗。
重試失敗的要求
如果用戶端在失敗後快速重複重試要求,可能會超出 Cloud Healthcare API 配額。以下各節將說明如何有效重試失敗的請求。
使用指數輪詢搭配抖動和持續重試佇列
指數輪詢搭配抖動,是網路應用程式的標準錯誤處理策略。用戶端會定期重試失敗的要求,每次重試之間的延遲時間會以指數方式增加,並加上一小段隨機延遲時間。
請確認指數輪詢實作方式在每次重試時皆為冪等,特別是如果您使用自訂邏輯來略過失敗條件時。如需更多資訊,請參閱 HTTP 規格的 9.2.2 同構方法。
大多數程式設計語言都提供程式庫,可簡化指數輪詢和類似的重試策略的實作。針對長期或多程序重試,請實作持續性重試佇列。如果超過最大延遲時間,這個佇列可以重設重試機制。
重試這些要求時,請使用指數輪詢:
- 修改 FHIR 資源或 FHIR 資源套件的作業。
同步 LRO 要求。如果 LRO 啟動時發生錯誤或 LRO 失敗,請重試。
LRO 有特殊錯誤,可能需要您實作下列重試策略:
- 使用個別的套件儲存匯入或建立作業失敗的資料。
- 針對無法處理的資料使用同步要求。
指數輪詢演算法的範例
指數輪詢演算法會以指數方式重試要求,並將每次重試之間的等待時間逐漸增加至最大輪詢時間,下列演算法會實作帶有抖動的部分指數輪詢:
傳送要求至 Cloud Healthcare API。
如果要求失敗,請等待 1 +
random-fraction
秒後再重試要求。如果要求失敗,請等待 2 +
random-fraction
秒後再重試要求。如果要求失敗,請等待 4 +
random-fraction
秒後再重試要求。繼續執行這個模式,每次重試後等待 2n +
random-fraction
秒,最多執行maximum-backoff
次。在
deadline
秒後停止重試要求。
實作演算法時,請使用下列值:
每次重試前,等待時間為
min((2n + random-fraction), maximum-backoff)
,n
會從 0 開始,每次重試時增加 1。將
random-fraction
替換為小於或等於 1 的隨機小數值。為每次重試使用不同的值。新增這個隨機值可避免用戶端同步處理,並同時傳送多個重試。將
maximum-backoff
替換為重試之間等待的時間上限 (以秒為單位)。一般值為 32 或 64 (25 或 26) 秒。請選擇最適合您用途的值。將
deadline
改成重試的秒數上限。選擇符合用途的值。
用戶端可在達到 maximum-backoff
時間後,使用與延遲相同的值重試。舉例來說,如果 maximum-backoff
時間為 64 秒,則每 64 秒重試一次。確保用戶端不會無限重試。
透過流量塑造實作用戶端頻率限制
頻率限制可保護大規模系統,避免系統因大量要求而超載。如果用戶端的頻率限制不足,Cloud Healthcare API 配額系統可能會限制資料傳輸量。詳情請參閱配額管理最佳做法。
如果您有其他要求,例如保證在重試時送達,重試失敗要求中的策略可能不足以應付。流量塑造 是一種頻率限制技術,可將用戶端要求的頻率控制在頻寬限制內。這可將負載尖峰分散到數小時或數分鐘,進而提高吞吐量。當配額受限時,流量塑造功能可避免推回並追蹤 worker 單位,因此比單獨使用重試功能可達到更高的處理量。
您可以為同步建立、刪除、更新和刪除 (CRUD) 作業 (包括 fhir.executeBundle
) 實作流量塑造功能。
流量型態規定
如要實作流量塑造功能,您的系統必須實作下列項目:
- 儲存空間支援的處理佇列,具有備援功能,可避免磁碟故障。
- 協調工作站從處理佇列中提取資料。
- 整體使用偵測功能,根據配額限制調整 worker 數量和處理速度。
- 儲存空間支援處理佇列的災難復原功能。發生災難時,系統必須能夠清除或復原佇列。
- 在尖峰時段減少 LRO。詳情請參閱「有效規劃及使用配額」和「排定及管理 LRO」。
在下列情況下,您可能只需要針對單一管道階段進行流量塑造:
- 限制從先前管道步驟中提取的工作站數量。
- 個別限制每個 worker。
- 使用 worker pool 協調器調整處理個別工作單元的速度,例如每秒查詢次數 (QPS) 或每秒攝入位元組數。
在系統的其他部分實作頻率限制
您可以使用現有的程式設計語言和架構來實作流量塑造功能。請考慮採用下列開放原始碼專案和預先建構的解決方案:
Apache Beam 中的用戶端節流。如要瞭解如何使用
numWorkers
和maxNumWorkers
標記控管頻寬限制,請參閱「水平自動調度資源」。Google Guava 核心 Java 程式庫集合的 Java
RateLimiter
類別。Python
ratelimiter
模組。
如要進行流量控管,請使用高階 Pub/Sub 用戶端程式庫。
選擇非同步或同步處理
用於包裝 Cloud Healthcare API 要求的用戶端 Proxy 層 (如「在多個層級處理錯誤」一節所示),也可以控制使用 Cloud Healthcare API 的各項服務的節流。請根據所需的流量塑造類型,使用下列其中一種做法:
- 非同步
- 使用非同步處理程序將要求排入佇列,並控制 worker。Proxy 層會將傳入要求寫入佇列,並在每個要求排入佇列後傳回
200 OK
回應。這項做法最適合用於寫入要求,但如果用戶端可以接收讀取結果,也可以在 LRO 架構中使用這項做法來處理讀取要求。 - 同步
如果某個工作單元取決於先前的單元完成,同步處理作業會提供簡單的回饋機制。Proxy 層會根據 QPS 或位元組吞吐量限制延遲傳出要求,而用戶端會封鎖並等待 Proxy 層的回應。
代理層可根據執行個體數量調整速率限制,也可以與控制器程序協調,每隔幾秒就調整速率限制。為了讓 Proxy 層追蹤執行個體數量和速率限制,每個 Proxy 執行個體都可以定期讀取檔案,或以編碼的速率限制進行遠端程序呼叫 (RPC)。
同步處理有時會有以下缺點:
在用戶端封鎖並等待回應時,用戶端和 Proxy 層中的資源無法使用。這可能會導致錯誤、逾時和資料吞吐量降低,導致難以擴充。
如果用戶端和 Proxy 層中斷連線,就需要進行更多工作,確保資料已依要求修改。
使用 Cloud Tasks
使用 Cloud Tasks 將要求卸載至佇列。Cloud Tasks 會自動設定並監控下列 Google Cloud 配額:
- 使用
RateLimits
物件設定爆發大小上限和要求並行作業上限 - 使用
RetryConfig
物件設定重試限制
請參閱「建立佇列」一文,瞭解如何在 Cloud Tasks 中建立佇列。Queue
資源會顯示可在佇列中設定的選項。舉例來說,您可以使用 RetryConfig
物件實作指數輪詢。如需特定語言的程式庫,請參閱 Cloud Tasks 用戶端程式庫。
使用 Cloud Tasks 時,請考量下列事項:
- Cloud Tasks 無法保證只會傳送一次。在「一次一送」的情況下,伺服器會將任何包含重複資料的要求視為重複,並予以忽略。詳情請參閱「在 Lambda 之後:Dataflow 中的一次性處理作業,第 1 部分」。
- 工作大小上限可能遠低於 Cloud Healthcare API 中的 FHIR 套件大小上限。詳情請參閱「Cloud Tasks 配額和限制」和「Cloud Healthcare API 配額和限制」。
- Cloud Tasks 有問題和限制。
將 FHIR 套裝組合與頻率限制器結合
使用指數型回退和速率限制器重試 FHIR 套件,有助於維持高資料傳輸量並管理負載尖峰。
用戶端可以將批次和交易 FHIR 組合傳送至 Cloud Tasks,後者會將組合中的要求傳送至 Cloud Healthcare API。如果速率限制器已達最大佇列大小並耗盡磁碟空間,導致已滿或超出配額,用戶端可以實作指數型退避機制,以便將套件排入佇列。
監控下列資源,避免速率限制器佇列已滿:
- Cloud Healthcare API 中的 FHIR 作業配額
- 頻率限制器配額
- 頻率限制器錯誤
如果速率限制佇列已滿,系統必須發出警報,並停止用戶端傳送要求。
使用 HTTP 永久 (可重複使用且保持運作的) 連線
根據預設,Cloud Healthcare API 會為每個 CRUD 要求開啟新的 TCP 連線。這需要進行 TCP 握手,可能會造成額外負載並降低效能。如要提升效能,請使用 HTTP 保持運作,讓 TCP 連線保持開啟狀態,以便處理多項要求。
如要在 HTTP/1.1 中使用 HTTP 保持運作功能,請將 Connection
標頭設為 keep-alive
:
Connection: keep-alive
HTTP/2 會使用一個 TCP 連線處理連續和並行的要求,因此可自動避免產生額外負擔。
Python requests
程式庫預設會使用 HTTP keep-alive。如果您使用的是 Node.js,請在建立 http.Agent
物件時將 keepAlive
設為 true
,然後在要求中傳遞該物件。
使用測試架構
測試架構可確保程式碼正常運作,並協助您執行下列操作:
- 為應用程式或管道中突然出現的流量尖峰做好準備。
- 測試指數回退和用戶端速率限制是否能提升效能。測試可以顯示這些實作是否會建立必須個別處理的工作積壓。
- 分隔及控管高優先順序的流量。舉例來說,如果使用者正在等待回應,則可減少背景處理工作負載,確保使用者體驗不會受到影響。
- 測試同步和非同步佇列策略,以便控管流量流程,或測試代理層是否處理推送。
- 災難復原規劃。這通常需要重設傳入流量,或在災難結束後使用佇列來恢復流量。
使用 Cloud Monitoring
使用 Cloud Monitoring 監控測試和實際環境。請遵循下列最佳做法:
- 將 Cloud Tasks 與其他Google Cloud 記錄和監控服務整合,例如 Cloud 稽核記錄。
- 使用 Cloud Monitoring API 建立自訂指標,追蹤重試、佇列大小和佇列年齡等重要指標。
- 為環境建立服務等級目標 (SLO) 和服務水準指標 (SLI)。如需相關最佳化建議,請參閱「SLI 簡介」。
- 使用 Google Cloud Observability 建立快訊政策。快訊政策會通知您系統是否處於高負載狀態,或需要人為介入等問題。
- 建立作業手冊,讓系統管理員知道在快訊政策傳送通知時該如何處理。
在測試環境中使用營運教戰手冊,回應下列情況:
- 因頻率限制而造成的積壓
- 因超出配額上限而導致的推遲
- 連入流量突然爆增
避免發生 429 Resource Exhausted operation_too_costly
錯誤
每天對 FHIR 資源進行數千次並行更新,可能會導致鎖定競爭、延遲,並阻止交易完成。無法完成的交易可能會產生大量 429 Resource Exhausted operation_too_costly
錯誤:
HTTP/1.1 429 Too many requests ... { "issue": [ { "code": "too-costly", "details": { "text": "operation_too_costly" }, "diagnostics": "aborted due to lock contention while executing transactional bundle. Resource type: FHIR_RESOURCE_TYPE", "severity": "error" } ], "resourceType": "OperationOutcome" }
在錯誤訊息中,「成本」是指資源用量和資料傳輸量,而非帳單費用。
429 Too Many Requests
錯誤不一定表示配額問題。當 Cloud Healthcare API FHIR 伺服器偵測到資料庫記錄的鎖定競爭過多時,就可能發生此錯誤。這可能是因為 FHIR 套件中包含許多作業,或 CRUD 作業的組合。
請考量下列情境:
- 更新患者資源和其他 FHIR 資源的 FHIR 交易套件會在交易完成前鎖定患者資源。
多個 FHIR 束縛程式嘗試並行更新病患資源,因此發生鎖定競爭。錯誤回應包含文字
Resource type: PATIENT
的diagnostics
欄位。您可以使用指數輪詢重試更新 Patient 資源,但長時間的鎖定爭用期間可能會導致逾時、吞吐量降低和資源用量增加。
Cloud Healthcare API FHIR 伺服器最終會透過傳回
operation_too_costly
錯誤,偵測到交易積壓和負載分散情形。這麼做可限制流量並避免發生更多錯誤。operation_too_costly
錯誤會限制Google Cloud 專案中的所有 FHIR CRUD 作業,進而影響與專案連結的所有應用程式。
排解 429 Too Many Requests
錯誤
如要排解 429 Too Many Requests
錯誤,請搜尋 Cloud Logging。含有 operation_too_costly
的錯誤表示發生鎖定爭用情形。如果錯誤是因為資源用盡而發生,請檢查配額問題。
如果發生調節,交易組合可能會因鎖定爭用率過高而失敗,並產生以下錯誤:
HTTP/1.1 429 Too many requests
...
{
"issue": [
{
"code": "too-costly",
"details": {
"text": "operation_too_costly"
},
"diagnostics": "aborted due to cumulative heavy load or lock contention in this project while executing transactional bundle, please see https://cloud.google.com/healthcare-api/docs/troubleshooting#fhir_transaction_bundle_heavy_load for more information",
"severity": "error"
}
],
"resourceType": "OperationOutcome"
}
如要排解錯誤,請前往 diagnostics
欄中的「FHIR 交易套件因累積大量負載而中止」連結。
避免使用大型套件
大型交易組合更有可能發生 429 Too Many Requests
錯誤。任何大小的套件都可能造成吞吐量瓶頸。測試不同的套裝組合,找出最佳尺寸。
大型套件如果有重試機制,可能會導致效能回報減少,且更容易發生多次失敗。用戶端應實作額外邏輯,以便管理在交易中失敗的 FHIR 資源子集。
如果批次套件過大或 QPS 過高,就可能發生 429 Too Many Requests
和 413 Request Entity Too Large
錯誤,並導致吞吐量瓶頸。
避免使用包含數千筆交易的大型套裝組合。請改用下列做法:
- 使用較小的交易組合,以便維持資料一致性。如果 FHIR 資源彼此不相關,請分別更新。舉例來說,FHIR 資源可能不會依附於同一套件中其他資源的特定版本。
- 在套件中使用一些批次,避免個別要求。批次處理可提升效能,但大量批次可能會導致錯誤,並降低資料處理量。相似大小的批次套件爭用情形較少,因為這些套件不會在 FHIR 資源更新中保留鎖定。
小型交易組合可避免爭用,因為它們每次只會保留幾個鎖定,且能快速完成。這有助於避免堆疊交易積壓。
LRO 處理量
請參閱「LRO 資料處理量」。
FHIR 資料儲存空間選項
如果 FHIR 資料量偏低或中等,請使用 fhir.create
儲存資料。如要儲存大量 FHIR 資源,請使用 fhir.executeBundle
或 fhirStores.import
。如要瞭解各個方法的相關資訊,請參閱「FHIR 匯入選項」。
匯入 FHIR 資源
決定是否使用 FHIR 匯入功能時,請考量下列事項:
FHIR 匯入功能不會限制匯入資料的總大小。如果 FHIR 組合超過 50 MB,您可以將 FHIR 資源上傳至 Cloud Storage 並匯入。請避免同時進行高延遲或大量匯入作業,否則資料傳輸量可能會受到限制。
使用 FHIR 匯入功能的複雜度,低於使用 FHIR 套件。舉例來說,您不必執行下列操作:
- 將大型套件分割成較小的套件
- 管理時間表
- 在資源或套件層級重試暫時性錯誤
FHIR 匯入作業不會強制執行參照完整性。詳情請參閱「FHIR 參照完整性」。
如果資料時效性是優先考量因素,請勿使用 FHIR 匯入功能。匯入作業可能很快就能完成,但也可能需要數小時或數天才能完成。
如果 Google Cloud 專案中的 LRO 數量不多,FHIR 匯入作業的效能會更好。
如果應用程式可處理部分資源的大量錯誤和失敗情形,FHIR 匯入作業就能達到高資料傳輸量。
使用 FHIR 套裝組合
在下列情況下,請使用 FHIR 套裝組合,而非 FHIR 匯入功能:
建立 pipeline 來儲存資料並匯入至 Cloud Storage 的費用 (無論是帳單費用或網路頻寬) 都太高。
必須強制執行參照完整性。
必須強制執行 FHIR 設定檔驗證。
儲存 FHIR 資源時,您需要傳送 Pub/Sub 通知。FHIR 匯入不支援 Pub/Sub 通知。
資料更新頻率是優先考量,因此資料必須在幾秒或幾分鐘內攝入。不過,即使是架構完善的系統,資料傳輸量也可能受到下列因素的限制:
- 處理管道上游延遲。管道可能需要更多時間準備資料,才能擷取資料。
- 回退、重試和流量塑造 Proxy 層。
FHIR 套件有下列限制:
配額和帳單會套用至套件中的每項作業,就好像每項作業都是獨立執行一樣。舉例來說,如果套件包含 10 項
POST
運算、5 項GET
運算和 1 項DELETE
運算,套用至套件的配額和帳單,就會與個別執行這些運算時相同。大型交易組合較有可能發生交易衝突,進而導致鎖定爭用情形。詳情請參閱「避免發生
429 Resource Exhausted operation_too_costly
錯誤」。批次套件可提升資料處理量,但沒有參照完整性等交易一致性功能。
大量批次套件可能會降低總處理量。詳情請參閱「避免使用大型套件」。
DICOM 資料儲存選項
您可以使用下列方法,在將資料從醫療影像儲存與通訊系統 (PACS) 傳送至 Cloud Healthcare API 時,達到高資料傳輸量:
- 使用 DICOM 訊息服務元素 (DIMSE) 通訊協定的開源 Cloud Healthcare API DICOM 轉接器
當您將 PACS 與 Cloud Healthcare API 同步時,轉接器會最佳化資料傳輸量。在同步處理前,請執行效能測試,確認轉接器能維持最高資料傳輸量。
如果您無法使用 Storage 移轉服務或其他轉移選項,將 DICOM 檔案上傳至 Cloud Storage,請使用這個轉接器。舉例來說,您可能無法符合下列 Storage Transfer Service 規定:
- 將檔案系統掛載至代理程式集區中每部主機,以便擷取來源資料。
- 如果您以定期間隔轉移資料,而不是一次性批次載入,就必須評估資料大小隨時間的變化,以便判斷變更內容。
- 發揮轉移代理程式最佳效能。
- 支付 Cloud Storage 儲存空間費用並分配儲存空間。
- 驗證資料傳輸至 Cloud Storage。
- 將資料匯入 Cloud Healthcare API 後移除 Cloud Storage 資源,並修正任何匯入錯誤。
- 根據臨床系統的網路和儲存空間容量,安排批次擷取間隔。
建議您使用 Storage 移轉服務,針對單一批次的資料載入作業填入 DICOM 儲存庫。定期使用 Storage 移轉服務需要額外的工作,例如同步匯入管道。詳情請參閱「Storage 移轉服務檔案系統轉移詳細資料」。
dicomStores.import
使用這種方法儲存大量 DICOM 資料。
- DICOMweb 儲存庫交易
使用這個方法,透過程式碼儲存 DICOM 資料。
管理配額,提升資料傳輸量
以下各節將說明如何管理及規劃配額,以最佳化資料傳輸量。如需配額管理的一般最佳做法,請參閱「配額管理最佳做法」。
針對可預測的流量規劃配額
請先分析用戶端應用程式的一般每日流量,再規劃配額需求。即使流量可預測,也請將配額設定為高於平均需求。這有助於避免錯誤,並提供安全邊際,以防流量激增或偶爾增加日常使用量。
下圖顯示傳送至 Cloud Healthcare API 的大小一致且可預測模式的請求:
為大量要求規劃配額
請避免在尖峰時段排程大量批次工作。詳情請參閱「持續偏好低交易量」一文。
下圖顯示可預測的流量模式。不過,在流量高峰期間提出大量批次要求,會超過可用配額。這可能會導致專案中的所有要求發生 429 Resource Exhausted
錯誤。
如果系統有額外的彈性配額,小型流量尖峰就不會導致錯誤,也不會導致可預測的尖峰負載發生錯誤。小型尖峰必須分散至許多資料儲存庫、應用程式和其他在 Google Cloud 專案中產生負載的用戶端。
如要避免單一大型批次工作導致流量激增,請參閱避免大型套件。
要求增加配額
如要維持高資料傳輸量並避免 429 Resource Exhausted
錯誤,請參閱本頁的最佳做法,特別是「管理配額以最佳化資料傳輸量」。這些最佳做法可確保您的用戶端應用程式穩健可靠,並能隨著要求量變化而調整。如果未實施最佳做法,就要求額外配額,長期而言不太可能避免發生錯誤。
如果您已實作最佳做法,但仍需要更多配額,請參閱申請額外配額的最佳做法。
資料擷取吞吐量資源
如要進一步瞭解資料攝入吞吐量,請參閱「在 Google Cloud中管理工作負載的流量和負載」。