In het land der blinden... part 5

Helaas kan ik ditmaal geen bedrijven aan de haren erbij sleuren en met namen gaan smijten; de 'stakes' liggen ditmaal érg hoog en we hebben het nu over bedragen van ettelijke tonnen aan software, nogmaals tonnen aan consultancy en tonnen aan overboord gemikkerde "cross your fingers and pray it works" oplossingen welke dus niet deden wat ze hoorden te doen. Ook kan ik, helaas weliswaar, niet alles uit de doeken doen of te specifiek worden omdat ditmaal dit blogitem niet is 'goedgekeurd' door de opdrachtgever. Niet omdat ze dat niet zouden doen maar omdat ik het niet aan ze heb voorgelegd om redenen die je verder niets aan gaan (en de ruzie die nog steeds woedt tussen hen en de software leverancier)

Het verzoek
Een paar maanden geleden werd ik benaderd door een goede klant van ons; ik zal ze voorlopig even Happy'n'Merry Inc. noemen; H&M zeg maar

Na dit korte telefonische verzoek, waarin ik meteen vertelde dat linksom of rechtsom de uitslag ze niet zou bevallen, werd besloten dat ik toch maar even op locatie moest gaan kijken. De reden waarom de uitslag niet zou bevallen en waarom ik dat al voorzag is simpel: Zou de applicatie ernstige problemen hebben dan moest er voor veel geld geïnvesteerd worden in een fix want een applicatie in die orde van grootte nestelt zich in ieder hoekje van je bedrijf en die kiep je dus niet even in een week buiten om te vervangen door een concurrerend product. En zou de applicatie wél deugdelijk zijn dan kon er niets aan gedaan worden behalve voor veel geld investeren in meer en betere hardware. Ongeacht mijn conclusie zou het ze veel geld gaan kosten en, at best, een werkbare situatie leveren die natuurlijk bij oplevering al geweest had moeten zijn. Het enige wat ze konden winnen met een technisch onderbouwde evaluatie was een stok om de softwareleverancier mee te slaan.
Ik ben dus, schoorvoetend omdat ik weet waar dit doorgaans op uit draait, op onderzoek uit gegaan. Ik had, omdat het systeem zo goed als 24/7 in bedrijf is, weinig kans om in de daadwerkelijke productieomgeving te kijken maar heb dat wel zo nu en dan toch even gedaan. Al met al was mijn bezoekje iets van 2 tot 3 uur tijd waarvan ik het grootste deel van dat bezoek vooral moeite heb moeten doen om mijn lach te bedwingen en ettelijke explosies van complete furie vanwege de schandalige kwaliteit van de software te onderdrukken. "Maar RobIII, hoe kun je dan zo'n applicatie, zonder specifieke domeinkennis, en in zo'n korte tijd, beoordelen?". Nou; oordeelt u zelf maar even mee en spot de WTF's...
Harware
Het grootste 'slachtoffer' was, voor mij, het arme 2U servertje dat de applicatie draaide; deze kreeg het meest op z'n donder in het hele verhaal. De software van Monster Inc. draaide op een, door hunzelf geadviseerde en voor H&M op maat 'berekende', Windows 2003 Server (64 bits) met 2 quad core XEON processors en 8Gb geheugen. De snelheid van deze processors is me helaas niet bijgebleven maar zelfs in het allergunstigste geval, uitgaand van state-of-the-art huidig leverbare modellen, niet echt relevant. De database is MSSQL Server 2005 Standard Edition (64 bits). De database was, op dat moment, ruim 90 Gigabyte groot (waarbij de log bestanden nog niet meegeteld zijn) en was opgeslagen op een RAID5 systeem. Er waren, doorgaans, 50+ concurrent gebruikers verbonden met SQL server.
Database - Tabellen
Bij het bekijken van de database, het hart van de applicatie, vielen een aantal zaken vrijwel meteen op. Zo bestond de DB uit, op dat moment, 3.256 tabellen. Dit aantal alleen al is een behoorlijke indicator van de kwaliteit van de architectuur van de applicatie (of het gebrek daar aan).
Van die tabellen werd, steekproefsgewijs vanwege het enorme aantal, geconcludeerd dat er een aantal tabellen aanwezig waren met 475+ velden. Ook dat aantal is wederom een reden om vraagtekens te gaan zetten bij de oplossing die Monster Inc. geproduceerd heeft. In de gevallen waar het toch voorkomt is het doorgaans een, voorzichtig gesteld, "gebrekkig" ontwerp. Van deze tabellen was de naamgeving ervan ook al een goede indicator; Het leek er op dat deze machinaal gegenereerd waren (wat doorgaans architectonisch en kwalitatief slecht blijkt te gaan). Tabelnamen als sy8326_001_5096_xo04, sy0860_000_0119_09B4_scr02 en du612099_lib04 zijn voor mensen doorgaans niet erg bruikbaar. Daarbij bleken er veel tabellen aanwezig met namen als vi2650_001_20090302, vi2650_001_20090402 en vi2650_001_20090502 wat er op wijst dat er maandelijks een nieuwe tabel in gebruik wordt genomen voor het opslaan van bepaalde data. Ook dit valt onder een "bad practice". Hoewel het in een aantal gevallen vanwege partitionering of archivering van gegevens bijvoorbeeld te verdedigen zou zijn leek het in dit geval niet aan de orde en helaas onderdeel te zijn van de vele slechte ontwerpkeuzes in de Monster Inc. applicatie.
Van deze tabellen werden er een aantal waargenomen waarbij "samengestelde primary keys" (compound primary keys) bestonden uit 5 of meer velden; in een extreem geval werd het aantal 13 zelfs waargenomen (welke tot overmaat van ramp ook nog clustered bleek te zijn); op onderbuikgevoel (wegens gebrek aan domein specifieke kennis van de gegevens erin) leek dit een rampzalige keuze te zijn geweest wegens a) de onwaarschijnlijke grootte van de samengestelde PK en b) de zeer waarschijnlijk niet-sequentiële aard van de gegevens erin welke een drastische performance impact hebben wegens clustering van de key. Vele tabellen bevatten velden van het type "Binary/BLOB" welke, op het oog, niet veel meer dan platte tekst leken te bevatten. De keuze voor binary zou, wanneer deze gegevens inderdaad platte tekst zouden zijn, minstens"vreemd" te noemen zijn.
Database - Views
De 58 views die de database rijk was zijn ook steekproefsgewijs bekeken. Een flink aantal daarvan, zo niet alle, bleken niet veel meer te doen dan gegevens uit verschillende'maandtabellen' te combineren middels een Union. An sich is dit geen vreemd gebruik; echter wegens de waarschijnlijk non-existente reden voor het bestaan van de 'maandtabellen' had dit al voorkomen kunnen worden. Daarbij bleek het SQL statement waaruit deze views bestaan in vele gevallen enkele tientallen en in veel gevallen zelfs honderden Kilobytes groot te zijn. In een extreem geval (let wel; ik heb enkel steekproeven genomen) bleek het SQL statement 215+ Kilobyte groot te zijn en middels een Union 25 tabellen zonder enige restricties in where-clauses (sterker: een compleet gebrek aan where-clauses) samen te voegen. Daarbij moet opgemerkt dat het aantal velden dat de SELECT retourneerde 373 velden bedroeg. Wederom een voor menselijke begrippen amper te bevatten enorm brouwsel aan onbegrijpelijke velden als RG3177_PR_EINHEIT_2, RG3775_MTV_B_MAX_ART_WERT en RG3177_SORT_GRP_10. Vele views bleken 300+ velden te retourneren en, zoals gezegd, enorme unions aan te gaan op vele, vele tabellen. Het zal zélfs de doorgewinterde DBA's inmiddels beginnen te duizelen.
Database - Algemeen
De database bleek, na enig onderzoek en tijdelijk aan mijn eigen kunnen getwijfeld te hebben, geen enkele Foreign Key te bevatten. Geen enkele. Ik heb een script ter plekke moeten schrijven om alle tabellen na te lopen om zéker te weten dat ik niet gek werd. Het hele nut van het gebruik van een RDBMS als SQL server (waarbij RDBMS staat voor Relational Database Management System en dus de R in deze afkorting volledig teniet wordt gedaan) is hierdoor zo goed als overbodig. Foreign Keys zorgen ervoor dat SQL server kan garanderen dat data consistent is en blijft. Het ontbreken van een FK kan, in bepaalde gevallen, verdedigd worden. Het ontbreken van enige FK in een database met ruimschoots 3.000 tabellen is echter ronduit ongehoord. Hierdoor komt de verantwoordelijkheid van het consistent houden van de data volledig bij de software te liggen en, hoewel dat in kleine(re) projecten soms nog te doen is, dat zal op den duur en zeker op deze schaal zo goed als gegarandeerd inconsistente data betekenen met alle gevolgen van dien. De schaal van de impact was moeilijk in te schatten en zal, afhankelijk van waar de inconsistenties optreden, groter of kleiner zijn maar het idee ervan alleen al deed me huiveren.
Tijdens mijn bezoek heb ik, érg omzichtig uiteraard, een "Profiler Trace" uitgevoerd op het gebruik van de database in een "real life scenario" (lees: in de productieomgeving). Deze trace werd, vanwege mijn voorzichtigheid, na een enkele minuut reeds gestopt. Tijdens een dergelijke trace wordt feitelijk het gebruik van de database aan een "hartmonitor" gehangen en wordt inzichtelijk gemaakt hoe de database door de vele gelijktijdige gebruikers benaderd wordt en welke gegevens opgevraagd worden. Vanwege diezelfde voorzichtigheid heb ik de trace erg compact gehouden en zijn de verkregen en gemeten gegevens dus erg beknopt geweest. Toch kon op basis hiervan ook een aantal conclusies getrokken worden. Zo kwam er tijdens deze trace geen enkele "join" voorbij; iets wat, zeker gezien het aantal gelijktijdige gebruikers en het aantal benaderingen van de DB in die tijd, toch wel verwacht mag worden. Een "join" koppelt gegevens van bepaalde tabellen aan elkaar en relateert dus feitelijk gegevens uit verschillende tabellen aan elkaar. Dit zijn bewerkingen waar SQL Server uitermate geschikt voor is en vallen onder basisprincipes van het opvragen van gegevens. Het gebrek aan deze joins en de manier waarop de DB benaderd wordt blijkens de trace wees er op dat de gegevens allemaal door de clientsoftware aan elkaar gekoppeld en dus gerelateerd werden. Dit betekent tevens dat de DB onnodig vaak benaderd zal worden om gegevens uit tabel X en dan weer uit Y en dan uit Z op te halen en verklaart, zoals overigens de meeste zo niet alle waarnemingen, de klacht dat het pakket onwerkbaar traag was.
Een flink aantal van de benaderingen die de cliëntsoftware op de DB uitvoerde bleek ook nog eens vele, vaak honderden, velden te bevragen uit tabellen. De hoeveelheid gegevens die opgevraagd werden leken te veel te zijn voor het praktisch gebruik dat de gebruikers van de software plegen. Het is haast ondenkbaar dat gebruikers op bepaalde momenten inzage nodig hebben in honderden velden. Uiteraard kan de hoeveelheid verklaard worden doordat deze nodig zijn voor intern gebruik van de software (en dus niet zo zeer het presenteren van die gegevens aan de gebruikers in een GUI) maar wederom zei mijn onderbuikgevoel dat dit niet het geval was. Tevens bleken alle verbindingen met de clients tijdens de trace gebruik te maken van het SA account; het "System Administrator" account. Dit betekent dat de software volledige toegang heeft tot alles, maar dan ook alles, binnen de database. An sich hoeft dit geen probleem te zijn zolang de software geen fouten bevat en gebruikers afschermt van acties waartoe zij niet gemachtigd zijn maar dan worden er dus onwerkelijke aannames gedaan dat a) de software geen fouten bevat (dat is een utopie) en b) gebruikers geen fouten maken of c) gebruikers geen kwaad zouden kunnen willen (denk aan ontevreden werknemers etc.). Het gebruik van het SA account zet dan ook de deur wagenwijd open voor catastrofes op enorme schaal.
Database / cliëntsoftware - Cursors
Een andere waarneming die ik deed en welke wél, tot op bepaalde hoogte, wat diepgaandere analyse heeft gehad, is dat ik zag dat alle benaderingen op de SQL server gebruik maakten van "server-side cursors". Hierbij doelen we niet op de bekende "cursors" binnen SQL server maar op driver-niveau aanwezige cursors. Software kan de SQL server op 2 manieren (2 cursors) benaderen; server-side cursors en client-side cursors. Bij het gebruik van client-side cursors wordt (eenvoudig gezegd) de SQL server benaderd voor bijv. het opvragen van bepaalde gegevens welke bijv. 10 resultaten zal opleveren. In het geval van een client-side cursor zullen deze 10 resultaten alle 10 meteen naar de client gestuurd worden. Dat houdt in dat er een enkele "roundtrip" naar SQL gemaakt wordt. De client benadert de server en ontvangt de resultaten.
Wat ik echter waarnam was het gebruik van server-side cursors. Het bestaan ervan alleen al is indicatie dat er reden is om hiervoor te kiezen; het is echter ten minste twijfelachtig te noemen dat deze zo frequent gebruikt werd. De werking van een server-side cursor is als volgt: De client benaderd de server, zoals in voorgaand voorbeeld, voor bepaalde gegevens. Wederom zal de server 10 resultaten verzamelen op basis van de vraag. Echter, in dit geval, retourneert de server volgens onze trace maar een enkel resultaat. Wanneer de client dit ontvangen heeft en het volgende resultaat wil hebben zal deze opnieuw de server moeten benaderen waarop deze het tweede resultaat retourneert. Dit zal zich, wanneer de client over alle 10 resultaten wil beschikken, dus 10 maal herhalen en dus 10 "roundtrips" betekenen. Dit houdt in dat het netwerk ook zwaarder belast wordt. Bedenk daarbij dat dit door 50+ clients gedaan wordt, SQL server van alle 50+ clients de (tijdelijke) resultaten zal moeten vasthouden voor volgende benaderingen etc. en duidelijk mag zijn dat de belasting vele malen zwaarder is voor het netwerk en de servers resources als CPU cycles en geheugengebruik. Ook de I/O resources zullen zwaarder belast worden welke toch al, wegens alle waarnemingen over o.a. de tabellen zoals eerder beschreven, erg hoog waren. Het is mogelijk om deze belasting te verlagen door, wanneer er toch vastgehouden wordt aan het server-side cursor principe, de server te vragen telkens meer dan 1 resultaat te retourneren. Zo kan, als voorbeeld, gevraagd worden om 5 resultaten per keer te retourneren. Dit zal betekenen dat er feitelijk, voor 10 resultaten, maar 2 "roundtrips" naar de server nodig zijn en de belasting op alle voorgenoemde resources en het netwerk verlagen (let wel: niet halveren!). In ons voorbeeld hebben we het over 10 resultaten maar het wordt pas écht interessant wanneer het over tientallen, honderden of zelfs duizenden resultaten gaat. Wat de beste "keuze" is voor het aantal resultaten geretourneerd per keer is zo niet te zeggen, maar vast staat dat het lang niet altijd 1 zal zijn. De trace toonde echter vele, vele "exec sp_cursorfetch x,y,z,1" statements waarbij x, y en z niet relevant zijn en de 1 aantoont dat er om een enkel resultaat wordt gevraagd door de client software (bron, zie punt 2). Naar mijn mening kan dit onmogelijk gunstig zijn geweest.
Software - Algemeen
Hoewel buiten de scope van het verzoek dat aan mij gericht was (ik werd er bij gehaald vanwege mijn SQL kennis), heb ik toch even gekeken naar de applicatie zelf. Omdat ik inhoudelijk niet kon oordelen over de werking van de applicatie heb ik dat dan ook nagelaten. De applicatie bleek, hoewel traag, wel te voldoen aan de vraag over het algemeen genomen; voor zover ik kon beoordelen althans en van de gebruikers vernam. Toch heb ik wat kanttekeningen gemaakt met betrekking tot de software architectuur van de applicatie. Zoals eerder besproken werd is de manier waarop de software de database benaderd twijfelachtig. Ook bleek de applicatiemap waarin de software stond 11.995 DLL bestanden te bevatten; een astronomisch aantal. Ook hier bleek de naamgeving van de bestanden erg "exotisch" te noemen en wees alles weer op machinaal gegenereerde bestanden (en dus code). Ter indicatie; een "aardig volle" PC met Windows en daarop geïnstalleerde allerhande software bevat rond de 4.000 a 8.000 DLL bestanden. Het aantal van bijna 12.000 bestanden an sich is al reden om verbazing te wekken, de daarbij toegepaste naamgeving (ev5762.dll, ev5765.dll, ev5767.dll, ko260902.dll, ko261003.dll etc. etc.) bevestigde enkel wederom mijn vermoeden van slecht doordachte software architectuur.
Deze hoeveelheid bestanden betekent ook, en dat is ook waargenomen, dat de gemiddelde client die de Monster Inc. software start tijdens het gebruik vele tientallen tot honderden file handles in gebruik heeft in een sessie. Dat betekent veel 'administratief werk' voor de server; in dit geval bleek tot overmaat van ramp de "file server" welke de bestanden bevatte ook nog eens dezelfde machine te zijn die de SQL Server taak toegewezen had gekregen. Deze had, zoals aangetoond, toch al een flinke belasting van de beschikbare resources.
Conclusie
Hoewel er dus her-en-der misschien wat zaken met een goede onderbouwing enigszins te verdedigen zouden zijn was de totale ervaring die ik daar opdeed niet al te best. Het mag een wonder heten dat 't gedrocht überhaupt iets deed en dat Monster Inc. weg kwam (en komt) met deze wanstaltige software. De conclusie van mijn 7 pagina's tellende rant rapport laat zich raden. Hoe dat afliep en hoe het gesprek ging toen ik op 't matje werd geroepen door Monster Inc. om mijn rapport toe te lichten bewaar ik voor deel 6















08-'09 In het land der blinden... part 6
08-'09 In het land der blinden... part 4
Reacties
Ik ben zelf software ontwikkelaar, en zal de laatste zijn om te beweren dat ik daarin extreem goed ben, maar hier krijg je gewoon kippenvel van

Hoe komen leveranciers erbij om dit soort draken van software op te leveren, en op deze manier te configureren. Volgens mij is 1 van de basisdingen dat je applicatieserver en databaseservers op 2 aparte machines installeerd

Leuk gemaakt met de foto's erbij.
Hier op het werk draaien wij sinds een tijdje een nieuw administratief en voorraadtechnische applicatie en een nieuwe server met Windows server 2008 Standaard...De server is ongeveer van het kaliber wat hierboven is beschreven alleen dan maar 500GB in 2 disk raid geloof ik. Het software programma is een Béta versie waar de foutmeldingen je om de oren vliegen en waar iedereen op de zelfde "demo" inlog zit te werken. Ook hier is gekozen voor 1 en dezelfde server voor applicatie en database omdat dat goedkoper is... lang verhaal kort: zodra er wat te besparen valt of mensen hebben het idee dat ze eerder kunnnen leveren doordat er geen verstand van zaken is of er niet naar word geluisterd (zoals in mijn geval) omdat er kosten bespaard moeten worden...
Het enige wat die server nu staat te doen is het nieuwe programma te draaien terwijl het eigenlijk de bedoeling was om de terminal server kant op te gaan. De rest van alle werkzaamheden gebeuren nog steeds lokaal dus die server staat uit z'n neus te vreten als een lamme.
Mooi verhaal iig. Ik kijk uit naar de volgende versie.

[Reactie gewijzigd op maandag 24 augustus 2009 09:22]
@ BM
Overigens is het met de moderne server steeds minder noodzakelijk om per rol een nieuwe server te hebben. Meestal is het niet de processor of geheugen wat de beperkende factor is van de server maar de schijven. Als je de applicaties over verschillende raidsets verdeelt zullen ze elkaar weinig in de weg zitten.


[Reactie gewijzigd op maandag 24 augustus 2009 10:11]
Verder als ik zo die structuur van de tabellen/dll's zie doet het mij sterk denken aan een code-generator op basis van een business model? Daar komt dan idd crap code uit die idd wel vaak doet waar het bedoeld voor is.
Oa cap gemini is daar wel fan van.
Het zou misschien niet slecht zijn om een grote schandpaal website te starten op internet met projecten, de uitvoerder en technische argumenten waarom die app nooit zou mogen bestaan, enkel de nda's houden me tegen



Onbruikbaar, Onwerkbaar, heb daar op zes maand tijd (kort lopend project) alles overhoop gehaald, DB volledig herschreven en de van hun javaapplicatie afgestapt en naar een simpele webapplicatie gegaan middels php ... resultaat, twee servers zijn nu buiten dienst gesteld omdat ze compleet overbodig zijn en de langste opbouwtijd van een pagina is 0,9 seconden, waardoor de gebruikers tegenwoordig meer dan tevreden zijn. En ik een aanbod gekregen heb om bij hen in vast dienstverband te gaan (wat ik trouwens geweigerd heb)
Erg jammer hoe GROTE bedrijven zo'n brakke software uitleveren om dan nog te zwijgen over de prijzen die ervoor betaald worden.

je verhaal is schitterend geschreven en voor de meeste (applicatie)beheerders te herkenbaar voor woorden, ik dacht even dat je het over software had die bij mijn laatste project gebruikt werd XD (maar dat was in-house ontwikkeld ipv door MI)

Ik moet van deze blog bijna huilen

Je doet alsof java daar een rol inspeelt, je kan in elke taal slecht programmeren, als je in php je hele db binnentrekt en daarin je bewerkingen doet loopt dat net zo goed slecht af.
Java zal indien goed gebruikt volgens mij zelfs een pak sneller zijn dan standaard php (volledige parsing vs bytecode+hotspot optimizations).
--
Dit doet mij trouwens terugdenken aan wat korte ervaring met navision, nu microsoft dynamics, dat ding maakte ook aan de lopende band tabellen aan. Dus ook zeker kans dat het dat is, als dat zo is kan dit best een interessant artikel zijn aangezien er nu een evaluatie onderweg is om naar dynamics te switchen.
[Reactie gewijzigd op maandag 24 augustus 2009 11:40]

Ben benieuwd of er volgende week een paar honderd tabellen en DLL's extra zijn

[Reactie gewijzigd op maandag 24 augustus 2009 15:43]



Eensch met Nmal! Prachtig verhaal!quote: NMalik zeg: insturen naar thedailywtf.com


Heb zelf weinig tot geen ervaring met Windows servers, maar wat was de load/belasting van die server?
Waar blijft part 6? Ben eigenlijk wel benieuwd hoe het gesprek bij Monsters Inc. is verlopen!





Ik hou je blog wel in de gaten!
ps,
geen tijd om te bloggen maar wel in 2 minuten reageren? Ga eens werken man

Reageren is niet meer mogelijk