Azt játszom a Microsofttal, hogy az Azure-ban
szándékosan, és lehetőleg a legvégsőkig a legkisebb szerverpéldánnyal
futtatom a weblapunkat. Small instance, egyetlenegy proci, 2 GB ram,
amíg bírja. Ez a kis konfiguráció szolgálja ki az itfactory.hu-t és a
netacademia.net, .hu-t is. Pörgősen teszi, bírja akár a többszáz fős
tanfolyamokat is. Erre pedig azért képes, mert kesselünk, mint az ördög,
az SQL Servert – ha lehet – egyáltalán nem kérdezzük le, és van
OutputCache-rendszerünk is, fut ez, mint a villám. Sőt, olyan gyorsan
fut, hogy csak kapkodom a fejem. (Korábban azt hittem, ez a teljesítmény
MS-platformon egyáltalán nem lehetséges, mert amilyen lassú mondjuk
maga az Azure.com, meg a LiveID-bejelentkezés (mondjuk ki: szánalmas),
arra a téves következtetésre jutottam, hogy nagy teljesítményű, friss,
gyorsan válaszoló webalkalmazást nem is lehet ezzel a felálással
készíteni. De lehet, csak kesselni kell, mint az ördög és az SQL Server
folyamatos szólongatását hanyagolni kell.
Szóval szépen megy
minden, fillérekért. Mégis, valahányszor nyílt napot hirdetünk, mindig
letérdel az egész, nem tudok mást tenni, mint hirtelen a Scale Up
funkcióhoz nyúlni, hozzácsapni még 6-8 szervert, amíg az esemény tart.
Ez egy bosszantó és zsebmetsző dolog, ezért úgy döntöttem, kimérem,
miért pont a nyílt napokon térdel le rendszeresen?
Elsőként
különböző http-teszteket futtattunk, aminek a részleteivel nem untatnám a
Tisztelt Érdeklődőket, hisz ez egy SQL-blog, hanem rögtön a
végeredményhez ugrok: az autentikáció miatt borul össze. Az pedig azért
van, mert a logint nem lehet bekesselni. Minden mást nagyjából igen, de
bejelentkezéskor mindenképpen az SQL Serverhez kell fordulni, hogy
létezik-e Gipsz Jakab, ezzel és ezzel a jelszóval?
Kezdjük
azzal, hogy az ASP.NET Forms autentikáció alaptábláin nincs egy darab
index sem. Ami nem is baj addig, amíg az embernek 4-5 júzere van. Na hát
ez nálunk egy picit magasabb szám, a százezret verdesi alulról. Ilyen
mennyiségű rekordszámon a sima Table Scan azért eltart egy darabig.
Konkrétan a rendszerünk jelenleg másodpercenként fél logint tud
megcsinálni
És
már meg is van, miért válik elérhetetlenné egy-egy nyílt napon:
ilyenkor szite egyidőben szeretne bejelentkezni 600-800 fő. Mindegyik
olyan 2-2 másodpercre kiakasztja a procit. A teljes létszám
bejelentkeztetése 1600 másodpercbe telne, ha csak ez az egy folyamat
futna. Na de ez enm így van, hisz a loginon felül weblapot is kellene
adni, meg SilverLight klienst meg kukit meg mittudomén miket. Ebből már
látszik is, hogy fél órára simán kiakad az egész hóblebanc.
Oldjuk meg a feladatot!
Első kísérletképpen tettem egy indexet a Users tábla Username mezőjére, mondván hogy a bejelentkezéskor erre keresünk rá.
create index usernameindex on users(username)
Remek.
A gyorsulásunk azonban kerek 0% lett! Valami miatt a rendszer nem
használja a szuperjó indexemet. Biztos azért nem csináltak “gyárilag”,
mert tudták, hogy felesleges
Nincs
mit tenni, ki kell mérni, mit is futtat az MVC, amikor bejelentkezünk.
Nosza, elő egy SQL Profilert! (Ez persze nem ilyen egyszerű, Azúrban
lévő SQL-adatbázisról lévén szó. Itt lerövidítve közlöm a történetet.)
Ez itt a bejelentkezés első lekérdezése (kigyomláltam a lényegtelen részeket):
select * from users where lower(UserName)='asdasd'
És
már meg is találtuk, miért nem használja az indexemet! Hát azért, mert
az ügyes redmondi fiúk ennek elejét vették azzal, hogy a
WHERE-feltételben a mezőm értékét kisbetűsítik. Ha nem lenne ott az a
lower(), rögtön indexhez nyúlna, és körülbelül harmincszor gyorsabban
futna le. Íme a bizonyíték (mindkér változat végrehajtási tervét
egyszerre kértem le, CTRL+L):
Nos,
ez most már megvan, de vajon hogyan lehetne rávenni a Membership
providert, hogy ne csinálja ezt a balfékséget (lower()), és ne vegyen ki
a zsebemből egy csomó pénzt?
Újra kellene írni az egészet, azt hiszem
Mert ha már hozzányúlok, akkor ezt is kesselni kellene (mint az
ördög!), mert például most vettem észre, hogy bizonyos lekérdezéseket
duplán futtat le. Arról nem is beszélve, hogy minden bejelentkezésnél
felülírja a LastLoginDate mezőt, ami egy fincsi Update utasítás bele a
közepébe… ami mindig elakad persze, mert a többi Login fogja az egész
táblát. Na de írjon providert, akinek nincs jobb dolga. Akkor viszont
zsákutcába jutottam.
Szép kis kalamajka! Nincs valakinek egy épkézláb ötlete?
Elküldve
2014. 02. 03. 15:08
by
Lecram
Megtekintve:
376
alkalommal