建立查詢以便有效率地列出 Batch 資源
大部分 Azure Batch 應用程式會執行監視或其他查詢 Batch 服務的作業。 這類清單查詢通常會定期發生。 例如,您必須取得作業中每個工作的資料,才能檢查該作業中的佇列工作。 減少 Batch 服務針對查詢所傳回資料量以改善應用程式的效能。 本文說明如何以最有效率的方式建立並執行這類查詢。 您可以使用 Batch .NET 程式庫,以針對 Batch 作業、工作、計算節點和其他資源建立篩選查詢。
注意
Batch 服務針對作業中計算工作的通用案例,以及 Batch 集區中計數計算節點,提供 API 支援。 您可以呼叫取得工作計數和列出集區節點計數作業,而不使用清單查詢。 但更有效率的作業傳回更多限制資訊,而這些資訊可能不是最新。 如需詳細資訊,請參閱依狀態計算工作和計算節點。
指定詳細層級
在生產 Batch 應用程式中,作業、工作和計算節點等實體可能有數千個。 針對資源執行的每個查詢時,可能導致大量資料從 Batch 服務傳送至應用程式, 所以限制查詢傳回項目的數量和資訊類型可以改善效能。
此 Batch .NET API 程式碼片段會列出作業相關的每個工作,以及每個工作的「所有」屬性。
// Get a collection of all of the tasks and all of their properties for job-001
IPagedEnumerable<CloudTask> allTasks =
batchClient.JobOperations.ListTasks("job-001");
套用詳細層級至您的查詢,可以更有效率地列出資訊。 提供 ODATADetailLevel 物件給 JobOperations.ListTasks 方法。 此程式碼片段只傳回已完成工作的識別碼、命令列和計算節點資訊屬性。
// Configure an ODATADetailLevel specifying a subset of tasks and
// their properties to return
ODATADetailLevel detailLevel = new ODATADetailLevel();
detailLevel.FilterClause = "state eq 'completed'";
detailLevel.SelectClause = "id,commandLine,nodeInfo";
// Supply the ODATADetailLevel to the ListTasks method
IPagedEnumerable<CloudTask> completedTasks =
batchClient.JobOperations.ListTasks("job-001", detailLevel);
在此範例案例中,如果作業中有數千個工作,則第二次查詢傳回結果的速度通常比第一次快很多。 如需透過 Batch .NET API 列出項目時使用 ODATADetailLevel
的詳細資訊,請參閱 Batch .NET 中具效率的查詢一節。
重要
我們強烈建議您一律提供 ODATADetailLevel
物件給 .NET API 清單呼叫,以發揮應用程式的最高效率和效能。 透過指定詳細層級,您可以幫助縮短 Batch 服務回應時間、提高網路使用率,以及讓用戶端應用程式的記憶體使用量降到最低。
使用查詢字串
您可以使用 Batch .NET 和 Batch REST API 來減少查詢傳回的項目數,以及查詢針對每個項目傳回的資訊量。 您可以使用三種查詢字串類型來縮小查詢範圍:$filter、$select 和 $expand。
如需 Batch .NET API,請參閱 ODATADetailLevel 類別屬性。 除此之外,請參閱 Batch .NET 中具效率的查詢章節。
針對 Batch REST API,請參閱 Batch REST API 參考。 針對您要查詢的資源,請尋找清單參考。 然後,參閱 URI 參數一節,了解 $filter
、$select
和 $expand
的詳細資料。 例如,請參閱集區的 URI 參數 - 清單。 另請參閱如何使用 Azure CLI 執行具效率的 Batch 查詢。
注意
建構三種查詢字串類型中的任何類型時,您必須確定屬性名稱和大小寫符合其 REST API 元素對應項目。 例如,使用 .NET CloudTask 類別時,即使 .NET 屬性是 CloudTask.State,也必須指定 state 而不是 State。 如需詳細資訊,請參閱 .NET 和 REST API 之間的屬性對應。
篩選器
$filter
運算式字串可減少傳回的項目數目。 例如,您可以只列出作業目前執行的工作,或只列出可執行工作的計算節點。
此字串包含一或多個運算式,而運算式是由屬性名稱、運算子和值所組成。 可指定的屬性及每個屬性支援的運算子,取決於您查詢的每個實體類型。 多個運算式可以透過邏輯運算子 and
和 or
結合。
此範例只列出目前執行的轉譯工作:(state eq 'running') and startswith(id, 'renderTask')
。
選取
$select
運算式字串會限制每個項目傳回的屬性值。 指定逗點分隔屬性名稱的清單後,查詢結果中只會針對項目傳回這些屬性值。 您可以針對正在查詢的實體類型指定任何屬性。
此範例指定每個工作傳回的屬性值只限三個:id, state, stateTransitionTime
。
展開
$expand
運算式字串可減少取得特定資訊所需的 API 呼叫次數。 您可以使用此字串以透過單一 API 呼叫來取得每個項目的詳細資訊。 此方法透過減少 API 呼叫來協助改善效能。 使用 $expand
字串而不是取得實體清單,以及要求每個清單項目的資訊。
類似於 $select
,$expand
可控制清單查詢結果是否包含特定資料。 當需要所有屬性且未指定選取字串時, $expand
必須使用 來取得統計數據資訊。 如果使用選取字串取得屬性子集,即可在選取字串中指定 stats
,而不必指定 $expand
。
支援使用此字串,包括列出作業、作業排程、工作和集區。 此字串目前僅支援統計資料資訊。
此範例指定針對清單中的每個項目應傳回統計資料資訊:stats
。
篩選、選取和展開字串的規則
- 請確定篩選中的屬性名稱,選取並展開字串,如同 Batch REST API 中的動作。 即使使用 Batch .NET 或其他 Batch SDK 的其中一個,仍適用此規則。
- 所有屬性名稱都會區分大小寫,但屬性值不會區分大小寫。
- 日期/時間字串有兩種格式,開頭必須加上
DateTime
。- W3C-DTF 格式範例:
creationTime gt DateTime'2011-05-08T08:49:37Z'
- RFC 1123 格式範例:
creationTime gt DateTime'Sun, 08 May 2011 08:49:37 GMT'
- W3C-DTF 格式範例:
- 布林值字串為
true
或false
。 - 如果指定無效的屬性或運算子,將會導致
400 (Bad Request)
錯誤。
在 Batch .NET 中有效率地查詢
在 Batch .NET API 中,ODATADetailLevel 類別會提供篩選、選取和展開字串給清單作業。 ODataDetailLevel
類別有三個公用字串屬性。 您可以在建構函式中指定這些屬性,或直接在物件上設定屬性。 然後,您可以傳遞 ODataDetailLevel
物件至各種清單作業 (例如 ListPools、ListJobs 和 ListTasks) 作為參數。
- ODATADetailLevel.FilterClause:限制傳回的項目數量。
- ODATADetailLevel.SelectClause:指定隨每個項目一起傳回的屬性值。
- ODATADetailLevel.ExpandClause:在單一 API 呼叫中擷取所有項目的資料,而不是每個項目的個別呼叫。
下列程式碼片段使用 Batch .NET API,有效率地查詢 Batch 服務,取得特定集區集合的統計資料。 Batch 使用者有測試和生產集區。 這些測試集區識別碼前面會加上 "test",而生產集區識別碼則會加上 "prod"。 myBatchClient 是 BatchClient 類別正確初始化的執行個體。
// First we need an ODATADetailLevel instance on which to set the filter, select,
// and expand clause strings
ODATADetailLevel detailLevel = new ODATADetailLevel();
// We want to pull only the "test" pools, so we limit the number of items returned
// by using a FilterClause and specifying that the pool IDs must start with "test"
detailLevel.FilterClause = "startswith(id, 'test')";
// To further limit the data that crosses the wire, configure the SelectClause to
// limit the properties that are returned on each CloudPool object to only
// CloudPool.Id and CloudPool.Statistics
detailLevel.SelectClause = "id, stats";
// Specify the ExpandClause so that the .NET API pulls the statistics for the
// CloudPools in a single underlying REST API call. Note that we use the pool's
// REST API element name "stats" here as opposed to "Statistics" as it appears in
// the .NET API (CloudPool.Statistics)
detailLevel.ExpandClause = "stats";
// Now get our collection of pools, minimizing the amount of data that is returned
// by specifying the detail level that we configured above
List<CloudPool> testPools =
await myBatchClient.PoolOperations.ListPools(detailLevel).ToListAsync();
提示
使用「選取」和「展開」子句設定的 ODATADetailLevel 執行個體也可以傳遞到適當的 Get 方法 (例如 PoolOperations.GetPool),以限制傳回的資料量。
Batch REST 與 .NET API 的對應
篩選、選取和展開字串中的屬性名稱在名稱和大小寫方面,必須反映其 REST API 對應項目。 下表提供 .NET 和 REST API 對應項目之間的對應。
篩選字串的對應
- .NET 清單方法:此欄的每個 .NET API 方法都接受 ODATADetailLevel 物件作為參數。
- REST 清單要求:此資料行中列出的每個 REST API 頁面包含資料表,及篩選字串中允許的屬性和作業。 建構 ODATADetailLevel.FilterClause 字串時,您可以使用這些屬性名稱和作業。
選取字串的對應
- Batch .NET types:Batch .NET API 類型。
- REST API entities:此資料行中的每個頁面包含一個或多個資料表,其中列出類型的 REST API 屬性名稱。 建構「選取」 字串時會使用這些屬性名稱。 建構 ODATADetailLevel.SelectClause 字串時,您可以使用這些相同的屬性名稱。
Batch .NET types | REST API entities |
---|---|
[MSSQLSERVER 的通訊協定內容] | 取得憑證的相關資訊 |
CloudJob | 取得作業的相關資訊 |
CloudJobSchedule | 取得作業排程的相關資訊 |
ComputeNode | 取得節點的相關資訊 |
CloudPool | 取得集區的相關資訊 |
CloudTask | 取得工作的相關資訊 |
範例:建構篩選字串
若要建構 ODATADetailLevel.FilterClause 的篩選字串,請尋找對應的 REST API 頁面。 可選取的屬性和其支援的運算子在第一個多列資料表中。 例如,若要擷取所有結束代碼不為零的工作,請查看針對適用的屬性字串和允許的運算子列出作業的相關工作:
屬性 | 允許的作業 | 類型 |
---|---|---|
executionInfo/exitCode |
eq, ge, gt, le , lt |
Int |
相關的篩選字串:
(executionInfo/exitCode lt 0) or (executionInfo/exitCode gt 0)
範例:建構選取字串
若要建構 ODATADetailLevel.SelectClause,請針對您要列出的實體,尋找對應的 REST API 頁面。 可選取的屬性和其支援的運算子在第一個多列資料表中。 例如,若要針對清單中的每個工作僅擷取識別碼和命令列,請查看取得工作資訊:
屬性 | 類型 | 備註 |
---|---|---|
id |
String |
The ID of the task. |
commandLine |
String |
The command line of the task. |
相關的選取字串:
id, commandLine
程式碼範例
有效清單查詢
EfficientListQueries 範例專案會顯示具效率的清單查詢如何影響應用程式效能。 這個 C# 主控台應用程式會建立並將大量工作加入至作業。 然後,應用程式會多次呼叫 JobOperations.ListTasks 方法,並傳遞 ODATADetailLevel 物件。 這些物件會使用不同的屬性值進行設定,以變更傳回的資料量。 此範例會產生類似下列的輸出:
Adding 5000 tasks to job jobEffQuery...
5000 tasks added in 00:00:47.3467587, hit ENTER to query tasks...
4943 tasks retrieved in 00:00:04.3408081 (ExpandClause: | FilterClause: state eq 'active' | SelectClause: id,state)
0 tasks retrieved in 00:00:00.2662920 (ExpandClause: | FilterClause: state eq 'running' | SelectClause: id,state)
59 tasks retrieved in 00:00:00.3337760 (ExpandClause: | FilterClause: state eq 'completed' | SelectClause: id,state)
5000 tasks retrieved in 00:00:04.1429881 (ExpandClause: | FilterClause: | SelectClause: id,state)
5000 tasks retrieved in 00:00:15.1016127 (ExpandClause: | FilterClause: | SelectClause: id,state,environmentSettings)
5000 tasks retrieved in 00:00:17.0548145 (ExpandClause: stats | FilterClause: | SelectClause: )
Sample complete, hit ENTER to continue...
此範例顯示您可以限制屬性和傳回的項目數量,以大幅降低查詢回應時間。 您可以在 GitHub 上的 azure-batch-samples 存放庫中,找到此範例專案與其他範例專案。
BatchMetrics 程式庫
下列 BatchMetrics 範例專案會示範如何使用 Batch API 有效率地監視 Azure Batch 作業進度。
此範例包含 .NET 類別庫專案,您可以將此專案併入自己的專案。 而另一個簡單的命令列程式,可用來練習或示範程式庫的使用方式。
專案中的範例應用程式會示範下列作業:
- 選取特定屬性,以只下載您需要的屬性
- 篩選狀態轉換時間,以只下載上次查詢後的變更
例如,下列方法會出現在 BatchMetrics 程式庫。 它會傳回 ODATADetailLevel,指出只應該取得所查詢實體的 id
和 state
屬性。 它也會指出只應傳回自指定的 DateTime
參數之後其狀態已變更的實體。
internal static ODATADetailLevel OnlyChangedAfter(DateTime time)
{
return new ODATADetailLevel(
selectClause: "id, state",
filterClause: string.Format("stateTransitionTime gt DateTime'{0:o}'", time)
);
}
下一步
- 使用並行節點工作以將 Azure Batch 計算資源的使用方式最佳化。 在較大 (但量少) 的計算節點上執行平行工作時,部分類型的工作負載可以從中獲益。 如需這類案例的詳細資訊,請查看 範例案例 。
- 依狀態計算作業和節點數目以監視 Batch 解決方案