Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... ·...

98
Academiejaar 2013–2014 Faculteit Ingenieurswetenschappen en Architectuur Valentin Vaerwyckweg 1 – 9000 Gent Ontwerp en implementatie van een framework om shopfloorberichten te monitoren Begeleiders: Jimmy HAEGEMAN Raf KEGELEERS Yves CHAVES Jonas WILLE Promotoren: dr. Leen BROUNS Hein VANHOUTTEGHEM Jens VANDECASTEELE Masterproef voorgedragen tot het behalen van het diploma van Master in de industriële wetenschappen: informatica Powered by TCPDF (www.tcpdf.org)

Transcript of Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... ·...

Page 1: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

Academiejaar 2013–2014 Faculteit Ingenieurswetenschappen en Architectuur

Valentin Vaerwyckweg 1 – 9000 Gent

Ontwerp en implementatie van een

framework om shopfloorberichten te

monitoren

Begeleiders: Jimmy HAEGEMAN

Raf KEGELEERS

Yves CHAVES

Jonas WILLE

Promotoren: dr. Leen BROUNS

Hein VANHOUTTEGHEM

Jens VANDECASTEELE

Masterproef voorgedragen tot het behalen van het diploma van

Master in de industriële wetenschappen: informatica

Powered by TCPDF (www.tcpdf.org)

Page 2: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

VOORWOORD ii

Voorwoord

Als eerste zou ik graag dhr. Jürgen Blondeel willen bedanken die een stage op Volvo

mogelijk gemaakt heeft. Verder wil ik mijn begeleiders , Yves Chaves, Raf Kegeleers en

Jonas Wille, bedanken voor de hulp en bijdrage tot deze masterproef. Daarnaast wil ik

ook Tom Geens bedanken voor het nalezen van de masterproef en het uittesten van het

framework. Ook de andere collega's op Volvo ben ik dankbaar voor de aangename sfeer

op de werkvloer. Als laatste zou ik ook graag mijn interne promotor, Leen Brouns, willen

bedanken voor de feedback en het nalezen van de scriptie.

Bedankt.

Jens Vandecasteele, juni 2014

Page 3: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

ABSTRACT iii

Abstract

In deze masterproef wordt een framework ontworpen om shop�oorberichten te monitoren.

Er wordt ook dieper ingegaan op de technische kanten van de implementatie. Als eerste

worden er twee ontwerpen met elkaar vergeleken. Bij het eerste ontwerp staat een actief- en

historiektabel centraal, bij het andere wordt er gebruikgemaakt van partitioning. Hierbij

is het vooral van belang dat de continue stroom aan berichten performant opgeslagen

kunnen worden op de databank en vervolgens eenvoudig en snel opvraagbaar zijn in tijden

van nood. Ten tweede werden er ook con�guratieschermen voorzien om de parsers in te

stellen die het bericht verwerken. Via deze schermen wordt ook de con�guratie verzorgd

van het opkuisprogramma dat periodiek loopt om oude records te verwijderen. Ten derde

werd er een loadbalancer ingezet om de werklast te verdelen over de verschillende processen.

Aansluitend werd dan ook het framework uitvoerig getest om de performantie na te gaan.

Tot slot volgt er een onderzoek naar interval-partitioning, de mogelijkheid om nadien te

parsen en het performanter maken van het opvragen van logberichten.

Page 4: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

ABSTRACT iv

Abstract

This paper describes the design of a framework to monitor shop �oor messages. Fur-

thermore it contains technical details about the implementation. It all starts with the

comparison of two designs. The �rst design embodies an active and history table, the

other one uses partitioning. The most important requirement is to save a continuous �ow

of messages in a performant way. Afterwards these messages should be easily accessible in

times of need. Additionally, it had to be possible to con�gure the parsers and the clean-up

program, which periodically runs to delete old records. A load balancer was used to di-

minish the workload across multiple processes. The paper concludes with research about

interval partitioning, the ability to parse logging messages after saving them on database

and enhancing the performance of fetching logging messages.

Page 5: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

INHOUDSOPGAVE v

Inhoudsopgave

Voorwoord ii

Abstract iii

Abstract iv

Inhoudsopgave v

1 Inleiding 1

2 Speci�eke Volvo-omgeving 3

2.1 SduClient - TClient - TServer . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.2 Scheduled en detached batch . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.3 ValueList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.4 Taalonafhankelijkheid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.5 Beperkingen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3 Ontwerp 7

3.1 Actief-historiek ontwerp . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3.2 Partitioning ontwerp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.3 Samenvatting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

4 Functionele analyse 12

4.1 Verwerken van binnenkomende berichten . . . . . . . . . . . . . . . . . . . 12

4.1.1 Loadbalancing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

4.1.2 Webservice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

4.2 Gebruikersscherm voor parserbeheer . . . . . . . . . . . . . . . . . . . . . . 14

4.3 Gebruikersscherm om logberichten te bekijken . . . . . . . . . . . . . . . . 17

4.4 Periodiek partities verwijderen en toevoegen . . . . . . . . . . . . . . . . . 20

4.5 Beheerscherm voor partitiecon�guraties . . . . . . . . . . . . . . . . . . . . 22

4.5.1 Hoofdscherm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

4.5.2 Mappingscherm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

Page 6: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

INHOUDSOPGAVE vi

4.5.3 Detailscherm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5 Partitioning 25

5.1 Algemeen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

5.2 Impact van onderhoudsoperaties . . . . . . . . . . . . . . . . . . . . . . . . 27

5.3 Partities toevoegen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

5.4 Partities verwijderen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

5.5 Create table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

5.6 Fetching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

5.7 Opvolging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

6 Technische analyse 33

6.1 Verwerking van binnenkomende berichten . . . . . . . . . . . . . . . . . . . 33

6.1.1 Loadbalancing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

6.1.2 Webservice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

6.1.3 Overzicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

6.1.4 Parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

6.2 Gebruikersscherm voor parsers . . . . . . . . . . . . . . . . . . . . . . . . . 39

6.2.1 Dynamisch herladen van de parsers . . . . . . . . . . . . . . . . . . 39

6.3 Periodiek partities verwijderen en toevoegen . . . . . . . . . . . . . . . . . 41

6.3.1 Resterende tijd opvragen . . . . . . . . . . . . . . . . . . . . . . . . 42

6.3.2 Oude partities verwijderen . . . . . . . . . . . . . . . . . . . . . . . 42

6.3.3 Toevoegen van nieuwe partities . . . . . . . . . . . . . . . . . . . . 44

6.4 Beheerscherm voor partitiecon�guraties . . . . . . . . . . . . . . . . . . . . 46

6.4.1 Werking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

6.4.2 Zoeken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

7 Testing 48

7.1 DbUnit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

7.2 Liquibase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

7.3 EasyMock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

7.4 Partitioning testomgeving . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

7.4.1 Opstelling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

7.4.2 Resultaten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

7.4.3 Bevindingen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

7.4.4 Conclusie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

8 Resultaten 54

8.1 Stresstest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

8.1.1 Lokaal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

Page 7: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

INHOUDSOPGAVE vii

8.1.2 VMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

8.1.3 Conclusie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

8.2 Opvragen logberichten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

8.2.1 Opstelling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

8.2.2 Bevindingen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

8.2.3 Conclusie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

9 Uitbreidingen 58

9.1 Gebruikersscherm voor logberichten . . . . . . . . . . . . . . . . . . . . . . 58

9.1.1 Aanpassingen aan Hibernate . . . . . . . . . . . . . . . . . . . . . . 58

9.1.2 Opzoeken met JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . 60

9.2 Slimmer maken van partities toevoegen . . . . . . . . . . . . . . . . . . . . 62

9.3 Verplaatsing van de parsingfunctionaliteit . . . . . . . . . . . . . . . . . . 62

9.3.1 ScheduledExecutorService . . . . . . . . . . . . . . . . . . . . . . . 62

9.3.2 Java.util.Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

9.3.3 Quartz scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

9.4 Interval partitioning bij Oracle 11g . . . . . . . . . . . . . . . . . . . . . . 65

10 Algemene conclusie 67

A Databanktabellen 69

B Klassendiagram van webservice en loadbalancer 71

C PL/SQL insert testomgeving 72

D Resultaten testomgeving 74

E Resultaten Hibernate 79

F Resultaten lokale stresstest 81

G Resultaten OpenVMS stresstest 84

Bibliogra�e 85

L¼st van �guren 87

L¼st van tabellen 88

Lijst van codefragmenten 90

Page 8: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

INLEIDING 1

Hoofdstuk 1

Inleiding

Deze masterproef werd uitgewerkt onder begeleiding van Volvo Car Gent. Volvo Car

Gent is één van de drie hoofdassemblagefabrieken van Volvo Car Corporation. De andere

assemblagefabrieken zijn Volvo Car Torslanda (Zweden) en Volvo Car Chengdu (China).

In Gent werken ongeveer 5000 werknemers aan vier verschillende Volvomodellen: de Volvo

S60, XC60 en de volledig vernieuwde V40 en V40 Cross Country. Om de productie van

wagens makkelijker op te volgen is er nood aan bijkomende software. De bedoeling is

om een framework te ontwikkelen dat shop�oorberichten1 monitort. Dit houdt in dat

er een continue stroom van logberichten opgevangen, verwerkt en opgeslagen zal worden.

Vervolgens moeten de verwerkte data eenvoudig geconsulteerd kunnen worden.

Concreet houdt dit het volgende in:

� Loggen van alle acties van de shop�oordevices2.

� Zorgen dat alle berichten geparset worden en opgeslagen worden in een databank.

� Zorgen dat de data ten gepaste tijde verwijderd worden.

� Ontwikkelen van een user interface met diverse selectiemogelijkheden om de logbe-

richten op te vragen voor een bepaald tijdsinterval, voor een bepaalde installatie of

voor een bepaalde wagen. Het resultaat moet zijn dat de data in een leesbaar formaat

getoond worden, zodat dit programma gebruikt kan worden door een niet-IT-pro�el.

� Ontwikkelen van een scherm waarin beheerd wordt hoe de verschillende berichten

geparset moeten worden om deze op een goede manier in de databank op te slaan.

1toestellen aan de productielijn sturen constant berichten uit die opgevangen moeten worden2toestellen aan de productielijn, bv. PLC, RFID antenne, lasrobot,...

Page 9: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

INLEIDING 2

Als eerste wordt er wat meer uitleg gegeven over de speci�eke Volvo-omgeving. Vervolgens

worden er twee ontwerpen nader bekeken en vergeleken met elkaar om uiteindelijk het beste

ontwerp dieper uit te werken. In de verdieping wordt eerst kort uitgelegd wat de algemene

functionaliteit van de uiteindelijke componenten is. Vervolgens wordt het principe en de

impact van partitioning van Oracle uitgewerkt, gevolgd door de technische aspecten van

de eindcomponenten. Daarna volgen de resultaten van de implementatie, aangevuld met

bedenkingen en uiteindelijke keuzes.

Page 10: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

SPECIFIEKE VOLVO-OMGEVING 3

Hoofdstuk 2

Speci�eke Volvo-omgeving

Op Volvo bestaan er verschillende systemen. De systemen waarop deze masterproef be-

trekking heeft zijn: CIP en SYS. CIP staat voor Common Information for Production en

is het productie sturings- en opvolgingssysteem van Volvo. SYS is afgeleid van SYSTEM

en bundelt alle algemene zaken zoals het framework, common libs, loginschermen, autho-

risaties, ... Elk systeem wordt onderverdeeld in projecten, gateways en utilities. Gateways

vallen uit de scope van deze masterproef. Utilities zijn modules die niet speci�ek gekop-

peld zijn aan projecten. Ze kunnen door alle andere modules gebruikt worden. Hier komen

vooral de gemeenschappelijke componenten in terecht. Projecten worden verder opgedeeld

in modules. Elk project heeft minstens één module en kan uit volgende modules bestaan:

� entity module: database access module (max 1)

� service module: business logica module (max 1)

� tclient module: visuele interface module (max 1)

� batch modules: achtergrondprocessen (meerdere mogelijk)

Figuur 2.1 geeft een overzicht van de projectstructuur bij Volvo. Elke module heeft als

parent de eProject-module. Deze module kan speci�eke con�guratie bevatten voor de on-

derliggende modules. De eProject-module heeft als parent de uBaseXXX-module, waarbij

xxx het systeem is. Deze module heeft een speci�eke con�guratie voor alle projecten en

modules in dit systeem. Hierin worden bijvoorbeeld de dataSources1 gede�nieerd naar

1object dat gebruikt wordt om te connecteren met een databank

Page 11: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

2.1 SduClient - TClient - TServer 4

de juiste databank voor dat systeem. De uBaseXXX modules hebben allemaal als pa-

rent uBasePom, hierin staat de con�guratie voor alle systemen, projecten en modules (bv.

repositories, build goals, ...). Projectnamen beginnen steeds met de letter 'e'.

Figuur 2.1: Projectstructuur in Volvo-omgeving

2.1 SduClient - TClient - TServer

SduClient is een programma gemaakt door Volvo om user interfaces te ontwikkelen. Het

biedt de mogelijkheid om componenten naar het scherm te slepen, vergelijkbaar met de

toolboxfunctionaliteit van Visual Studio. Toch zijn er enkele verschillen merkbaar. Er

onderscheiden zich twee views: de Designview en de Treeview . De Designview geeft visueel

weer hoe de user interface er zal uitzien. Op de Treeview zijn alle gebruikte componenten

zichtbaar in een boomstructuur. Hierop staan ook de details van de componenten weerge-

geven. Een belangrijk voordeel van de Treeview is het tonen van de verborgen elementen,

deze worden namelijk niet weergegeven op de Designview. Nog een ander voordeel van de

Treeview, is de mogelijkheid om reeds bestaande componenten, inclusief hun kindercom-

ponenten, te kopiëren uit een ander SduClient-project. Om een voorbeeld te geven: het is

mogelijk om de statusbar en menubar te copy-pasten. Het platform ondersteunt ook meer-

taligheid. Bovendien kunnen er voorgede�nieerde types gebruikt worden die elementen uit

de databank voorstellen om herbruikbaarheid te promoten. Eens het design afgerond is,

kan er Java code gegenereerd worden om de user interface te gebruiken in de code. Om

Page 12: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

2.2 Scheduled en detached batch 5

de gegenereerde code in de juiste map te plaatsen wordt WinMerge gebruikt. Indien de

bestanden al bestonden, geeft dit de mogelijkheid om beide versies met elkaar te verge-

lijken. Doordat er in de gegenereerde code commentaarlijnen voorzien zijn waartussen de

code-behind geplaatst kan worden, is het eenvoudig om mogelijke wijzigingen samen te

voegen.

Vanuit TClient kunnen de ontwikkelde user interfaces gestart worden. TServer is het

platform waarop de schermtransacties draaien.

2.2 Scheduled en detached batch

Scheduled batch programma's zijn programma's die op bepaalde tijdstippen worden opge-

start door externe triggers. Het programma erft steeds over van AbstractBatch. Dit zorgt

voor de juiste initialisatie van Spring en Hibernate en start de batch op via de executeBatch

methode.

Vcom batch programma's zijn programma's die continu in de achtergrond draaien. Ze rea-

geren op binnenkomende berichten van externe programma's. Ze verwerken deze berichten

en kunnen antwoorden terugsturen. De communicatie gebeurt via het messaging frame-

work VCOM. Vcom batches erven steeds over van AbstractVComBatch. Ook hier zorgt

dit voor de juiste initialisatie en wordt de batch gestart via de executeBatch methode.

In tegenstelling tot Scheduled batches blijven deze programma's draaien tot ze manueel

gestopt of herstart worden.

2.3 ValueList

Om programma's eenvoudig te con�gureren, worden con�guratieparameters opgeslagen in

de databank. Deze parameters kunnen dan gemakkelijk aangepast worden via een TClient-

scherm zonder in de programmacode te moeten neuzen.

2.4 Taalonafhankelijkheid

Door in programma's gebruik te maken van errorcodes wordt er taalonafhankelijkheid on-

dersteund. In TClient kunnen de errorcodes gelinkt worden met een bericht in verschillende

talen. Er kunnen berichtjes voorzien worden in vier talen: Nederlands, Engels, Zweeds en

Page 13: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

2.5 Beperkingen 6

Chinees. Al naargelang de pro�elinstellingen van de eindgebruiker worden de foutmeldin-

gen dan in één van deze talen op het scherm weergegeven.

2.5 Beperkingen

Bij het deployen van de programma's moet er rekening mee gehouden worden dat de servers

OpenVMS draaien. Bovendien zal ook het aantal threads beperkt moeten blijven. Verder

wordt er bij de implementatie Java 6 gebruikt met Oracle 10.2g als databank.

Page 14: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

ONTWERP 7

Hoofdstuk 3

Ontwerp

Voor het ontwerp van het framework werd er begonnen met een actief-historiek model. Na

grondig onderzoek werd er overgeschakeld naar partitioning. Dit hoofdstuk verduidelijkt

wat deze twee ontwerpen precies inhouden en waarom er uiteindelijk gekozen werd voor

partitioning.

Er zijn componenten die in beide ontwerpen voorkomen:

� een loadbalancer die webservicecalls verdeelt over meerdere processen,

� een webservice die de logberichten verwerkt,

� een beheerscherm om parsers te con�gureren,

� een beheerscherm om logberichten te bekijken,

� een programma dat periodiek oude data verwijdert.

Page 15: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

3.1 Actief-historiek ontwerp 8

3.1 Actief-historiek ontwerp

Dit ontwerp steunt op het gebruik van twee tabellen om de logberichten op te slaan, een

actieve tabel en een historiektabel. De actieve tabel houdt alle records van de huidige

shift1 bij. De historiektabel houdt alle oudere logberichten bij. Dit wordt afgebeeld in

�guur 3.1 om duidelijk het verschil aan te tonen met het andere ontwerp. Het voordeel

van dit concept schuilt in het opvragen van informatie uit de huidige shift. Dit zal zeer

performant gebeuren doordat er slechts een beperkt aantal data voorkomen in vergelijking

met het totale pakket. Door het gebruik van twee tabellen ontstaan er wel enkele nadelen.

Ten eerste moet er een apart programma voorzien worden om de records te verplaatsen van

de actieve tabel naar de historiektabel. Bovendien blijft de performantie om records op te

vragen uit de historiektabel ongeveer even slecht. Het komt dus neer op een verplaatsing

van het probleem, hoewel er meestal enkel in de huidige shift zal gezocht worden. Ten

tweede zal er ook een UNION gebruikt moeten worden indien er over meerdere shifts

gezocht wordt.

Figuur 3.1: Tabeloverzicht voor het actief-historiek ontwerp

Bij dit concept zouden de webserviceprocessen de logberichten onveranderd opslaan in de

databank. Hierbij wordt geen parsing van het binnenkomend bericht toegepast, zodat

maximale performantie van het webserviceproces bekomen wordt. Figuur 3.2 geeft een

overzicht van de benodigde componenten.

1tijdsspanne van acht uur in een ploegensysteem

Page 16: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

3.2 Partitioning ontwerp 9

Figuur 3.2: Eerste ontwerp via twee tabellen

3.2 Partitioning ontwerp

Het voordeel van dit ontwerp schuilt in het gebruik van slechts één tabel. Hierdoor is

het niet meer nodig om records te verplaatsen van de ene naar de andere tabel. Zoals

weergegeven in �guur 3.3, worden de gegevens opgedeeld in groepen, elke groep is één

werkshift. Dit zorgt ervoor dat verwijdering van de oude gegevens vereenvoudigt omdat

deze nu per groep (partitie) verwijderd kunnen worden. Bovendien zal Oracle proberen de

query's te optimaliseren door gebruik te maken van partition pruning (zie hoofdstuk 5).

Hierdoor kan bij opzoekingen in de huidige shift dezelfde performantie bekomen worden als

bij het andere ontwerp. Daarenboven zullen opzoekingen in vorige shifts sneller verlopen,

doordat er slechts een beperkt deel van de tabel bekeken zal worden.

Figuur 3.3: Tabeloverzicht voor het partitioning ontwerp

Page 17: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

3.2 Partitioning ontwerp 10

Dit ontwerp ziet er op het eerste zicht eenvoudig uit, maar door de grote waaier aan

mogelijkheden brengt het heel wat onderzoek met zich mee. Een bijkomstig nadeel is dat

de partities op voorhand aangemaakt moeten worden. Dit kan samen met het verwijderen

van oude gegevens gebeuren. Bij dit ontwerp wordt er voor gekozen om het parsen van

de logberichten toch in de webservice uit te voeren. Zo wordt het eindeloos updaten van

de gepartitioneerde tabel voorkomen. Figuur 3.4 geeft een overzicht van de benodigde

componenten.

Figuur 3.4: Tweede ontwerp via partitioning

Page 18: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

3.3 Samenvatting 11

3.3 Samenvatting

Uiteindelijk werd er gekozen voor het tweede ontwerp door de betere performantie, de grote

waaier aan mogelijkheden en het eenvoudig verwijderen van oude records. Tabel 3.1 zet

alles nog even op een rijtje.

Tabel 3.1: Vergelijking Actief-historiek ontwerp met partitioning ontwerp

Actief-Historiek Partitioning

Voordelen-e�ciënt opzoeken in de hui-

dige shift

-minder belasting op de web-

service

-e�ciënt opzoeken in de hui-

dige shift en de oudere shifts

(partition pruning)

-eenvoudig om oude gegevens

te verwijderen

-veel mogelijkheden

-volledig transparant

Nadelen-UNION

-verplaatsing van de records

uit de huidige shift noodzake-

lijk

-opzoekingen buiten de hui-

dige shift zijn traag

-meer belasting op de webser-

vice

-partities moeten op voorhand

bestaan

Verschil

componenten-update-programma

-move-programma

-programma nodig om nieuwe

partities aan te maken

Page 19: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

FUNCTIONELE ANALYSE 12

Hoofdstuk 4

Functionele analyse

Dit hoofdstuk beschrijft wat er precies allemaal moet ontwikkeld worden zonder diep in

te gaan op de technische details. De details en de uitwerking worden in de volgende

hoofdstukken besproken. Concreet wordt er bij elke component wat meer uitleg gegeven

en wordt er verduidelijkt wat er verwacht wordt. De componenten worden in dezelfde

volgorde doorlopen als het pad dat het bericht a�egt.

4.1 Verwerken van binnenkomende berichten

Om de binnenkomende logberichten in de databank te krijgen, werden er twee concepten

gebruikt, meer bepaald een loadbalancer en een webservice. De webservice zorgt ervoor dat

de logberichten eenvoudig naar een url verstuurd kunnen worden, terwijl de loadbalancer

de werklast zal verdelen over meerdere instanties van de webservice.

4.1.1 Loadbalancing

De VEM1 doet een webservicecall waarbij het logbericht, het stationnummer2, het bo-

dynummer3 en het berichttype worden doorgegeven als JSON-string. JSON staat voor

JavaScript Object Notation en zorgt ervoor dat objecten voorgesteld kunnen worden in

tekstformaat. De loadbalancer vangt de webservicecall op en verwijst hem door naar een

ander proces op dezelfde computer. Dit zorgt ervoor dat de werklast verdeeld wordt over

de verschillende processen en bijgevolg sneller webservicecalls verwerkt kunnen worden

1Virtual Escort Memory , vormt de brug tussen de shop�oordevices en de Volvoprogramma's2identi�catie van de machine3identi�catie van de wagen

Page 20: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.1 Verwerken van binnenkomende berichten 13

(Figuur 4.1). De loadbalancer is transparant voor de client. Dit betekent dat de gebrui-

ker niets merkt van de loadbalancer en het gevoel heeft dat hij rechtstreeks een van de

webservices aanspreekt.

Figuur 4.1: Schematisch overzicht van het principe van loadbalancing

4.1.2 Webservice

De webservice verwerkt de JSON-string door het station, het bodynummer, het berichttype

en het logbericht eruit te �lteren. Het berichttype geeft aan welke parser er gebruikt moet

worden. Vervolgens wordt het logbericht geparset met de juiste parser. De velden van

het verwerkte logbericht worden opgeslagen in de databank. Dit proces wordt schematisch

voorgesteld in �guur 4.2. De webservice omvat verschillende threads om de logberichten te

verwerken. Het aantal threads kan via een constante gewijzigd worden. De parsers kunnen

beheerd worden via een user interface (sectie 4.2).

Figuur 4.2: Schematisch overzicht van de verwerking van een binnenkomend bericht

Page 21: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.2 Gebruikersscherm voor parserbeheer 14

4.2 Gebruikersscherm voor parserbeheer

Dit scherm biedt de mogelijkheid om nieuwe parsers aan te maken en reeds bestaande te

wijzigen of te verwijderen. In een spreadsheet worden alle bestaande parsers weergegeven.

De omschrijving van de kolommen is terug te vinden in tabel 4.1. Het is belangrijk dat het

type uniek is zodat er slechts één parser geassocieerd kan worden met een bepaald type.

Het unieke type wordt afgedwongen door het beheerscherm. Voor de eenvoud worden enkel

voorgede�nieerde formaten gebruikt die opgehaald worden uit een ValueList. Figuur 4.3

toont hoe het hoofdscherm eruitziet.

Figuur 4.3: Hoofdscherm van het parserbeheer

Het is mogelijk te zoeken op parsernaam, type en formaat. Op het hoofdscherm staat er ook

een validatieknop die het mogelijk maakt om een gede�nieerde parser te testen. Door een

parser te selecteren en op de validatieknop te klikken, wordt het validatiescherm geopend.

Dit nieuw venster bevat een textarea, een validatieknop en een lijst van gede�nieerde

itemParsers. In de textarea kan een voorbeeldbericht ingegeven worden om te controleren

of de itemParsers het gewenste resultaat leveren. De validatieknop genereert de resultaten

naast elk lijstitem. Het resultaat van een voorbeeldbericht is zichtbaar in �guur 4.4.

Het detailscherm wordt weergegeven in �guur 4.5. Hierin kunnen de itemParsers gede�-

Page 22: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.2 Gebruikersscherm voor parserbeheer 15

Tabel 4.1: Omschrijving van spreadsheetvelden in beheerscherm voor parsers

Eigenschap Omschrijving

type het type waarvoor de parser gebruikt wordt

parser de naam van de parser

format het formaat van de parser, XPATH of STRING

updatedTimestamp het tijdstip waarop het logbericht is gewijzigd

updatedBy het personeelsnummer van de gebruiker die het laatst

wijzigingen aanbracht

Figuur 4.4: Validatescherm voor parsers

nieerd worden met behulp van een XPathexpressie4. De XPathexpressie wordt dynamisch

ingeladen bij het opstarten of refreshen van de webservices. Het refreshen gebeurt door

gebruik te maken van JMX (sectie 6.2.1). Zowel voor het XPATH-formaat als voor het

STRING-formaat wordt er achter de schermen XPATH gebruikt. Het STRING-formaat

wordt omgezet in XPATH door het logbericht te omvatten in een STRING-tag en ver-

volgens de substring-functie5 toe te passen. Een voorbeeld van een expressie voor het

STRING-formaat ziet er dan als volgt uit: substring(/STRING/text(),startindex,lengte).

4XML Path Language (XPATH) is een manier om velden uit een XML-bestand te �lteren5functie om een deelstring uit een string te halen

Page 23: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.2 Gebruikersscherm voor parserbeheer 16

Hierbij geeft de startindex aan waar het eerste karakter van de te zoeken string zich be-

vindt (1-based). Een voorbeeld van een expressie voor het XPATH-formaat kan er als

volgt uitzien: /TAG/text(). De itemParsersleutels in het detailscherm komen overeen met

de attributen die gebruikt worden in de verpakkingsklasse van het logbericht. Bij het op-

slaan van een itemParser wordt er gecontroleerd als de XPathexpressie wel geldig is en als

de juiste expressie gebruikt werd afhankelijk van het formaat. Met andere woorden als

bij het STRING-formaat het eerste deel bestaat uit 'substring(/STRING/text(),' en het

XPATH-formaat eindigt op '/text()'.

In volgende gevallen wordt er een foutboodschap getoond:

� indien er een parser opgeslagen wordt voor een type die al een parser heeft,

� als er een itemParserveld leeg gelaten wordt,

� als de parser in tussentijd reeds aangepast werd,

� als de opgegeven XPathexpressie niet geldig is.

Figuur 4.5: Detailscherm van het parserbeheer

Page 24: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.3 Gebruikersscherm om logberichten te bekijken 17

4.3 Gebruikersscherm om logberichten te bekijken

Deze user interface biedt de mogelijkheid om logberichten op te zoeken in de databank aan

de hand van enkele �lters. Er kan ge�lterd worden op station, bodynummer, berichttype

en werkshift. Veelal zullen enkel de records uit de huidige werkshift van belang zijn, maar

verder zoeken moest ook mogelijk zijn. Figuur 4.6 toont hoe het scherm er uitziet.

Figuur 4.6: Overzichtsscherm voor de logberichten

Filteren op station en bodynummer gebeurt via een editeerbare combobox die gevuld is

met alle bestaande stations, respectievelijk bodynummers. Als de gebruiker iets invult

in de combobox, wordt er versprongen in de suggestielijst. Het is ook mogelijk om te

zoeken op items die niet in de lijst voorkomen. Deze implementatie zorgt ervoor dat

zoeken via een 'equals' kan gebeuren en dat er bijgevolg sneller resultaten weergegeven

kunnen worden. Er werden radioknoppen voorzien om niet telkens de tijdsgrenzen te

moeten ingeven. De radioknoppen zorgen automatisch voor de juiste tijden in de twee

tijdslabels, start- en stoptijd. Ze bieden ook de mogelijkheid om de huidige shift tot en

met drie shiften daarvoor te selecteren. Er is ook een radioknop om de tijdslabels zelf

aan te passen. Deze tijdslabels kunnen eenvoudig ingesteld worden door op de knoppen

Page 25: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.3 Gebruikersscherm om logberichten te bekijken 18

naast de tijdsaanduidingen te klikken. Er verschijnt dan een kalender waarop een tijdstip

kan geselecteerd worden (Figuur 4.7). De kalender is een bestaande component van Volvo

waarin de shiftinformatie reeds verwerkt is. De component bevat ook reeds testen op

begin- en eindtijdstip. Het formaat van de weergegeven tijd is, yyyywwEE$HH_mm_ss.

Deze voorstelling toont de week en de dag van de week. Zo duidt '2014071 22:00:00' op

maandag, week 7, om 22 uur. Het zoeken kan gestart worden door op ENTER te drukken

of handmatig op de zoekknop te klikken.

Figuur 4.7: Kalenderscherm om een tijdsspanne in te stellen

In een spreadsheet worden alle records weergegeven die voldoen aan de zoekcriteria. Tabel

4.2 geeft een omschrijving van de kolommen. Alle velden zijn read-only. Door eerst één of

meerdere records te selecteren en vervolgens op de detailknop te klikken, of te dubbelklikken

op een record, verschijnt er een detailvenster waar ook het logbericht in getoond wordt.

Tabel 4.2: Omschrijving van de spreadsheetkolommen in het logberichtenscherm

Naam Omschrijving

station de alfanumerieke naam van het werkstation

bodyNummer het bodynummer van de wagen

berichttype type van het bericht

timestamp het tijdstip waarop het logbericht is aangemaakt

Het aantal resultaten wordt beperkt via paginering omwille van de performantie en het

gebruikersgemak. Het maximum aantal records per pagina kan ingesteld worden in de

voorziene pagineringcomponent. Hierdoor zal het minder lang duren voordat de gebruiker

de resultaten te zien krijgt. Er werd ook een bovengrens ingesteld voor het aantal resultaten

Page 26: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.3 Gebruikersscherm om logberichten te bekijken 19

per pagina en afgedwongen dat er op z'n minst één �lter ingevuld wordt, om te voorkomen

dat het scherm overspoeld wordt met data. In de statusbar rechtsonder wordt het aantal

opgehaalde records weergegeven.

In het detailscherm, �guur 4.8, worden dezelfde velden weergegeven als in het hoofdscherm:

station, bodynummer, berichttype en het tijdstip van aanmaak. Er is ook één bijkomend

veld, het logbericht. Het logbericht wordt indien mogelijk geformatteerd voorgeschoteld.

Alle velden zijn eveneens read-only. Ook hier wordt de standaard menubar voorzien, maar

zonder de knoppen voor toevoegen, opslaan en verwijderen. Aanpassen van logberichten

is namelijk nutteloos. Indien er meerdere records geselecteerd werden bij het oproepen

van het detailscherm, kan er tussen deze records genavigeerd worden door op de pijltjes

bovenaan de menubar te klikken.

Figuur 4.8: Detailscherm voor het tonen van logberichten

Page 27: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.4 Periodiek partities verwijderen en toevoegen 20

4.4 Periodiek partities verwijderen en toevoegen

Om gemakkelijk nieuwe partities aan te maken werd er eerst een veld 'aantal toekomstige

partities' voorzien. Aan de hand van dit aantal kon WhatShift6 gebruikt worden om dy-

namisch de partitiegrenzen op te halen van de komende werkshifts. Deze implementatie

werd uiteindelijk aan de kant geschoven doordat weekendwerk niet ruim op voorhand ge-

pland kan worden. Ongepland weekendwerk zou als gevolg hebben dat logberichten van het

weekendwerk in de eerste partitie van de maandag zouden terechtkomen indien de week-

endpartitie niet bestaat. Om dit te voorkomen werden meteen alle mogelijke shifts voor

het weekend aangemaakt. Hierdoor kon WhatShift niet meer aangewend worden en was

er nood aan vaste tijdsgrenzen om nieuwe partities aan te maken. Deze grenzen konden

ingesteld worden in het gebruikersscherm voor partitiecon�guraties (sectie 4.5) en waren

voor elke con�guratie hetzelfde.

Ook dit concept werd uiteindelijk niet benut doordat de vaste grenzen niet overeenkwa-

men met de echte shiftgrenzen. Om toch grenzen te hebben die overeenkomen met de

shiftgrenzen, werd het werkschema gebruikt die alle mogelijke werkploegen vastlegt. Door-

dat er meerdere de�nities beschikbaar zijn, moet er een referentiepunt opgegeven worden

en rekening gehouden worden met de meest recentste versie.

Het is de bedoeling dat dit programma elk weekend loopt om de gede�nieerde partitie-

con�guraties uit te voeren. In deze con�guraties staat aangegeven hoeveel partities er

bijgehouden moeten worden. Er wordt altijd een week aan partities toegevoegd aan de

tabel, met de optie om meerdere weken toe te voegen door het veranderen van een con-

stante. Indien het programma afgevuurd wordt tijdens de week, creëert het programma

indien nodig de partities vanaf de maandag in de huidige week. Als het programma in het

weekend loopt, zullen de partities voor de komende week aangemaakt worden, startende

vanaf maandag.

Volgende eigenschappen zijn con�gureerbaar:

� Systeem

� Tabelnaam

� Optie om de aanmaak van nieuwe partities te forceren

� Optie om het verwijderen van oude partities te forceren

6dit is een programma om shiftinformatie op te vragen

Page 28: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.4 Periodiek partities verwijderen en toevoegen 21

� Tijd die het programma maximaal nodig heeft om het programma vlekkeloos uit te

voeren

� Gewijzigd door

� Gewijzigd op

Dit programma werd zo generiek mogelijk gemaakt door de mogelijkheid om een systeem en

een tabel te kiezen. Bijgevolg kan dit programma later gebruikt worden om alle bestaande

gepartitioneerde tabellen te voorzien van partities en om verouderde data te verwijderen.

Partities moeten op voorhand bestaan alvorens er een record in die tijdsspanne wordt

toegevoegd. Indien dit niet het geval zou zijn, komt het record in de MAXVALUE-partitie

terecht. Hierin worden alle records verzameld die niet binnen een partitiegrens vallen. In

het geval dat alle records in de MAXVALUE-partitie zouden terechtkomen, verliezen we

het voordeel van partitioning, zijnde partition pruning (zie hoofdstuk 5).

Als voorzorgsmaatregel voor locking7 worden con�guraties enkel uitgevoerd als er geen

shift bezig is en als er nog genoeg tijd over is tot de aanvang van de eerstvolgende shift. De

shiftinformatie kan opgevraagd worden met WhatShift en bijgevolg kan ook de resterende

tijd berekend worden en aan de hand van de opgegeven maximale tijd bepaald worden als

de con�guratie al dan niet uitgevoerd mag worden. Om toch de mogelijkheid te bieden om

een con�guratie uit te voeren zonder deze voorwaarden, werden de forceeropties voorzien.

Bij het verwijderen van de partities wordt WhatShift wel gebruikt. Hierdoor wordt er

rekening gehouden met vakantiedagen zodat gegevens van voor de vakantie nog steeds

beschikbaar zijn na de vakantie, zelfs na het lopen van het programma. Dit komt doordat

enkel gewerkte shifts meegeteld worden en bijgevolg lege partities genegeerd worden.

De volledige con�guratie die uitgevoerd moet worden, wordt opgeslagen in een ini-bestand

die onderveeld is in verschillende secties. De namen van de secties in het ini-bestand kunnen

aangepast worden in de constantenklasse van de ePartition-services-module. Alle secties

zijn con�gureerbaar via het gebruikersscherm (Sectie 4.5). Indien er fouten optreden bij

het laden of het opslaan van het ini-bestand of bij het gebruik van WhatShift, worden de

nodige errors gelogd.

7toegang tot de databank blokkeren tot de operatie klaar is

Page 29: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.5 Beheerscherm voor partitiecon�guraties 22

4.5 Beheerscherm voor partitiecon�guraties

4.5.1 Hoofdscherm

Dit scherm biedt de mogelijkheid om partitiecon�guraties en systeemmappings te behe-

ren. Het hoofdscherm, �guur 4.9, geeft aan als het con�guratiebestand gevonden werd.

Indien dit niet het geval is, wordt dit aangegeven in het rood en worden de zoek- en de-

tailknop onbeschikbaar gemaakt. Als het con�guratiebestand gevonden werd, wordt er

gecontroleerd als er reeds een systeemmapping aanwezig is. Pas als deze sectie bestaat,

zullen de knoppen beschikbaar worden. Om de systeemmapping te beheren, is er een apart

menu-item 'beheer' voorzien. Verder is het mogelijk om te �lteren op systeem en tabel.

In een spreadsheet worden alle bestaande con�guraties weergegeven. De kolommen zijn de

eigenschappen die vermeld werden in sectie 4.4.

Figuur 4.9: Hoofdscherm om partitiecon�guraties te beheren

Page 30: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.5 Beheerscherm voor partitiecon�guraties 23

4.5.2 Mappingscherm

Dit scherm, �guur 4.10, biedt de mogelijkheid om de systeemmapping te beheren. Door

nieuwe mappings toe te voegen, zullen ze beschikbaar worden in het detailscherm. Er

werd een extra veld 'Rdb driver' voorzien voor systemen die de databank van OpenVMS

gebruiken.

Figuur 4.10: Scherm om systeemmapping te beheren voor partitiecon�guraties

4.5.3 Detailscherm

In het detailscherm, �guur 4.11, wordt er gebruikgemaakt van comboboxen om de systeem-

en tabelwaarden in te vullen. Dit zorgt ervoor dat de waarden zeker juist zijn. Indien

een bestaande con�guratie geopend wordt, zullen beide comboboxen ingeschakeld zijn.

Indien er een nieuwe con�guratie aangemaakt wordt, zal enkel de systeembox beschikbaar

zijn. Van zodra er hier iets in geselecteerd wordt, zal de tabelbox beschikbaar worden

met alle gepartitioneerde tabellen in het geselecteerde systeem als waarde. Eens de tabel

geselecteerd werd, zullen alle namen van de reeds bestaande partities getoond worden

in een spreadsheet. Eerst kwamen enkel de kolommen van het type TIMESTAMP in

aanmerking voor de kolombox, maar doordat het opvragen van metadata8 traag verliep,

wordt er hierop niet meer gecontroleerd. De overige velden - de maximum tijd en het

aantal shifts - worden gecontroleerd op numerieke waarden. De 'Force'-checkbox'en zorgen

ervoor dat de aangevinkte operatie voor die con�guratie toch uitgevoerd kan worden op

momenten dat er wel een shift aan de gang is, ook als er onvoldoende tijd is. Wijzigingen

of nieuwe con�guraties worden weggeschreven naar het ini-bestand.

8tabel- en kolomeigenschappen

Page 31: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

4.5 Beheerscherm voor partitiecon�guraties 24

Figuur 4.11: Detailscherm om partitiecon�guraties te beheren

Page 32: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

PARTITIONING 25

Hoofdstuk 5

Partitioning

Dit hoofdstuk geeft wat meer uitleg over het partitioning concept van Oracle, meer bepaald

de werking en de gevolgen. Partitioning houdt in dat records verdeeld worden in groepen

zodat opzoekingen zich kunnen beperken tot een aantal partities. Anders gezegd, de sql

statements worden geoptimaliseerd om slechts de nodige partities op te vragen en over-

bodige partities te elimineren. Dit principe heet partition pruning en wordt transparant

uitgevoerd. Door partition pruning zullen query's performanter uitgevoerd worden. Met

transparantie wordt bedoeld dat er geen extra toeters of bellen nodig zijn bij het uitvoeren

van een normale query.[10]

5.1 Algemeen

Hoewel het niet noodzakelijk is om elke partitie in een aparte tablespace1 op te slaan, heeft

het toch zijn voordelen. Partities opslaan in verschillende tablespaces zorgt voor:

� een verminderde kans op data corruption in meerdere partities,

� onafhankelijke back-ups en herstelling van elke partitie,

� controle over de mapping van partities over verschillende disks,

� een verbetering in beheerbaarheid, beschikbaarheid en performantie.

1abstractielaag tussen fysieke en logische data, via tablespaces kunnen data verdeeld worden over ver-

schillende harde schijven

Page 33: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

5.1 Algemeen 26

Het maximum aantal partities dat een tabel kan hebben, is 1024K-1. Oracle biedt ver-

schillende methodes aan om een opdeling te maken in partities:

� Range partitioning

� List partitioning

� Hash partitioning

� Composite partitioning

Range partitioning verdeelt de tabel op in verschillende ranges. Dit is het meest gebruikte

type en maakt een opdeling aan de hand van een datum eenvoudig. Bij List partitio-

ning wordt de opdeling in partities gemaakt door een lijst van waarden op te geven. Dit

heeft als voordeel dat ongeordende en onafhankelijke data gegroepeerd kunnen worden.

Hash partitioning zorgt voor de opdeling van data waarbij er geen goede opdeling kan

gemaakt worden in ranges of lists. Hash partitioning kan gebruikt worden in het geval

dat de gegevens te zwaar geclusterd worden bij range partitioning of om performantiere-

denen. Composite partitioning is een combinatie van range partitioning met list of hash

partitioning als subpartitionering. Hierdoor kunnen de voordelen gecombineerd worden.

Er wordt gebruikgemaakt van RANGE partitioning doordat de shifts zorgen voor een ge-

lijke opdeling aan de hand van een timestamp. Ze zijn ook eenvoudig aan te maken door

een bovengrens en een partitiesleutel op te geven. In ons geval is de partitiesleutel de time-

stampkolom en de bovengrens telkens de stoptijd van een shift. Enkel tabellen die LONG

of LONG RAW kolommen bevatten, kunnen niet gepartitioneerd worden. Dit komt omdat

LONG data types enkel nog ondersteund worden voor neerwaartse compatibiliteit2. Oracle

raadt dan ook aan om bestaande LONG kolommen om te zetten in LOB kolommen3.[14]

Vervolgens bestaat de mogelijkheid om verschillende soorten indexen te gebruiken: non-

partitioned global indexes , range of hash-partitioned global indexes , en local indexes . Non-

partitioned global indexes zijn de standaard indexes die gebruikt worden en hebben invloed

op de hele tabel. Local indexes zijn indexes die op dezelfde manier gepartitioneerd zijn

als de gepartitioneerde tabel. Dit zijn de eenvoudigste indexes aangezien je niet zelf de

indexpartities moet beheren. Ze worden automatisch aangemaakt door de databank. Een

2ondersteunen van oudere versies3LOB kolommen zijn de nieuwe LONG kolommen en staan in voor het opslaan van grote blokken ruwe

data

Page 34: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

5.2 Impact van onderhoudsoperaties 27

gepartitioneerde global index is een index gegroepeerd op een kolom verschillend van de ge-

partitioneerde tabel. Dit is met andere woorden een index waarop partitioning is toegepast.

Deze moeten dan wel zelf beheerd worden. De tabeloptie ENABLE ROW MOVEMENT

schakelt de optie aan om records te updaten, dit zou geen nevene�ecten mogen hebben

buiten de verandering in ROWID.[17] Deze optie is standaard uitgeschakeld.

5.2 Impact van onderhoudsoperaties

Met onderhoudsoperaties worden operaties bedoeld die aanpassingen aanbrengen aan de

tabel, zoals het verwijderen of het aanmaken van partities. Veel onderhoudsoperaties op

gepartitioneerde tabellen markeren de overeenkomstige indexen als 'UNUSABLE'. Vervol-

gens moet de volledige index herbouwd worden of in het geval van gepartitioneerde globale

indexen, elk van zijn partities. Door 'UPDATE INDEXES' te gebruiken bij een ALTER

TABLE opdracht zal er geen reconstructie van de indexen meer moeten gebeuren. De in-

dexen worden dan geüpdatet op het moment dat de onderhoudsopdracht wordt uitgevoerd.

Dit heeft volgende voordelen:

� De index is meer beschikbaar aangezien hij niet gemarkeerd wordt als 'UNUSABLE'

en bijgevolg moet de index ook niet herbouwd worden.

� Er is geen opzoeking nodig naar de namen van alle onbeschikbare indexes om ze te

herconstrueren.

Nog enkele opmerkingen:

� Door 'UPDATE INDEXES' te gebruiken zal de partition DDL statement4 langer

duren. Dit komt doordat de onbruikbare indexen rechtstreeks geüpdatet worden. De

extra tijd die hiervoor nodig is, moet vergeleken worden met de benodigde tijd om

beide acties apart uit te voeren. Een vuistregel hierbij is dat het sneller is om de

indexen te updaten als de grootte van de partitie kleiner is dan 5% van de grootte

van de tabel.

� De DROP, TRUNCATE en EXCHANGE operaties met 'UPDATE INDEXES' zijn

niet langer snelle operaties doordat de indexen meteen mee geüpdatet worden. Hier

moet er eveneens vergeleken worden met de uitvoertijd om de indexen te herbouwen.

4Data De�nition language, hiermee worden de CREATE, DROP en ALTER statements bedoeld.

Page 35: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

5.3 Partities toevoegen 28

5.3 Partities toevoegen

Er kunnen enkel nieuwe partities toegevoegd worden na de hoogst gede�nieerde partitie

door middel van 'ALTER TABLE tabelnaam ADD PARTITION'. Hierbij worden de local

en global indexes niet beïnvloed en blijven ze bruikbaar. Er kan ook een nieuwe partitie

tussenin toegevoegd worden met 'ALTER TABLE tabelnaam SPLIT PARTITION'. Als de

te splitsen partitie data bevat, zullen de indexen als 'UNUSABLE' gemarkeerd worden. Dit

is zowel het geval bij local indexes, als bij global indexes. De 'UNUSABLE' markering kan

voorkomen worden door 'UPDATE INDEXES' toe te voegen aan de 'SPLIT PARTITION'-

statement. SPLIT PARTITION zorgt ervoor dat de records verdeeld worden over de twee

nieuwe partities volgens de opgegeven grens. Alles onder de grens komt in de eerste partitie

terecht, alles erboven in de tweede. Als er geen namen voor de nieuwe partities opgegeven

worden, zullen ze automatisch een naam krijgen (SYS_Pn, waarbij n een willekeurig getal

is).

1 ALTER TABLE vem_log_message SPLIT PARTITION other

2 at ( grenstimestamp ) INTO ( PARTITION "20140722" , PARTITION other )

3 UPDATE INDEXES;

Codefragment 5.1: Partitie toevoegen met SPLIT PARTITION en ALTER INDEX

Optimalizeren van SPLIT PARTITION

SPLIT PARTITION is een dure operatie doordat alle records van de op te splitsen partitie

gescand moeten worden en één voor één toegevoegd moeten worden aan de nieuwe parti-

ties. Bovendien moeten zowel local als global indexes geherconstrueerd worden als er geen

'UPDATE INDEXES' gebruikt wordt. In het geval dat één van de nieuwe partities alle

records bevat, kunnen er optimalisaties plaatsvinden. Dit zorgt voor een snelle splitsing,

vergelijkbaar met een ADD PARTITION operatie. Deze optimalisatie gebeurt enkel als

onderstaande voorwaarden voldaan zijn:

� Eén van de twee nieuwe partities moet leeg zijn.

� De niet-lege nieuwe partitie moet dezelfde opslagkarakteristieken5 hebben als de oor-

spronkelijke partitie.

5Dit heeft betrekking op composite partitioning (dezelfde subpartitionering hebben) en het gebruik van

LOB kolommen(tablespace, caching, logging,...)

Page 36: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

5.4 Partities verwijderen 29

Als deze voorwaarden voldaan zijn, dan zullen alle global indexes bruikbaar blijven, zelfs

zonder 'UPDATE INDEXES' te vermelden. De local index partities overeenkomstig met de

nieuwe partities blijven ook bruikbaar zolang ze voor het splitsen ook bruikbaar waren.[12]

5.4 Partities verwijderen

Dit kan gebeuren met 'ALTER TABLE tabelnaam DROP PARTITION partitienaam'. Als

er local indexes aanwezig zijn dan wordt de overeenkomstige partitie van de local index

automatisch mee verwijderd. Alle global indexes, zowel gewone als partitioned global

indexes, worden als 'UNUSABLE' gemarkeerd tenzij 'UPDATE INDEXES' bij de operatie

gebruikt werd of als de te droppen partitie leeg is. Er zijn drie verschillende methodes voor

het verwijderen van partities van een tabel met global indexes:[11]

Methode 1

'ALTER TABLE tabelnaam DROP PARTITION partitienaam' gevolgd door 'rebuild'. In

het geval er range-partitioned global indexes gebruikt worden, moet elke index per partitie

herbouwd worden.

ALTER INDEX sales_area_ix REBUILD PARTITION jan99_ix;

ALTER INDEX sales_area_ix REBUILD PARTITION feb99_ix;

Deze methode is het meest geschikt voor grote tabellen waar de gedropte partitie een groot

deel van het geheel aan data bevat.

Methode 2

Gebruik het DELETE statement om eerst alle records van de partitie te verwijderen voor-

dat een 'ALTER TABLE tabelnaam DROP PARTITION partitienaam' opgeroepen wordt.

DELETE zorgt ervoor dat global indexes geüpdatet worden. Deze methode kan gebruikt

worden bij kleine tabellen, of voor grote tabellen waar de te droppen partities slechts een

klein deel van de totale data bevatten.

Methode 3

Gebruik 'UPDATE INDEXES' zodat de globale indexes automatisch geüpdatet worden.

Page 37: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

5.5 Create table 30

5.5 Create table

Om partities te gebruiken moeten we bij het aanmaken van de tabel de partities de�niëren

(codefragment 5.2). Een bestaande tabel kan niet rechtstreeks omgezet worden in een

gepartitioneerde tabel. Er zijn meerdere stappen vereist indien dit gewenst zou zijn. Dit

moet dan gebeuren via ofwel DBMS_REDEFINITION ofwel 'EXCHANGE PARTITION'.

1 CREATE TABLE vem_log_message

2 ( messageId NUMBER(6)

3 , message VARCHAR2(100)

4 , t s TIMESTAMP

5 )

6 PARTITION BY RANGE ( t s )

7 ( PARTITION "20140711" VALUES LESS THAN (TO_DATE( ' 2014−02−10 08 : 00 : 00 ' , '

yyyy−MM−dd HH24 :MI : s s ' ) )

8 , PARTITION "20140712" VALUES LESS THAN (TO_DATE( ' 2014−02−10 16 : 00 : 00 ' , '

yyyy−MM−dd HH24 :MI : s s ' ) )

9 , PARTITION "20140713" VALUES LESS THAN (TO_DATE( ' 2014−02−11 00 : 00 : 00 ' , '

yyyy−MM−dd HH24 :MI : s s ' ) )

10 ) ;

Codefragment 5.2: Aanmaken van een tabel met partities

Codefragment 5.2 toont hoe een tabel met drie partities aangemaakt wordt. Elke partitie

de�nieert een bovengrens via VALUES LESS THAN ... . Dit wil zeggen dat alles wat

onder deze grens valt (exclusief grens zelf), maar boven een andere partitiegrens, in die

partitie terechtkomt. De naamgeving van de partities is vrij te kiezen, maar aangezien

de partities in ons geval een shift voorstellen, wordt dit op de standaard Volvomanier

voorgesteld onder de vorm van yyyywwEX waarbij yyyy het jaartal, ww de week van het

jaar, E de dag van de week en X de shift op een bepaalde dag voorstelt. Bv. '2014-02-

10 15:00:00' valt in partitie '20140712', want deze waarde is kleiner dan de bovengrens

van partitie '20140712' en groter dan de bovengrens van partitie '20140711'. Indien een

waarde boven de hoogst gede�nieerde bovengrens valt, in dit geval '2014-02-11 00:00:00'

van partitie '20140713', dan zal er een fout optreden. Bijgevolg zal bij het starten van een

nieuwe shift de volgende partitie reeds moeten bestaan. Door een partitie te de�niëren

met als bovengrens MAXVALUE, zal er geen fout optreden. De MAXVALUE-partitie zal

voor de zekerheid altijd aanwezig zijn. Toch is het beter dat de partities al op voorhand

bestaan zodat records meteen in de juiste partitie terechtkomen en achteraf geen onnodig

werk meer verricht moet worden.

Page 38: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

5.6 Fetching 31

5.6 Fetching

Opvragen van records gebeurt op de gebruikelijke manier zoals bijvoorbeeld codefragment

5.3. Hierbij speci�ceren we dus best een tijdsinterval dat een shift voorstelt. Dit zorgt

ervoor dat er slechts in één partitie zal bezocht worden. Dit is dus perfect van toepassing

op het zoeken van logberichten aangezien daar altijd shiftintervallen meegegeven worden.

Oracle regelt het opzoeken van de juiste partitie achter de schermen, dit principe is dus

volledig transparant. Omdat de bovengrens niet in de partitie is meegerekend, kan het zoe-

ken met 'BETWEEN' in de 'WHERE'-clausule ervoor zorgen dat er meer dan één partitie

bekeken wordt. Dit komt doordat 'BETWEEN' zowel de ondergrens als de bovengrens

includeert.

1 s e l e c t *

2 from vem_log_message

3 where t s >= TO_DATE( ' 2014−02−10 16 : 00 : 00 ' , ' yyyy−MM−dd HH24 :MI : s s ' )

4 and t s < TO_DATE( ' 2014−02−11 00 : 00 : 00 ' , ' yyyy−MM−dd HH24 :MI : s s ' )

Codefragment 5.3: Fetchen van records uit partitioned table

5.7 Opvolging

Om na te gaan of er wel degelijk maar in één partitie gezocht werd, kan er gebruikgemaakt

worden van 'EXPLAIN PLAN FOR' (codefragment 5.4). Vervolgens kan het explainplan

opgevraagd worden met: select * from table(dbms_xplan.display).

1 exp la in plan f o r

2 s e l e c t * from vem_log_message where . . .

Codefragment 5.4: Explainplan opvragen van een query

Figuur 5.1 toont de uitvoer bij het opvragen van een explainplan. De uitvoer is afhankelijk

van hoeveel partities er aanwezig zijn en wat de zoekquery precies was. Hierbij geeft

'PARTITION RANGE SINGLE' aan dat er slechts één partitie gebruikt werd. Pstart en

Pstop geven ook aan welke partities er gebruikt werden. In het geval alle partities gebruikt

zouden worden, zou er 'PARTITION RANGE ALL' staan.

Page 39: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

5.7 Opvolging 32

Figuur 5.1: Voorbeelden van de uitvoer van 'EXPLAIN PLAN FOR'

Page 40: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

TECHNISCHE ANALYSE 33

Hoofdstuk 6

Technische analyse

Dit hoofdstuk gaat dieper in op elk van de besproken componenten. Het is de bedoeling

om de verschillende mogelijke strategieën op te lijsten en te besluiten welke strategie er

uiteindelijk gebruikt werd. Om dit te bereiken, zullen er codefragmenten voorzien worden

om de principes te verduidelijken.

6.1 Verwerking van binnenkomende berichten

6.1.1 Loadbalancing

Als loadbalancer wordt het pakket 'Malabarista' gebruikt. Dit pakket werd reeds in het

Volvo-framework geïntegreerd voor een ander project en kan dus handig herbruikt worden.

Malabarista heeft tot nog toe feilloos gewerkt en is stabiel onder zware belasting. Bovendien

is het ook mogelijk om zelf een strategie te schrijven voor het verdelen van de werklast.

Werking

Het programma Cpr981 wordt zowel gebruikt voor de webservice, als voor de loadbalan-

cer. Dit is dus één en dezelfde klasse, waarbij de opstartparameters bepalen welke functie

de instantie precies uitvoert. Indien de systeemeigenschap1 'type=server' wordt meegege-

ven, start de loadbalancer op. In het geval deze variabele weggelaten wordt, start er een

webservice op. Codefragment 6.1 beschrijft het opzetten en starten van de loadbalancer.

Voor het opzetten van de loadbalancer wordt de loadbalancerbuilder 2 van het Framework

1een variable die op het classpath meegegeven wordt bv. �Deigenschap=waarde2hulpklasse die de loadbalancer aanmaakt via de meegegeven parameters

Page 41: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.1 Verwerking van binnenkomende berichten 34

gebruikt. Deze builder roept achter de schermen de main van Malabarista aan. Vooraleer

de loadbalancer aangemaakt kan worden, moeten er eerst nog enkele parameters meege-

geven worden. Als eerste moeten er poorten ingesteld worden waarnaar de loadbalancer

de webservicecalls mag doorgeven. Deze poorten worden gescheiden door een komma op

het classpath gezet via de variabele 'clients'. De waarde van deze variabele kan vervol-

gens opgehaald worden met System.getProperty('clients') en ontbonden worden met een

StringTokenizer. Bij het aanmaken van de loadbalancer moet ook een strategie meegegeven

worden. Round Robin is momenteel de enige techniek van loadbalancing die geïmplemen-

teerd is. Deze techniek zal elke client a�open in eenzelfde cyclus, m.a.w. als een client aan

de beurt was, dan zullen eerst alle andere clients een call moeten verkrijgen voordat hij

zelf weer aan de beurt komt.[16] Dit principe zorgt voor een gelijkmatige verdeling over

de webservices. Als uitbreiding zou er getest kunnen worden als een strategie die rekening

houdt met het aantal berichten in de queue van elke webservice, performanter is dan de

'Round Robin'-strategie. Het hostadres en de poort waarop de loadbalancer draait, wordt

opgehaald uit een ValueList.

1 Bui lder b = new Loadbalancer . Bui lder ( ) ;

2 Str ingToken ize r t ok en i z e r = new Str ingToken ize r ( c l i e n t s , " , " ) ;

3 /* add c l i e n tPo r t s to l oadba lance rBu i lde r */

4 whi le ( t ok en i z e r . hasMoreTokens ( ) ) {

5 t ry {

6 i n t c l i e n tPo r t = In t eg e r . pa r s e In t ( t ok en i z e r . nextToken ( ) ) ;

7 b . addDest inat ion ( InetAddress . getLoca lHost ( ) . getHostAddress ( ) , c l i e n tPo r t ) ;

8 l o gg e r . i n f o ( " loadba lanc ing s t a r t ed from "+serve rPor t+" to "+c l i e n tPo r t ) ;

9 } catch ( Exception e ) {

10 // . . .

11 }

12 }

13 /* use Round Robin */

14 b . s e tS t r a t egy ( LoadbalancerStrategy .ROUND_ROBIN) ;

15 /* bu i ld and s t a r t */

16 Loadbalancer l oadba lance r = b . bu i ld ( "*" , s e rve rPor t ) ;

17 l oadba lance r . s t a r t ( ) ;

Codefragment 6.1: Aanmaken van de loadbalancer

Page 42: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.1 Verwerking van binnenkomende berichten 35

6.1.2 Webservice

Zoals eerder vermeld, wordt een webservice ook opgestart met Cpr981. Hiervoor wordt de

systeemeigenschap 'type' weggelaten en wordt er een poort meegegeven waarop de webser-

vice moet draaien (systeemeigenschap 'port'). Om de webservice te draaien wordt de Jetty

server gebruikt. Dit moet bij het opstarten vermeld worden door een systeemeigenschap

in te vullen (codefragment 6.2). Het aantal webservices kan vermeerderd worden door

meerdere instanties op te starten, elk op een andere poort.

1 System . se tProper ty ( "com . sun . net . h t tp s e rv e r . HttpServerProvider " , " org . mortbay

. j e t t y . j 2 s e 6 . Jet tyHttpServerProv ider " ) ;

Codefragment 6.2: Gebruik Jetty server vermelden

De Jetty server moet ook nog expliciet opgestart worden. Hierdoor zal de webservice

gepubliceerd worden zodat ze beschikbaar wordt op de voorgede�nieerde poort. Er werd

gekozen voor Jetty omdat deze server zeer lightweight is en bovendien eenvoudig is in

gebruik. Deze server doet ook zeker niet onder op vlak van performantie vergeleken met

andere applicatieservers.[5]

RemoteLoggingServer

De webservice zelf zit verpakt in een bestaande component, de RemoteLoggingServer. Het

opstarten van de webservice staat beschreven in codefragment 6.3. Vooraleer de Remo-

teloggingServer gestart wordt, wordt er een BlockingQueue geabonneerd aan de server.

Hierdoor zullen de binnenkomende berichten, geëencodeerd met JSON, op de queue te-

rechtkomen. De queue houdt rekening met concurrentie. De berichtjes in de queue worden

systematisch verwerkt door een aantal RecordInserters. RecordInserters zijn threads die

het logbericht verwerken en opslaan op de databank (codefragment 6.4). Het aantal threads

kan aangepast worden in een constante.

1 /** c r e a t e j e t t y s e r v e r */

2 Server j e t t yS e r v e r = new Server ( port ) ;

3

4 /* only l i s t e n to VEM type */

5 BlockingQueue<Str ing> queue = new LinkedBlockingQueue<Str ing >() ;

6 s e r v e r . sub s c r i b e (RemoteLoggingType .VEM, queue ) ;

7 i f ( l o gg e r . i s In foEnab l ed ( ) ) l o gg e r . i n f o ( " Server subsc r ibed ( type = VEM) . " ) ;

Page 43: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.1 Verwerking van binnenkomende berichten 36

8

9 /* s t a r t RemoteLoggingServer */

10 s e r v e r . s t a r t ( host , port ) ;

11 i f ( l o gg e r . i s In foEnab l ed ( ) ) l o gg e r . i n f o ( "RemoteLoggingServer s t a r t ed at "+

host + " : " + port + " . " ) ;

12

13 /* s t a r t j e t t y s e r v e r */

14 j e t t yS e r v e r . s t a r t ( ) ;

15 i f ( l o gg e r . i s In foEnab l ed ( ) ) l o gg e r . i n f o ( " Je t tySe rve r s t a r t ed at "+port+" . " ) ;

16

17 /* s t a r t THREADS Reco rd In s e r t e r s to parse logmessages */

18 i f ( l o gg e r . i s In foEnab l ed ( ) ) l o gg e r . i n f o ( " S ta r t i ng "+ Cpr981Constants .THREADS

+" Reco rd In s e r t e r s . . . " ) ;

19 ExecutorServ i ce pool=Executors . newFixedThreadPool ( Cpr981Constants .THREADS) ;

20 i n s e r t e r s = new ArrayList<RecordInser ter >() ;

21 f o r ( i n t i = 0 ; i < Cpr981Constants .THREADS ; i++) {

22 Record Inse r t e r r i = new Record Inse r t e r ( queue ) ;

23 i n s e r t e r s . add ( r i ) ;

24 pool . execute ( r i ) ;

25 }

26 i f ( l o gg e r . i s In foEnab l ed ( ) ) l o gg e r . i n f o ( Cpr981Constants .THREADS +"

Reco rd In s e r t e r s s t a r t ed . " ) ;

Codefragment 6.3: Opstarten van de webservice

De take() methode in codefragment 6.4 zorgt ervoor dat slechts één thread het bericht

krijgt, de andere RecordInserters blokkeren tot ze zelf een bericht kunnen bemachtigen.[13]

Dit wordt visueel voorgesteld in �guur 6.1. Vervolgens wordt het bericht verwerkt en

opgeslagen op de databank door gebruik te maken van Hibernate.

1 @Override

2 pub l i c void run ( ) {

3 whi le ( t rue ) {

4 t ry {

5 /* wait t i l l message i s a v a i l a b l e */

6 St r ing message = queue . take ( ) ;

7 /* parse and s t o r e message on db */

8 } catch ( Inter ruptedExcept ion e ) {// . . .

9 }

10 }

11 }

Codefragment 6.4: RecordInserter

Page 44: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.1 Verwerking van binnenkomende berichten 37

Figuur 6.1: Visualisatie van RemoteLoggingServer

6.1.3 Overzicht

Figuur 6.2 geeft het algemeen overzicht van de samenwerking tussen de loadbalancer en de

webservices. Ook de opstartparameters van elk proces worden aangegeven.

Figuur 6.2: Technisch overzicht van loadbalancer en webservices

6.1.4 Parsing

In elke RecordInserter wordt een Map voorzien met parsers. Eenzelfde map voor alle th-

reads is niet mogelijk omdat javax.xml.transform.Transformer.transform niet concurrent is.

Doordat de RecordInserter zich in een oneindige lus bevindt, zal deze Map slechts eenmalig

Page 45: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.1 Verwerking van binnenkomende berichten 38

geïnitialiseerd worden. Op deze manier wordt er zo weinig mogelijk tijd verloren. Bij het

binnenkomen van het bericht wordt er gekeken naar het berichttype. Door dit veld als

sleutel te gebruiken in de parserMap, wordt de juiste parser verkregen. Het binnenkomend

bericht kan vervolgens verwerkt worden door de 'parse'-methode van de verkregen parser

op te roepen. Deze methode geeft eveneens een Map terug die de geparsete waarden bevat.

Hiermee worden alle lege velden van de verpakkingsklasse 'VemLogMessage' aangevuld,

maar er wordt niets overschreven.

Door gebruik te maken van het parserbeheerscherm, kunnen er eenvoudig nieuwe types

en parsers bijgevoegd worden. Achter de schermen wordt er gebruikgemaakt van een

XPathParser die bestaat uit een lijst van XPathItemParsers. Elke itemParser heeft zijn

eigen XPathexpressie. Codefragment 6.5 toont hoe een XPathItemParser aangemaakt

wordt en hoe er geparset wordt. Door een lijst van itemParsers te gebruiken staat het

concept open voor uitbreiding. Op de databank worden hiervoor twee verschillende tabellen

voorzien, VEM_PARSERCONFIG en VEM_PARSERITEMCONFIG. De beschrijving

van deze tabellen is te vinden in bijlage A. Om bij het STRING-formaat ook XPath te

kunnen gebruiken, werd er een STRINGTAG rond de geleverde string geplaatst.

1 pub l i c XPathItemParser ( S t r ing name , S t r ing expr e s s i on ) {

2 super ( ) ;

3 super . setName (name) ;

4 XPathFactory xPathfactory = XPathFactory . newInstance ( ) ;

5 XPath xpath = xPathfactory . newXPath ( ) ;

6 t ry {

7 t h i s . e xp r e s s i on = xpath . compi le ( exp r e s s i on ) ;

8 } catch ( XPathExpressionException e ) { // . . .

9 }

10 }

11 @Override

12 pub l i c S t r ing parse (Document document ) {

13 t ry {

14 re turn ( St r ing ) exp r e s s i on . eva luate ( document , XPathConstants .STRING) ;

15 } catch ( XPathExpressionException e ) { // . . .

16 re turn "" ;

17 }

18 }

Codefragment 6.5: Voorbeeld gebruik van XPath parsing

Page 46: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.2 Gebruikersscherm voor parsers 39

6.2 Gebruikersscherm voor parsers

Om er voor te zorgen dat de itemParsersleutels overeenkomen met de sleutels voorzien

in de verpakkingsklasse 'VemLogMessage', werd er gebruikgemaakt van re�ectie. Vem-

LogMessage gebruikt intern een Map waarin de eigenschappen van het logbericht opgesla-

gen worden. De sleutels van de eigenschappen worden opgeslagen in constanten waarvan de

naam begint met 'KEY_'. Om de eigenschappen uit de Map op te vragen, zijn er getters

voorzien die gebruikmaken van de gede�nieerde constanten. Om er dus voor te zorgen dat

bij het parsen de juiste keys gebruikt worden, zodat dat de getters de juiste informatie

weergeven, werd er beroep gedaan op re�ectie om alle gede�nieerde sleutels dynamisch te

laden.

6.2.1 Dynamisch herladen van de parsers

Voor het dynamisch herladen van de parsers werd er gebruikgemaakt van Java Management

Extensions (JMX). JMX biedt de mogelijkheid om resources , onder de vorm van Managed

Beans (MBeans), te beheren terwijl ze aan het draaien zijn. Om dit te verwezenlijken

moeten de MBeans geregistreerd zijn bij een MBeanserver. De MBeanserver wordt beheerd

door een JMX agent . Het de�niëren van een MBean gebeurt door een interface te maken

met de naam van de implementerende klasse, gevolgd door 'MBean' (codefragment 6.6).

Om te voorkomen dat de interface en de implementor zich in dezelfde package moeten

bevinden, werd er een MXBean gebruikt.

1 pub l i c i n t e r f a c e WebserviceMXBean {

2 pub l i c void r e l o adA l lPa r s e r s ( ) ;

3 }

Codefragment 6.6: JMX: bean interface voor het herladen van parsers

Het registreren van de bean gebeurt in codefragment 6.7. In dit geval speelt de klasse

'Webservice' zowel de rol van MBean, als van JMX agent. De ObjectName is vrij te kiezen,

enkel het type moet overeen komen met de JMX-interfacenaam zonder 'MBean'. Door het

registeren zal de bean beschikbaar worden buiten de Java Virtual Machine (Java VM)

onder de opgegeven objectName waardoor de bean aanspreekbaar wordt via RMI3, HTTP

en SNMP4. In dit geval wordt er RMI gebruikt om de bean aan te spreken. Onderstaande

3Remote Method Invocation4Simple Network Management Protocol, protocol voor het beheer van apparaten in een netwerk

Page 47: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.2 Gebruikersscherm voor parsers 40

parameters worden op het classpath meegeven om de MBeanserver op een vaste poort te

laten draaien (codefragment 6.8).

1 pub l i c c l a s s Webservice implements IWebservice , WebserviceMXBean{

2 @Override

3 pub l i c void s t a r t ( ) throws Exception {

4 // . . .

5 /* s t a r t up MBeanServer */

6 MBeanServer mbs = ManagementFactory . getPlatformMBeanServer ( ) ;

7 ObjectName name = new ObjectName ( "e_ngids . Cpr981 : type=Webservice " ) ;

8 mbs . registerMBean ( th i s , name) ;

9 }

10 }

Codefragment 6.7: Implementeren en registreren van bean voor JMX

1 −Dcom. sun . management . jmxremote . port=8451

2 −Dcom. sun . management . jmxremote . au thent i ca t e=f a l s e

3 −Dcom. sun . management . jmxremote . s s l=f a l s e

Codefragment 6.8: Classpath variabelen voor het draaien van de MBean server

Codefragment 6.9 beschrijft hoe de beans van buitenaf aangesproken worden. Er wordt

eerst een JMXServiceURL opgesteld met de hostnaam en de poort van de MBeanserver.

Eens er connectie gemaakt werd met de server, kan er een proxy-object opgezet worden om

de nodige methodes uit te voeren. In het geval van het herladen van de parsers, werden

alle MBeanservers op dezelfde poort van de webservice gestart plus 100. Een webservice

die bijvoorbeeld op poort 8351 draait, zal een MBeanserver op poort 8451 draaien hebben.

Het herladen van de parsers komt er op neer dat elke RecordInserter om beurt de oude

parsers verwijdert en vervolgens de parsers opnieuw inlaadt. Het om beurt herladen van

de parsers moet ervoor zorgen dat er zeker geen berichten verloren gaan.

Doordat enkel de loadbalancer weet op welke poorten de webservices draaien, werden de

JMX ports hardgecodeerd. Om dit op te lossen kan er eerst een JMX call gedaan worden

naar de loadbalancer, die op zijn beurt een JMX call doet naar elke webservice.[8]

Page 48: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.3 Periodiek partities verwijderen en toevoegen 41

1 // f e t ch webserv ice por t s

2 va lu eL i s t = Va lueL i s tUt i l . g e tVa lue sForVa lueL i s tDe f in i t i on ( NextGenIdConstants

.DATABASE, NextGenIdConstants .VALUELIST_PARSER_JMX_PORTS) ;

3 f o r ( S t r ing port : v a l u eL i s t ) {

4 t ry {

5 JMXServiceURL ur l = new JMXServiceURL( " s e r v i c e : jmx : rmi : // "+HOST+"/

jnd i /rmi : // " + HOST + " : " + port + "/jmxrmi" ) ;

6

7 JMXConnector jmxConnector = JMXConnectorFactory . connect ( u r l ) ;

8 MBeanServerConnection mbeanServerConnection = jmxConnector .

getMBeanServerConnection ( ) ;

9 //ObjectName should be same as your MBean name

10 ObjectName mbeanName = new ObjectName ( "e_ngids . Cpr981 : type=

Webservice " ) ;

11

12 //Get MBean proxy ins tance , used to make c a l l s to r e g i s t e r e d MBean

13 WebserviceMXBean mbeanProxy = (WebserviceMXBean )

MBeanServerInvocationHandler . newProxyInstance ( mbeanServerConnection ,

mbeanName , WebserviceMXBean . c l a s s , f a l s e ) ;

14

15 mbeanProxy . r e l o adA l lPa r s e r s ( ) ;

16 jmxConnector . c l o s e ( ) ;

17 su c c e s s . add ( port ) ;

18 }

19 catch ( Exception ex ) {

20 // . . .

21 }

22 }

Codefragment 6.9: Herladen van parsers met behulp van een JMX bean

6.3 Periodiek partities verwijderen en toevoegen

De con�guraties voor het beheer van de partities worden opgeslagen in een ini-bestand. De

naam van het ini-bestand wordt opgeslagen in een ValueList. Bij het starten van Syk750,

het programma dat de partities toevoegt en/of verwijdert, zullen alle con�guraties overlo-

pen worden. Indien er momenteel een shift aan de gang is, zullen enkel de con�guraties

met een 'Force'-optie op true uitgevoerd worden. Indien er geen shift bezig is, worden alle

partitiecon�guraties uitgevoerd met voldoende tijd tot de volgende shift. Om het behe-

ren van het ini-bestand te vereenvoudigen, werd de 'PartitionIni'-klasse geschreven. Deze

Page 49: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.3 Periodiek partities verwijderen en toevoegen 42

klasse gebruikt achter de schermen IniFramework. IniFramework werd in het Framework

van Volvo ingebouwd zodat toekomstig gebruik van ini-bestanden vereenvoudigd wordt.

De 'PartitionIni'-klasse is een wrapper rond het IniFramework met extra functionaliteit

voor het beheren van de partities. IniFramework maakt gebruik van Ini4j. Alle methodes

voor het verwijderen en toevoegen van partities zit verpakt in de 'PartitionService'-klasse,

ook de eerste implementaties - die uiteindelijk verworpen werden - zitten hier in verweven.

6.3.1 Resterende tijd opvragen

Om na te gaan hoeveel tijd er nog rest tot de volgende shift wordt WhatShift gebruikt.

Dit is een reeds bestaande component in een ander Volvo-project. WhatShift maakt het

mogelijk om shiftinformatie op te vragen door middel van een registratiepunt en een start-

tijdstip. Na een berekening zal WhatShift een ShiftInfo-object teruggeven waaruit de

status, de starttijd, de stoptijd en de naam van de shift afgeleid kan worden. Indien de

statuscode gelijk is aan 'OUT_OF_SHIFT', is er momenteel geen shift bezig. De start-

en stoptijd die hier meegegeven worden, zijn de tijden van de volgende shift. Hierdoor kan

de resterende tijd berekend worden en kan er bepaald worden of er nog genoeg tijd over is

om de con�guratie uit te voeren.

6.3.2 Oude partities verwijderen

Een bestaande partitie verwijderen, samen met al zijn records, gebeurt als volgt: ALTER

TABLE vem_log_message DROP PARTITION partitienaam. Om te weten welke partities

er precies gedropt moeten worden, waren er twee mogelijkheden:

� Gebruikmaken van WhatShift om de naam te achterhalen van X aantal shifts terug

en vervolgens alle vroegere shifts verwijderen door de namen op te zoeken.

� Gebruikmaken van SQL en alle shifts opvragen kleiner dan de huidige shift.

Oudste shifts opvragen met WhatShift

WhatShift kan gebruikt worden om de partitienaam van de shift op te vragen die X aantal

shifts in het verleden voorkwam. Dit kan gebeuren volgens codefragment 6.10. De terugge-

geven waarde wordt vervolgens gebruikt als parameter in de SQLquery van codefragment

6.11 om alle oudere shifts op te vragen. Het voordeel van WhatShift te gebruiken is dat er

ook rekening gehouden wordt met vakantieperiodes.

Page 50: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.3 Periodiek partities verwijderen en toevoegen 43

1 pub l i c S t r ing getOldestPart it ionName ( i n t keepNShi f t s ) throws

SemanticException {

2 // s t a r t at cur rent s h i f t

3 Date tempRegDate = cu r r e n t Sh i f t I n f o . getStartTime ( ) ;

4 Sh i f t I n f o s h i f t I n f o= cu r r e n t Sh i f t I n f o ;

5 f o r ( i n t i =0; i< keepNShi f t s +1; i++) {

6 // f e t ch prev ious s h i f t s t a r t i n g from given time

7 Vor i g eSh i f t v o r i g e Sh i f t = new Vor i g eSh i f t ( regPoint , tempRegDate ) ;

8 // save s h i f t in fo rmat ion

9 s h i f t I n f o = vo r i g e Sh i f t . g e t S h i f t I n f o ( ) ;

10 // subt rac t 30 minutes to make sure the prev ious s h i f t i s f e t ched i f

i t e r a t e d again

11 tempRegDate= subtract30min ( s h i f t I n f o . getStartTime ( ) ) ;

12 }

13 // return p a r t i t i o n name

14 re turn s h i f t I n f o . getVolvoDate ( )+s h i f t I n f o . g e t Sh i f t ( ) ;

15 }

Codefragment 6.10: Shiftinformatie opvragen van X aantal shifts terug

1 SELECT PARTITION_NAME

2 FROM USER_TAB_PARTITIONS

3 WHERE TABLE_NAME = UPPER( ' vem_log_message ' ) and PARTITION_NAME < ?

Codefragment 6.11: Opvragen oudste shifts via shiftinformatie van WhatShift

Oudste shifts opvragen met enkel SQL

Deze methode maakt enkel gebruik van SQL. De query wordt weergegeven in codefragment

6.12. Hierbij zijn de eerste twee parameters de partitienaam van de huidige shift en is de

derde parameter het aantal shifts dat bewaard moet blijven. Dit levert hetzelfde resultaat

op als het vorige, maar er is slechts één query nodig. Deze methode heeft als belangrijk

nadeel dat er geen rekening gehouden wordt met vakantieperiodes. Dit wil zeggen dat als er

partities aangemaakt werden in de vakantieperiode dat er veel kans is dat de logberichten

van voor de vakantie verwijderd worden bij het lopen van het programma. Dit is niet het

geval bij het gebruik van WhatShift, aangezien WhatShift de vakantieperiode niet meetelt

als werkshifts. Het is wel mogelijk om de query uit te breiden zodat lege partities genegeerd

worden. Dit zou ongeveer hetzelfde e�ect moeten hebben als de WhatShift-methode.

Page 51: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.3 Periodiek partities verwijderen en toevoegen 44

1 s e l e c t x .PARTITION_NAME

2 from USER_TAB_PARTITIONS x

3 j o i n USER_TAB_PARTITIONS y on x .PARTITION_NAME < y .PARTITION_NAME

4 and x .TABLE_NAME=y .TABLE_NAME

5 where x .PARTITION_NAME < ? and y .PARTITION_NAME < ?

6 and x .TABLE_NAME = UPPER( ' vem_log_message ' )

7 group by x .PARTITION_NAME

8 having count (1 ) > ?

Codefragment 6.12: Opvragen oudste shifts via SQL

Droppen

Eens de partitienamen opgehaald zijn, kunnen ze één voor één gedropt worden met volgende

query: ALTER TABLE vem_log_message DROP PARTITION ?.

6.3.3 Toevoegen van nieuwe partities

Doordat we gebruikmaken van een MAXVALUE-partitie kunnen we niet rechtstreeks een

ADD PARTITION uitvoeren. De nieuwe partitiegrens moet namelijk altijd hoger zijn dan

de laatst toegevoegde. Dit is niet mogelijk door de MAXVALUE-partitie. Om toch de

nieuwe partities klaar te zetten gebruiken we SPLIT PARTITION. Hierdoor zal Oracle de

bestaande records in de op te splitsen partitie verdelen over de twee nieuwe partities. Aan-

gezien de MAXVALUE-partitie normaal gezien leeg is, zal er altijd een geoptimaliseerde

split-operatie plaatsvinden.

Voor het uitvoeren van alle query's werd de 'PartitionCon�gDaoImpl'-klasse geschreven

die overerft van JdbcDaoSupport. Omdat de dao5 toegang moest hebben tot verschillende

databanken, wordt bij elke query de dataSource uit de cache gehaald of aangemaakt. Dit

mechanisme wordt getoond in codefragment 6.13.

5Data Access Object

Page 52: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.3 Periodiek partities verwijderen en toevoegen 45

1 pr i va t e DataSource getDataSource ( S t r ing db) {

2 DataSource dataSource = dataSources . get (db) ;

3 i f ( dataSource == nu l l ) {

4 // c r ea t e new dataSource

5 dataSource = new HibernateBasicDataSource (db) ;

6 dataSources . put (db , dataSource ) ;

7 }

8 re turn dataSource ;

9 }

Codefragment 6.13: Opvragen van de juiste dataSource

Ophalen van het werkschema

Voor het ophalen van het huidige werkschema moet er rekening gehouden worden met het

registratiepunt (kursprd) en met de geldigheidsdatum. Een registratiepunt is een knoop-

punt of post op de weg die een auto a�egt gedurende het productieproces. Het is belangrijk

dat enkel de meest recentste gegevens opgevraagd worden. De gebruikte query wordt ge-

toond in codefragment 6.14. Hierbij is de parameter het gebruikte registratiepunt.

1 s e l e c t *

2 from tcp007 x

3 where x . kursprd= ? and x . dy4tkgeldv = ( s e l e c t max(y . dy4tkgeldv )

4 from tcp007 y

5 where x . idagweek = y . idagweek

6 and x . k s h i f t = y . k s h i f t

7 and x . kursprd = y . kursprd

8 )

9 order by x . kursprd , x . idagweek , x . k s h i f t

Codefragment 6.14: Opvragen recentste werkschema

Eens de 'WorkSchedule'-objecten opgevraagd zijn, kunnen de nieuwe partities aangemaakt

worden. Het is hierbij mogelijk dat een bovengrens van een partitie op de volgende dag

valt. Dit moet gecontroleerd worden door de begin- en eindtijd van het 'WorkSchedule'-

object met elkaar te vergelijken. Bij elke partitie die toegevoegd moet worden, wordt er

nagegaan als ze nog niet bestaat. Bovendien moet opgepast worden bij het werken met

Calendar-dagen aangezien zaterdag de eerste dag van de week is in plaats van maandag.

Page 53: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.4 Beheerscherm voor partitiecon�guraties 46

6.4 Beheerscherm voor partitiecon�guraties

Het ini-bestand dat gebruikt wordt voor de partitiecon�guraties wordt opgedeeld in ver-

schillende secties. Codefragment 6.15 geeft een voorbeeld van een ini-bestand. De eerste

sectie is een systeemsectie. Hierin staan alle bestaande systemen die gemapt worden op

databanknaam. Deze mapping wordt gebruikt zodat de gebruiker de systeemnaam kan ge-

bruiken in plaats van de databanknaam. Alle secties erna stellen de verschillende partities

voor, samengenomen in een 'PartitionCon�guration'-sectie. De hoofdsectienamen kunnen

eenvoudig aangepast worden door de klasseconstanten van de 'PartitionIni'-klasse te wij-

zigen. De sectienaam van een con�guratie heeft volgend formaat: systeem.tabelnaam. Dit

vereenvoudigt het opzoeken (subsectie 6.4.2).

1 [ SystemConf igurat ion ]

2 CIP = DCP

3 SYS = DSY_NATIVE

4

5 [ Pa r t i t i onCon f i gu ra t i on /CIP .VEM_LOG_MESSAGE]

6 system = CIP

7 t ab l e = VEM_LOG_MESSAGE

8 f o r c e S p l i t = f a l s e

9 forceDrop = f a l s e

10 keepNprevShi f t s = 30

11 timeNeeded = 5

12 updatedBy = jvandec2

13 updatedTimestamp = . . .

Codefragment 6.15: Voorbeeld ini-bestand voor partitiebeheer

6.4.1 Werking

Om de werking van ini4j eenvoudiger te maken, werd er een wrapperklasse voorzien die

intern ini4j gebruikt, IniFramework. Deze klasse werd vervolgens in het Framework van

Volvo opgenomen zodat ook andere projecten er gebruik van kunnen maken. Vervolgens

werd er nog een klasse voorzien die intern de wrapperklasse gebruikt, PartitionIni. Deze

klasse zorgt voor een eenvoudige interface voor het beheren van de partitiecon�guraties.

Page 54: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

6.4 Beheerscherm voor partitiecon�guraties 47

6.4.2 Zoeken

Het zoeken gebeurt in de PartitionCon�guration-sectie. De gede�nieerde partitiecon�gu-

raties kunnen opgevraagd worden met getPartition(). Aangezien de naam van de partities

alle �lterinformatie bevat, kan er eenvoudig gezocht worden naar de juiste partities. Dit

kan gebeuren door de sectienaam te splitsen op de plek waar het punt staat. Het linkerdeel

wordt dan vergeleken met het opgegeven systeem en het rechterdeel met de tabelnaam.

Het zoekalgoritme staat uitgewerkt in codefragment 6.16.

1 pub l i c Li s t<Part i t i onConf ig> search ( St r ing system , St r ing tab l e ) {

2 List<Part i t i onConf ig> l i s t = new ArrayList<Part i t i onConf ig >() ;

3 i f ( S t r i n gUt i l . i sStr ingEmpty ( system ) && St r i n gUt i l . i sStr ingEmpty ( tab l e ) ) {

4 // no f i l t e r s , f e t ch a l l

5 l i s t = g e tPa r t i t i o n s ( ) ;

6 }

7 e l s e i f ( ! S t r i n gUt i l . i sStr ingEmpty ( system ) && ! S t r i n gUt i l . i sStr ingEmpty (

t ab l e ) ) { // both f i l t e r s , f e t ch s e c t i o n

8 Par t i t i onCon f i g c on f i g = ge tPa r t i t i o n ( system+" . "+tab l e ) ;

9 i f ( c on f i g != nu l l ) l i s t . add ( c on f i g ) ;

10 }

11 e l s e {

12 f o r ( S t r ing partit ionName : getPart it ionNames ( ) ) {

13 /* s p l i t on point , reminder : regexp po int i s d i f f e r e n t , \\ needed */

14 St r ing [ ] s p l i t = partit ionName . s p l i t ( " \\ . " ) ;

15 i f ( ( ! S t r i n gUt i l . i sStr ingEmpty ( system ) && system . equa l s IgnoreCase (

s p l i t [ 0 ] ) ) | |

16 ( ! S t r i n gUt i l . i sStr ingEmpty ( t ab l e ) && tab l e . equa l s IgnoreCase ( s p l i t

[ 1 ] ) ) ) {

17 // match

18 l i s t . add ( g e tPa r t i t i o n ( partit ionName ) ) ;

19 }

20 }

21 }

22 re turn l i s t ;

23 }

Codefragment 6.16: Zoeken naar de juiste partitiecon�guratie

Page 55: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

TESTING 48

Hoofdstuk 7

Testing

Dit hoofdstuk beschrijft wat er precies gebruikt werd bij het testen en hoe bepaalde zaken

getest werden. Allereerst werden de user interfaces handmatig getest. Verder werd DbUnit

en Liquibase gebruikt om code te testen die gebruikmaakt van een databankconnectie. Voor

het kiezen van de indexen werd er speciaal een testomgeving opgezet.

7.1 DbUnit

Om de DAO's te testen werd DbUnit gebruikt. DbUnit biedt de mogelijkheid om tijdelijk

enkele records toe te voegen zonder dat ze blijvend op de databank worden opgeslagen.

Deze records zijn gekenmerkt door een zelfopgegeven negatieve id. Vervolgens kunnen alle

methodes van de dao getest worden. Eens alles getest is, wordt de tabel hersteld naar zijn

oorspronkelijke staat. De toe te voegen records worden aangereikt in een xml-bestand.

7.2 Liquibase

Omdat DbUnit geen 'ALTER TABLE'-statements ondersteunt, werd er gebruikgemaakt

van Liquibase. Liquibase gebruikt changeSets om wijzigingen op de databank aan te

geven. Hierdoor kan er tijdelijk een gepartitioneerde tabel aangemaakt worden om alle

'ALTER TABLE'-statements en functionaliteit van Syk750 te testen. Na het uitvoeren

van de tests kan de aanmaak van de tabel ongedaan gemaakt worden door een rollback 1.

Het gebruik van Liquibase wordt getoond in codefragment 7.1. Doordat de 'createTable'-

tag van Liquibase geen partitionering ondersteunt, werd de 'sql'-tag gebruikt. Ook de

1tabel herstellen naar oorspronkelijke staat

Page 56: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

7.2 Liquibase 49

'dropTable'-tag werd vervangen door een 'sql'-tag om de 'purge'-optie mee te geven. 'Purge'

zorgt ervoor dat de verwijderde gegevens niet in de prullenbak terechtkomen, maar direct

verwijderd worden. Codefragment 7.2 toont de changeSet die Liquibase inlaadt voor het

opzetten en afbreken van de tabel.

1 @Override

2 protec ted void onSetUp ( ) throws Exception {

3 super . onSetUp ( ) ;

4 pa r t i t i o n S e r v i c e = Par t i t i onSe rv i c eLoca t o r . g e tPa r t i t i o nS e r v i c e ( ) ;

5

6 conn = th i s . dataSource . getConnect ion ( ) ;

7

8 Database database = DatabaseFactory . g e t In s tance ( )

9 . f indCorrectDatabaseImplementat ion (new JdbcConnection ( conn ) ) ;

10 l i q u i b a s e = new Liqu ibase ( Pa r t i t i onSe rv i c eTe s t . c l a s s . getResource ( "/db−t e s tda ta . xml" ) . g e tF i l e ( ) . t oS t r i ng ( ) ,new Fi leSystemResourceAccessor ( ) ,

database ) ;

11 Contexts cont = nu l l ;

12 l i q u i b a s e . update ( cont ) ;

13 }

14

15 @Override

16 protec ted void onTearDown ( ) throws Exception {

17 super . onTearDown ( ) ;

18 Contexts cont = nu l l ;

19 l i q u i b a s e . r o l l b a ck (1000 , cont ) ;

20 conn . c l o s e ( ) ;

21 }

Codefragment 7.1: Opzetten van Liquibase

1 <databaseChangeLog

2 xmlns=" ht tp : //www. l i q u i b a s e . org /xml/ns/dbchangelog "

3 xmlns :x s i=" ht tp : //www.w3 . org /2001/XMLSchema−i n s t ance "

4 xs i : s chemaLocat ion=" ht tp : //www. l i q u i b a s e . org /xml/ns/dbchangelog

5 ht tp : //www. l i q u i b a s e . org /xml/ns/dbchangelog /dbchangelog −3.1 . xsd">

6 <changeSet author=" jvandec2 " id=" createTab leWithPart i t ionsv1 ">

7 <sq l>

8 c r e a t e t ab l e Pa r t i t i onSe rv i c eTe s t 2

9 (

10 VEM_MESSAGE_ID number (22) NOT NULL

11 , DATAPOINT VARCHAR2(32)

12 , IBODYNR VARCHAR2(32)

Page 57: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

7.3 EasyMock 50

13 , TSREG TIMESTAMP

14 , MSG VARCHAR2(4000)

15 , MSG_TYPE VARCHAR2(100)

16 , PRIMARY KEY (VEM_MESSAGE_ID)

17 )

18 PARTITION BY RANGE (TSREG)

19 (

20 PARTITION "20141541" VALUES LESS THAN (TO_DATE( ' 2014−04−10 13 : 2 9 : 5 9 '

, ' yyyy−MM−dd HH24:MI:ss ' ) )

21 , PARTITION "20141542" VALUES LESS THAN (TO_DATE( ' 2014−04−10 21 : 2 9 : 5 9 '

, ' yyyy−MM−dd HH24:MI:ss ' ) )

22 , PARTITION "20141543" VALUES LESS THAN (TO_DATE( ' 2014−04−11 05 : 1 4 : 5 9 '

, ' yyyy−MM−dd HH24:MI:ss ' ) )

23 , PARTITION "20141551" VALUES LESS THAN (TO_DATE( ' 2014−04−11 12 : 1 4 : 5 9 '

, ' yyyy−MM−dd HH24:MI:ss ' ) )

24 , PARTITION "20141552" VALUES LESS THAN (TO_DATE( ' 2014−04−11 18 : 5 9 : 5 9 '

, ' yyyy−MM−dd HH24:MI:ss ' ) )

25 , PARTITION other VALUES LESS THAN (MAXVALUE)

26 )

27 </ sq l>

28 <ro l l b a ck>

29 <sq l>drop tab l e Pa r t i t i onSe rv i c eTe s t 2 purge</ sq l>

30 </ ro l l b a ck>

31 </changeSet>

32 </databaseChangeLog>

Codefragment 7.2: XML met changeSet gebruikt door liquibase

7.3 EasyMock

Om de te testen klasses onafhankelijk te maken van hun dependencies werd EasyMock

gebruikt. Hiermee kunnen methodes of klasses gemockt worden. Dit wil zeggen dat er op

voorhand ingesteld wordt wat een bepaalde methode of klasse moet teruggeven. Codefrag-

ment 7.3 toont hoe de resterende tijd gemockt wordt voor het testen van ParititonService.

1 pa r t i t i o n S e r v i c e = createMockBui lder ( Pa r t i t i o nS e r v i c e . c l a s s ) . addMockedMethod

( " ca l cu la t eT imeLe f t " ) . createMock ( ) ;

2 expect ( p a r t i t i o n S e r v i c e . ca l cu la t eT imeLe f t ( ) ) . andReturn ( 4 . 9 ) . t imes (1 ) ;

3 expect ( p a r t i t i o n S e r v i c e . ca l cu la t eT imeLe f t ( ) ) . andReturn ( 5 . 1 ) ;

4 r ep lay ( p a r t i t i o n S e r v i c e ) ;

Codefragment 7.3: Voorbeeld gebruik van EasyMock

Page 58: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

7.4 Partitioning testomgeving 51

7.4 Partitioning testomgeving

7.4.1 Opstelling

Voor de testomgeving werd er een gepartitioneerde tabel aangemaakt met dezelfde struc-

tuur als de echte tabel. Hierbij werd een week aan partities aangemaakt waarbij de partities

op de weekdagen gevuld werden met 500.000 records. Dit komt neer op precies 7,5 miljoen

records. Vervolgens werden allerlei query's uitgevoerd om na te gaan wat de beste metho-

des zijn om in het uiteindelijke ontwerp te gebruiken. Om de gegevens aan te maken en

om snel opnieuw de gedropte records in te voeren werd er PL/SQL gebruikt. De scripts

werden uitgevoerd in Toad en de sqlquery's werden uitgevoerd in Squirrel. De bedoeling

was om een beeld te krijgen van de uitvoertijden van de verschillende soorten operaties.

De verschillende testcases worden beschreven in tabel 7.1. Enkel de 'equals'-operator werd

onder de loep genomen omdat enkel deze operator in de eindopstelling wordt gebruikt.

Tabel 7.1: Omschrijving verschillende testcases voor testomgeving

Omschrijving

TESTCASE 1 enkel een primary key (unique index)

TESTCASE 2 een index op de kolom waarop GEEN partitioning wordt uitgevoerd

TESTCASE 3 twee indexen op de kolommen waarop GEEN partitioning wordt

uitgevoerd

TESTCASE 4 een index op de kolom waarop WEL partitioning wordt uitgevoerd

TESTCASE 5 een gecombineerde index met de kolom waarop WEL partitioning

wordt uitgevoerd

TESTCASE 6 een local index op de kolom waarop GEEN partitioning wordt uit-

gevoerd

TESTCASE 7 een gecombineerde local index met de kolom waarop WEL partiti-

oning wordt uitgevoerd

TESTCASE 8 een local index op de kolom waarop WEL partitioning wordt uit-

gevoerd

Page 59: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

7.4 Partitioning testomgeving 52

7.4.2 Resultaten

Tabel 7.2 vat de resultaten samen voor het verwijderen van een partitie. De andere resul-

taten werden ondergebracht in bijlage D.

Tabel 7.2: Verwijderen van een partitie: gemiddelden naast elkaar

UPDATE INDEXES ALTER INDEX

TESTCASE 1 21,681 62,276

TESTCASE 2 50,255 141,422

TESTCASE 3 61,932 257,254

TESTCASE 4 59,731 209,767

TESTCASE 5 39,323 154,148

TESTCASE 6 21,546 64,960

TESTCASE 7 22,291 64,750

TESTCASE 8 24,026 65,309

7.4.3 Bevindingen

De resultaten bij insert en delete komen bij elke testcase ongeveer overeen. Toch zorgt de

aanwezigheid van een index voor een lichte verhoging in uitvoertijd, maar dit is miniem.

Ook bij het splitsen van een partitie is er nauwelijks verschil in uitvoertijd. Het grootste

verschil zit vooral in het droppen van de partities. Hieruit kan geconcludeerd worden dat

het gebruik van 'UPDATE INDEXES' merkelijk beter presteert in vergelijking met de

'ALTER INDEX'- en de 'DELETE'-methode. Concreet kan vastgesteld worden dat de

methode met 'UPDATE INDEXES' ongeveer drie keer sneller is als de 'ALTER INDEX'-

methode. Er kan ook afgeleid worden dat elke extra index ongeveer evenveel extra tijd in

beslag neemt, 60 tot 80 seconden. Een gecombineerde index duurt ongeveer anderhalve

keer zo lang als een enkele index. Doordat local indexes niet onbeschikbaar worden bij

het droppen van een partitie, is de uitvoertijd vergelijkbaar met een opstelling waar enkel

een primary key constraint aanwezig is. Verder is er bij de opzoekingen ook niet echt veel

verschil op te merken tussen de performantie van globale en lokale indexen. Het verschil

in performantie bij aanwezigheid van een index is echter enorm.

Page 60: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

7.4 Partitioning testomgeving 53

7.4.4 Conclusie

Local indexes genieten de voorkeur bij het beheren van de partities. Door 'UPDATE IN-

DEXES' te gebruiken zullen de indexen nooit onbruikbaar worden. De combinatie local

indexes met 'UPDATE INDEXES' is dan ook de uiteindelijk gebruikte combinatie. Aan-

gezien er bij de uitvoertijden van de selectiequery's relatief weinig verschil merkbaar was

tussen lokale en globale indexen, zullen lokale indexen ook op dit vlak voldoen. Bij de

uiteindelijke opstelling werd er dus gekozen voor lokale indexen op station, bodynummer

en berichttype.

Page 61: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN 54

Hoofdstuk 8

Resultaten

8.1 Stresstest

Om de verwerkingskracht van de loadbalancer en de webservices te testen, werd er een

stresstest ontwikkeld. Dit komt neer op een programma die zo snel mogelijk een hele

hoop berichten verstuurd. Om geen onderscheid te maken in XPath-berichten en String-

berichten, werden er telkens even veel berichten van beide verstuurt. Ondertussen werd

er nagekeken welke opstelling er uiteindelijk best gebruikt zal worden. Dit werd nagegaan

door het aantal webservices en het aantal threads te laten wijzigen. Deze opstelling werd

twee maal uitgevoerd, éénmaal lokaal en éénmaal op OpenVMS. Het lokaal uitvoeren van

de opstelling geeft een idee van de maximale doorvoer zonder belasting van andere proces-

sen. Het testen op OpenVMS geeft aan wat het programma zal doen op de uiteindelijke

omgeving en onder meer belasting van andere processen. De productieserver en de testser-

ver zijn hetzelfde type toestel, maar in de productieomgeving worden er meerdere servers

gebruikt, waardoor er minder werklast is. De speci�caties van de gebruikte systemen wor-

den opgelijst in tabel 8.1. Het eindelijke doel voor de verwerking van de berichten werd

geschat op maximaal twintig berichten per seconde.

Tabel 8.1: Vergelijking systeemspeci�caties voor de stresstest

Lokaal Server

Besturingssysteem Windows 7 Enterprise 64-bit OpenVMS

Type Dell OPTIPLEX 790 HP RX6600

Processor i5-2400 @ 3.10 GHz Intel Itanium 2

Geheugen 4 GB 96 GB

Page 62: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

8.1 Stresstest 55

8.1.1 Lokaal

De resultaten zijn te vinden in bijlage F. Het is meteen duidelijk dat te veel threads of

processen zorgt voor een overbelasting van het systeem, waardoor er ook berichten verloren

gaan. Verder blijkt een opstelling met twee of drie webservices het stabielst te draaien. Er

kan ook afgeleid worden dat het verwerken van 300 berichten per seconde geen probleem

blijkt te zijn. Vanaf 350 berichten per seconde begint het systeem echter onstabiel te

worden.

8.1.2 VMS

De resultaten zijn te vinden in bijlage G. Het eerste wat opvalt is het grote verschil in

het verwerkte aantal berichten per seconde. Dit aantal ligt beduidend lager dan bij de

lokale tests, afgerond 90 berichten per seconde vergeleken met 300 lokaal. Vermoedelijk

komt dit door de hogere belasting van andere processen, wat minder het geval zal zijn in

productieomgeving. Bovendien brengt het verhogen van het aantal processen slechts een

kleine verhoging van de performantie met zich mee. Het verhogen van het aantal threads

zorgt voor crashes. Gezien de server meer geheugen heeft, zal het uitbreiden in processen

beter zijn dan het verhogen van het aantal threads. Het is ook belangrijk op te merken

dat er geen berichten verloren gaan.

8.1.3 Conclusie

Ook al ligt de verwerking van het aantal berichten per seconde lager op de testomgeving,

het doel om twintig berichten per seconde te verwerken is ruim bereikt. De lokale uitvoering

geeft een idee van het potentieel van de opstelling. Verder zullen twee of drie webservices

met elk vijftien threads volstaan als startopstelling. Het verhogen van het aantal threads

wordt best achterwege gelaten om onstabiliteit te vermijden.

Page 63: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

8.2 Opvragen logberichten 56

8.2 Opvragen logberichten

8.2.1 Opstelling

De performantie van de uiteindelijke opstelling werd getest door opnieuw een week aan

testdata te voorzien en vervolgens een hoop selectiequery's uit te voeren met behulp van

het VemLogViewer-scherm. Hierbij werd er gevarieerd in het aantal records per pagina, in

het gebruik van �lters en de opzoekgrenzen. Door telkens te zoeken op verschillende waar-

den, werd caching zoveel mogelijk tegengegaan. De resultaten zijn te vinden in tabel 8.2

en bijlage E. Tabel 8.2 zet de resultaten van Native SQL en Hibernate naast elkaar bij op-

zoekingen in verschillende partities met het aantal records gelimiteerd tot 500. Vervolgens

werden de resultaten zonder �lters nog eens uitgetekend in een staafdiagram, weergegeven

in �guur 8.1.

8.2.2 Bevindingen

De relatief hoge uitvoertijden zonder �lters bij een volledige tabelscan via Hibernate is het

eerste wat opvalt. Het gebruik van �lters geeft wel een enorme performantiewinst. Verder

heeft het wijzigen van het aantal resultaten per pagina van 50 naar 1000, weinig of geen

impact. Ook het opzoeken in slechts één shift geeft een gigantisch verschil bij Hibernate,

maar dit is begrijpelijk aangezien het aantal records ook aanzienlijk afneemt. De verhou-

ding van het aantal records met de snelheid blijft ongeveer gelijk, ongeveer twee seconden

per opgevraagde partitie. Als de uitvoertijden van Hibernate naast deze met native SQL

gelegd worden, kan vastgesteld worden dat er wel degelijk een performantieverschil is. De

opzoektijden van Native SQL blijven min of meer constant, onafhankelijk van het aantal

partities, terwijl de opzoektijden van Hibernate lineair stijgen met het aantal partities. Dit

heeft te maken met de extra query die uitgevoerd wordt om het aantal records op te vragen,

in vergelijking met Native SQL waarbij het limiteren van de records achter de schermen

gebeurt.

8.2.3 Conclusie

Aangezien er vooral opzoekingen zullen gebeuren in de huidige shift, of de twee recentste

shifts, voldoet de opzoeksnelheid aan de eisen. Het verschil in performantie met Native

SQL is behoorlijk, maar voor het zoeken in één of twee partities valt dit relatief mee. Het

omschakelen naar Native SQL via JDBC is in eerste instantie niet nodig, tenzij er in de

toekomst vaker in grotere tijdsspannes gezocht zal worden.

Page 64: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

8.2 Opvragen logberichten 57

Tabel 8.2: Vergelijking opzoektijden van Native SQL met Hibernate in eindopstelling met resul-

taten gelimiteerd tot 500 records

Scope Filter Native SQL Hibernate

één partitie geen 2,249 2,809

één partitie station 0,006 0,037

één partitie bodyNr 0,006 0,028

twee partities geen 2,383 4,578

twee partities station 0,018 0,028

twee partities bodyNr 0,009 0,028

zes partities geen 2,572 13,012

volledig geen 2,226 31,363

volledig station 0,006 0,030

volledig bodyNr 0,006 0,115

Figuur 8.1: Native SQL vs Hibernate: staafdiagram die uitvoertijd toont bij het aantal partities

Page 65: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

UITBREIDINGEN 58

Hoofdstuk 9

Uitbreidingen

Dit hoofdstuk gaat dieper in op mogelijke uitbreidingen. Als eerste wordt er gekeken om

de logberichten sneller op te vragen. Vervolgens wordt er onderzocht wat er moet gebeuren

indien de functionaliteit van het parsen verplaatst zou worden naar een update-programma.

Er wordt ook dieper ingegaan op een uitbreiding van range partitioning, waarbij partities

automatisch aangemaakt worden.

9.1 Gebruikersscherm voor logberichten

Momenteel wordt bij het ophalen van de logberichten Hibernate gebruikt met paginering.

Het zou natuurlijk geen kwaad kunnen om over te schakelen naar JDBC of enige aanpassin-

gen te doen aan Hibernate om de performantie wat op te krikken. De volgende paragrafen

geven aan wat de verschillende mogelijkheden zijn. Indien er JDBC gebruikt zou worden,

moet er wel rekening mee gehouden worden dat paginering beschikbaar moet blijven om

de wachttijden te drukken.

9.1.1 Aanpassingen aan Hibernate

Scrollable resultset

Een scrollable resultset zorgt ervoor dat elke entiteit1 apart behandeld wordt. De 'evict'-

methode in codefragment 9.1 voorkomt dat het geheugen volgeraakt. Hierbij moet er wel

rekening gehouden worden dat er geen aanpassingen meer kunnen gebeuren aan de entiteit

zelf, maar aangezien we enkel records opvragen, zal dat geen probleem zijn. Er kan ook

1omzetting van record naar object

Page 66: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

9.1 Gebruikersscherm voor logberichten 59

geen lazy fetching gebruikt worden. Lazy fetching wil zeggen dat eigenschappen van een

object pas opgehaald worden als ze nodig zijn. Indien dit af staat, zullen de eigenschappen

direct ingeladen worden bij het ophalen van het record. Het is dan ook logisch dat lazy

fetchen niet gebruikt kan worden, aangezien het object uit de cache gehaald is met de

'evict'-methode. SetReadOnly optimaliseert de query.[4]

1 Ses s i on s e s s i o n = se s s i onFac to ry . ge tCurrentSes s i on ( ) ;

2 S c r o l l a b l eR e s u l t s s c r o l l a b l eR e s u l t s = s e s s i o n . createQuery ( " from DemoEntity" )

. setReadOnly ( t rue ) . s c r o l l ( Scrol lMode .FORWARD_ONLY) ;

3 i n t count = 0 ;

4 whi le ( s c r o l l a b l eR e s u l t s . next ( ) ) {

5 DemoEntity demoEntity = (DemoEntity ) s c r o l l a b l eR e s u l t s . get ( ) [ 0 ] ;

6 // Process and wr i t e r e s u l t

7 s e s s i o n . e v i c t ( demoEntity ) ;

8 }

Codefragment 9.1: Gebruik van een Scrollable resultset met Hibernate

Stateless session

Ook hier kan een scrollable resultset gebruikt worden, maar in plaats van een normale

sessie te gebruiken, wordt er geopteerd voor een statusloze sessie. Hierdoor zal Hibernate

min of meer al zijn features uitschakelen, dwz. geen dirty detection2, geen lazy loading, ...

. Het enige wat Hibernate nog doet is records omzetten naar objecten met als voordeel

dat er niet manueel ge�usht of evicted moet worden. De werking wordt beschreven in

codefragment 9.2.

Deze methode heeft als nadeel dat er geen sessionfactory gebruikt kan worden om de sessie

op te starten. Omdat openStatelessConnection() automatisch een nieuwe java.sql.Connection

start, moet er gebruikgemaakt worden van de Hibernate Work API om de huidige connectie

te kunnen benutten. Dit voorbeeld is enkel goed voor read-only toepassingen, maar dat is

opnieuw geen probleem aangezien aangezien logberichten aanpassen geen gewenst gedrag

is. Deze manier is mogelijk een beter alternatief dan het eerste.[4]

2controle of entiteit overeenkomt met het record op de databank

Page 67: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

9.1 Gebruikersscherm voor logberichten 60

1 s e s s i onFac to ry . ge tCurrentSes s i on ( ) . doWork(new Work( ) {

2 @Override

3 pub l i c void execute ( Connection connect ion ) throws SQLException {

4 S t a t e l e s s S e s s i o n s t a t e l e s s S e s s i o n = se s s i onFac to ry . op enS ta t e l e s s S e s s i on (

connect ion ) ;

5 t ry {

6 S c r o l l a b l eR e s u l t s s c r o l l a b l eR e s u l t s = s t a t e l e s s S e s s i o n . createQuery ( "

from DemoEntity" ) . s c r o l l ( Scrol lMode .FORWARD_ONLY) ;

7 i n t count = 0 ;

8 whi le ( s c r o l l a b l eR e s u l t s . next ( ) ) {

9 DemoEntity demoEntity = (DemoEntity ) s c r o l l a b l eR e s u l t s . get ( ) [ 0 ] ;

10 // Process and wr i t e r e s u l t

11 }

12 } f i n a l l y {

13 s t a t e l e s s S e s s i o n . c l o s e ( ) ;

14 }

15 }

16 }) ;

Codefragment 9.2: Gebruik van een Stateless session met Hibernate

9.1.2 Opzoeken met JDBC

Het gebruik van paginering met JDBC steunt op dezelfde principes als bij Hibernate.

Deze methode gebruikt een zelfgemaakte klasse 'PaginationHelper<E>' voor het ophalen

van een pagina. Intern wordt hierbij een ResultSetExtractor gebruikt om een pagina op te

vullen. De ParameterizedRowMapper<E> voorziet in het omzetten van records in objecten

(codefragment 9.3). Om dit principe verder te optimaliseren kan het aantal records per

pagina gecachet worden. Dit vermijdt het nodeloos opzoeken van het aantal pagina's indien

het aantal resultaten per pagina niet aangepast werd. Bovendien kan er ook een scrollable

resultset gebruikt worden.[1]

Page 68: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

9.1 Gebruikersscherm voor logberichten 61

1 pub l i c c l a s s Paginat ionHelper<E> {

2

3 pub l i c Page<E> fetchPage (

4 f i n a l JdbcTemplate j t ,

5 f i n a l S t r ing sqlCountRows ,

6 f i n a l S t r ing sqlFetchRows ,

7 f i n a l Object args [ ] ,

8 f i n a l i n t pageNo ,

9 f i n a l i n t pageSize ,

10 f i n a l ParameterizedRowMapper<E> rowMapper ) {

11

12 // determine how many rows are a v a i l a b l e

13 // c a l c u l a t e the number o f pages

14 // c r ea t e the page ob j e c t

15 // f e t ch a s i n g l e page o f r e s u l t s

16 f i n a l i n t startRow = (pageNo − 1) * pageS ize ;

17 j t . query ( sqlFetchRows , args , new Resu l tSetExtractor ( ) {

18 pub l i c Object extractData ( Resu l tSet r s ) throws SQLException ,

DataAccessException {

19 f i n a l L i s t pageItems = page . getPageItems ( ) ;

20 i n t currentRow = 0 ;

21 whi le ( r s . next ( ) && currentRow < startRow + pageS ize ) {

22 i f ( currentRow >= startRow ) {

23 pageItems . add ( rowMapper .mapRow( rs , currentRow ) ) ;

24 }

25 currentRow++;

26 }

27 re turn page ;

28 }

29 }) ;

30 re turn page ;

31 }

32

33 }

Codefragment 9.3: Paginering met behulp van JDBC

Page 69: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

9.2 Slimmer maken van partities toevoegen 62

9.2 Slimmer maken van partities toevoegen

Als eerste zou er een functie voorzien kunnen worden die alle partities in de toekomst

verwijdert. Dit kan bijvoorbeeld handig zijn bij het instellen van een nieuw werkschema.

Als volgende feature zou er bij het verkrijgen van een fout bij het toevoegen van een

nieuwe partitie, gekeken kunnen worden of het werkschema veranderd is. Indien dit het

geval is, kan de bestaande partitie verwijderd worden en vervolgens opnieuw toegevoegd

worden met de nieuwe grens. Bovendien wordt momenteel enkel de MAXVALUE-partitie

gesplitst. Bij het toevoegen zou er bijgevolg gecontroleerd kunnen worden of er nog een

andere partitie tussen de nieuwe, toe te voegen partitie en de MAXVALUE-partitie ligt.

Als deze situatie zich voordoet, moet de tussenliggende partitie opgesplitst worden in plaats

van de MAXVALUE-partitie. Momenteel wordt ervan uitgegaan dat er nooit een partitie

tussen ligt.

9.3 Verplaatsing van de parsingfunctionaliteit

Indien er toch zou beslist worden om het parsen niet rechtstreeks in de webservice uit

te voeren, maar achteraf via een update, kan volgend onderzoek gebruikt worden. Hier-

bij wordt er wat meer uitleg gegeven over een ScheduledExecutorService, de verschillen

met java.util.Timer en een uitwerking van Quartz. Het verplaatsen van de functionaliteit

heeft als voordeel dat de webservice minder belast wordt en dat de berichten dus sneller

opgeslagen kunnen worden op de databank.

9.3.1 ScheduledExecutorService

De werking van een ScheduledExecutorService wordt beschreven in codefragment 9.4. Bij

initialisatie wordt een threadpool aangemaakt met het aantal threads als parameter.[9] De

MessageHandler erft over van Runnable om de logica af te scheiden. Spring kan eventueel

gebruikt worden om de handler te injecteren. Het volledige proces draait continu als Ab-

stractVComBatch. Het parsen van de opgehaalde records kan op dezelfde manier gebeuren

als bij de RecordInserter.

Page 70: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

9.3 Verplaatsing van de parsingfunctionaliteit 63

1 import s t a t i c java . u t i l . concurrent . TimeUnit . * ;

2 pub l i c c l a s s MessageHandlerBatch extends AbstractVComBatch<Str ing , Str ing >{

3 @Override

4 protec ted void be foreExecute ( ) {

5 f i n a l ScheduledExecutorServ ice s chedu l e r = Executors .

newScheduledThreadPool (15) ;

6 f i n a l Runnable msgHandler = new MessageHandler ( ) ;

7 f i n a l long INITIAL_DELAY = 10 ;

8 f i n a l long PERIOD = 60 ;

9 f i n a l ScheduledFuture<?> con t r o l = schedu l e r . scheduleAtFixedRate (

msgHandler , INITIAL_DELAY , PERIOD, SECONDS) ;

10 }

11 }

12

13 pub l i c c l a s s MessageHandler extends Runnable{

14 @Override

15 pub l i c void run ( ) {

16 // f e t ch XX reco rd s

17 // parse r e co rd s

18 // i n s e r t r e co rd s

19 }

20 }

Codefragment 9.4: Uitwerking met ScheduledExecutorService

9.3.2 Java.util.Timer

Het gebruik van de java.util.Timer is ook een mogelijkheid, maar die heeft zo zijn tekortko-

mingen ten opzichte van ScheduledExecutor.[3] Het voordeel is dat ze beide built-in3 zijn

en dat ze weinig con�guratie vergen om te gebruiken. Tabel 9.1 zet de verschillen even op

een rijtje.

9.3.3 Quartz scheduler

Met een eenvoudige con�guratie zoals beschreven in codefragment 9.5, zou hetzelfde re-

sultaat bekomen moeten worden als met de ScheduledExecutor. Quartz staat wel meer

open voor con�guratie.[6] Het biedt wel een alternatief voor latere uitbreiding, indien meer

con�guratie zou nodig zijn. Bijkomend is wel dat de nodige dependencies moeten voorzien

3ingebouwd in Java

Page 71: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

9.3 Verplaatsing van de parsingfunctionaliteit 64

Tabel 9.1: Java.util.Timer versus ScheduledExecutor

Situatie Java.util.Timer ScheduledExecutor

Aanpassen van systeemklok Kan problemen opleveren. Geen probleem.

Aantal threads Slechts één, bijgevolg kun-

nen lang draaiende taken

andere taken ophouden.

Een con�gureerbaar aantal

die elk volledig controleer-

baar zijn.

RuntimeException Beëindigt de timer zodat er

geen taken meer uitgevoerd

worden.

Vangt de exceptie op met

de mogelijkheid om ze zelf

te verwerken. Andere ta-

ken blijven gewoon doorlo-

pen. (threadpool)

worden, wat niet het geval is bij de Executors, aangezien deze standaard verweven zitten

in Java 6. Voor de eenvoud worden er dus best ScheduledExecutors gebruikt.

1 pub l i c c l a s s MessageHandlerBatch extends AbstractVComBatch<Str ing , Str ing >{

2 @Override

3 protec ted void be foreExecute ( ) {

4 f i n a l long INITIAL_DELAY = 10000; //ms

5 f i n a l long PERIOD = 30000; //ms

6 JobDeta i l job = new JobDeta i l ( ) ;

7 job . setName ( "messageHandler " ) ;

8 job . s e tJobClas s (MessageHandler . c l a s s ) ;

9

10 // con f i gu r e the s chedu l e r time

11 SimpleTr igger t r i g g e r = new SimpleTr igger ( ) ;

12 t r i g g e r . setStartTime (new Date ( System . cur r entT imeMi l l i s ( ) +

INITIAL_DELAY) ) ;

13 t r i g g e r . setRepeatCount ( S impleTr igger .REPEAT_INDEFINITELY) ;

14 t r i g g e r . s e tRepea t In t e rva l (PERIOD) ;

15

16 // schedu le i t

17 Scheduler s chedu l e r = new StdSchedulerFactory ( ) . ge tSchedu le r ( ) ;

18 s chedu l e r . s t a r t ( ) ;

19 s chedu l e r . scheduleJob ( job , t r i g g e r ) ;

20 }

21 }

22

23

Page 72: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

9.4 Interval partitioning bij Oracle 11g 65

24 pub l i c c l a s s MessageHandler implements Job{

25 @Override

26 pub l i c void execute ( JobExecutionContext context )

27 throws JobExecutionException {

28 // f e t ch XX reco rd s

29 // parse r e co rd s

30 // i n s e r t r e co rd s

31 }

32 }

Codefragment 9.5: Voorbeelduitwerking van Quartz scheduler

9.4 Interval partitioning bij Oracle 11g

Interval partitioning is een uitbreiding van Range partitioning en werd pas in Oracle 11g ge-

ïntroduceerd. Dit concept heeft als voordeel dat partities automatisch aangemaakt worden

bij het toevoegen van een record buiten de bestaande grenzen. Er moet op z'n minst één

range partitie aanwezig zijn. Om een bestaande range gepartitioneerde tabel te upgraden

naar een interval partitionering zullen er twee problemen opgelost moeten worden.[7]

� ORA-14759: SET INTERVAL is not legal on this table.

� ORA-14758: Last partition in the range section cannot be dropped.

Om de eerste error te vermijden moet de MAXVALUE-partitie eerst verwijderd worden.

Dit gebeurt als volgt:

1 ALTER TABLE vem_log_message DROP PARTITION other

Vervolgens kan de bestaande tabel omgezet worden naar een interval partitionering:

1 ALTER TABLE vem_log_message s e t INTERVAL (NUMTODSINTERVAL(8 , 'HOUR' ) )

Door de partities automatisch te laten genereren, krijgen ze een gegenereerde partitienaam.

De grens is gebaseerd op het vaste interval waardoor het niet mogelijk is om hier gebruik te

maken van WhatShift grenzen. De partitienaam is geen probleem omdat de partitie een-

voudig hernoemt kan worden, maar zelfs dit is niet nodig. De partities zijn aanspreekbaar

met de 'PARTITION for'-statement, zoals aangegeven in codefragment 9.6.

Page 73: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

9.4 Interval partitioning bij Oracle 11g 66

1 ALTER TABLE vem_log_message DROP PARTITION f o r

2 (TO_DATE ( ' 2014−07−01 00 : 00 : 00 ' , 'YYYY−MM−DD HH24 :MI : SS ' ) )

Codefragment 9.6: 'PARTITION for'-statement

Met behulp van codefragment 9.6 kan ook de oudste partitie gedropt worden. Dit zal echter

falen als het de laatste zelfgemaakte partitie is. Zelfgemaakte partities worden gekenmerkt

door de kolom 'INT'. Deze kolom staat voor INTERVAL en bevat 'NO' indien de partitie

zelfgemaakt is. Dit is het tweede probleem dat hierboven vermeld werd. Er zijn drie

manieren om dit probleem te omzeilen.

Als eerste kan het probleem opgelost worden door twee partities te mergen. Dit heeft tot

gevolg dat alle records van beide partities gekopieerd moeten worden in een nieuwe partitie.

Omdat het de bedoeling is de oudste partitie te droppen, kan deze partitie eenvoudigweg

eerst gewist worden. De andere manier houdt in dat er tijdelijk naar range partitioning

overgeschakeld wordt zodat de automatisch aangemaakte partities nu ook een 'NO' krijgen

in de INT-kolom. Deze methoden genieten echter niet de voorkeur omdat ze ofwel data

verplaatsen ofwel een tijdsspanne van onbeschikbaarheid veroorzaken.[15] De laatste mo-

gelijkheid bestaat erin om de laatste partitie gewoon te behouden zonder data. We kunnen

deze partitie dan ook hernoemen naar MINVALUE. Vervolgens kunnen de gegenereerde

partities met DROP PARTITION verwijderd worden.

Page 74: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

ALGEMENE CONCLUSIE 67

Hoofdstuk 10

Algemene conclusie

Uit de eerste vergelijking werd al snel duidelijk dat partitioning een verantwoorde keuze

was. Deze keuze opende ook het pad naar een uitgebreid onderzoek. Dit had natuurlijk

gevolgen voor het kiezen van de indexen. Daarom werd elke index uitvoerig getest en

werd er vastgesteld dat lokale indexen de beste keuze waren. Niet alleen op vlak van

opzoekperformantie voldoen lokale indexen, maar ook op vlak van beheer zijn ze eenvoudig

en snel in gebruik. Er werd ook vastgesteld dat het statement 'UPDATE INDEXES' veel

betere resultaten oplevert dan de andere besproken methodes voor het verwijderen van

partities.

Verder kan er besloten worden dat de loadbalancer voldoet aan de eis om twintig berichten

per seconde te verwerken. Met een snelheid van ongeveer 90 berichten per seconde op

de testserver en ongeveer 300 berichten per seconde lokaal, is er meer dan genoeg ruimte

voorzien. Hierbij moesten de resultaten van de testserver beschouwd worden als een situatie

met hoge belasting van andere processen en de lokale resultaten als een bovengrens voor

de performantie. Bovendien werd er ook geconcludeerd dat een stabiele oplossing een

opstelling is met drie webservices en elk vijftien threads. Om de performantie van de

loadbalancer mogelijk nog te verhogen kan er in de toekomst zelf een verdeelstrategie

geschreven worden.

Het performant opvragen van de logberichten was een belangrijk punt van deze masterproef.

Er werd dan ook vastgesteld dat Hibernate als eerste versie voldeed aan de eisen. Toch werd

er opgemerkt dat de uitvoertijden met Hibernate lineair oplopen per opgevraagde partitie

met ongeveer twee seconden, maar dat - doordat er vooral in één, maximaal twee, partities

tegelijk gezocht wordt - de wachttijden relatief meevallen. Met dit in het achterhoofd werd

er toch al wat onderzoek gedaan om het opvragen te optimaliseren. Hierbij werden er twee

Page 75: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

ALGEMENE CONCLUSIE 68

paden onderzocht, zijnde optimaliseren van Hibernate via een scrollable resultset en het

overschakelen naar JDBC met behoud van paginering.

Over het algemeen kan besloten worden dat het ontworpen systeem voldoet aan de eisen.

Toch zijn er hier en daar nog wat verbeteringen en uitbreidingen mogelijk. Het belangrijkste

is dat er veel bijgeleerd is en dat het een verrijkende ervaring was om te proeven van het

bedrijfsleven.

Page 76: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

DATABANKTABELLEN 69

B¼lage A

Databanktabellen

Tabel A.1: Databankkolommen van VEM_LOG_MESSAGE

Logical name Physical name Type Length

id VEM_MESSAGE_ID NUMBER 22

station DATAPOINTID VARCHAR2 50

bodyNr IBODY VARCHAR2 7

timestamp CHANGETS TIMESTAMP 6

message MESSAGECONTENTDESC VARCHAR2 4000

messageType MESSAGETYPEID VARCHAR2 20

Tabel A.2: Databankkolommen van VEM_PARSERCONFIG

Logical name Physical name Type Length

id VEM_PARSERCONFIG_ID NUMBER 22

messageType MESSAGETYPEID VARCHAR 20

description PARSERDESC VARCHAR2 50

format FORMATCODE VARCHAR2 32

updatedTimestamp CHANGETS TIMESTAMP 6

updatedBy ICDSID CHAR 15

nlock NLOCK NUMBER 22

Page 77: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

DATABANKTABELLEN 70

Tabel A.3: Databankkolommen van VEM_PARSERITEMCONFIG

Logical name Physical name Type Length

id VEM_PARSERITEMCONFIG_ID NUMBER 22

vemParserCon�gId VEM_PARSERCONFIG_ID NUMBER 22

key PROPERTYKEYCODE VARCHAR2 32

value PROPERTYVALUEDESC VARCHAR2 1024

updatedTimestamp CHANGETS TIMESTAMP 6

updatedBy ICDSID VARCHAR2 15

nlock NLOCK NUMBER 22

Page 78: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

KLASSENDIAGRAM VAN WEBSERVICE EN LOADBALANCER 71

B¼lage B

Klassendiagram van webservice en

loadbalancer

Figuur B.1: Klassendiagram van eNextGenId-module-sCpr981

Page 79: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

PL/SQL INSERT TESTOMGEVING 72

B¼lage C

PL/SQL insert testomgeving

1 de c l a r e

2 idNumber i n t ;

3 dag i n t ;

4 s t a r t Index i n t ;

5 s h i f t s t a r t i n t ;

6 sh i f tReco rd s i n t ;

7 strName varchar (32) ;

8 strName2 varchar (32) ;

9 msgcontent varchar (4000) ;

10 t s r e g timestamp ;

11 begin

12 msgcontent := ' . . . ' ;

13 f o r dag in 6 . . 10

14 loop

15 sh i f tReco rd s := 500000;

16 s t a r t Index := (dag−1)*3* sh i f tReco rd s ;

17 f o r j in 1 . . 3

18 loop

19 s h i f t s t a r t :=( j−1)* sh i f tReco rd s ;

20 f o r i in 1 . . s h i f tReco rd s

21 loop

22 idNumber := s ta r t Index + s h i f t s t a r t + i ;

23 strName := subs t r (DBMS_RANDOM.RANDOM,0 , 7 ) ;

24 strName2 := dbms_random . random ;

25 i f j = 1 then

26 t s r e g := TO_DATE ( '2014−01− ' | | lpad ( dag , 2 , ' 0 ' ) | | '

0 0 : 00 : 00 ' , 'YYYY−MM−DD HH24 :MI : SS ' ) + DBMS_RANDOM.VALUE

(0 ,8/24−1/(24*60*60) ) ;

Page 80: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

PL/SQL INSERT TESTOMGEVING 73

27 e l s i f j= 2 then

28 t s r e g := TO_DATE ( '2014−01− ' | | lpad ( dag , 2 , ' 0 ' ) | | '

0 8 : 00 : 00 ' , 'YYYY−MM−DD HH24 :MI : SS ' ) + DBMS_RANDOM.VALUE

(0 ,8/24−1/(24*60*60) ) ;

29 e l s i f j =3 then

30 t s r e g := TO_DATE ( '2014−01− ' | | lpad ( dag , 2 , ' 0 ' ) | | '

1 6 : 00 : 00 ' , 'YYYY−MM−DD HH24 :MI : SS ' ) + DBMS_RANDOM.VALUE

(0 ,8/24−1/(24*60*60) ) ;

31 end i f ;

32 i n s e r t i n to vem_log_message va lue s ( idNumber , strName2 ,

strName , t s r eg , msgcontent ,NULL) ;

33 i f mod( i , 1 00 ) = 0 then

34 commit ;

35 end i f ;

36 end loop ;

37 end loop ;

38 end loop ;

39 commit ;

40 end ;

Codefragment C.1: PL/SQL insert testomgeving

Page 81: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN TESTOMGEVING 74

B¼lage D

Resultaten testomgeving

De indexen werden geplaatst op station en bodynummer die bij de testomgevingtabel

elk een VARCHAR2 van 32 byte waren. De uiteindelijk tabel heeft voor station een

VARCHAR2 van 50 byte en bodynummer heeft een VARCHAR2 van 7 byte. Dit kan

mogelijk voor wat verschillen zorgen tussen beide opstellingen.

Tabel D.1: Native SQL: zoeken op station in één partitie (eq)

#1 #2 #3 Gem.

TESTCASE 1 0,717 0,537 0,555 0,603

TESTCASE 2 0,019 0,006 0,006 0,010

TESTCASE 3 0,017 0,004 0,004 0,008

TESTCASE 4 0,182 0,637 0,519 0,446

TESTCASE 5 0,014 0,004 0,007 0,008

TESTCASE 6 0,020 0,023 0,013 0,019

TESTCASE 7 0,026 0,011 0,020 0,019

TESTCASE 8 0,170 0,668 0,505 0,448

Page 82: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN TESTOMGEVING 75

Tabel D.2: Native SQL: zoeken op bodynummer in één partitie (eq)

#1 #2 #3 Gem.

TESTCASE 1 0,659 0,495 0,607 0,587

TESTCASE 2 0,330 0,581 0,503 0,471

TESTCASE 3 0,029 0,013 0,004 0,015

TESTCASE 4 0,699 0,349 0,344 0,464

TESTCASE 5 0,193 0,767 0,502 0,487

TESTCASE 6 0,151 0,656 0,508 0,438

TESTCASE 7 0,187 0,701 0,552 0,480

TESTCASE 8 0,618 0,388 0,348 0,451

Tabel D.3: Native SQL: zoeken op station over ganse tabel (eq)

#1 #2 #3 Gem.

TESTCASE 1 9,049 8,901 8,615 8,855

TESTCASE 2 0,009 0,004 0,003 0,005

TESTCASE 3 0,004 0,002 0,003 0,003

TESTCASE 4 8,871 8,937 8,859 8,889

TESTCASE 5 0,006 0,002 0,002 0,003

TESTCASE 6 0,004 0,006 0,003 0,004

TESTCASE 7 0,003 0,006 0,002 0,004

TESTCASE 8 9,645 9,940 9,957 9,847

Tabel D.4: Native SQL: zoeken op bodynummer over ganse tabel (eq)

#1 #2 #3 Gem.

TESTCASE 1 9,138 8,980 8,477 8,865

TESTCASE 2 8,860 9,007 8,469 8,779

TESTCASE 3 0,005 0,003 0,001 0,003

TESTCASE 4 8,937 8,859 8,436 8,744

TESTCASE 5 8,751 8,676 8,868 8,765

TESTCASE 6 8,881 8,839 9,123 8,948

TESTCASE 7 10,501 10,879 10,689 10,690

TESTCASE 8 9,572 9,309 8,756 9,212

Page 83: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN TESTOMGEVING 76

Tabel D.5: Uitvoertijden van INSERT bij de verschillende testcases

#1 #2 #3 #4 #5 Gem.

TESTCASE 1 0,017 0,020 0,024 0,015 0,012 0,018

TESTCASE 2 0,021 0,026 0,022 0,040 0,021 0,026

TESTCASE 3 0,036 0,039 0,040 0,059 0,030 0,041

TESTCASE 4 0,080 0,034 0,028 0,039 0,028 0,042

TESTCASE 5 0,073 0,031 0,021 0,029 0,033 0,037

TESTCASE 6 0,059 0,018 0,028 0,018 0,015 0,028

TESTCASE 7 0,038 0,038 0,018 0,025 0,021 0,028

TESTCASE 8 0,045 0,031 0,026 0,027 0,020 0,030

Tabel D.6: Uitvoertijden van DELETE bij de verschillende testcases

#1 #2 #3 #4 #5 Gem.

TESTCASE 1 0,007 0,005 0,005 0,005 0,005 0,005

TESTCASE 2 0,006 0,005 0,005 0,005 0,005 0,005

TESTCASE 3 0,005 0,005 0,005 0,005 0,006 0,005

TESTCASE 4 0,007 0,006 0,006 0,019 0,005 0,009

TESTCASE 5 0,009 0,006 0,005 0,005 0,005 0,006

TESTCASE 6 0,007 0,006 0,005 0,005 0,004 0,005

TESTCASE 7 0,008 0,005 0,005 0,005 0,006 0,006

TESTCASE 8 0,006 0,005 0,005 0,005 0,007 0,006

Page 84: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN TESTOMGEVING 77

Tabel D.7: Uitvoertijden DROP PARTITION met update indexes en alter index (case 1-4)

#1 #2 #3 Gem.

TESTCASE 1 update indexes 22,160 21,658 21,226 21,681

drop 0,170 0,138 0,156 0,155

alter index 61,142 64,330 60,893 62,122

totaal 61,312 64,468 61,049 62,276

TESTCASE 2 update indexes 37,455 49,723 57,724 50,255

drop 0,290 0,294 0,335 0,306

alter index pk 60,629 59,568 62,579 60,925

alter index dp 75,742 78,314 86,514 80,190

totaal 136,661 138,176 149,428 141,422

TESTCASE 3 update indexes 55,000 74,000 56,795 61,932

drop 0,159 0,363 0,261

alter index pk 84,000 89,498 86,749

alter index bd 86,000 87,880 86,940

alter index dp 92,000 74,607 83,304

totaal 262,159 252,348 257,254

TESTCASE 4 updates indexes 49,108 64,623 65,463 59,731

drop 0,624 0,180 0,362 0,389

alter index pk 62,826 58,918 60,402 60,715

alter index dp 78,676 76,736 82,234 79,215

alter index ts 76,451 65,431 66,460 69,447

totaal 218,577 201,265 209,458 209,767

Page 85: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN TESTOMGEVING 78

Tabel D.8: Uitvoertijden DROP PARTITION met update indexes en alter index (case 5-8)

#1 #2 #3 Gem.

TESTCASE 5 update indexes 38,182 39,281 40,505 39,323

drop 0,147 0,294 0,286 0,242

alter index pk 60,692 63,614 58,878 61,061

alter index dp_ts 101,497 90,081 86,956 92,845

totaal 162,336 153,989 146,120 154,148

TESTCASE 6 update indexes 23,417 21,564 19,657 21,546

drop 0,141 0,060 0,371 0,191

alter index pk 62,351 66,434 65,522 64,769

totaal 62,492 66,494 65,893 64,95967

TESTCASE 7 update indexes 22,291 22,291

drop 0,133 0,133

alter index pk 64,617 64,617

totaal 64,750 64,750

TESTCASE 8 update indexes 24,026 24,026

drop 0,114 0,114

alter index pk 65,195 65,195

totaal 65,309 65,309

Page 86: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN HIBERNATE 79

B¼lage E

Resultaten Hibernate

Dit zijn oudere testresultaten dan die uit hoofdstuk 8, maar zijn zeker de moeite waard om

te bekijken. De opzoektijden zijn lager omdat er in deze resultaten geen rekening gehouden

werd met uitvoertijd om het aantal records op te vragen.

Tabel E.1: Hibernate: zoeken zonder �lters in volledige tabel

Resultset #1 #2 #3 Gem.

50 22,031 22,144 22,275 22,150

200 21,928 22,538 22,611 22,359

1000 22,440 22,404 22,044 22,296

Tabel E.2: Hibernate: zoeken met �lters in volledige tabel (resultset 50)

Filter #1 #2 #3 Gem.

station (like) 10,696 10,650 10,652 10,666

bodyNr (eq) 0,014 0,012 0,013 0,013

station+bodyNr 0,009 0,008 0,008 0,008

Page 87: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN HIBERNATE 80

Tabel E.3: Hibernate: zoeken zonder �lters in één partitie

Resultset #1 #2 #3 Gem.

50 1,535 1,663 1,683 1,627

200 1,665 1,645 1,734 1,681

1000 1,928 1,829 1,938 1,898

Tabel E.4: Hibernate: zoeken met �lters in één partitie (resultset 1000)

Filter #1 #2 #3 Gem.

station (like) 1,254 1,096 1,213 1,188

bodyNr (eq) 0,006 0,006 0,006 0,006

station+bodyNr 0,007 0,035 0,011 0,018

Tabel E.5: Hibernate: zoeken zonder �lters in twee partities

Resultset #1 #2 #3 Gem.

50 3,297 3,197 3,077 3,190

200 3,277 3,375 3,089 3,247

1000 3,175 3,122 3,226 3,174

Tabel E.6: Hibernate: zoeken met �lters in twee partities (resultset 1000)

Filter #1 #2 #3 Gem.

station (like) 1,909 2,067 1,968 1,981

bodyNr (eq) 0,006 0,006 0,007 0,006

station+bodyNr 0,006 0,006 0,007 0,006

Page 88: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN LOKALE STRESSTEST 81

B¼lage F

Resultaten lokale stresstest

Tabel F.1: Lokale opstelling met 15 webservice threads en 2 webservices

Webservice #1 #2 #3 #4

8351 11617 39065 57376 23838

8352 8383 20935 42624 26036

total 20000 60000 100000 498741

tijd 01:30 03:14 04:40 02:39

berichten/s 222 309 357 313

1120.000 berichten verstuurd

Tabel F.2: Lokale opstelling met 30 webservice threads en 2 webservices

Webservice #1 #2 #3 #4

8351 11617 38903 58306 23838

8352 8383 21097 41694 26036

totaal 20000 60000 100000 498741

tijd 01:30 03:12 05:07 02:39

berichten/s 222 312 326 313

1120.000 berichten verstuurd

Page 89: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN LOKALE STRESSTEST 82

Tabel F.3: Lokale opstelling met 50 webservice threads en 2 webservices

Webservice #1

8351 55649

8352 44351

totaal 100000

tijd 04:58

berichten/s 335

Tabel F.4: Lokale opstelling met 15 webservice threads en 3 webservices

Webservice #1 #2 #3 #4

8351 14128 30131 50054 30501

8352 3364 12557 26989 12639

8353 2508 17312 22957 14625

total 20000 60000 100000 577651

tijd 01:40 03:04 04:52 02:37

berichten/s 200 326 342 367

1120.000 berichten verstuurd

Tabel F.5: Lokale opstelling met 30 webservice threads en 3 webservices

Webservice #1 #2 #3 #4

8351 10385 30274 26410 15247

8352 4315 14818 10576 16758

8353 5300 14908 13460 9537

totaal 20000 60000 504461 415422

tijd 01:36 03:13 02:34 02:39

berichten/s 208 310 327 261

1100.000 berichten verstuurd2120.000 berichten verstuurd

Page 90: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN LOKALE STRESSTEST 83

Tabel F.6: Lokale opstelling met 15 webservice threads en 4 webservices

Webservice #1 #2 #3

8351 11873 27162 11093

8352 2201 10455 6235

8353 2508 10454 12629

8354 3418 11897 5579

totaal 20000 599681 355362

tijd 01:46 03:18 01:54

berichten/s 188 302 311

160.000 berichten verstuurd2120.000 berichten verstuurd

Page 91: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

RESULTATEN OPENVMS STRESSTEST 84

B¼lage G

Resultaten OpenVMS stresstest

Bij het gebruik van 50 threads crasht het programma.

Tabel G.1: VMS-opstelling met 15 webservice threads en 3 webservices

Webservice #1 #2 #3

8351 18086 54051 41648

8352 1106 32550 28903

8353 808 33399 29449

totaal 20000 120000 100000

tijd 10:05 27:56 19:44

berichten/s 33 71 84

Tabel G.2: VMS-opstelling met 15 webservice threads en 4 webservices

Webservice #1 #2 #3

8351 3398 7843 27976

8352 1897 3581 22803

8353 2755 3684 25100

8354 1950 4892 24121

totaal 10000 20000 100000

tijd 01:53 04:35 19:11

berichten/s 88 72 86

Page 92: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

BIBLIOGRAFIE 85

Bibliogra�e

[1] codefutures. Spring JDBC Pagination Tutorial. http://www.codefutures.com/

spring-pagination/. Meerdere keren geraadpleegd in mei 2014.

[2] craig. Why you shouldn't use Quartz Scheduler. http://www.carfey.com/blog/

why-you-shouldnt-use-quartz-scheduler/, 2012. Geraadpleegd op: 19/02/2014.

[3] Java Concurrency in Practice. Java timer vs executorservice? http://

stackoverflow.com/questions/409932/java-timer-vs-executorservice. Ge-

raadpleegd op: 19/02/2014.

[4] Koen Serneels. Bulk fetching with Hibernate. http://koenserneels.blogspot.

be/2013/03/bulk-fetching-with-hibernate.html, 2013. Geraadpleegd op:

19/02/2014.

[5] Simon Maple. The Great Java Application Server Debate with Tomcat, JBoss,

GlassFish, Jetty and Liberty Pro�le. http://zeroturnaround.com/rebellabs/

the-great-java-application-server-debate-with-tomcat-jboss-glassfish-jetty-and-liberty-profile/,

2013. Meerdere keren geraadpleegd in maart,april en mei 2014.

[6] mkyong. Quartz 1.6 Scheduler Tutorial. http://www.mkyong.com/java/

quartz-scheduler-example/, 2012. Geraadpleegd op: 19/02/2014.

[7] Jaromir D.B. Nemec. Rolling Window Using Interval Partitioning. http://

www.db-nemec.com/rolling_window_interval_part.html, 2011. Geraadpleegd op:

27/04/2014.

[8] Oracle. Java management extensions (jmx). http://docs.oracle.com/javase/

tutorial/jmx/index.html. Meerdere keren geraadpleegd in mei 2014.

[9] Oracle. Scheduled Executor. http://docs.oracle.com/javase/6/docs/api/

java/util/concurrent/ScheduledExecutorService.html. Geraadpleegd op:

19/02/2014.

Page 93: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

BIBLIOGRAFIE 86

[10] Oracle. Partition Pruning. http://docs.oracle.com/cd/B19306_01/server.102/

b14220/partconc.htm#i462783, 2005. Meerdere keren geraadpleegd in april en mei

2014.

[11] Oracle. Dropping Partitions. http://docs.oracle.com/cd/B19306_01/server.

102/b14231/partiti.htm#i1007479, 2006. Meerdere keren geraadpleegd in april en

mei 2014.

[12] Oracle. Optimizing SPLIT PARTITION and SPLIT SUBPARTITION Operati-

ons. http://docs.oracle.com/cd/B19306_01/server.102/b14231/partiti.htm#

i1008028, 2006. Meerdere keren geraadpleegd in april en mei 2014.

[13] Oracle. Blockingqueue. http://docs.oracle.com/javase/6/docs/api/java/util/

concurrent/BlockingQueue.html, 2011. Meerdere keren geraadpleegd in maart,april

en mei 2014.

[14] Oracle. Oracle Data Types. http://docs.oracle.com/cd/B28359_01/server.111/

b28318/datatype.htm, 2011. Geraadpleegd op: 24/05/2014.

[15] Harald van Breederode. Dropping interval partitions. http://prutser.

wordpress.com/2010/01/11/dropping-interval-partitions/, 2010. Geraad-

pleegd op: 27/04/2014.

[16] Wikipedia. Round-robin dns. http://en.wikipedia.org/wiki/Round-robin_DNS,

2014. Meerdere keren geraadpleegd in maart 2014.

[17] Markus Winand. Row Migration and Row Movement. http://blog.fatalmind.

com/2010/02/23/row-migration-and-row-movement/, 2010. Meerdere keren ge-

raadpleegd in april 2014.

Page 94: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

L�ST VAN FIGUREN 87

L¼st van �guren

2.1 Projectstructuur in Volvo-omgeving . . . . . . . . . . . . . . . . . . . . . . 4

3.1 Tabeloverzicht voor het actief-historiek ontwerp . . . . . . . . . . . . . . . 8

3.2 Eerste ontwerp via twee tabellen . . . . . . . . . . . . . . . . . . . . . . . . 9

3.3 Tabeloverzicht voor het partitioning ontwerp . . . . . . . . . . . . . . . . . 9

3.4 Tweede ontwerp via partitioning . . . . . . . . . . . . . . . . . . . . . . . . 10

4.1 Schematisch overzicht van het principe van loadbalancing . . . . . . . . . . 13

4.2 Schematisch overzicht van de verwerking van een binnenkomend bericht . . 13

4.3 Hoofdscherm van het parserbeheer . . . . . . . . . . . . . . . . . . . . . . . 14

4.4 Validatescherm voor parsers . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4.5 Detailscherm van het parserbeheer . . . . . . . . . . . . . . . . . . . . . . 16

4.6 Overzichtsscherm voor de logberichten . . . . . . . . . . . . . . . . . . . . 17

4.7 Kalenderscherm om een tijdsspanne in te stellen . . . . . . . . . . . . . . . 18

4.8 Detailscherm voor het tonen van logberichten . . . . . . . . . . . . . . . . 19

4.9 Hoofdscherm om partitiecon�guraties te beheren . . . . . . . . . . . . . . . 22

4.10 Scherm om systeemmapping te beheren voor partitiecon�guraties . . . . . 23

4.11 Detailscherm om partitiecon�guraties te beheren . . . . . . . . . . . . . . . 24

5.1 Voorbeelden van de uitvoer van 'EXPLAIN PLAN FOR' . . . . . . . . . . 32

6.1 Visualisatie van RemoteLoggingServer . . . . . . . . . . . . . . . . . . . . 37

6.2 Technisch overzicht van loadbalancer en webservices . . . . . . . . . . . . . 37

8.1 Native SQL vs Hibernate: staafdiagram die uitvoertijd toont bij het aantal

partities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

B.1 Klassendiagram van eNextGenId-module-sCpr981 . . . . . . . . . . . . . . 71

Page 95: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

L�ST VAN TABELLEN 88

L¼st van tabellen

3.1 Vergelijking Actief-historiek ontwerp met partitioning ontwerp . . . . . . . 11

4.1 Omschrijving van spreadsheetvelden in beheerscherm voor parsers . . . . . 15

4.2 Omschrijving van de spreadsheetkolommen in het logberichtenscherm . . . 18

7.1 Omschrijving verschillende testcases voor testomgeving . . . . . . . . . . . 51

7.2 Verwijderen van een partitie: gemiddelden naast elkaar . . . . . . . . . . . 52

8.1 Vergelijking systeemspeci�caties voor de stresstest . . . . . . . . . . . . . . 54

8.2 Vergelijking opzoektijden van Native SQL met Hibernate in eindopstelling

met resultaten gelimiteerd tot 500 records . . . . . . . . . . . . . . . . . . 57

9.1 Java.util.Timer versus ScheduledExecutor . . . . . . . . . . . . . . . . . . 64

A.1 Databankkolommen van VEM_LOG_MESSAGE . . . . . . . . . . . . . . 69

A.2 Databankkolommen van VEM_PARSERCONFIG . . . . . . . . . . . . . . 69

A.3 Databankkolommen van VEM_PARSERITEMCONFIG . . . . . . . . . . 70

D.1 Native SQL: zoeken op station in één partitie (eq) . . . . . . . . . . . . . . 74

D.2 Native SQL: zoeken op bodynummer in één partitie (eq) . . . . . . . . . . 75

D.3 Native SQL: zoeken op station over ganse tabel (eq) . . . . . . . . . . . . . 75

D.4 Native SQL: zoeken op bodynummer over ganse tabel (eq) . . . . . . . . . 75

D.5 Uitvoertijden van INSERT bij de verschillende testcases . . . . . . . . . . . 76

D.6 Uitvoertijden van DELETE bij de verschillende testcases . . . . . . . . . . 76

D.7 Uitvoertijden DROP PARTITION met update indexes en alter index (case

1-4) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

D.8 Uitvoertijden DROP PARTITION met update indexes en alter index (case

5-8) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

E.1 Hibernate: zoeken zonder �lters in volledige tabel . . . . . . . . . . . . . . 79

Page 96: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

L�ST VAN TABELLEN 89

E.2 Hibernate: zoeken met �lters in volledige tabel (resultset 50) . . . . . . . . 79

E.3 Hibernate: zoeken zonder �lters in één partitie . . . . . . . . . . . . . . . . 80

E.4 Hibernate: zoeken met �lters in één partitie (resultset 1000) . . . . . . . . 80

E.5 Hibernate: zoeken zonder �lters in twee partities . . . . . . . . . . . . . . . 80

E.6 Hibernate: zoeken met �lters in twee partities (resultset 1000) . . . . . . . 80

F.1 Lokale opstelling met 15 webservice threads en 2 webservices . . . . . . . . 81

F.2 Lokale opstelling met 30 webservice threads en 2 webservices . . . . . . . . 81

F.3 Lokale opstelling met 50 webservice threads en 2 webservices . . . . . . . . 82

F.4 Lokale opstelling met 15 webservice threads en 3 webservices . . . . . . . . 82

F.5 Lokale opstelling met 30 webservice threads en 3 webservices . . . . . . . . 82

F.6 Lokale opstelling met 15 webservice threads en 4 webservices . . . . . . . . 83

G.1 VMS-opstelling met 15 webservice threads en 3 webservices . . . . . . . . . 84

G.2 VMS-opstelling met 15 webservice threads en 4 webservices . . . . . . . . . 84

Page 97: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

LIJST VAN CODEFRAGMENTEN 90

Lijst van codefragmenten

5.1 Partitie toevoegen met SPLIT PARTITION en ALTER INDEX . . . . . . 28

5.2 Aanmaken van een tabel met partities . . . . . . . . . . . . . . . . . . . . 30

5.3 Fetchen van records uit partitioned table . . . . . . . . . . . . . . . . . . . 31

5.4 Explainplan opvragen van een query . . . . . . . . . . . . . . . . . . . . . 31

6.1 Aanmaken van de loadbalancer . . . . . . . . . . . . . . . . . . . . . . . . 34

6.2 Gebruik Jetty server vermelden . . . . . . . . . . . . . . . . . . . . . . . . 35

6.3 Opstarten van de webservice . . . . . . . . . . . . . . . . . . . . . . . . . . 35

6.4 RecordInserter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

6.5 Voorbeeld gebruik van XPath parsing . . . . . . . . . . . . . . . . . . . . . 38

6.6 JMX: bean interface voor het herladen van parsers . . . . . . . . . . . . . . 39

6.7 Implementeren en registreren van bean voor JMX . . . . . . . . . . . . . . 40

6.8 Classpath variabelen voor het draaien van de MBean server . . . . . . . . . 40

6.9 Herladen van parsers met behulp van een JMX bean . . . . . . . . . . . . 41

6.10 Shiftinformatie opvragen van X aantal shifts terug . . . . . . . . . . . . . . 43

6.11 Opvragen oudste shifts via shiftinformatie van WhatShift . . . . . . . . . . 43

6.12 Opvragen oudste shifts via SQL . . . . . . . . . . . . . . . . . . . . . . . . 44

6.13 Opvragen van de juiste dataSource . . . . . . . . . . . . . . . . . . . . . . 45

6.14 Opvragen recentste werkschema . . . . . . . . . . . . . . . . . . . . . . . . 45

6.15 Voorbeeld ini-bestand voor partitiebeheer . . . . . . . . . . . . . . . . . . . 46

6.16 Zoeken naar de juiste partitiecon�guratie . . . . . . . . . . . . . . . . . . . 47

7.1 Opzetten van Liquibase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

7.2 XML met changeSet gebruikt door liquibase . . . . . . . . . . . . . . . . . 49

7.3 Voorbeeld gebruik van EasyMock . . . . . . . . . . . . . . . . . . . . . . . 50

9.1 Gebruik van een Scrollable resultset met Hibernate . . . . . . . . . . . . . 59

9.2 Gebruik van een Stateless session met Hibernate . . . . . . . . . . . . . . . 60

9.3 Paginering met behulp van JDBC . . . . . . . . . . . . . . . . . . . . . . . 61

9.4 Uitwerking met ScheduledExecutorService . . . . . . . . . . . . . . . . . . 63

Page 98: Ontwerp en implementatie van een framework om ...lib.ugent.be/fulltxt/RUG01/002/154/020/RUG01... · Valentin Vaerwyckweg 1 9000 Gent Ontwerp en implementatie van een framework om

LIJST VAN CODEFRAGMENTEN 91

9.5 Voorbeelduitwerking van Quartz scheduler . . . . . . . . . . . . . . . . . . 64

9.6 'PARTITION for'-statement . . . . . . . . . . . . . . . . . . . . . . . . . . 66

C.1 PL/SQL insert testomgeving . . . . . . . . . . . . . . . . . . . . . . . . . . 72