Ha, mening eski noutbukim sizning ishlab chiqarish serveringizdan bir necha barobar kuchliroq

Aynan shular bizning ishlab chiquvchilarimizdan eshitgan shikoyatlardir. Eng qizig'i shundaki, bu haqiqat bo'lib, uzoq tergovga sabab bo'ldi. Biz VMware da ishlaydigan SQL serverlari haqida gapiramiz.

Ha, mening eski noutbukim sizning ishlab chiqarish serveringizdan bir necha barobar kuchliroq

Aslida, ishlab chiqarish serveri umidsiz ravishda noutbukning orqasida ekanligiga ishonch hosil qilish oson. Kodni bajaring (tempdb-da emas va kechiktirilgan chidamlilik yoqilgan ma'lumotlar bazasida emas):

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

Mening ish stolimda bu 5 soniya, ishlab chiqarish serverida esa 28 soniya davom etadi. Chunki SQL tranzaksiya jurnaliga kirishning jismoniy tugashini kutishi kerak va biz bu yerda juda qisqa tranzaktsiyalarni bajaramiz. Taxminan aytganda, biz katta, kuchli yuk mashinasini shahar tirbandligiga haydadik va uni skuterlarda pitsa yetkazib beruvchilar quvib o'tib ketishayotganini kuzatdik - bu erda o'tkazish qobiliyati muhim emas, faqat kechikish muhim. Va hech qanday tarmoq xotirasi, uning narxida qancha nol bo'lishidan qat'i nazar, kechikish bo'yicha mahalliy SSD-ni mag'lub eta olmaydi.

(sharhlarda yolg'on gapirganim ma'lum bo'ldi - men ikkala joyda ham chidamlilikni kechiktirganman. Kechiktirilgan chidamliliksiz shunday bo'ladi:
Ish stoli - 39 soniya, 15K tr/sek, 0.065 ms/io aylanish tezligi
PROD - 360 soniya, 1600 tr/sek, 0.6 ms
Bu juda tez ekanligini payqagan bo'lardim)

Biroq, bu holda biz arzimas misol bilan Riemann zeta funktsiyasining ahamiyatsiz nollarini ko'rib chiqamiz. Ishlab chiquvchilar menga olib kelgan misolda u boshqacha edi. Men ularning to'g'ri ekanligiga amin bo'ldim va misoldan ularning biznes mantig'iga oid barcha xususiyatlarini olib tashlashni boshladim. Bir nuqtada men ularning kodini butunlay tashlab, o'zimni yozishim mumkinligini angladim - bu xuddi shu muammoni ko'rsatadi - ishlab chiqarishda u 3-4 baravar sekin ishlaydi:

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

Agar hamma narsa yaxshi bo'lsa, unda raqamning asosiyligini tekshirish 6-7-8 soniya davom etadi. Bu bir qator serverlarda sodir bo'ldi. Ammo ba'zilarida tekshirish 25-40 soniya davom etdi. Qizig'i shundaki, bajarilish, aytaylik, 14 soniya davom etadigan serverlar yo'q edi - kod juda tez yoki juda sekin ishladi, ya'ni muammo, aytaylik, qora va oq edi.

Men nima qildim? Ishlatilgan VMware ko'rsatkichlari. U erda hamma narsa yaxshi edi - resurslarning ko'pligi bor edi, tayyor vaqt = 0, hamma narsa etarli edi, tez va sekin serverlarda sinov paytida bitta vCPUda CPU = 100. Men Pi raqamini hisoblash uchun test topshirdim - test har qanday serverda bir xil natijalarni ko'rsatdi. Qora sehrning hidi kuchliroq va kuchliroq bo'ldi.

DEV fermasiga kelganimdan so'ng, serverlar bilan o'ynashni boshladim. Ma'lum bo'lishicha, vMotion xostdan xostga serverni "davolashi" mumkin, ammo u "tezkor" serverni ham "sekin" serverga aylantirishi mumkin. Bu shunday tuyuladi - ba'zi xostlarda muammo bor... lekin... yo'q. Ayrim virtual mashina xostda sekin edi, deylik, A, lekin B hostida tez ishladi. Boshqa virtual mashina esa, aksincha, A da tez ishladi va B da sekinlashdi! "Tez" va "sekin" mashinalar ko'pincha uy egasida aylanardi!

Shu paytdan boshlab havoda aniq oltingugurt hidi paydo bo'ldi. Axir, muammoni virtual mashinaga bog'lab bo'lmaydi (masalan, Windows yamoqlari) - axir u vMotion bilan "tezkor" ga aylandi. Ammo muammoni uy egasiga ham bog'lab bo'lmaydi - axir u "tez" va "sekin" mashinalarga ega bo'lishi mumkin. Bundan tashqari, bu yuk bilan bog'liq emas edi - men uy egasiga "sekin" mashinani olishga muvaffaq bo'ldim, bu erda undan boshqa hech narsa yo'q edi.

Men umidsizlikdan Sysinternals-dan Process Explorer-ni ishga tushirdim va SQL stekiga qaradim. Sekin mashinalarda chiziq darhol e'tiborimni tortdi:

ntoskrnl.exe!KeSynchronizeExecution+0x5bf6
ntoskrnl.exe!KeWait For MultipleObjects+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
... o'tkazib yubordi
sqldk.dll!SystemThread::MakeMiniSOSThread+0xa54
KERNEL32.DLL!BaseThreadInitThunk+0x14
ntdll.dll!RtlUserThreadStart+0x21

Bu allaqachon bir narsa edi. Dastur yozildi:

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

Ushbu dastur yanada aniqroq sekinlashuvni ko'rsatdi - "tez" mashinalarda u soniyada 16-18 million tsiklni, sekin mashinalarda esa bir yarim million yoki hatto 700 mingni ko'rsatadi. Ya'ni, farq 10-20 marta (!!!). Bu allaqachon kichik g'alaba edi: har qanday holatda, Microsoft va VMware qo'llab-quvvatlashlari o'rtasida o'qlarni bir-biriga aylantirishi uchun qolib ketish xavfi yo'q edi.

Keyin taraqqiyot to'xtadi - ta'tillar, muhim ishlar, virusli isteriya va ish yukining keskin ortishi. Men hamkasblarimga sehrli muammo haqida tez-tez gapirib berardim, lekin ba'zida ular menga har doim ham ishonmaganday tuyulardi - VMware kodni 10-20 marta sekinlashtiradi, degan gap juda dahshatli edi.

Meni nima sekinlashtirayotganini o'zim qazib olishga harakat qildim. Ba'zida men bir yechim topgandek tuyulardi - Hot-plug'larni yoqish va o'chirish, xotira hajmini yoki protsessorlar sonini o'zgartirish ko'pincha mashinani "tezkor"ga aylantiradi. Lekin abadiy emas. Ammo haqiqat bo'lib chiqdi, buning uchun tashqariga chiqish va g'ildirakni taqillatish - ya'ni o'zgartirish kifoya har qanday virtual mashina parametri

Nihoyat, amerikalik hamkasblarim birdaniga asosiy sababni topdi.

Ha, mening eski noutbukim sizning ishlab chiqarish serveringizdan bir necha barobar kuchliroq

Mezbonlar chastotada farq qilishdi!

  • Qoida tariqasida, bu katta ish emas. Ammo: "mahalliy" xostdan "boshqa" chastotali xostga o'tishda VMware GetTimePrecise natijasini sozlashi kerak.
  • Qoidaga ko'ra, SQL serveri kabi soniyada millionlab marta aniq vaqtni so'raydigan dastur bo'lmasa, bu muammo emas.
  • Ammo bu qo'rqinchli emas, chunki SQL server har doim ham buni qilmaydi (Xulosaga qarang)

Ammo bu rake qattiq urilgan holatlar mavjud. Va shunga qaramay, ha, g'ildirakni bosish orqali (VM sozlamalarida biror narsani o'zgartirish orqali) men VMware-ni konfiguratsiyani "qayta hisoblash" ga majbur qildim va joriy xost chastotasi mashinaning "mahalliy" chastotasiga aylandi.

qaror

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

TSC virtualizatsiyasini o'chirib qo'yganingizda, TSCni virtual mashina ichidan o'qish jismoniy mashinaning TSC qiymatini qaytaradi va TSCni virtual mashina ichidan yozish hech qanday ta'sir qilmaydi. Virtual mashinani boshqa xostga o'tkazish, uni to'xtatilgan holatdan davom ettirish yoki oniy rasmga qaytarish TSC uzluksiz o'tishga olib keladi. Ba'zi mehmon operatsion tizimlari TSC virtualizatsiyasi o'chirilgan bo'lsa, ishga tushmaydi yoki boshqa vaqtni hisoblash muammolarini ko'rsatadi. Ilgari, bu xususiyat ba'zan TSCni tez-tez o'qiydigan ilovalarning ishlashini yaxshilash uchun tavsiya etilgan, lekin virtual TSCning ishlashi joriy mahsulotlarda sezilarli darajada yaxshilandi. Bu xususiyat virtual mashinada real vaqtning aniq manbasini talab qiladigan oβ€˜lchovlarni amalga oshirishda ham foydalanish uchun tavsiya etilgan.

Muxtasar qilib aytganda, siz parametrni qo'shishingiz kerak

monitor_control.virtual_rdtsc = FALSE

xulosa

Sizda savol tug'ilishi mumkin: nega SQL GetTimePrecise-ni tez-tez chaqiradi?

Menda SQL server manba kodi yo'q, lekin mantiq buni aytadi. SQL deyarli bir vaqtning o'zida hamkorlik qiladigan operatsion tizim bo'lib, har bir ip vaqti-vaqti bilan "taslim bo'lishi" kerak. Buni qilish uchun eng yaxshi joy qayerda? Tabiiy kutish bo'lgan joyda - qulf yoki IO. Yaxshi, lekin agar biz hisoblash tsikllarini aylantirsak nima bo'ladi? Keyin aniq va deyarli yagona joy tarjimonda (bu haqiqatan ham tarjimon emas), keyingi bayonotni bajargandan so'ng.

Umuman olganda, SQL serveri sof hisoblash mixlash uchun ishlatilmaydi va bu muammo emas. Ammo har xil vaqtinchalik jadvallar bilan ishlaydigan tsikllar (ular darhol keshlanadi) kodni juda tez bajariladigan bayonotlar ketma-ketligiga aylantiradi.

Aytgancha, agar siz NATIVELY COMPILED funksiyasini o'rab qo'ysangiz, u vaqt so'rashni to'xtatadi va uning tezligi 10 barobar ortadi.Kooperativ multitasking haqida nima deyish mumkin? Lekin mahalliy kompilyatsiya qilingan kod uchun biz SQL da PREEMPTIVE MULTITASKING ni bajarishimiz kerak edi.

Manba: www.habr.com

a Izoh qo'shish