Jo, mäi alen Laptop ass e puer Mol méi staark wéi Äre Produktiounsserver.

Dëst sinn d'Fuerderungen déi ech vun eisen Entwéckler héieren hunn. Déi interessantst Saach ass datt dëst richteg erausgestallt gouf, wat zu enger laanger Enquête entsteet. Mir schwätzen iwwer SQL Serveren déi op VMware lafen.

Jo, mäi alen Laptop ass e puer Mol méi staark wéi Äre Produktiounsserver.

Eigentlech, de Produktiounsserver hoffnungslos hannert dem Laptop ze kréien ass einfach. Run (net op tempdb an net op enger Datebank mat Delayed Durability aktivéiert) de Code:

set nocount on
create table _t (v varchar(100))
declare @n int=300000
while @n>0 begin 
  insert into _t select 'What a slowpoke!'
  delete from _t
  set @n=@n-1
  end
GO
drop table _t

Et dauert 5 Sekonnen op mengem Desktop an 28 Sekonnen op der Produktioun Server. Well SQL muss op de kierperlechen Enn vum Schreiwen op den Transaktiounsprotokoll waarden, a mir maachen hei ganz kuerz Transaktiounen. Grof geschwat, mir sinn e grousse mächtege Camion an de Stadverkéier gefuer, a mir kucken wéi d'Pizza Liwwerungsleit op Scooter et berühmt iwwerhuelen - Duerchgang ass net wichteg hei, nëmmen latency ass wichteg. An net eng eenzeg Netzwierkspäicherung, egal wéi vill Nullen et a sengem Präis sinn, wäert fäeg sinn eng lokal SSD a punkto latency ze iwwerwannen.

(an de Kommentaren huet sech erausgestallt, datt ech gelunn hunn - ech hat op béide Plazen Verspéidung.
Desktop - 39 Sekonnen, 15K tr/s, 0.065ms /io Roundtrip
PROD - 360 Sekonnen, 1600 tr/s, 0.6 ms
Ech hätt gemierkt datt et ze séier ass)

Mä an dësem Fall hu mir mat trivial Nullen vun der Riemann Zeta Funktioun mat engem triviale Beispill ze dinn. Am Beispill dat d'Entwéckler mech bruecht hunn, war et anescht. Ech war iwwerzeegt datt se richteg waren, an hunn ugefaang all hir Spezifizitéiten am Zesummenhang mat der Geschäftslogik aus dem Beispill ze botzen. Irgendwann hunn ech gemierkt datt ech hire Code komplett ewechgeheien konnt, a meng eegen schreiwen - wat deeselwechte Problem weist - an der Produktioun leeft et 3-4 Mol méi lues:

create function dbo.isPrime (@n bigint)
returns int
as
  begin
  if @n = 1 return 0
  if @n = 2 return 1
  if @n = 3 return 1
  if @n % 2 = 0 return 0
  declare @sq int
  set @sq = sqrt(@n)+1 -- check odds up to sqrt
  declare @dv int = 1
  while @dv < @sq 
    begin
	set @dv=@dv+2
	if @n % @dv = 0 return 0
	end
  return 1
  end
GO
declare @dt datetime set @dt=getdate()
select dbo.isPrime(1000000000000037)
select datediff(ms,@dt,getdate()) as ms
GO

Wann alles gutt ass mat Iech, dann iwwerpréift fir d'Einfachheet vun enger Nummer 6-7-8 Sekonnen. Dëst ass op enger Rei vu Serveren geschitt. Awer op e puer huet de Scheck 25-40 Sekonnen gedauert. Interessanterweis gouf et keng Serveren wou d'Ausféierung, zum Beispill, 14 Sekonnen dauert - de Code huet entweder ganz séier oder ganz lues geschafft, dat heescht, de Problem war, loosst eis soen, schwaarz a wäiss.

Wat hunn ech gemaach? Gitt an VMware Metriken. Alles war gutt do - et waren vill Ressourcen, Ready Zäit = 0, et war genuch vun allem, während dem Test souwuel op séier a lues Serveren CPU = 100 op engem vCPU. Ech hunn en Test gemaach fir d'Zuel vu Pi ze berechnen - den Test huet déiselwecht Resultater op all Server gewisen. De Geroch vu schwaarzer Magie ass ëmmer méi staark ginn.

Nodeems ech op der DEV Bauerenhaff erauskomm sinn, hunn ech ugefaang mat Serveren ze spillen. Et huet sech erausgestallt datt vMotion vum Host zum Host e Server "heure" kann, awer et kann och e "schnell" Server an e "luesen" maachen. Et schéngt, datt dëst et ass - e puer Hosten hunn e Problem ... awer ... nee. Eng virtuell Maschinn huet op Host, sot A, verlangsamt, awer huet séier um Host B geschafft. An déi aner virtuell Maschinn, am Géigendeel, huet séier op A geschafft an op B verlangsamt! Souwuel "schnell" wéi och "lues" Autoen hunn dacks um Host gedréint!

Vun deem Moment un war et en däitleche Geroch vu Schwefel an der Loft. No all, konnt de Problem net un all virtuell Maschinn zougeschriwwen ginn (Windows Patches, zum Beispill) - schliisslech ass et zu engem "séier" mat vMotion ëmgewandelt. Awer de Problem konnt och net dem Host zougeschriwwe ginn - schliisslech kéint et souwuel "schnell" wéi och "lues" Maschinnen hunn. Och war et net mat der Belaaschtung verbonnen - ech hunn et fäerdeg bruecht eng "lues" Maschinn op den Host ze kréien, wou et guer näischt ausser et war.

Aus Verzweiflung hunn ech de Sysinternals 'Prozess Explorer opgeléist an de SQL Stack gekuckt. Op luesen Maschinnen huet d'Linn direkt d'Aen gefaang:

ntoskrnl.exe!KeSynchronizeExecution+0x5bf6
ntoskrnl.exe!KeWaitForMultipleObjects+0x109d
ntoskrnl.exe!KeWaitForMultipleObjects+0xb3f
ntoskrnl.exe!KeWaitForSingleObject+0x377
ntoskrnl.exe!KeQuerySystemTimePrecise+0x881 < - !!!
ntoskrnl.exe!ObDereferenceObjectDeferDelete+0x28a
ntoskrnl.exe!KeSynchronizeExecution+0x2de2
sqllang.dll!CDiagThreadSafe::PxlvlReplace+0x1a20
... iwwersprongen
sqldk.dll!SystemThread::MakeMiniSOSThread+0xa54
KERNEL32.DLL!BaseThreadInitThunk+0x14
ntdll.dll!RtlUserThreadStart+0x21

Et war schonn eppes. De Programm gouf geschriwwen:

    class Program
    {
        [DllImport("kernel32.dll")]
        static extern void GetSystemTimePreciseAsFileTime(out FILE_TIME lpSystemTimeAsFileTime);

        [StructLayout(LayoutKind.Sequential)]
        struct FILE_TIME
        {
            public int ftTimeLow;
            public int ftTimeHigh;
        }

        static void Main(string[] args)
        {
            for (int i = 0; i < 16; i++)
            {
                int counter = 0;

                var stopwatch = Stopwatch.StartNew();

                while (stopwatch.ElapsedMilliseconds < 1000)
                {
                    GetSystemTimePreciseAsFileTime(out var fileTime);
                    counter++;
                }

                if (i > 0)
                {
                    Console.WriteLine("{0}", counter);
                }
            }
        }
    }

Dëse Programm huet eng nach méi ausgeschwat Ralentissement gewisen - op "séier" Maschinnen et weist 16-18 Millioune Zyklen pro Sekonn, iwwerdeems op luesen - eng an eng hallef Millioun, oder souguer 700 dausend. Dat ass, den Ënnerscheed ass 10-20 Mol (!!!). Dëst war schonn eng kleng Victoire: op alle Fall war et keng Bedrohung tëscht Microsoft a VMware Support ze hänken, sou datt se Pfeile matenee wiesselen.

Dunn huet de Fortschrëtt gestoppt - Vakanz, wichteg Saachen, viral Hysterie an eng schaarf Erhéijung vun der Aarbechtsbelaaschtung. Ech hunn dacks de magesche Problem u Kollegen ernimmt, awer heiansdo huet et geschéngt datt se mir net emol ëmmer gleewen - d'Ausso datt VMware de Code ëm 10-20 Mol verlangsamt huet war ze monstréis.

Ech hu probéiert selwer erauszegruewen wat et verlangsamt. Heiansdo huet et mir geschéngt datt ech eng Léisung fonnt hunn - d'Hot Plugs auszeschalten an auszeschalten, d'Quantitéit vum Erënnerung änneren oder d'Zuel vun de Prozessoren hunn d'Maschinn dacks an e "schnell" ëmgewandelt. Awer net fir ëmmer. Awer wat sech richteg erausgestallt huet, ass datt et genuch ass fir eraus ze goen an op d'Rad ze klappen - dat ass ze änneren iergendeen virtuell Maschinn Parameter

Endlech hunn meng amerikanesch Kollegen op eemol eng root Ursaach fonnt.

Jo, mäi alen Laptop ass e puer Mol méi staark wéi Äre Produktiounsserver.

Hosten ënnerscheede sech an der Frequenz!

  • Als Regel, ass dëst net Angscht. Awer: wann Dir vun engem 'native' Host op e Host mat enger 'anerer' Frequenz plënnert, muss VMware d'GetTimePrecise Resultat upassen.
  • Als Regel ass dëst kee Problem, ausser et gëtt eng Applikatioun déi déi exakt Zäit Millioune Mol pro Sekonn freet, wéi SQL Server.
  • Awer dëst ass och net Angscht, well de SQL Server dëst net ëmmer mécht (kuckt Conclusioun)

Awer et gi Fäll wou dës Rake wéideet. A jo, andeems ech op d'Rad klappen (duerch eppes an de VM Astellungen z'änneren), hunn ech VMware gezwongen d'Konfiguratioun ze 'recalculéieren', an d'Frequenz vum aktuellen Host gouf déi 'gebierteg' Frequenz vun der Maschinn.

Decisioun

www.vmware.com/files/pdf/techpaper/Timekeeping-In-VirtualMachines.pdf

Wann Dir d'Virtualiséierung vum TSC auszeschalten, den TSC vu bannent der virtueller Maschinn liesen gëtt den TSC-Wäert vun der kierperlecher Maschinn zréck, an den TSC aus der virtueller Maschinn ze schreiwen huet keen Effekt. D'Migratioun vun der virtueller Maschinn op en aneren Host, et aus dem suspendéierte Staat zréckzeféieren oder op e Snapshot zréckzekréien verursaacht den TSC diskontinuéierlech ze sprangen. E puer Gaaschtbetribssystemer versoen net ze booten, oder weisen aner Zäitproblemer, wann TSC Virtualiséierung behënnert ass. An der Vergaangenheet gouf dës Feature heiansdo recommandéiert fir d'Performance vun Uwendungen ze verbesseren déi den TSC dacks liesen, awer d'Performance vum virtuelle TSC gouf wesentlech an den aktuellen Produkter verbessert. D'Feature gouf och recommandéiert fir ze benotzen wann Dir Miessunge maacht, déi eng präzis Quell vun Echtzäit an der virtueller Maschinn erfuerderen.

Kuerz gesot, Dir musst de Parameter addéieren

monitor_control.virtual_rdtsc = FALSCH

Konklusioun

Dir hutt wahrscheinlech eng Fro: firwat géif SQL GetTimePrecise sou dacks ruffen?

Ech hunn net de SQL Server Quellen, mä d'Logik seet dëst. SQL ass bal e Betribssystem mat kooperativer Gläichzäiteg, wou all Thread vun Zäit zu Zäit muss "bewege loossen". Wou ass déi bescht Plaz et ze maachen? Wou et eng natierlech Erwaardung - Spär oder IO. Okay, awer wat wa mir Berechnungszyklen spinnen? Dann ass déi offensichtlech a bal déi eenzeg Plaz am Dolmetscher (dëst ass net ganz en Dolmetscher), no der Ausféierung vum nächste Bedreiwer.

Als Regel gëtt SQL Server net fir pure Informatik benotzt an dëst ass kee Problem. Awer Zyklen mat Aarbecht mat all méiglechen temporäre Etiketten (déi direkt cache sinn) verwandelen de Code an eng Sequenz vu ganz séier ausgefouerten Aussoen.

Iwwregens, wann d'Funktioun an NATIVELY COMPILED gewéckelt ass, da stoppt se Zäit ze froen, a seng Geschwindegkeet klëmmt ëm 10 Mol.Awer wat iwwer kooperativ Multitasking? Awer fir nativ kompiléiert Code, ech hu PREEMPTIVE MULTITASKING an SQL ze maachen.

Source: will.com

Setzt e Commentaire