Já, gamla fartölvan mín er margfalt öflugri en framleiðsluþjónninn þinn.

Þetta eru fullyrðingarnar sem ég heyrði frá hönnuðum okkar. Athyglisverðast er að þetta reyndist rétt og varð tilefni til langrar rannsóknar. Við munum tala um SQL netþjóna sem keyra á VMware.

Já, gamla fartölvan mín er margfalt öflugri en framleiðsluþjónninn þinn.

Reyndar er auðvelt að koma framleiðsluþjóninum vonlaust á bak við fartölvuna. Keyra (ekki á tempdb og ekki á gagnagrunni með Delayed Durability virkt) kóðann:

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

Það tekur 5 sekúndur á skjáborðinu mínu og 28 sekúndur á framleiðsluþjóninum. Vegna þess að SQL þarf að bíða eftir því að skrifa í færsluskrána og við erum að gera mjög stuttar færslur hér. Í grófum dráttum keyrðum við stórum öflugum vörubíl inn í borgarumferð og fylgjumst með því hvernig pítsusendingarfólk á vespum er frægt að taka fram úr honum - afköst skiptir ekki máli hér, aðeins leynd skiptir máli. Og ekki ein netgeymsla, sama hversu mörg núll það eru í verði hennar, mun geta staðið sig betur en staðbundin SSD hvað varðar leynd.

(í athugasemdum kom í ljós að ég laug - ég var með seinkun á endingu á báðum stöðum. Án seinkaðrar endingar kemur í ljós:
Skrifborð - 39 sekúndur, 15K tr/sek, 0.065ms /io fram og til baka
PROD - 360 sekúndur, 1600 st/sek, 0.6ms
Ég hefði átt að taka eftir því að það er of hratt)

Hins vegar, í þessu tilfelli, erum við að fást við léttvæg núll í Riemann zeta fallinu með léttvægu dæmi. Í dæminu sem teymið færðu mér var þetta öðruvísi. Ég var sannfærður um að þeir hefðu rétt fyrir sér og byrjaði að hreinsa út allar sérstöður þeirra tengdar viðskiptarökfræði úr dæminu. Á einhverjum tímapunkti áttaði ég mig á því að ég gæti alveg hent kóðanum þeirra og skrifað minn eigin - sem sýnir sama vandamálið - í framleiðslu keyrir hann 3-4 sinnum hægar:

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

Ef allt er í lagi með þig, þá mun það taka 6-7-8 sekúndur að athuga hvort númer sé einfalt. Þetta hefur gerst á fjölda netþjóna. En hjá sumum tók athugunin 25-40 sekúndur. Athyglisvert var að það voru engir netþjónar þar sem framkvæmdin myndi taka, segjum, 14 sekúndur - kóðinn virkaði annað hvort mjög hratt eða mjög hægt, það er að segja að vandamálið var, segjum, svart og hvítt.

Hvað hef ég gert? Komst inn í VMware mælingar. Allt var í lagi þar - það var nóg af tilföngum, Tilbúinn tími = 0, það var nóg af öllu, meðan á prófuninni stóð bæði á hröðum og hægum netþjónum CPU = 100 á einum vCPU. Ég tók próf til að reikna út fjölda Pi - prófið sýndi sömu niðurstöður á hvaða netþjónum sem er. Lyktin af svörtum galdur varð sterkari og sterkari.

Eftir að hafa komist út á DEV bænum byrjaði ég að spila með netþjónum. Það kom í ljós að vMotion frá gestgjafa til gestgjafa getur „læknað“ netþjón, en það getur líka breytt „hröðum“ netþjóni í „hægur“. Svo virðist sem þetta sé það - sumir gestgjafar eiga í vandræðum ... en ... nei. Einhver sýndarvél hægði á vélinni, segjum A, en virkaði hratt á hýsil B. Og hin sýndarvélin, þvert á móti, virkaði hratt á A og hægði á B! Bæði „hraðir“ og „hægir“ bílar voru oft að snúast á gestgjafann!

Frá þeirri stundu var greinileg lykt af brennisteini í loftinu. Þegar öllu er á botninn hvolft var ekki hægt að rekja vandamálið til neinnar sýndarvélar (til dæmis Windows plástra) - þegar allt kemur til alls breyttist það í „hratt“ með vMotion. En vandamálið var heldur ekki hægt að rekja til gestgjafans - þegar allt kemur til alls gæti hann haft bæði „hröð“ og „hægur“ vélar. Það var heldur ekki tengt álaginu - mér tókst að koma „hægri“ vél á gestgjafann, þar sem ekkert var fyrir utan hana.

Af örvæntingu kveikti ég í Process Explorer Sysinternals og horfði á SQL stafla. Á hægum vélum kom línan strax í augun:

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
… sleppt
sqldk.dll!SystemThread::MakeMiniSOSTthread+0xa54
KERNEL32.DLL!BaseThreadInitThunk+0x14
ntdll.dll! RtlUserThreadStart + 0x21

Það var nú þegar eitthvað. Dagskráin var skrifuð:

    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);
                }
            }
        }
    }

Þetta forrit sýndi enn áberandi hægagang - á "hröðum" vélum sýnir það 16-18 milljón lotur á sekúndu, en á hægum - ein og hálf milljón, eða jafnvel 700 þúsund. Það er, munurinn er 10-20 sinnum (!!!). Þetta var nú þegar lítill sigur: í öllum tilvikum var engin hætta á því að festast á milli Microsoft og VMware stuðnings svo þeir myndu skipta örvum á milli.

Þá stöðvuðust framfarir - frí, mikilvægir hlutir, veiruhystería og mikið aukið vinnuálag. Ég minntist oft á töfrandi vandamálið við samstarfsmenn, en stundum virtist sem þeir trúðu mér ekki einu sinni alltaf - fullyrðingin um að VMware hægði á kóðanum um 10-20 sinnum var of voðaleg.

Ég reyndi sjálfur að grafa út hvað hægir á því. Stundum virtist mér sem ég hefði fundið lausn - að kveikja og slökkva á Hot plugs, breyta minnismagni eða fjölda örgjörva breytti vélinni oft í „hratt“. En ekki að eilífu. En það sem reyndist rétt er að það er nóg að fara út og banka á hjólið - það er að breyta til allir færibreytu sýndarvélar

Loksins fundu bandarískir kollegar mínir skyndilega undirrót.

Já, gamla fartölvan mín er margfalt öflugri en framleiðsluþjónninn þinn.

Gestgjafar voru mismunandi í tíðni!

  • Að jafnaði er þetta ekki skelfilegt. En: þegar þú færir frá 'innfæddum' hýsingaraðila yfir í hýsil með 'öðruvísi' tíðni, verður VMware að stilla GetTimePrecise niðurstöðuna.
  • Að jafnaði er þetta ekki vandamál, nema það sé forrit sem biður um nákvæman tíma milljón sinnum á sekúndu, eins og SQL þjónn.
  • En þetta er ekki skelfilegt heldur, þar sem SQL server gerir þetta ekki alltaf (sjá ályktun)

En það eru tilfelli þegar þessi hrífa er sár. Og já, með því að banka á hjólið (með því að breyta einhverju í VM stillingunum), neyddi ég VMware til að 'endurreikna' stillingarnar og tíðni núverandi hýsils varð að 'native' tíðni vélarinnar.

ákvörðun

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

Þegar þú slekkur á sýndarvæðingu TSC, þá skilar lestur TSC innan sýndarvélarinnar TSC gildi líkamlegrar vélar og að skrifa TSC innan sýndarvélarinnar hefur engin áhrif. Flutningur sýndarvélarinnar yfir á annan hýsil, endurtekning úr biðstöðu eða aftur í skyndimynd veldur því að TSC hoppar óslitið. Sum gestastýrikerfi ræsast ekki, eða sýna önnur tímatökuvandamál, þegar TSC sýndarvæðing er óvirk. Í fortíðinni hefur stundum verið mælt með þessum eiginleika til að bæta árangur forrita sem lesa TSC oft, en árangur sýndar TSC hefur verið bætt verulega í núverandi vörum. Einnig hefur verið mælt með eiginleikanum til notkunar þegar gerðar eru mælingar sem krefjast nákvæmrar rauntímauppsprettu í sýndarvélinni.

Í stuttu máli, þú þarft að bæta við breytu

monitor_control.virtual_rdtsc = FALSE

Ályktun

Þú hefur líklega spurningu: hvers vegna myndi SQL hringja í GetTimePrecise svona oft?

Ég er ekki með SQL miðlara heimildir, en rökfræðin segir þetta. SQL er nánast stýrikerfi með samvinnusamhliða, þar sem hver þráður verður að „víkja“ af og til. Hvar er best að gera það? Þar sem það er eðlileg vænting - læsa eða IO. Allt í lagi, en hvað ef við erum að snúast reiknilotur? Þá er augljósi og nánast eini staðurinn í túlknum (þetta er ekki alveg túlkur), eftir aftöku næsta rekstraraðila.

Að jafnaði er SQL netþjónn ekki notaður fyrir hreina tölvuvinnslu og þetta er ekki vandamál. En lotur með vinnu með alls kyns tímabundnum töflum (sem eru strax í skyndiminni) breyta kóðanum í röð af mjög fljótt keyrðum setningum.

Við the vegur, ef aðgerðin er pakkað inn í NATIVELY COMPILED, þá hættir hún að biðja um tíma og hraði hennar eykst um 10 sinnum. En hvað með samvinnu fjölverkavinnsla? En fyrir innfæddan kóða þurfti ég að gera PREEMPTIVE MULTITASKING í SQL.

Heimild: www.habr.com

Bæta við athugasemd