Conseils pour les requêtes limitées dans Azure Resource Graph
Article
Lors de l'utilisation programmatique des données Azure Resource Graph, il est important de tenir compte de l'impact de l'étranglement sur les résultats des requêtes. En modifiant la façon dont les données sont demandées, votre organisation et vous pouvez éviter les problèmes de limitation et maintenir le flux de données en temps voulu à propos de vos ressources Azure.
Cet article traite de quatre domaines et modèles en rapport avec la création de requêtes dans Azure Resource Graph :
Comprenez les en-têtes de limitation.
Regroupement des requêtes.
Échelonnement des requêtes.
L’effet de la pagination.
Présentation des en-têtes de limitation
Azure Resource Graph alloue un quota à chaque utilisateur en fonction d’une fenêtre de temps. Par exemple, un utilisateur peut envoyer au maximum 15 requêtes durant chaque fenêtre de cinq secondes sans être limité. La valeur de quota est déterminée par de nombreux facteurs et est susceptible de changer.
Dans chaque réponse de requête, Azure Resource Graph ajoute deux en-têtes de limitation :
x-ms-user-quota-remaining (int) : quota de ressources restant pour l'utilisateur. Cette valeur correspond au nombre de requêtes.
x-ms-user-quota-resets-after (hh:mm:ss) : délai à attendre avant la réinitialisation de la consommation du quota d’un utilisateur.
Quand un principal de sécurité a accès à plus de 10 000 abonnements au sein du client ou du groupe d’administration étendue de la requête, la réponse est limitée aux 10 000 premiers abonnements et l’en-tête x-ms-tenant-subscription-limit-hit est retourné en tant que true.
Pour illustrer le fonctionnement des en-têtes, jetons un œil à une réponse de requête qui a les en-têtes et valeurs x-ms-user-quota-remaining: 10 et x-ms-user-quota-resets-after: 00:00:03.
Pendant les trois secondes suivantes, 10 requêtes au plus peuvent être envoyées sans limitation.
En trois secondes, les valeurs de x-ms-user-quota-remaining et x-ms-user-quota-resets-after sont réinitialisées respectivement vers les valeurs 15 et 00:00:05.
Pour voir un exemple d’utilisation des en-têtes pour effectuer une interruption lors des demandes d’interrogation, consultez l’exemple fourni dans Interroger en parallèle.
Regroupement des requêtes
Regrouper les requêtes d’après l’abonnement, le groupe de ressources ou la ressource est plus efficace que paralléliser les requêtes. Le coût du quota d’une requête plus grande est souvent inférieur à celui de nombreuses requêtes petites et ciblées. Nous vous recommandons de choisir une taille de groupe inférieure à 300.
Exemple d’approche mal optimisée.
C#
// NOT RECOMMENDEDvar header = /* your request header */var subscriptionIds = /* A big list of subscriptionIds */foreach (var subscriptionId in subscriptionIds)
{
var userQueryRequest = new QueryRequest(
subscriptions: new[] { subscriptionId },
query: "Resources | project name, type");
var azureOperationResponse = awaitthis.resourceGraphClient
.ResourcesWithHttpMessagesAsync(userQueryRequest, header)
.ConfigureAwait(false);
// ...
}
Exemple d’approche de regroupement optimisée.
C#
// RECOMMENDEDvar header = /* your request header */var subscriptionIds = /* A big list of subscriptionIds */constint groupSize = 100;
for (var i = 0; i <= subscriptionIds.Count / groupSize; ++i)
{
var currSubscriptionGroup = subscriptionIds.Skip(i * groupSize).Take(groupSize).ToList();
var userQueryRequest = new QueryRequest(
subscriptions: currSubscriptionGroup,
query: "Resources | project name, type");
var azureOperationResponse = awaitthis.resourceGraphClient
.ResourcesWithHttpMessagesAsync(userQueryRequest, header)
.ConfigureAwait(false);
// ...
}
Exemple d’approche de regroupement optimisée afin d’obtenir plusieurs ressources dans une même requête.
Kusto
Resources | where id in~ ({resourceIdGroup}) | project name, type
C#
// RECOMMENDEDvar header = /* your request header */var resourceIds = /* A big list of resourceIds */constint groupSize = 100;
for (var i = 0; i <= resourceIds.Count / groupSize; ++i)
{
var resourceIdGroup = string.Join(",",
resourceIds.Skip(i * groupSize).Take(groupSize).Select(id => string.Format("'{0}'", id)));
var userQueryRequest = new QueryRequest(
subscriptions: subscriptionList,
query: $"Resources | where id in~ ({resourceIdGroup}) | project name, type");
var azureOperationResponse = awaitthis.resourceGraphClient
.ResourcesWithHttpMessagesAsync(userQueryRequest, header)
.ConfigureAwait(false);
// ...
}
Échelonnement des requêtes
En raison de la manière dont la limitation est appliquée, nous vous recommandons d’échelonner les requêtes. Par exemple, au lieu d’envoyer 60 requêtes en même temps, échelonnez-les dans quatre fenêtres de cinq secondes.
Planification de requêtes sans échelonnement.
Nombre de requêtes
60
0
0
0
Intervalle de temps (sec)
0-5
5-10
10-15
15-20
Planification de requêtes avec échelonnement.
Nombre de requêtes
15
15
15
15
Intervalle de temps (sec)
0-5
5-10
10-15
15-20
Le code suivant présente un exemple montrant comment respecter les en-têtes de limitation lors de l’interrogation d’Azure Resource Graph.
C#
while (/* Need to query more? */)
{
var userQueryRequest = /* ... */// Send post request to Azure Resource Graphvar azureOperationResponse = awaitthis.resourceGraphClient
.ResourcesWithHttpMessagesAsync(userQueryRequest, header)
.ConfigureAwait(false);
var responseHeaders = azureOperationResponse.response.Headers;
int remainingQuota = /* read and parse x-ms-user-quota-remaining from responseHeaders */
TimeSpan resetAfter = /* read and parse x-ms-user-quota-resets-after from responseHeaders */if (remainingQuota == 0)
{
// Need to wait until new quota is allocatedawait Task.Delay(resetAfter).ConfigureAwait(false);
}
}
Interrogation en parallèle
Bien que le regroupement soit préférable à la parallélisation, il arrive parfois que les requêtes soient difficiles à regrouper. Dans ces cas-là, vous souhaitez peut-être interroger Azure Resource Graph en envoyant plusieurs requêtes de manière parallèle. L’exemple suivant montre comment effectuer une interruption en fonction des en-têtes de limitation.
C#
IEnumerable<IEnumerable<string>> queryGroup = /* Groups of queries */// Run groups in parallel.await Task.WhenAll(queryGroup.Select(ExecuteQueries)).ConfigureAwait(false);
async Task ExecuteQueries(IEnumerable<string> queries)
{
foreach (var query in queries)
{
var userQueryRequest = new QueryRequest(
subscriptions: subscriptionList,
query: query);
// Send post request to Azure Resource Graph.var azureOperationResponse = awaitthis.resourceGraphClient
.ResourcesWithHttpMessagesAsync(userQueryRequest, header)
.ConfigureAwait(false);
var responseHeaders = azureOperationResponse.response.Headers;
int remainingQuota = /* read and parse x-ms-user-quota-remaining from responseHeaders */
TimeSpan resetAfter = /* read and parse x-ms-user-quota-resets-after from responseHeaders */if (remainingQuota == 0)
{
// Delay by a random period to avoid bursting when the quota is reset.var delay = (new Random()).Next(1, 5) * resetAfter;
await Task.Delay(delay).ConfigureAwait(false);
}
}
}
Pagination
Azure Resource Graph retournant au maximum 1 000 entrées dans une unique réponse de requête, vous devrez peut-être paginer vos requêtes afin d’obtenir le jeu de données complet que vous voulez. Mais certains clients Azure Resource Graph gèrent la pagination différemment des autres.
Quand vous utilisez le SDK ResourceGraph, vous devez gérer la pagination en passant le jeton d’évitement ($skiptoken) retourné à partir de la réponse de requête précédente à la requête paginée suivante. Cette conception signifie que vous devez recueillir les résultats de tous les appels paginés et les combiner à la fin. Dans ce cas, chaque requête paginée que vous envoyez prend un quota de requête.
C#
var results = new List<object>();
var queryRequest = new QueryRequest(
subscriptions: new[] { mySubscriptionId },
query: "Resources | project id, name, type");
var azureOperationResponse = awaitthis.resourceGraphClient
.ResourcesWithHttpMessagesAsync(queryRequest, header)
.ConfigureAwait(false);
while (!string.IsNullOrEmpty(azureOperationResponse.Body.SkipToken))
{
queryRequest.Options ??= new QueryRequestOptions();
queryRequest.Options.SkipToken = azureOperationResponse.Body.SkipToken;
var azureOperationResponse = awaitthis.resourceGraphClient
.ResourcesWithHttpMessagesAsync(queryRequest, header)
.ConfigureAwait(false);
results.Add(azureOperationResponse.Body.Data.Rows);
// Inspect throttling headers in query response and delay the next call if needed.
}
Vous rencontrez toujours des limitations ?
Si vous avez utilisé les recommandations de cet article et si vos requêtes Azure Resource Graph sont toujours limitées, contactez l’équipe Azure Resource Graph. L’équipe prend en charge Azure Resource Graph, mais pas la limitation affectant Microsoft Graph.
Fournissez ces informations lorsque vous contactez l’équipe Azure Resource Graph :
Votre cas d’usage spécifique et les axes stratégiques qui imposent de disposer d’une limite plus élevée.
À combien de ressources avez-vous accès ? Combien d’entre elles sont retournées par une requête unique ?
Quels sont les types de ressources qui vous intéressent ?
Quel est votre modèle de requête ? X requêtes toutes les Y secondes, etc.
Azure HPC est une fonctionnalité cloud conçue spécialement pour les charges de travail HPC et IA, qui utilise des processeurs de pointe et une interconnexion InfiniBand de classe HPC pour offrir les meilleures performances, scalabilité et valeur aux applications. Azure HPC permet aux utilisateurs de laisser libre cours à l’innovation, la productivité et l’agilité métier grâce à une gamme de technologies HPC et IA hautement disponibles qui peuvent être allouées dynamiquement à mesure que vos besoins technico
Écrivez des requêtes efficaces, créez des stratégies d’indexation, gérez et approvisionnez des ressources dans l’API SQL et le Kit de développement logiciel (SDK) avec Microsoft Azure Cosmos DB.
Découvrez comment obtenir, mettre en forme, paginer et ignorer des enregistrements dans des jeux de données volumineux quand vous utilisez Azure Resource Graph.
Découvrez comment le service Azure Resource Graph permet d’exécuter des requêtes complexes sur des ressources à grande échelle entre des abonnements et des locataires.
Découvrez comment résoudre les problèmes liés aux différents Kits de développement logiciel (SDK) lors de l’interrogation des ressources Azure avec Azure Resource Graph.