Skip to main content
Les dossiers MSDN

La performance

Article par Pascal Belaud, Microsoft France

Pascal est en charge, depuis plus de 10 années, de la relation technique avec les développeurs chez Microsoft France. Vous pouvez le retrouver sur son blog à l’adresse : http://blogs.msdn.com/Pascal

Cet article a été originellement publié dans le magazine Programmez ! du mois d’octobre et novembre 2008 : www.programmez.com

 

Resource Governor

Jusqu’à présent, nous n’avions pas la possibilité d’allouer “plus de ressources" à telle ou telle catégorie d’utilisateurs ou d’applications et « moins de ressources » à d’autres. Avec le « Resource Governor », il est désormais possible d’allouer tout ou partie des processeurs de la machine hébergeant votre instance SQL Server 2008. De la même manière, une répartition de la mémoire utilisée peut être envisagée. Il est à noter que chaque instance SQL Server 2008 ne peut affecter l’utilisation que des seuls processeurs et ressource mémoire qui lui sont alloués. La compréhension du fonctionnement du « Resource Governor » passe impérativement par la compréhension des concepts suivants :

  • Pool
  • Workload Group
  • Fonction de classification

Pool

Un « pool » représente les ressources physiques du serveur hébergeant l’instance SQL Server 2008. Dans cette version, seules la (ou les) CPU et la mémoire physique peuvent être gérées dans ce pool (il n’est pas exclu que d’autres ressources physiques soient rajoutées à cette notion de « pool » dans des versions ultérieures). Pour chacune de ces ressources, il est possible d’affecter une valeur « Min » et une valeur « Max ». Ces valeurs vont permettre d’affiner l’utilisation des ressources pour telle ou telle catégorie d’application/utilisateur. La valeur « Min » correspondra à la valeur minimum garantie tandis que la valeur « Max » ne pourra être honorée que si les ressources disponibles au moment de la demande le permettent. Il est à noter qu’il existe deux « pools » qui sont créés à l’installation de l’instance SQL Server 2008 :

  • “internal pool” : ce “pool” correspond aux ressources utilisées en interne par l’instance. Il ne peut en aucun cas être altéré.
  • “default pool”: ce “pool” sera celui à utiliser si l’instance SQL n’arrive pas à déterminer la catégorie (« workload group », voir plus bas) à laquelle appartient l’appelant.

La somme de toutes les valeurs « Min » de l’ensemble des « pools » définis ne pourra pas dépasser la valeur 100%. Chaque valeur « Max » devra quant à elle être comprise entre la valeur « Min » et 100%.

Voici un exemple de création de « pools » :

Create Resource Pool [Pool1] With (Min_Cpu_Percent=30, Max_Cpu_Percent=100, Min_Memory_Percent=0, Max_Memory_Percent=100)

Create Resource Pool [Pool2] With (Min_Cpu_Percent=30, Max_Cpu_Percent=100, Min_Memory_Percent=25, Max_Memory_Percent=100)

Create Resource Pool [Pool3] With (Min_Cpu_Percent=60, Max_Cpu_Percent=100, Min_Memory_Percent=0, Max_Memory_Percent=100)

Workload group

Un « workload group » représente un « conteneur » pour des sessions SQL Server 2008 permettant de les regrouper ensemble, ceci basé sur un critère de classification défini par l’administrateur lui-même (voir plus bas). A chaque « workload group » est associé un et un seul « pool ». Ce « workload group » exécutera l’ensemble des sessions qui lui seront rattachées en respectant à la lettre les impératifs d’utilisation des ressources décrits dans les caractéristiques du « pool ». Voici un exemple de création de « workload group »:

Create Workload Group [Workload1] With(Group_Max_Requests=0, Importance=High, Request_Max_Cpu_Time_Sec=0, Request_Max_Memory_Grant_Percent=25, Request_Memory_Grant_Timeout_Sec=0, Max_Dop=0) Using [Pool1]

Create Workload Group [Workload2] With(Group_Max_Requests=0, Importance=High, Request_Max_Cpu_Time_Sec=0, Request_Max_Memory_Grant_Percent=25, Request_Memory_Grant_Timeout_Sec=0, Max_Dop=0) Using [Pool2]

Dans cet exemple, toute session qui sera rattachée au « workload1 » sera exécutée avec les caractéristiques décrites dans le « pool1 ». Toute session qui sera rattachée au « workload2 » sera quant à elle exécutée avec les caractéristiques décrites dans le « pool2 ».

Il ne nous reste plus qu’un seul point à élucider. Comment le moteur SQL Server 2008 peut-il décider d’affecter telle session à tel ou tel autre « workload group » ? Et bien, qu’on se rassure, il n’y a aucun arbitraire ici. Vous êtes le seul, et le plus à même de prendre cette décision ! C’est tout l’objet de la fonction de classification.

Fonction de classification

En effet, pour prendre cette décision, il vous suffit d’écrire vous-même la fonction de classification qui va permettre au système de déterminer que la session demandée doit être rattachée au bon « workload group ». Imaginons que nous ayons deux utilisateurs déclarés dans l’instance SQL Server 2008 :

Create Login Utilisateur1 With Password = 'MotDePasse1', Check_Policy = Off

Create Login Utilisateur2 With Password = 'MotDePasse2', Check_Policy = Off

Un exemple de fonction de classification pourrait être :

Create Function FonctionClassification() returns sysname with Schemabinding

Begin

       Declare @Val sysname

       Declare @LogonActuel sysname = Lower(Suser_Sname())

       If @LogonActuel = 'utilisateur1' Set @Val='Workload1';

       If @LogonActuel = 'utilisateur2' Set @Val='Workload2';

       Return @Val

 End

Ici nous décidons que toute requête exécutée sous le compte Utilisateur1 sera affecté au “workload1”, tandis celle réalisée sous le compte Utilisateur2 sera affecté au “workload2”. Cette classification est extrêmement simple et permet de répartir les ressources de votre instance SQL Server 2008 entre différents utilisateurs ou groupes d’utilisateurs.

Il ne reste plus qu’à indiquer au « Resource Governor » de l’instance SQL Server 2008 quelle est la bonne fonction de classification à utiliser :

Grant Execute On FonctionClassification To Public

Alter Resource Governor With (Classifier_Function = FonctionClassification)

Alter Resource Governor Reconfigure

On peut désormais tester le fonctionnement de notre paramétrage en utilisant une requête très gourmande en temps processeur :

Set Nocount On

Declare @I int = 100000000

Declare @S varchar(100)

While @I > 0

Begin

       Select @S = @@Version

       Set @I = @I - 1

 End

Nous allons exécuter cette requête simultanément sous les deux comptes précédents, à savoir Utilisateur1 et Utilisateur2. Pour juger de l’efficacité du « Resource Governor », nous allons utiliser « Performance Monitor (perfmon) » et constater que deux nouveaux compteurs sont apparus suite à la création des deux « workload group » précédents :

Nous allons maintenant exécuter les tâches suivantes :

  • Etape 1 : exécution de la requête sous le compte Utilisateur1 dans un premier temps
  • Etape 2 : exécution, en parallèle, de la requête sous le compte Utilisateur2

Avant d’aller plus loin, il est à noter que visiblement, nous n’utilisons pas 100% de la CPU de la machine mais seulement 50%. Ceci est absolument normal dans le cadre de cette démonstration car, en fait, la machine sur laquelle ces requêtes sont exécutées possède deux processeurs (CPU0 et CPU1). L’instance SQL Server 2008 a été configurée pour n’utiliser que le premier processeur (CPU0). Il est affiché en bleu et on voit bien qu’il est utilisé à 100%.

Lorsque la première requête est exécutée, le système lui alloue 100% de la CPU0 (soit 50% de l’ensemble du temps processeur du système). A la deuxième étape, nous décidons de lancer en parallèle la seconde requête et l’on voit que le système répartit immédiatement la charge CPU de manière équitable, soit 50% de CPU0 pour la première requête et 50% de CPU0 pour la seconde requête (traduit ici par 25% du temps total processeur pour chacune d’elle).

Nous allons maintenant changer la répartition de l’utilisation de la CPU entre les deux utilisateurs. Nous avons la possibilité de modifier toutes les caractéristiques de notre « resource governor » via l’outil d’administration de SQL Server 2008 appelé « Management Studio » (Etape 3) :

Il est également possible d’effectuer ces paramétrages par script T-SQL (Etape 4) :

Alter Resource Pool Pool1 With (Max_Cpu_Percent = 30)

Alter Resource Pool Pool2 With (Max_Cpu_Percent = 70)

 Alter Resource Governor Reconfigure

Comme le montre la figure suivante, un changement de paramétrage devient actif immédiatement et à chaud, c'est-à-dire que les requêtes, alors qu’elles sont encore en train de tourner, bénéficient de la nouvelle répartition dès que cette dernière est enregistrée dans le système :

Pour rappel, voici les valeurs de répartition constatées sur le « Performance Monitor » compte-tenu du fait que la machine possède 2 processeurs :

Pour finir, il se peut que la classification souhaitée soit beaucoup plus complexe qu’une simple répartition par utilisateur. Par exemple, on peut très bien gérer un scénario aussi complexe que celui décrit dans le schéma suivant :

Create Function FonctionClassificationAvancée() returns sysname with schemabinding

Begin

  Declare @Val sysname = 'WorkloadNormal'

  Declare @AppName nvarchar(128) = Lower(App_Name())

  If DatePart(weekday, GetDate()) = 5
      And DatePart(hour, GetDate()) between 14 and 18

      If @AppName = 'logiciel de compta'

          Set @Val = 'WorkloadCompta'

      Else

          If Is_Member('Direction') = 1

              Set @Val = 'WorkloadMiniDirection'

          Else

              Set @Val = 'WorkloadMiniAutre'

  Else

      If @AppName = 'logiciel de la direction'

          Set @Val = 'WorkloadDirection'

      Else

          If Is_Member('Direction') = 1

              Set @Val = 'WorkloadDSI'

          Else

              Set @Val = 'WorkloadNormal'

  Return @Val

 End

Comme vous venez de le voir, le “Resource Governor” permet d’arriver à un niveau de personnalisation intéressant. Cette fonctionnalité peut également répondre au cas les plus complexes.

Microsoft réalise une enquête en ligne pour comprendre votre opinion sur le site Web de. Si vous choisissez de participer, l’enquête en ligne vous sera présentée lorsque vous quitterez le site Web de.

Souhaitez-vous y participer ?