Integration eines relationalen Datenbanksystems als

Werbung
Diplomarbeit
DIPL – WIRTSCH – INF
Integration eines relationalen
Datenbanksystems als
Nachrichtenspeicher in das
Demaq-Ausführungssystem
vorgelegt bei
Prof. Dr. Carl-Christian Kanne
Juniorprofessur für Praktische Informatik (Informationssysteme)
Universität Mannheim
von
Dennis Knochenwefel
Mannheim, im August 2008
INHALTSVERZEICHNIS
INHALTSVERZEICHNIS
Inhaltsverzeichnis
Abkürzungsverzeichnis
vii
Abbildungsverzeichnis
viii
Tabellenverzeichnis
x
1 Einleitung
1
1.1
Zielsetzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
1.2
Gliederung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
1.3
Darstellungskonventionen . . . . . . . . . . . . . . . . . . . . . . .
3
2 Grundlagen
2.1
2.2
2.3
4
Demaq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.1.1
Konzept . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.1.2
Bestandteile . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.1.2.1
Die Sprache Demaq . . . . . . . . . . . . . . . .
5
2.1.2.2
Das Demaq-Ausführungssystem . . . . . . . . . .
5
Natix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
2.2.1
Konzepte . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
2.2.1.1
Fragmente . . . . . . . . . . . . . . . . . . . . . .
7
2.2.1.2
Requests
. . . . . . . . . . . . . . . . . . . . . .
8
2.2.1.3
Views . . . . . . . . . . . . . . . . . . . . . . . .
9
2.2.1.4
XQuery-Auswertung . . . . . . . . . . . . . . . .
9
2.2.2
Features . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
2.2.3
Einschränkungen . . . . . . . . . . . . . . . . . . . . . . .
10
DB2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
2.3.1
Features . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
2.3.2
Einschränkungen . . . . . . . . . . . . . . . . . . . . . . .
12
2.3.2.1
Allgemeine Einschränkungen . . . . . . . . . . .
12
2.3.2.2
XQuery Einschränkungen . . . . . . . . . . . . .
13
3 Problemstellung
14
3.1
Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
3.2
Ziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
i
INHALTSVERZEICHNIS
3.3
3.4
INHALTSVERZEICHNIS
Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
3.3.1
Korrektheit . . . . . . . . . . . . . . . . . . . . . . . . . .
16
3.3.2
Modularisierung . . . . . . . . . . . . . . . . . . . . . . . .
17
3.3.3
Leistungsverhalten . . . . . . . . . . . . . . . . . . . . . .
17
Herausforderungen . . . . . . . . . . . . . . . . . . . . . . . . . .
17
3.4.1
Überprüfung der Korrektheit
. . . . . . . . . . . . . . . .
18
3.4.2
Modularisierung . . . . . . . . . . . . . . . . . . . . . . . .
18
3.4.3
Modellierung der Datenstrukturen und Features . . . . . .
19
3.4.4
Physische Optimierung des Leistungsverhaltens . . . . . .
20
3.4.4.1
Parallelisierung . . . . . . . . . . . . . . . . . . .
20
3.4.4.2
Nebenläufigkeit . . . . . . . . . . . . . . . . . . .
20
3.4.4.3
Anfrageoptimierung . . . . . . . . . . . . . . . .
21
3.4.4.4
Indizes . . . . . . . . . . . . . . . . . . . . . . . .
21
3.4.5
Untersuchung des Leistungsverhaltens
. . . . . . . . . . .
4 Architektur
4.1
4.2
23
Demaq System-Varianten . . . . . . . . . . . . . . . . . . . . . . .
23
4.1.1
Übersicht der System-Varianten . . . . . . . . . . . . . . .
23
4.1.2
Demaq mit NATIX und Saxon
. . . . . . . . . . . . . . .
25
4.1.3
Demaq mit der DB2 und Saxon . . . . . . . . . . . . . . .
26
4.1.4
Demaq mit der DB2 . . . . . . . . . . . . . . . . . . . . .
29
Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
4.2.1
DB2-Datenbankmodul: Konzeptuelles Design . . . . . . . .
32
4.2.2
Schnittstelle zum Nachrichtenspeicher . . . . . . . . . . . .
32
4.2.3
Schnittstelle zur Regelauswertung: Saxon
. . . . . . . . .
34
4.2.4
DB2-Fassade . . . . . . . . . . . . . . . . . . . . . . . . .
36
4.2.5
DB2-Datenbankmodul: Varianten der Abbildung von Slices
37
5 Feinentwurf
5.1
21
39
Demaq mit der DB2 und Saxon . . . . . . . . . . . . . . . . . . .
39
5.1.1
Überführung des ER-Diagramms in ein logisches Schema .
40
5.1.1.1
Regeln . . . . . . . . . . . . . . . . . . . . . . . .
40
5.1.1.2
Warteschlangen . . . . . . . . . . . . . . . . . . .
40
5.1.1.3
Nachrichten . . . . . . . . . . . . . . . . . . . . .
41
5.1.1.4
Eigenschaften . . . . . . . . . . . . . . . . . . . .
42
ii
INHALTSVERZEICHNIS
5.1.2
INHALTSVERZEICHNIS
5.1.1.5
Slicings . . . . . . . . . . . . . . . . . . . . . . .
42
5.1.1.6
Schemata . . . . . . . . . . . . . . . . . . . . . .
42
5.1.1.7
Beziehung Warteschlangen-Regel . . . . . . . . .
42
5.1.1.8
Beziehung Slicing-Regeln
43
5.1.1.9
Beziehung
. . . . . . . . . . . . .
Warteschlange
zu
Antwort-
Warteschlange . . . . . . . . . . . . . . . . . . .
43
5.1.1.10 Beziehung -Warteschlange zu Regeln . . . . . . .
44
5.1.1.11 Beziehung Schema zu Warteschlangen . . . . . .
44
5.1.1.12 Beziehung Nachricht-Warteschlange . . . . . . . .
44
5.1.1.13 Beziehung Eigenschaftswerte-Nachricht . . . . . .
44
5.1.1.14 Beziehung Eigenschaften-Warteschlangen . . . . .
45
5.1.1.15 Beziehung Eigenschaft-Slicing . . . . . . . . . . .
46
Verfeinerung der DDL . . . . . . . . . . . . . . . . . . . .
46
5.1.2.1
Zusammenfassung Regeln und Error-Queues . . .
46
5.1.2.2
Zusammenfassung
Warteschlangen
mit
der
Queue-Resonsequeue-Beziehung . . . . . . . . . .
5.1.2.3
Zusammenfassung Nachrichten und NachrichtWarteschlange-Beziehung . . . . . . . . . . . . .
5.1.2.4
5.1.2.5
5.1.3
5.1.4
47
47
Zusammenfassung von Slicings und SlicingProperty-Beziehung . . . . . . . . . . . . . . . .
48
Wegfall Schemata und Schema-Queue-Beziehung
48
Weitere Anpassungen des logischen Designs . . . . . . . .
48
5.1.3.1
Anpassungen an das Demaq-Ausführungssystems
48
5.1.3.2
Anpassungen an DB2 . . . . . . . . . . . . . . .
49
Varianten der Warteschlangenabbildung . . . . . . . . . .
49
5.1.4.1
Variante 1: Einfache Relation . . . . . . . . . . .
51
5.1.4.2
Variante 2: Mehrere Einfache Relationen . . . . .
55
5.1.4.3
Variante 3: Paarweise Relationen . . . . . . . . .
58
5.1.4.4
Variante 4: Einfache Relation mit Pointern . . . .
63
5.1.4.5
Variante 5: Einfache Relation mit Verkettung . .
65
5.1.4.6
Variante 6: Trennung von Daten und Statusinformationen . . . . . . . . . . . . . . . . . . . . . .
5.1.4.7
68
Variante 7: Einfache Relation mit redundanter
Queue im Hauptspeicher . . . . . . . . . . . . . .
iii
71
INHALTSVERZEICHNIS
5.1.4.8
Tabellarische Übersicht der Varianten . . . . . .
75
DB2-Datenbankmodul: Varianten der Abbildung von Slices
76
5.1.5.1
Slicing Zugriffe über einen Index . . . . . . . . .
76
5.1.5.2
Slicings mit Materialized Views . . . . . . . . . .
77
5.1.5.3
Slicings als eigene Tabellen . . . . . . . . . . . .
78
Änderung des Demaq-Codes . . . . . . . . . . . . . . . . .
79
5.1.6.1
Umstrukturierungen . . . . . . . . . . . . . . . .
80
5.1.6.2
Neue C++ Klassen . . . . . . . . . . . . . . . . .
81
Erweiterung des NATIX-Codes . . . . . . . . . . . . . . .
82
5.1.7.1
Umstrukturierungen . . . . . . . . . . . . . . . .
82
5.1.7.2
Änderungen des bestehenden Codes
. . . . . . .
83
5.1.7.3
Neue C++ Klassen . . . . . . . . . . . . . . . . .
83
DB2-Fassade . . . . . . . . . . . . . . . . . . . . . . . . .
85
5.1.8.1
Kommunikationstechnik . . . . . . . . . . . . . .
86
5.1.8.2
Implementierung . . . . . . . . . . . . . . . . . .
86
5.1.8.3
Neue C++ Klassen . . . . . . . . . . . . . . . . .
87
Demaq mit der DB2 . . . . . . . . . . . . . . . . . . . . . . . . .
88
5.2.1
Änderung des Demaq-Kerns . . . . . . . . . . . . . . . . .
88
5.2.1.1
Umstrukturierungen . . . . . . . . . . . . . . . .
88
5.2.1.2
Änderungen des bestehenden Codes
. . . . . . .
89
5.2.1.3
Neue C++ Schnittstellen . . . . . . . . . . . . .
90
Erweiterung der DB2-Fassade . . . . . . . . . . . . . . . .
91
5.1.5
5.1.6
5.1.7
5.1.8
5.2
INHALTSVERZEICHNIS
5.2.2
6 Implementierung
6.1
6.2
94
Optimierung der DB2 als Nachrichtenspeicher . . . . . . . . . . .
94
6.1.1
Indizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94
6.1.2
Datenblöcke für große XML-Nachrichten . . . . . . . . . .
95
6.1.3
Parallelisierung von Lese- und Schreibzugriffen . . . . . . .
97
6.1.4
Nebenläufige Verarbeitung von Nachrichten . . . . . . . .
99
Optimierung der Regelauswertung mit der DB2 . . . . . . . . . . 100
6.2.1
Vermeidung von Serialisier- und Parsingvorgängen . . . . . 100
6.2.2
Implementierung der Regelauswertung mit DB2 . . . . . . 103
6.2.2.1
Regelauswertung mit Stored Procedures . . . . . 104
iv
INHALTSVERZEICHNIS
6.2.2.2
INHALTSVERZEICHNIS
Regelauswertung durch ein atomares SQLStatement . . . . . . . . . . . . . . . . . . . . . . 107
6.2.3
Steuerung der Weiterverarbeitung von Nachrichten mit
Triggern . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
7 Evaluation
7.1
7.2
111
Qualitative Evaluation . . . . . . . . . . . . . . . . . . . . . . . . 111
7.1.1
Korrektheit . . . . . . . . . . . . . . . . . . . . . . . . . . 111
7.1.2
Modularisierung . . . . . . . . . . . . . . . . . . . . . . . . 112
7.1.3
Leistungsverhalten . . . . . . . . . . . . . . . . . . . . . . 112
Quantitative Evaluation . . . . . . . . . . . . . . . . . . . . . . . 113
7.2.1
Erfüllung der Anforderungen für formale Experimente . . . 114
7.2.2
Konzeption der Experimente . . . . . . . . . . . . . . . . . 115
7.2.3
7.2.2.1
Ziele des Experiments Warteschlange . . . . . . . 115
7.2.2.2
Ziele des Experiments Regelauswertung . . . . . 116
Testanwendungen . . . . . . . . . . . . . . . . . . . . . . . 116
7.2.3.1
Testanwendung 1: Client/Server-Simulation . . . 118
7.2.3.2
Testanwendung 2: Client/Server-Simulation mit
qs:queue() . . . . . . . . . . . . . . . . . . . . . . 119
7.2.4
7.2.5
7.2.3.3
Testanwendung 3: Prozesskette mit Überkreuzung 119
7.2.3.4
Testanwendung 4: Prozess-Simulation Split/Join . 121
Design des Experiments Warteschlange . . . . . . . . . . . 122
7.2.4.1
Unabhängige Variable . . . . . . . . . . . . . . . 123
7.2.4.2
Abhängige Variablen . . . . . . . . . . . . . . . . 123
7.2.4.3
Andere konstante Faktoren . . . . . . . . . . . . 124
7.2.4.4
Hypothesen . . . . . . . . . . . . . . . . . . . . . 125
7.2.4.5
Beschränkungen . . . . . . . . . . . . . . . . . . 125
Design des Experiments Regelauswertung . . . . . . . . . . 125
7.2.5.1
Unabhängige Variable . . . . . . . . . . . . . . . 126
7.2.5.2
Abhängige Variablen . . . . . . . . . . . . . . . . 126
7.2.5.3
Andere konstante Faktoren . . . . . . . . . . . . 126
7.2.5.4
Hypothese . . . . . . . . . . . . . . . . . . . . . . 126
7.2.6
Beschränkungen . . . . . . . . . . . . . . . . . . . . . . . . 126
7.2.7
Vorbereitung der Experimente . . . . . . . . . . . . . . . . 127
v
INHALTSVERZEICHNIS
INHALTSVERZEICHNIS
7.2.8
Durchführung der Experimente . . . . . . . . . . . . . . . 127
7.2.9
Analyse der Ergebnisse . . . . . . . . . . . . . . . . . . . . 128
7.2.9.1
Ergebnisse des Experiments Warteschlange . . . . 129
7.2.9.2
Ergebnisse des Experiments Regelauswertung . . 129
7.2.10 Zusammenfassung der Ergebnisse . . . . . . . . . . . . . . 130
8 Zusammenfassung und Ausblick
137
8.1
Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
8.2
Ausblick . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
8.2.1
Konvertierungen vermeiden . . . . . . . . . . . . . . . . . 139
8.2.2
Auf Properties und Slicekeys beliebiger Nachrichten zugreifen139
8.2.3
Nebenläufigkeit . . . . . . . . . . . . . . . . . . . . . . . . 139
8.2.4
Untersuchung der Slicing-Abbildungen . . . . . . . . . . . 140
8.2.5
Parallelisierung der Aktionen . . . . . . . . . . . . . . . . 140
8.2.6
Abgleich der Verbindungen der DB2-Fassade mit den
Processing-Threads . . . . . . . . . . . . . . . . . . . . . . 140
8.2.7
Nachrichten-Validierung . . . . . . . . . . . . . . . . . . . 140
8.2.8
Rewrites für die DB2
. . . . . . . . . . . . . . . . . . . . 141
Literaturverzeichnis
142
A Anhang
150
A.1 Quellcodes der Tests . . . . . . . . . . . . . . . . . . . . . . . . . 150
A.1.1 Testfälle Entwicklungsphase / Korrektheitsüberprüfung . . 150
A.1.1.1 demaqTestcase1.dql . . . . . . . . . . . . . . . . 150
A.1.1.2 demaqTestcase2.dql . . . . . . . . . . . . . . . . 150
A.1.1.3 demaqTestcase3.dql . . . . . . . . . . . . . . . . 151
A.1.1.4 demaqTestcase4.dql . . . . . . . . . . . . . . . . 151
A.1.1.5 demaqTestcase5.dql . . . . . . . . . . . . . . . . 152
A.1.2 Testanwendungen Experimente . . . . . . . . . . . . . . . 154
A.1.2.1 test1ClientServer.dql . . . . . . . . . . . . . . . . 154
A.1.2.2 test2ClientServer2.dql . . . . . . . . . . . . . . . 160
A.1.2.3 test3ProcessChain.dql . . . . . . . . . . . . . . . 166
A.1.2.4 test4SplitJoin.dql . . . . . . . . . . . . . . . . . . 172
vi
ABKÜRZUNGSVERZEICHNIS
Abkürzungsverzeichnis
ACID
Atomicity, Concurrency, Integrity, Durability
AST
Abstract Syntax Tree
CLI
Das Call Level Interface der DB2
CLOB
Character Large Object (siehe auch LOB)
DB2
IBM DB2 Universal Database
DBMS
Datenbank-Management-System
DDL
SQL-Data Definition Language
DOM
Document Object Model
DQL
Demaq Querying Language: Besteht aus der QDL und
der QRL
ER
Entity-Relationship
ERM
Entity-Relationship-Model
FIFO
First-In-First-Out
I/O
Input/Output
JDBC
Java Database Connectivity
LOB
Large Objects in relationalen Datenbanken (bis 2GB [35])
MDC
Multidimensional Clustering
ODBC
Open Database Connectivity (Microsoft Standard)
OTL
Oracle, Odbc and DB2-CLI Template Library [32]
QDL
Queue Definition Language
QRL
Queue Rule Language
REST
Representational State Transfer
RPM
Revolutions Per Minute
RSS
Really Simple Syndication
SOA
Service Oriented Architecture
SOAP
Simple Object Access Protocol
UDF
User Defined Function
UML
Unified Modeling Language
URI
Uniform Resource Identifier
vii
ABBILDUNGSVERZEICHNIS
Abbildungsverzeichnis
1
Varianten des Demaq-Systems . . . . . . . . . . . . . . . . . . . .
2
Varianten des Demaq-Systems: Komponenten und deren individu-
19
elle Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
3
Schematischer Kontrollfluss im Demaq-System . . . . . . . . . . .
25
4
Bisheriges Demaq-System: Detailansicht der wichtigsten Module
in den Komponenten . . . . . . . . . . . . . . . . . . . . . . . . .
5
Demaq-System mit der DB2 und Saxon : Detailansicht der wichtigsten Module in den Komponenten . . . . . . . . . . . . . . . .
6
28
Demaq-System mit der DB2 : Detailansicht der wichtigsten Module
in den Komponenten . . . . . . . . . . . . . . . . . . . . . . . . .
7
27
30
Detailansicht der Vererbungshierarchien im Kontext der Kontrollflüsse im Demaq-Kern . . . . . . . . . . . . . . . . . . . . . . . .
31
8
Das ER-Modell vom Demaq-System . . . . . . . . . . . . . . . . .
33
9
Abhängigkeiten von Komponenten und Modulen im Demaq-System 37
10
Varianten der Implementierung einer Warteschlange [9] . . . . . .
50
11
Warteschlangen als einfache Relation . . . . . . . . . . . . . . . .
52
12
Warteschlangen als einfache Relation (optimiert) . . . . . . . . . .
54
13
Warteschlangen als mehrere einzelne Relationen . . . . . . . . . .
55
14
Warteschlangen als mehrere einzelne Relationen (optimiert)
. . .
57
15
enqueue und dequeue auf paarweisen Relationen . . . . . . . . .
58
16
Warteschlange als paarweise Relationen . . . . . . . . . . . . . . .
60
17
Warteschlange als paarweise Relationen (optimiert) . . . . . . . .
61
18
Warteschlange als paarweise Relationen blockiert vor der Rotation
61
19
Warteschlangen als einfache Relation mit Pointern
. . . . . . . .
62
20
Warteschlangen als einfache Relation mit Pointern (optimiert) . .
64
21
Warteschlangen als einfache Relation mit Verkettung . . . . . . .
66
22
Warteschlange mit Statusinformationen in Form einer extra Tabelle 69
viii
ABBILDUNGSVERZEICHNIS
23
ABBILDUNGSVERZEICHNIS
Warteschlange mit Statusinformationen in Form einer extra Tabelle (optimiert) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
70
24
Warteschlange mit Informationsverwaltung im Hauptspeicher . . .
73
25
Warteschlange mit Informationsverwaltung im Hauptspeicher (optimiert) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
74
26
Räumlich getrennt gespeicherte Daten auf der Festplatte . . . . .
96
27
Automatische Speicherverwaltung über mehrere Festplatten . . .
99
28
Serialisierungs- und Parsing-Vorgänge im Demaq-System mit der
DB2 und Saxon
29
. . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Serialisierungs- und Parsing-Vorgänge im Demaq-System mit der
DB2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
30
Serialisierungs- und Parsing-Vorgänge im Demaq-System mit der
DB2 (optimiert) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
31
Übersicht der Testanwendungen für die Experimente und deren
benutzte Demaq-Features . . . . . . . . . . . . . . . . . . . . . . 116
32
Testanwendung 1 und 2: Simulation mit einem Server und mehreren Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
33
Testanwendung 3: Prozesskette mit Überkreuzung . . . . . . . . . 119
34
Testanwendung 4: Prozess-Simulation Split/Join . . . . . . . . . . 121
ix
TABELLENVERZEICHNIS
Tabellenverzeichnis
1
Matrix der unterstützten Views für Fragment Types (Adaptiert
von [45]) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
2
Erweiterung der Fragment/View -Matrix von Seite 8 . . . . . . . .
35
3
Übersicht der Varianten der Warteschlangenabbildung in einem
relationalen DBMS . . . . . . . . . . . . . . . . . . . . . . . . . .
76
4
Rewrites für Demaq-spezifische Funktionen . . . . . . . . . . . . .
90
5
Eigenschaften von Experimenten
6
Varianten der Testanwendungen 1 und 2 . . . . . . . . . . . . . . 118
7
Varianten der Testanwendung 3 . . . . . . . . . . . . . . . . . . . 120
8
Varianten der Testanwendung 4 . . . . . . . . . . . . . . . . . . . 122
9
Testergebnisse Teilexperiment A: Erster Teil . . . . . . . . . . . . 131
10
Testergebnisse Teilexperiment A: Zweiter Teil . . . . . . . . . . . 132
11
Testergebnisse Teilexperiment B: Erster Teil . . . . . . . . . . . . 133
12
Testergebnisse Teilexperiment B: Zweiter Teil . . . . . . . . . . . 134
13
Testergebnisse Experiment Regelauswertung: Erster Teil . . . . . 135
14
Testergebnisse Experiment Regelauswertung: Zweiter Teil . . . . . 136
x
. . . . . . . . . . . . . . . . . . 114
Einleitung
1
Einleitung
Verteilte und serviceorientierte Anwendungen spielen eine zunehmend wichtige
Rolle für Unternehmen [40]. In diesem Teilbereich der Informationssysteme wurden viele Neuerungen hervorgebracht, denen heute eine zentrale Bedeutung im
Bereich der Informationssysteme zukommt. Beispiele hierfür sind Technologien
wie Web Services, RSS oder REST.
Für Technologien, die in der Vergangenheit einen hohen Grad der Verbreitung
erreicht hatten, bestand regelmäßig eine Nachfrage nach einer Vereinfachung der
Handhabung und Steigerung der Effizienz im Umgang mit diesen Technologien.
Als Beispiel kann hier SQL angeführt werden: SQL entstand, weil die weitläufige
Nachfrage nach Zugriff auf Daten und deren Persistenzierung eine Vereinfachung
der Handhabung durch eine zusätzliche Abstraktion mithilfe einer deklarativen
Sprache notwendig machte [7].
Eine solche Vereinfachung der Handhabung sowie Steigerung der Effizienz bei
der Entwicklung und Ausführung serviceorientierter verteilter Anwendungen bietet Demaq [6]. Demaq ist zum einen eine deklarative Sprache zur Entwicklung
verteilter Anwendungen, die auf dem Austausch und der Verarbeitung standardisierter XML-Nachrichten basiert. Zum anderen ist es ein System, das Anwendungen ausführen kann, die mit der Sprache Demaq entwickelt wurden.
Im Rahmen dieser Diplomarbeit wird das Demaq-System flexibler gestaltet,
indem es modularisiert und einzelne Komponenten austauschbar gemacht werden.
Beispielhaft wird untersucht, inwiefern eine Integration von Demaq mit einem
kommerziellen relationalen Datenbanksystem praktikabel und effizient ist. Auf
diese Weise soll die Eignung des Systems für einen möglichen zukünftigen Einsatz
in Unternehmen erhöht werden.
Die Problemstellung dieser Arbeit liegt im Bereich des Software-Engineerings.
Dabei sollen die Anforderungen für die zu entwickelnden System-Veränderungen
analysiert, designt und implementiert werden. Anschließend wird die Effizienz
1
1.1 Zielsetzung
Einleitung
der aus der Veränderung entstehenden System-Varianten mithilfe von Tests untersucht.
1.1
Zielsetzung
Ziel dieser Diplomarbeit ist es, den Nachrichtenspeicher und den Mechanismus der
Regelauswertung im Demaq-System zu modularisieren und dadurch austauschbar
zu machen. Beispielhaft soll die relationale Datenbank DB2 in das Ausführungssystem integriert werden. Ferner soll die Leistungsfähigkeit der implementierten
System-Varianten untersucht werden.
1.2
Gliederung
Im Rahmen dieser Diplomarbeit soll Software verändert sowie einige Teile neu
entwickelt und getestet werden. Die Aufgabenstellung fällt demnach in den Bereich des Software-Engineerings. Aus diesem Grund wird eine Gliederung wie
folgt gewählt:
1. Grundlagen In Kapitel 2 werden die theoretischen Grundlagen für diese Arbeit geschaffen, die Voraussetzung für das Verständnis sind.
2. Problemstellung Kapitel 3 erläutert die Motivation und Ziele dieser Arbeit.
Als Konsequenz werden die Anforderungen des zu entwickelnden Systems
analysiert und als Herausforderungen problemorientiert formuliert.
3. Architektur Die umzusetzenden Änderungen am System werden grob auf
konzeptioneller Ebene entworfen (Kapitel 4).
4. Feinentwurf Der Grobentwurf wird verfeinert und auf logischer Ebene betrachtet (Kapitel 5).
5. Implementation Der System-Entwurf wird im Detail auf physischer Ebene
optimiert (Kapitel 6).
2
1.3 Darstellungskonventionen
Einleitung
6. Evaluation Die Integration der entwickelten Komponenten wird in Kapitel 7
zunächst qualitativ anhand von Tests und anschließend mithilfe geeigneter
Experimente quantitativ evaluiert.
7. Zusammenfassung und Ausblick Zum Abschluss werden die Ergebnisse
in Kapitel 8 zusammengefasst sowie ein Ausblick auf zukünftige Untersuchungen und Weiterentwicklungsmöglichkeiten gegeben.
1.3
Darstellungskonventionen
Einige Ausdrücke, die in dieser Diplomarbeit verwendet werden, werden im wissenschaftlichen und/oder allgemeinen Sprachgebrauch in Englisch verwendet. Um
Missverständnisse zu vermeiden, werden diese in dieser Arbeit nur übersetzt sofern dies die Verständlichkeit nicht einschränkt. Fachausdrücke, die wörtlich aus
dem Englischen übernommen werden, werden kursiv dargestellt.
Programm-Code jeglicher Art, wie beispielsweise Variablen, Funktionen, Klassen oder andere Ausschnitte im Speziellen der Programmiersprachen C++, SQL,
XQuery und DQL, werden in Schreibmaschinen-Schrift dargestellt. Ebenso
werden Dateien und Pfade im Dateisystem durch Schreibmaschinen-Schrift
kenntlich gemacht.
3
Grundlagen
2
Grundlagen
Bevor die eigentliche Aufgabenstellung dieser Arbeit in nachfolgenden Kapiteln
behandelt wird, widmet sich dieses Kapitel den Grundlagen, welche notwendiges
Wissen zum Verständnis enthalten. Die Grundlagen erläutern Konzepte, Bestandteile, Funktionalitäten sowie Vor- und Nachteile bezogen auf Demaq selbst sowie
auf konkret verwendete und zu verwendende Systemkomponenten im DemaqUmfeld. Dieses Kapitel soll im Speziellen dem unbedarften Leser den Zugang zu
dieser Arbeit erleichtern.
2.1
Demaq
In diesem Abschnitt wird das Demaq-System ganzheitlich abstrakt betrachtet.
Dabei soll auf metakonzeptioneller Ebene beschrieben werden, welches Konzept
hinter Demaq steht (Kapitel 2.1.1) und welche Bestandteile es ausmachen (2.1.2).
2.1.1
Konzept
Das Konzept von Demaq basiert auf der Bearbeitung von XML-Nachrichten,
die in Warteschlangen eingereiht und anschließend regelbasiert weiterverarbeitet
werden. Dabei wird das Verhalten durch XQuery-basierte deklarative Regeln definiert. Auf diese Weise können komplexe Anwendungen auf einfache Weise erstellt
werden.
2.1.2
Bestandteile
Demaq setzt sich aus zwei Teilaspekten zusammen. Einerseits stellt Demaq eine
deklarative Sprache zur Erstellung von Warteschlangen für XML-Nachrichten dar
sowie zur Beschreibung der XML-Nachrichten. Auf der anderen Seite umfasst Demaq ein Ausführungssystem, welches diese deklarative Sprache interpretieren und
umsetzen kann. Im Nachfolgenden werden beide Teilaspekte einzeln vorgestellt.
4
2.1 Demaq
2.1.2.1
Grundlagen
Die Sprache Demaq Die deklarative Sprache Demaq ist wesentli-
cher Bestandteil des Demaq-Konzeptes. Die Sprache unterteilt sich in zwei Teilsprachen für unterschiedliche Zwecke: Die Definitionssprache QDL und die Manipulationssprache QRL. Der jeweilige Zweck der Sprachteile kann wie folgt beschrieben werden:
QDL: Mit den Sprachkonstrukten von QDL werden Queues (Warteschlangen),
Slicings (Gruppen von Nachrichten mit bestimmten Properties) und Properties (Attribute) definiert.
QRL: QRL wird verwendet, um Regeln anzulegen, die beschreiben wie Nachrichten in einer Warteschlange oder in einem Slicing weiterverarbeitet werden.
Da die Regeln auf XML-Nachrichten angewandt werden, besteht QRL zum
größten Teil aus XQuery.
2.1.2.2
Das Demaq-Ausführungssystem Das Demaq-Ausführungssystem
ist bezüglich der Prozesse und Abläufe im System detailliert spezifiziert [6]. Die
wichtigsten Bestandteile im Kontext dieser Diplomarbeit werden im Folgenden
kurz erläutert:
Nachrichtenspeicher Im Nachrichtenspeicher werden Warteschlangen für
XML-Nachrichten angelegt und verwaltet. Außerdem werden hier die meisten vom System benötigten Daten gespeichert, wie z.B. Properties, Regeln
oder andere Metadaten.
RuleProcessor Der Regelauswerter (RuleProcessor) wendet Regeln auf einzelne Nachrichten an und generiert als Ergebnis eine Liste auszuführender
Aktionen (QueryResult).
QueryResult Das QueryResult ist eine Liste von Aktionen (Pending Action
List), die durch die Anwendung von Regeln auf eine Nachricht entsteht
und zur Ausführung bestimmt ist.
5
2.1 Demaq
Grundlagen
Actioninterpreter Der Actioninterpreter bekommt ein QueryResult übergeben und führt die darin enthaltenen Aktionen aus.
Dispatcher Im Demaq-Ausführungssystem kann ein Dispatcher für eine oder
mehrere Warteschlangen verantwortlich sein. Eine Warteschlange ist genau
einem Dispatcher zugeordnet.
In jedem Dispatcher können ein oder mehrere ProcessingThreads laufen,
die für die Steuerung des Kontroll- und Datenflusses bei der Abarbeitung einer Nachricht verantwortlich sind. Die abzuarbeitende Nachricht wird einer
Warteschlange entnommen, für die dieser Dispatcher zuständig ist.
ProcessingThread Die ProcessingThreads holen sich Informationen über neu
eingereihte Nachrichten von dem QueueScheduler und starten die Regelauswertung für diese mithilfe eines RuleProcessors. Nach der Regelauswertung übergeben sie das resultierende QueryResult an den Actioninterpreter. Dieser widerum gibt eine ConsequenceList als Ergebnis seiner
Arbeit zurück. Die ConsequenceList leitet der ProcessingThread an den
QueueScheduler weiter, der diese interpretiert. Die interpretierten Informationen stellt der QueueScheduler den ProcessingThreads zur weiteren
Verarbeitung zur Verfügung.
QueueScheduler Der QueueScheduler bestimmt die Reihenfolge der abzuarbeitenden Nachrichten innerhalb einer Warteschlange. Er bekommt vom Actioninterpreter in Form einer ConsequenceList mitgeteilt, welche Nachrichten neu aufgenommen wurden.
ConsequenceList Eine ConsequenceList ist das Resultat der Ausführung von
Aktionen. Wurde z.B. eine neue Nachricht in eine Warteschlange eingereiht,
wird dies dem QueueScheduler in einer solchen Konsequenzen-Liste mitgeteilt.
6
2.2 Natix
2.2
Grundlagen
Natix
NATIX [11] ist ein natives XML-DBMS, dass zu Forschungszwecken entwickelt
wurde, inzwischen aber auch kommerziell zum Einsatz kommt. Die Datenbank
zeichnet sich dabei durch Konzepte aus, die für diese Diplomarbeit eine besondere
Rolle spielen. Diese Konzepte werden im Nachfolgenden beschrieben.
Des Weiteren unterstützt die Datenbank Features für die Speicherung von
XML-Daten, die in Kapitel 2.2.2 eingehender beschrieben werden. Schließlich
werden in Kapitel 2.2.3 einige Einschränkungen erläutert, denen NATIX unterliegt.
2.2.1
Konzepte
In NATIX existieren einige neuartige Konzepte, die den Umgang mit XML-Daten
vereinfachen. Diese Konzepte werden in diesem Kapitel kurz erläutert.
2.2.1.1
Fragmente Fragmente stellen in NATIX eine Abstraktion von XML-
Daten dar [45]. Diese Daten können in verschiedenster Form vorliegen, z.B. als
Datei im Dateisystem, gespeichert in NATIX oder als Ergebnis einer XQueryAuswertung. Dementsprechend können Fragmente in verschiedene Fragmenttypen (Fragment Types) unterteilt werden, je nachdem in welchem Container sie
sich befinden. NATIX sind diese Typen bekannt und das System reagiert entsprechend auf die Daten eines Fragmenttypes.
Repräsentiert werden die Fragmente durch Fragment Descriptors. Diese beinhalten nicht die eigentlichen Daten des Fragments, sondern Informationen, um
auf diese Daten zuzugreifen. Beispielsweise genügt es für XML-Daten, die in einer
Datei gespeichert sind, den absoluten Dateipfad zu kennen. Oder für ein XMLFragment, das in NATIX gespeichert ist, genügt die Dokument-ID. Ähnlich wie
ein FileHandle kann ein Fragment Desctiptor wie ein Zeiger auf die eigentlichen
Fragment-Daten verstanden werden.
7
2.2 Natix
Grundlagen
Tabelle 1: Matrix der unterstützten Views für Fragment Types (Adaptiert von [45])
2.2.1.2
Requests Ein Request wird benötigt, um NATIX zu steuern [45].
Sollen beispielsweise Daten von NATIX angefordert werden, so muss die dazu
notwendige Operation in NATIX mit Hilfe eines Requests ausgelöst werden. Dem
Request-Objekt werden dabei alle erforderlichen Daten übergeben.
Ausgeführt werden kann der Request zum einen, indem er der Funktion process() einer natix::Transaction übergeben wird. Zum anderen wird er automatisch nach dem Erzeugen ausgeführt, wenn dem Konstruktor des Requests eine
natix::Transaction übergeben wurde.
In den Fällen, in denen ein Request nur ein atomares Ergebnis liefert, wird
dieses Ergebnis durch eine automatische Konvertierung bei der Ausführung zurückgeliefert. Ein Beispiel soll dies verdeutlichen:
1 n a t i x : : F r a g m e n t D e s c r i p t o r doc=n a t i x : : OpenDocument ( n a t i x T r a n s a c t i o n ,
docid ) ;
In dem Beispiel wird ein Request mit dem Namen OpenDocument erzeugt,
der eine Dokumenten-ID benötigt. Durch diese ID kann NATIX das Dokument
eindeutig zuordnen. Durch die Übergabe des Objekts natixTransaction vom
Typ natix::Transaction wird der Request sofort ausgeführt. Da es nur einen
Ergebniswert für diese Operation gibt, wird dieser durch einen automatischen
Konvertierungsmechanismus zurückgeliefert. In diesem Fall ist das Ergebnis ein
natix::FragmentDescriptor.
8
2.2 Natix
2.2.1.3
Grundlagen
Views Views werden in NATIX verwendet, um auf Fragmente und
damit auf XML-Daten zuzugreifen [45]. Dabei verkörpern sie verschiedene Zugriffsformen auf XML-Daten. Beispielsweise kann ein XML-Dokument als DOMTree oder als Stream geöffnet werden. Tabelle 1 stellt in einer Übersicht dar,
welche Fragmenttypen mit welcher View geöffnet werden können.
Das Fragment, das zu dem natix::FragmentDescriptor ”doc“ aus dem Beispiel in Abschnitt 2.2.1.2 gehört, könnte z.B. wie folgt als Stream geöffnet werden:
1 n a t i x : : OpenView<n a t i x : : StreamView> streamView ( n a t i x T r a n s a c t i o n , doc ) ;
s t d : : i o s t r e a m∗=streamView . getView ( )−>getStream ( ) ;
Um eine bestimmte View auf ein XML-Dokument zu öffnen, muss ein entsprechender Request an NATIX übermittelt werden (vgl. Abschnitt 2.2.1.2).
2.2.1.4
XQuery-Auswertung In NATIX können verschiedene Engines zur
Auswertung von XQuery eingesetzt werden. Standardmäßig wird Saxon [30] verwendet. Für Saxon gibt es in NATIX Erweiterungen (Callbacks), damit Demaqspezifische Sprachkonstrukte, wie beispielsweise qs:queue() oder qs:slice(),
ausgewertet werden können. Diese Callbacks werden benutzt, um während der
Regelverarbeitung dynamisch Daten aus dem Nachrichtenspeicher nachzuladen.
Auf diese Weise können Nachrichten oder Properties durch Funktionsaufrufe innerhalb der QRL dynamisch in den Regeln verarbeitet werden. Ein Beispiel:
create r u l e count f o r queue1
2
enqueue message <r e s u l t >
{ f n : count ( qs : queue ( ’ queue1 ’ ) ) }
4
</ r e s u l t > into r e s p o n s e q u e u e ;
In obigem Beispiel wird eine Regel mit dem Namen count für die Warteschlange queue1 erzeugt. In dieser werden die Nachrichten, die sich in der Warteschlange befinden, gezählt und das Ergebnis in die Antwort-Warteschlange responsequeue übermittelt. An der Stelle mit dem Ausdruck “qs:queue(’queue1’)” wird
9
2.2 Natix
Grundlagen
bei Auswertung der Regel ein Callback ausgeführt, der auf den Nachrichtenspeicher zugreift. Als Resultat wird eine Sequenz aller Nachrichten der Warteschlange
queue1 zurückliefert. Das Zwischenergebnis nach Auswertung des Callbacks sieht
in dem Beispiel wie folgt aus:
create r u l e count f o r queue1
2
enqueue message <r e s u l t >
{ f n : count((<xml i d= ’ 1 ’ />, <xml i d= ’ 2 ’ />) ) }
4
</ r e s u l t > into r e s p o n s e q u e u e ;
Nach der Auswertung des Callbacks wird die Regel von Saxon weiter verarbeitet.
2.2.2
Features
NATIX speichert XML-Daten nativ, d.h. XML-Dokumente werden nicht als flache Text-Strukturen gespeichert, sondern als Baumstruktur mit dem DokumentKnoten als Wurzel.
Außerdem unterstützt NATIX die Verwaltung von XML-Daten mit Hilfe von
Warteschlangen. Dabei sind die Warteschlangen in NATIX nativ implementiert,
d.h. eine spezielle Datenstruktur wird genutzt, die explizit für diesen Zweck optimiert ist.
2.2.3
Einschränkungen
NATIX unterliegt Einschränkungen in den folgenden Bereichen:
Nebenläufigkeit In NATIX kann nur eine Transaktion gleichzeitig verarbeitet
werden, die Updates auf Daten durchführt. Das ACID-Konzept [31] wird
hierbei umgesetzt, indem Änderungen am Datenbestand seriell abgearbeitet
werden.
Datenformate Daten werden ausschließlich im XML-Format abgespeichert.
10
2.3 DB2
Grundlagen
Anfrageoptimierung Eine automatische Anfrage-Optimierung, z.B. von
XQuery-Ausdrücken, wird von NATIX nicht durchgeführt, da hierfür integrierte XQuery-Engines verwendet werden (vgl. Abschnitt 2.2.1.4). Aus
diesem Grund können keine Indizes oder andere interne Strukturen, wie
beispielsweise Dictionaries, ausgenutzt werden.
2.3
DB2
Für eine beispielhafte Integration einer relationalen Datenbank mit nativer XMLUnterstützung in das Demaq-System kommen eine Reihe kommerzieller DBMS in
Frage. Die gängigsten relationalen Datenbanken sind (mit über 85% Marktanteil
in 2006 [12]):
• Database 11g (Oracle)
• DB2 (IBM)
• SQL Server (Microsoft)
Für die Umsetzung dieser Diplomarbeit wurde DB2 gewählt. Die Gründe für
diese Wahl werden in Kapitel 2.3.1 erläutert. In Abschnitt 2.3.2 werden anschließend die Einschränkungen von DB2 beleuchtet.
2.3.1
Features
Folgende Kriterien waren entscheidend für die Wahl von DB2 als beispielhafte
Integrationslösung in das Demaq-Ausführungssystem im Rahmen dieser Diplomarbeit:
Unterstützte Sprachen Die DB2 unterstützt XQuery (einschließlich der
XQuery Update Facility), SQL/XML und SQL.
11
2.3 DB2
Grundlagen
Daten-Kompression XML-Daten können in der DB2 automatisch komprimiert
werden. Die Kompression der Daten spielt im Hinblick auf das Leistungsverhalten eine wichtige Rolle.
Automatische Optimierung Die DB2 Execution-Engine ist ein hybrides System [4]. Dieses kann sowohl XQuery, SQL/XML als auch SQL optimieren.
Die Grenzen sind hierbei fließend, d.h. Ausdrücke, die beispielsweise XQuery und SQL enthalten, können sprachübergreifend optimiert werden.
Parallelität DB2
unterstützt
sowohl
die
parallele
Ausführung
auf
Multiprozessor-Maschinen als auch die parallelisierte Speicherung auf
mehreren Datenträgern mit automatisierter Speicherverwaltung (Automatic Storage) [1].
ACID Die Einhaltung des ACID-Konzepts [31] wird von DB2 auch für XMLbasierte Vorgänge zugesichert.
2.3.2
Einschränkungen
Einschränkungen der Funktionalitäten von DB2, die diese Diplomarbeit betreffen,
werden im nachfolgenden Kapitel aufgeführt.
2.3.2.1
Allgemeine Einschränkungen Einige allgemeine Einschränkungen
begrenzen die Verwendung von DB2-Features, insbesondere im Umgang mit
XML-Daten:
• XML kann von DB2 nur serialisiert an externe Applikationen zurückgegeben
werden. Eine Rückgabe z.B. als DOM-Tree ist nicht möglich [8].
• Der XML-Datentyp kann nicht als Rückgabewert und nicht als Parameter
einer UDF verwendet werden [16].
12
2.3 DB2
Grundlagen
• XQuery-Ausdrücke können innerhalb einer Stored Procedure oder UDF
nicht direkt, sondern nur mithilfe eines SQL/XML-Statements ausgeführt
werden [38].
• In temporären Tabellen kann der XML-Datentyp nicht verwendet werden
[21].
• XML-Spalten können nicht in Bereichs-Cluster - und MDC-Tabellen verwendet werden [21].
2.3.2.2
XQuery Einschränkungen Folgende Sprachkonstrukte des aktuel-
len XQuery Standards (Version 1.0) [5], die diese Diplomarbeit betreffen, werden
von der DB2 XQuery Engine nicht unterstützt [28]:
• declare module und import module
• declare function
• declare variable
• qualifizierte Variablennamen (Beispiel: $demaq:systemVariable)
• qualifizierte Funktionsnamen (Beispiel: qs:queue(); Ausnahme sind die
qualifizierten Funktionsnamen, die aus dem statischen Kontext der DB2
XQuery Engine bekannt sind, wie z.B. db2-fn:sqlquery())
Außerdem existieren folgende Einschränkungen beim Zugriff auf relationale
Daten aus XQuery heraus, beispielsweise mit der Funktion db2-fn:sqlquery
[22]:
• Es können nur reine Select-Statements und keine SQL-Update-Ausdrücke
verwendet werden
• Aus XQuery kann nicht mittels db2-fn:sqlquery auf Sequenzen zugegriffen werden
13
Problemstellung
3
Problemstellung
Nachdem im vorangehenden Kapitel die Grundlagen zum Verständnis dieser Arbeit geschaffen wurden, wird in diesem Kapitel die eigentliche Problemstellung
erarbeitet.
Die zu lösenden Probleme werden anhand der folgenden stringenten Vorgehensweise identifiziert: Zunächst wird die Umsetzung des Vorhabens motiviert
(Abschnitt 3.1). Aus der Motivation heraus werden anschließend die Ziele dieser
Arbeit abgeleitet (Abschnitt 3.2). Aus den Zielen ergeben sich die Anforderungen für die Umsetzung (Abschnitt 3.3), aus denen letztendlich unmittelbar die
Herausforderungen abgeleitet werden (Abschnitt 3.4).
3.1
Motivation
Demaq ist ein Ausführungssystem für XML-nachrichtenbasierte verteilte Anwendungen. Es unterscheidet sich insbesondere durch seine vollständig deklarative
Sprache und das warteschlangenbasierte Ausführungsmodel von der Architektur
aktueller Systeme [6].
Für Unternehmen bedeutet die Einführung neuer Software mit eigenen Komponenten ein Risiko, da der daraus entstehende Wartungsaufwand schwer abzuschätzen ist. Besser ist es, wenn neue Software mit flexiblen Komponenten
lauffähig ist, damit eine nahtlose Integration in bestehende Systemlandschaften
im Unternehmen möglich ist.
Bis dato wurde die native XML-Datenbank NATIX als Nachrichtenspeicher
für das System benutzt. Dies begründet sich dadurch, dass hauptsächlich Daten im XML-Format gespeichert und verarbeitet werden. In gängigen DBMS war
zum Zeitpunkt der Entwicklung von Demaq eine native Unterstützung des XMLDatentyps nicht implementiert. Ein weiterer Grund, weshalb NATIX als Nachrichtenspeicher für das Demaq-System gewählt wurde, ist, dass der Quelltext von
NATIX vorliegt, so dass evtl. nötige Anpassungen im Nachrichtenspeicher ohne
14
3.1 Motivation
Problemstellung
Probleme vorgenommen werden können.
Allerdings weist die Benutzung von NATIX innerhalb des Demaq-Systems
mehrere Nachteile (vgl. Kapitel 2.2.3) auf, da die XML-Datenbank ursprünglich
nicht explizit für diesen Zweck konzipiert wurde [11]. Zudem verfügen relationale
Datenbanken inzwischen nicht nur über einen nativen XML-Datentyp, sondern
auch eine Verarbeitung von XML-Daten mit XQuery oder SQL/XML ist möglich.
Zusammenfassend soll das Demaq-System im Rahmen dieser Diplomarbeit
modularer und damit flexibler gestaltet werden. Zu diesem Zweck wird die Integration eines relationalen DBMS (beispielhaft mit der DB2 (vgl. Kapitel 2.3.1))
sowohl als Nachrichtenspeicher als auch zur Regelauswertung im Demaq-System
untersucht.
Hierbei wird insbesondere auf folgende Punkte näher eingegangen:
• Ist das Demaq-Ausführungssystem geeignet, um eine relationale Datenbank
als Nachrichtenspeicher/Regelauswerter zu verwenden?
• Welche Anpassungen sind notwendig, damit dies möglich wird? Ist dies
praktikabel?
• Ist die DB2 zur Integration als Nachrichtenspeicher und Regelauswerter im
Demaq-System geeignet?
• Wie können Mechanismen (Indizes, Anfrageoptimierung, Parallelität1 , Nebenläufigkeit2 ) der DB2 zur Optimierung genutzt werden?
• Wie lassen sich ggf. Funktionalitäten des Demaq-Systems in das relationale
DBMS verlagern?
1
Parallelisierung bedeutet, dass mehrere Programmteile physisch gleichzeitig ausgeführt wer-
den: ”A condition that arises when at least two threads are executing simultaneously.“ [44, S.16].
2
Nebenläufigkeit (Concurrency) bezeichnet die Abarbeitung verschiedener Aufgaben in unterschiedlichen Threads. Dabei muss die Bearbeitung nicht unbedingt physisch gleichzeitig erfolgen: ”A condition that exists when at least two threads are making progress. A more generalized
form of parallelism that can include time-slicing as a form of virtual parallelism.“ [44, S.16].
15
3.2 Ziele
3.2
Problemstellung
Ziele
In dem Demaq-Ausführungssystem soll der Nachrichtenspeicher NATIX durch
eine relationale Datenbank – im konkreten Fall die DB2 (vgl. hierzu Kapitel
2.3.1) – ersetzt werden. Hierzu werden zunächst die Möglichkeiten zur Abbildung der eingesetzten Warteschlangen auf das relationale Datenmodell evaluiert,
um anschließend die hieraus resultierenden Änderungen in Bezug auf das Leistungsverhalten mit geeigneten Experimenten auszuwerten. Ebenso wird deren
Leistungsverhalten mit der nativen Warteschlangenimplementierung in NATIX
verglichen.
Ein weiteres Ziel ist es, die Ausführung der Regeln in das relationale Datenbanksystem zu verlagern. Anstelle von Saxon soll hierbei die XQuery-Engine der
DB2 zur Regelauswertung verwendet werden. Über eine Kompilier-Option soll
steuerbar sein, mit welchem Regelauswerter das Demaq-System ausgeführt wird.
Im Rahmen der vorliegenden Arbeit wird gezeigt, wie das DemaqAusführungssystem für einen Austausch des Nachrichtenspeichers und des Regelauswertungsmechanismus anzupassen ist.
3.3
Anforderungen
Im Nachfolgenden werden weitere Anforderungen dargestellt, die im Rahmen der
Implementierung zu berücksichtigen sind.
3.3.1
Korrektheit
Die Korrektheit der Funktionsweise des Systems nach dem Austausch des Nachrichtenspeichers bzw. des Regelauswertungsmechanismus ist anhand von Testfällen zu zeigen. Zu diesem Zweck muss zunächst eine praktikable Lösung zum
Austausch gefunden werden. Mittels dieser ist zu überprüfen, ob das System
dieselben Ergebnisse für gleiche Anwendungen liefert wie das aktuelle DemaqAusführungssystem.
16
3.4 Herausforderungen
3.3.2
Problemstellung
Modularisierung
In der vorliegenden Diplomarbeit werden der Nachrichtenspeicher und die Regelauswertung im Demaq-System ausgetauscht. Hierbei ist eine Modularisierung
angestrebt, um einzelne Komponenten später gegeneinander auszutauschen bzw.
neu miteinander zu kombinieren. Auf diese Weise können sie auch in zukünftigen
Untersuchungen durch weitere Alternativen ersetzt werden.
Die zu verwendende Variante des Demaq-Systems (vgl. Abbildung 1) soll zur
Kompilier-Zeit festgelegt werden. Es wird nicht möglich sein, während der Laufzeit des Systems den Nachrichtenspeicher zu wechseln. Dazu müsste das System
erst gestoppt, neu kompiliert und gestartet werden.
3.3.3
Leistungsverhalten
Das Leistungsverhalten der zu entwickelnden Komponenten hat eine hohe Priorität. Allerdings steht zunächst die generelle Machbarkeit im Vordergrund. Sollte
diese jedoch gegeben sein, ist es eine Anforderung, das System bezüglich des
Leistungsverhaltens zu optimieren.
Außerdem soll das Leistungsverhalten der Varianten (vgl. Abbildung 1) mit
dem aktuellen NATIX-basierten System verglichen werden. Im Idealfall sind Aussagen über Veränderungen einzelner Funktionalitäten zu treffen, wie z.B. über
Zugriffe auf Slices oder Properties.
3.4
Herausforderungen
Aus den Zielen und Anforderungen dieser Diplomarbeit ergeben sich einige Herausforderungen, die im Nachfolgenden kurz dargestellt werden. Dieses Kapitel
zielt dabei auf die Frage ab, welche Probleme zu lösen sind, um die Anforderungen und Ziele zu erfüllen.
17
3.4 Herausforderungen
3.4.1
Problemstellung
Überprüfung der Korrektheit
Zur Überprüfung der Korrektheit des Demaq-Systems sind Tests auszuführen,
die den vollständigen Funktionsumfang von Demaq abdecken. Alle lauffähigen
Varianten müssen in diesen Tests nicht nur das gleiche, sondern auch das der
Spezifikation [6, 46] entsprechende Ergebnis liefern.
3.4.2
Modularisierung
Aus den Zielen (vgl. Kapitel 3.2) dieser Diplomarbeit können zwei getrennt voneinander zu bearbeitende Teilprobleme abgeleitet werden: Zum einen der Austausch des Nachrichtenspeichers und zum anderen der Austausch der Regelauswertung. Die betroffenen Komponenten sollen frei miteinander kombinierbar bleiben (vgl. Kapitel 3.3.2). Daraus ergeben sich drei lauffähige Varianten des DemaqSystems.
Das Demaq-System wird entweder mit NATIX und Saxon oder ausschließlich
mit der DB2 kompilierbar sein. Außerdem wird es eine weitere Mischform des
Demaq-Systems geben, welche die DB2 als Nachrichtenspeicher und Saxon als
Regelauswerter verwendet. Dadurch können Experimente durchgeführt werden,
deren Ergebnisse eindeutig dem Austausch des Nachrichtenspeichers zuzurechnen
sind. Eine weitere Variante mit NATIX als Nachrichtenspeicher und der DB2 als
Regelauswerter ist nicht sinnvoll, da der Arbeitsaufwand zu groß ist und Optimierungsmechanismen innerhalb der Komponenten nicht genutzt werden können.
Abbildung 1 veranschaulicht die angestrebten möglichen Ausführungsversionen
des Demaq-Systems.
Die Modularisierung stellt eine große Herausforderung dar, da an mehreren
Stellen im Quelltext des Demaq-Ausführungssystems NATIX-spezifischer Code
direkt inkludiert und verwendet wird. Dementsprechend wurde bei der Entwicklung von Demaq keine strikte Kapselung verfolgt, da eine Austauschbarkeit von
einzelnen Komponenten nicht vorgesehen war.
18
3.4 Herausforderungen
Problemstellung
Abbildung 1: Varianten des Demaq-Systems
3.4.3
Modellierung der Datenstrukturen und Features
Die Modellierung der Datenstrukturen und Features ist eine Herausforderung, die
sich aus der Anforderung zur Optimierung des Leistungsverhaltens ergibt (vgl.
Kapitel 3.3.3). Im Wesentlichen stellt sich die Frage, wie die internen Datenstrukturen im Demaq-System effizient auf ein relationales Datenbanksystem abgebildet
werden können. Hierzu zählt nicht nur die Abbildung der Warteschlangen, sondern auch die Modellierung der sonstigen Daten und Metadaten, wie z.B. der
Regeln (Rules) und Eigenschaften (Properties).
Die DB2 stellt viele Mechanismen und Erweiterungsmöglichkeiten bereit, die
es erlauben, ähnliche Features abzubilden wie sie das Demaq-System bietet. Im
Rahme dieser Arbeit sind Möglichkeiten zu untersuchen, wie einzelne Funktionalitäten in das relationale DBMS verlagert werden können, um Leistungssteige19
3.4 Herausforderungen
Problemstellung
rungen zu erzielen. Dabei ist deren Vorteilhaftigkeit kritisch zu beleuchten und
zu diskutieren.
3.4.4
Physische Optimierung des Leistungsverhaltens
Bei der Optimierung des Leistungsverhaltens der Demaq-Varianten mit der DB2
spielen insbesondere die Parallelisierung der Abläufe, Nebenläufigkeit, die Anfrageoptimierung und Indizes eine wichtige Rolle.
3.4.4.1
Parallelisierung Die Parallelisierung umfasst die physische Opti-
mierung der DB2. Dabei sind zwei Bereiche besonders wichtig: Zum einen die
Speicherung der Daten, da diese unabhängig vom Prozessor durchgeführt werden kann. Zum anderen betrifft es den/die Prozessor(en) selbst. Dabei ist eine
Kontrolle über die Auslastung der Prozessoren nur über das DB2 Control Center
möglich, da der Quelltext der DB2 nicht offen ist. Hierbei stellt sich die Frage,
welche Mechanismen zur Beeinflussung der Parallelität zur Verfügung stehen und
wie diese im Sinne des Demaq-Ausführungssystems leistungssteigernd eingesetzt
werden können.
3.4.4.2
Nebenläufigkeit Im Demaq-Ausführungssystem ist Nebenläufigkeit
für die Abarbeitung der Warteschlangen vorgesehen, indem verschiedene Nachrichten auf mehreren nebenläufigen Threads verarbeitet werden können. Allerdings unterstützt NATIX keine nebenläufigen Zugriffe (vgl. Kapitel 2.2.3), so
dass immer nur eine Transaktion gleichzeitig auf den Nachrichtenspeicher zugreifen kann. Wenn eine NATIX-Transaktion gestartet ist, werden alle anderen
ausgeführten Threads blockiert, die ebenfalls eine Transaktion initiieren wollen.
Da der Zugriff auf den Nachrichtenspeicher essentiell für den Programmablauf im
Demaq-Ausführungssystem ist, kann eine nebenläufige Verarbeitung mit NATIX
nicht unterstützt werden. Dies führt so weit, dass das Starten mehrerer Threads
das System verlangsamt, da diese untereinander synchronisiert werden müssen,
20
3.4 Herausforderungen
Problemstellung
obwohl keine Nebenläufigkeit möglich ist.
Die Integration der DB2 als Nachrichtenspeicher ermöglicht eine nebenläufige
Verarbeitung. Mithilfe der DB2 können beliebig viele Transaktionen gleichzeitig
gestartet werden, die simultan auf den Nachrichtenspeicher zugreifen und Daten ändern können. Diese Option soll genutzt und optimiert werden, um eine
Verbesserung des Leistungsverhaltens zu erzielen.
3.4.4.3
Anfrageoptimierung Eine Anfrageoptimierung findet in der DB2
automatisch statt. Ein Einfluss hierauf ist nur beschränkt über die Datenbankadministration möglich. Grundsätzlich gilt, dass mehrere einzelne Anfragen möglichst zusammengefasst werden, damit die automatische Optimierung übergreifende Synergieeffekte realisieren kann (vgl. beispielsweise [3]).
3.4.4.4
Indizes Indizes bieten eine gute Möglichkeit, um Zugriffe auf be-
stimmte Datensätze innerhalb einer Tabelle zu beschleunigen. Ebenso können
sie aber die Verarbeitung von Daten verlangsamen, insbesondere wenn viele Update-Operationen jeweils die Anpassung eines Index erfordern. Als Folge kann der
Aufwand für die Pflege eines Index so groß sein, dass er den Gewinn beim Zugriff
übersteigt. Insofern ist die Verwendung von Indizes im Vorfeld abzuwägen.
3.4.5
Untersuchung des Leistungsverhaltens
Das im Rahmen dieser Arbeit implementierte System soll nach der Änderung
des Leistungsverhaltens beurteilt werden, das sich aufgrund des Austauschs des
Regelauswertungsmechanismus und des Nachrichtenspeichers ergibt. Durch breit
angelegte Experimente wird die Veränderung derart gemessen werden, so dass
diese:
1. eindeutig auf eine Ursache zurückzuführen ist
21
3.4 Herausforderungen
Problemstellung
2. möglichst generalisierbar, d.h. im besten Fall auf alle denkbaren Anwendungsszenarien übertragbar ist.
Die Ergebnisse von Tests, die ausschließlich mit sehr kurzen Nachrichten und
einfachen Regeln definiert sind, können erheblich von den Ergebnissen von Tests
abweichen, die mit sehr langen Nachrichten und komplexen Regeln arbeiten. Aus
diesem Grund müssen vernünftig formulierte Tests alle denkbaren Anwendungsszenarien abdecken und idealtypisch nach ihrer Komplexität skalierbar sein. Hierdurch können Veränderungen des Leistungsverhaltens für einzelne Features des
Demaq-Systems identifiziert werden. Beispielsweise könnten sich Zugriffe auf Properties als besonders effizient herausstellen, während sich Zugriffe auf Slices als
uneffizient erweisen.
Veränderungen des Leistungsverhaltens bei gleichzeitigem Austausch des
Nachrichtenspeichers und des Regelauswertungsmechanismus können nicht eindeutig auf eine der beiden Ursachen zurückgeführt werden. Deshalb liegt eine
Herausforderung in der Definition von zwei unabhängigen Experimenten, die beide Veränderungen getrennt voneinander untersuchen (vgl. Kapitel 3.4.2).
22
Architektur
4
Architektur
Nachdem im vorangegangenen Kapitel die Ziele formuliert und die Anforderungen des zu entwickelnden Systems analysiert wurden, wird in diesem Kapitel das
Design des Systems auf konzeptioneller Ebene entworfen. Zu diesem Zweck werden die Architekturen der Demaq System-Varianten vorgestellt, die im Rahmen
dieser Diplomarbeit entwickelt werden. Während Kapitel 4.1 die Architekturen
variantenbezogen und schematisch vorstellt, befasst sich das Kapitel 4.2 detaillierter mit den Modulen, die zu mehreren Varianten in Bezug stehen.
4.1
Demaq System-Varianten
Ein zentrales Ziel der vorliegenden Arbeit ist es, das Demaq-System komponentenbasiert zu realisieren. Mit diesen Komponenten können durch freie Kombination mehrere Varianten des Systems erzeugt werden, von denen im Rahmen
dieser Ausarbeitung drei beschrieben werden (vgl. Kapitel 3.4.2). Die Architektur der Varianten wird in den folgenden Unterkapiteln beleuchtet. Dabei werden
die Komponenten analysiert und beschrieben, sofern sie für die Aufgabenstellung
dieser Diplomarbeit relevant sind. Zusätzliche Komponenten, wie beispielsweise
das Kommunikationssystem [46], bleiben unberücksichtigt.
4.1.1
Übersicht der System-Varianten
In dem Demaq-Ausführungssystem sind folgende Komponenten für diese Diplomarbeit relevant:
Demaq Kern: Der Code, der die Hauptfunktionalität von Demaq enthält. In
diesem werden die Systemabläufe gesteuert und weitere Aufgaben an den
Nachrichtenspeicher und die Regelauswertung deligiert.
Nachrichtenspeicher: Im Nachrichtenspeicher werden alle Nachrichten und
weitere Daten gespeichert.
23
4.1 Demaq System-Varianten
Architektur
Regelauswertung: Die Regelauswertung (XQuery-Processing) verarbeitet
Nachrichten im XML-Format.
Abbildung 2: Varianten des Demaq-Systems: Komponenten und deren individuelle Module
Nach der Implementation wird es drei Kompilier-Alternativen des DemaqSystems geben. Diese werden in Abbildung 2 gruppiert nach der Komponentenzugehörigkeit dargestellt. Außerdem werden die Module dargestellt, die für diese
Komponenten individuell zum Einsatz kommen.
Für die Regelauswertung mit Saxon wird NATIX zur Steuerung des Kontrollflusses verwendet, wie in Kapitel 4.2.3 ausführlich diskutiert werden wird. Eine
Kompilierung mit NATIX als Nachrichtenspeicher und der DB2-XQuery-Engine
als Regelauswerter wird nicht betrachtet.
In den folgenden Kapiteln werden die Varianten detaillierter beschrieben. Dabei werden die individuellen Module der Varianten in den Gesamtkontext der
Module eingeordnet, die unverändert bleiben.
24
4.1 Demaq System-Varianten
4.1.2
Architektur
Demaq mit NATIX und Saxon
Das bisherige Demaq-Ausführungssystem benutzt folgende drei Hauptkomponenten:
Demaq Kern: Der Kern des Demaq-Systems mit den individuellen Modulen
NatixGateway, NatixRuleProcessor, NatixQueryResult und NatixActionInterpreter.
Nachrichtenspeicher: Die XML-Nachrichten werden im nativen XMLDatenbanksystem NATIX gespeichert.
Regelauswertung: Wird mit der Saxon-XQuery-Engine [30] durchgeführt.
Der Demaq-Kern beinhaltet die wesentlichen Teile des Ausführungssystems,
welche die Steuerung des Kontrollflusses übernehmen. Während des Systemstarts
werden hier zunächst die Hauptspeicherstrukturen und der Nachrichtenspeicher
initialisiert.
Abbildung 3: Schematischer Kontrollfluss im Demaq-System
Jede vom Kommunikationssystem eingehende Nachricht wird vom NatixActionInterpreter über das NatixGateway in NATIX abgespeichert. Außerdem
wird der QueueScheduler mittels einer ConsequenceList über den Eingang einer Nachricht informiert. Dieser wiederum veranlasst die Ausführung der Regeln
für die Nachricht mit dem NatixRuleProcessor, der mit Hilfe von NATIX die
25
4.1 Demaq System-Varianten
Architektur
Saxon-XQuery-Engine nutzt. Während der Auswertung kann die XQuery-Engine
über Callbacks (vgl. Abschnitt 2.2.1.4) auf den Nachrichtenspeicher zugreifen. Die
erfolgreiche Verarbeitung einer Regel liefert eine Pending Action List, die in Form
eines NatixQueryResult an den NatixActionInterpreter weitergegeben wird.
Der NatixActionInterpreter führt die ausstehenden Aktionen, wie z.B. Nachrichten in Warteschlangen einreihen oder Antworten in Kommunikationskanäle
übermitteln, aus und leitet erneut eine ConsequenceList an den QueueScheduler weiter. Auf diese Weise können mehrere iterative Durchgänge entstehen (vgl.
Abbildung 3).
Abbildung 4 zeigt das bisherige Demaq-System mit NATIX als Nachrichtenspeicher und Saxon als Regelauswerter. Die Kommunikation zwischen NatixActionInterpreter, QueueScheduler und dem RuleExecutor regeln Dispatcher,
die einer oder mehreren Warteschlangen zugeordnet sind. Die Dispatcher unterstützen Nebenläufigkeit, indem sie mit mehreren ProcessingThreads verschiedene Kommunikationsflüsse gleichzeitig steuern können.
4.1.3
Demaq mit der DB2 und Saxon
Die zweite Variante des Demaq-Systems (vgl. Abbildung 1) umfasst folgende
Komponenten:
Demaq Kern: Der Kern des Demaq-Systems mit den individuellen Modulen
DB2Gateway, NatixRuleProcessor, NatixQueryResult und NatixActionInterpreter.
Nachrichtenspeicher: Alle relevanten Daten werden im relationalen DBMS
DB2 gespeichert.
Regelauswertung: Die Regeln werden mit der Saxon-XQuery-Engine [30] ausgewertet. Die Callback-Services sind für die DB2 angepasst.
26
4.1 Demaq System-Varianten
Architektur
Abbildung 4: Bisheriges Demaq-System: Detailansicht der wichtigsten Module in den Komponenten
Die Implementierung dieser Version betrifft zwei Schnittstellen (vgl. Abbildung 4): Zum einen die funktionale Schnittstelle zwischen Demaq-Kern und Nachrichtenspeicher, die im System mit NATIX als Nachrichtenspeicher im NatixGateway implementiert ist. Zum anderen die Schnittstelle zwischen Regelauswertung und Nachrichtenspeicher, implementiert in den Callback Services.
Abbildung 5 veranschaulicht die Architektur dieser System-Variante. Im Gegensatz zu Abbildung 4 wurde das NatixGateway durch das DB2Gateway ersetzt,
um die Kommunikation mit der DB2 als Nachrichtenspeicher aus dem DemaqKern heraus zu ermöglichen. Das DB2Gateway greift dabei nicht direkt auf die
DB2 zu, sondern nutzt die Funktionalitäten der Klasse DB2Transaction, die im
Wesentlichen eine Fassade [42] für den Nachrichtenspeicher darstellt.
27
4.1 Demaq System-Varianten
Architektur
Abbildung 5: Demaq-System mit der DB2 und Saxon : Detailansicht der wichtigsten Module
in den Komponenten
Bei der Regelauswertung wird NATIX zur Steuerung von Saxon verwendet.
Damit die Callback Services weiterhin auf den Nachrichtenspeicher zugreifen können, müssen diese entsprechend angepasst werden. Außerdem muss NATIX selbst
erweitert werden, um Zugang zu den Nachrichten in der DB2 zu bekommen. Auf
diese Weise kann der Rest des Demaq-Systems unverändert gegenüber der aktuellen Version bleiben, d.h. beispielsweise der NatixRuleProcessor, das NatixQueryResult und der NatixActionInterpreter können wie bisher verwendet werden.
28
4.1 Demaq System-Varianten
4.1.4
Architektur
Demaq mit der DB2
Die dritte Variante des Demaq-Systems (vgl. Abbildung 1) benutzt folgende Komponenten:
Demaq Kern: Der
Modulen
Kern
DB2Gateway,
des
Demaq-Systems
DB2RuleProcessor,
mit
den
individuellen
DB2QueryResult
und
DB2ActionInterpreter.
Nachrichtenspeicher: Alle relevanten Daten werden im relationalen DBMS
DB2 gespeichert.
Regelauswertung: Die XQuery-Engine der DB2 wird zur Regel-Auswertung
benutzt. Die Callback-Services sind für die DB2 angepasst.
Im Vergleich zu der vorhergehenden Version mit der DB2 und Saxon
muss zunächst die Schnittstelle zur Regelauswertung (NatixRuleProcessor)
ausgetauscht werden. Allerdings könnte in Weiterentwicklungen ein Fallback Mechanismus implementiert werden, der Saxon in den Fällen zur Regelauswertung benutzt, in denen die Regel von der DB2 nicht ausgewertet werden kann
(z.B. wenn XQuery-Module importiert oder Funktionen deklariert werden; vgl.
Abschnitt 2.3.2.2).
Außerdem müssen das NatixQueryResult und der NatixActionInterpreter
durch angepasste Varianten ersetzt werden, die auf die DB2 abgestimmt sind.
Die Schnittstelle zum Nachrichtenspeicher (DB2Gateway) kann von der zweiten
System-Version (siehe Kapitel 4.1.3) übernommen werden. In Abbildung 6 wird
das System schematisch mit den Modulen dargestellt.
Der NatixRuleProcessor wird im Demaq-Quelltext nur in einer Klasse aufgerufen (RuleExecutor). Dort wird er erzeugt und zur Regelauswertung eingesetzt.
Dabei enthält der NatixRuleProcessor außer der Funktion executeRule() keine weiteren wesentlichen Funktionen. Aus diesem Grund kann die Implementierung mit wenig Aufwand über eine Vererbungshierarchie geregelt werden: Der
29
4.1 Demaq System-Varianten
Architektur
Abbildung 6: Demaq-System mit der DB2 : Detailansicht der wichtigsten Module in den Komponenten
RuleProcessor wird als Oberklasse verwendet und an zwei Unterklassen NatixRuleProcessor und DB2RuleProcessor vererbt. Auf diese Weise kann im RuleExecutor die Regelauswertung in gleicher Weise sowohl mit NATIX als auch
mit der DB2 als Regelauswerter vorgenommen werden. Außerdem wird es ermöglicht einen NatixRuleProcessor sowie einen DB2RuleProcessor parallel in
einem System ausführen zu können.
Nach der Regelauswertung mit NATIX oder der DB2 werden strukturell unterschiedliche Ergebnisse zurückgeliefert (siehe Kapitel 6.2). Deshalb werden die
Klassen, die für die Weiterverarbeitung des QueryResults zuständig sind ebenfalls angepasst. Analog zum RuleProcessor wird eine Vererbungsstruktur gewählt, damit die Handhabung für alle Versionen gleich ist und verschiedene
30
4.2 Module
Architektur
Abbildung 7: Detailansicht der Vererbungshierarchien im Kontext der Kontrollflüsse im DemaqKern
Regelauswerter parallel in einem System eingesetzt werden können. Entsprechend wird eine Klasse QueryResult umgesetzt, die an die individuellen Klassen
DB2QueryResult und NatixQueryResult vererbt. Außerdem wird eine Basisklasse ActionInterpreter implementiert, von der die Klassen NatixActionInterpreter und DB2ActionInterpreter erben. Die Vererbungshierachien (gestrichelte Pfeile) werden in Abbildung 7 im Ablaufschema im Demaq-Kern dargestellt.
Die Query-Auswertung mit der DB2 über NATIX abzuwickeln bringt keine
Vorteile mit sich. Zudem würde dies das System von NATIX abhängig machen.
Aus diesem Grund wird von dieser Architekturvariante abgesehen.
4.2
Module
Module werden von den Komponenten benutzt. Es kann sich dabei um Klassen
innerhalb von Komponenten oder Funktionseinheiten handeln. Beispielsweise besteht der DB2 Nachrichtenspeicher aus zwei Modulen (Funktionseinheiten): Der
Datenbank DB2 und der DB2-Fassade mit der Klasse DB2Transaction.
Die Module können den in dieser Arbeit beschriebenen Varianten des DemaqSystems nicht eindeutig zugeordnet werden. Sie werden wiederverwendet und sind
abhängig von den benutzten Komponenten, müssen aber nicht zu diesen gehören.
31
4.2 Module
Architektur
Als Beispiel: Das Modul DB2Gateway (Schnittstelle zum Nachrichtenspeicher) ist
abhängig von der Komponente ”Nachrichtenspeicher“, gehört aber zu der Komponente ”Demaq-Kern“.
In diesem Kapitel werden die Module nicht vollständig beschrieben, sondern
bestimmte Aspekte detailliert beleuchtet, welche für die Ziele dieser Diplomarbeit
entscheidend sind.
4.2.1
DB2-Datenbankmodul: Konzeptuelles Design
Auf Grundlage des bereits vorhandenen Demaq Handbuches [46] können die Gegenstände, Beziehungen und Attribute für das ER-Modell [31] identifiziert werden. Darauf aufbauend kann das entsprechende Schema entwickelt werden.
Abbildung 8 zeigt einen möglichen Entwurf, der die Daten im Demaq-System
übersichtlich darstellt und miteinander in Beziehung setzt. Als Besonderheit werden hierbei zwei Generalisierungen modelliert: Sowohl Queues als auch Slicings
sind Container für Nachrichten (Message Container ); und Basic- sowie GatewayQueues gehören zu den Warteschlangen (Queues). Weiterhin ist noch zu beachten, dass einem Slicing genau eine Property-Definition zugeordnet ist, während
einem Nachrichtencontainer (und folglich auch den Nachrichten) beliebig viele
Property-Definitionen zugewiesen sein können. Der Wert (Value) eines Properties jedoch ist immer genau einer Nachricht zugeordnet.
4.2.2
Schnittstelle zum Nachrichtenspeicher
Der Zugriff auf den Nachrichtenspeicher muss derart angepasst werden, dass
mit einer Kompilier-Option wahlweise mit NATIX oder der DB2 als Speicher
kompiliert werden kann. Dementsprechend bieten sich vier in Frage kommende
Entwicklungs-Alternativen:
• das NATIX-Interface wird auch für die DB2 abgebildet
32
4.2 Module
Architektur
Abbildung 8: Das ER-Modell vom Demaq-System
• an jeder Stelle im Quelltext, an der NATIX-spezifischer Code auftaucht
wird mit #ifdefs wahlweise DB2-spezifischer Code eingefügt
33
4.2 Module
Architektur
• die bisherige Schnittstelle (NatixGateway) wird unabhängig vom Nachrichtenspeicher entworfen und entsprechend neu implementiert
• die bisherige Schnittstelle wird beibehalten und kann mit einem typedef
entweder als NatixGateway oder als DB2Gateway kompiliert werden. Die
Deklaration des typedefs wird über eine Makrovariable gesteuert, die in
der Datei configure.ac gesetzt wird.
Das NATIX-Interface nachzubauen ist nicht geeignet, da der Aufwand hierfür
im Rahmen einer Diplomarbeit nicht zu bewerkstelligen ist. Diese Option kann
für zukünftige Weiterentwicklungen in Erwägung gezogen werden.
Der übermäßige Gebrauch von #ifdefs im Quelltext führt zur Unlesbarkeit
bzw. Unbeherrschbarkeit des Codes, im besonderen, wenn in Zukunft weitere
Alternativen für den Nachrichtenspeicher integriert werden. Aus diesem Grund
wird von dieser Variante der Implementierung abgesehen. Zusätzlich läuft sie
der Modularisierung entgegen, die eine möglichst hohe Flexibilität mit Blick auf
zukünftige Untersuchungen garantieren soll (vgl. Kapitel 3.3.2).
Eine Neuimplementierung der NATIX-Schnittstelle wäre bei einer starken
Ausrichtung auf diesen Nachrichtenspeichertyp notwendig. Dies ist aber nicht der
Fall, da in den Funktionssignaturen des NatixGateways kein NATIX-spezifischer
Code vorkommt. Als beste Wahl bietet sich demnach die dargestellte Alternative
mit einem typedef an.
4.2.3
Schnittstelle zur Regelauswertung: Saxon
In dieser Version des Demaq-Systems soll die Regelauswertung weiterhin mit
Saxon ausgeführt werden. Demnach gibt es für die Realisierung zwei Optionen:
• die Regelauswertung mit Saxon wird neu implementiert
• der Teil von NATIX, der die Regelauswertung im aktuellen System durchführt, wird weiterverwendet und eine Zugriffsmöglichkeit aus NATIX auf
34
4.2 Module
Architektur
Tabelle 2: Erweiterung der Fragment/View -Matrix von Seite 8
die DB2 wird ergänzt
In dem ersten Fall, dass NATIX bei der Regelauswertung nicht mehr eingesetzt
wird, müsste die Regelauswertung noch einmal vollständig neu implementiert
werden. Dies wäre mit einem hohen Aufwand verbunden, da z.B. die Query Vorbereitung, die Callback -Funktionalität und das Parsen der XML-Dokumente
erneut umgesetzt werden müsste.
Auf der anderen Seite ist die gesamte Funktionalität zur Regelauswertung
mit Saxon bereits im NATIX-System integriert. Dabei werden von NATIX die
Konzepte der Fragmente und Sichten (vgl. Abschnitt 2.2.1) genutzt, die sich leicht
um zusätzliche Quellen für XML-Daten erweitern lassen. So kann einfach ein
Fragmenttyp DB2Document realisiert werden, der in verschiedenen Sichten geöffnet
werden kann (vgl. Tabelle 2). Auf diese Weise kann die Regelauswertung von
NATIX wiederverwendet werden, ohne an dem Ablauf selbst etwas zu ändern.
Nur die Behandlung der Callback -Funktionalität (vgl. auch Kapitel 2.2.1.4) ist
hierbei anzupassen. Zu diesem Zweck müssen die Callback-Services innerhalb der
Datei saxonxqueryquerystreamviewfactory.cc so geändert werden, dass sie
über SQL-Ausdrücke, die an die DB2 weitergeleitet werden, die gewünschten
35
4.2 Module
Architektur
Daten liefern. Beispielsweise könnte folgendes Sprachkonstrukt:
(:
...
2
:)
qs : queue ( ’ queue1 ’ )
(:
...
:)
innerhalb des Callback-Handler s mit folgendem SQL-Statement an die DB2 weitergeleitet werden:
1
SELECT message
FROM me ssa g es
3
WHERE queuename= ’ queue1 ’ ;
und das Ergebnis an Saxon zurückgeliefert werden. Auf diese Weise können für alle Demaq-spezifischen Sprachkonstrukte die Callback-Services für die DB2 implementiert werden. Über eine Kompilier-Option kann dann die Datei saxonxqueryquerystreamviewfactory.cc wahlweise für die DB2 oder NATIX kompiliert
werden.
Aus diesem Grund wird von einer Neuimplementierung der Regelauswertung
mit Saxon abgesehen, da diese sehr arbeitsintensiv wäre, aber ansonsten keine
weiteren Vorteile hätte. Stattdessen wird die Regelauswertung von NATIX wiederverwendet, die um einen Fragmenttyp DB2Document erweitert wird.
4.2.4
DB2-Fassade
Die Implementierung der Funktionen zum Zugriff auf die DB2 wird in einer Fassade [42] als eigenständige Shared Library umgesetzt. Hierbei macht es die geplante
Realisierung der Integration der DB2 in das Demaq-Ausführungssystem notwendig, dass sowohl das Demaq-System selbst als auch NATIX auf das relationale
DBMS zugreifen können (vgl. Kapitel 4.2.3). Würde der verwendete Code innerhalb des NATIX-Projektes angesiedelt werden, so wäre Demaq immer abhängig
von NATIX, auch wenn das System mit der DB2 als Nachrichtenspeicher und
Regelauswerter kompiliert würde. Auf der anderen Seite könnte die Funktionali36
4.2 Module
Architektur
Abbildung 9: Abhängigkeiten von Komponenten und Modulen im Demaq-System. (a) Durch
Integration der Kommunikation mit der DB2 in den Demaq-Kern entstehen zyklische Abhängigkeiten. (b) Als eigenständiges Projekt können die zyklischen Abhängigkeiten aufgelöst werden.
tät zum Zugriff auf die DB2 voll in das Demaq-Projekt integriert werden. Dann
allerdings würde sich eine zirkuläre Abhängigkeit ergeben. In diesem Fall wäre
NATIX abhängig vom Demaq-Code und umgekehrt auch der Demaq-Kern abhängig von NATIX, da NATIX zur Regelauswertung benutzt wird. Aus diesem
Grund muss die Funktionalität der DB2 als eigenständiges Modul ausgegliedert
werden (wie in Abbildung 9 dargestellt).
4.2.5
DB2-Datenbankmodul: Varianten der Abbildung von Slices
Grundsätzlich existieren zwei Varianten, auf welche Weise Slicings im DemaqSystem behandelt werden. In der ersten Variante werden die Slicing-Definitionen
vom DQL-Compiler durch Rewrites ersetzt. Hierdurch werden Slicings als Queues
mit einem Property aufgefasst. In diesem Fall werden alle Slicing-Properties in der
Tabelle für Warteschlangen-Properties gespeichert und nicht gesondert behandelt.
In der zweiten Variante werden Slices nativ verarbeitet, d.h. für sie wird gesondert Speicherplatz zur Verfügung gestellt. Folglich kann die Behandlung der
Slices isoliert optimiert werden, wodurch die Effizienz erhöht werden kann. Da
37
4.2 Module
Architektur
die Optimierung des Leistungsverhaltens eine Anforderung dieser Diplomarbeit
ist (vgl. Kapitel 3.3.3), wird eine native Unterstützung implementiert. Vorschläge
für mögliche Abbildungen von Slices werden in Kapitel 5.1.5 vorgestellt.
38
Feinentwurf
5
Feinentwurf
In diesem Kapitel werden die konzeptionellen Entwürfe aus Kapitel 4 auf logischer
Ebene betrachtet und detailliert verfeinert. Dabei werden die Anforderungen und
Ziele aus Kapitel 3 weiter verfolgt.
Die Enwürfe auf logischer Ebene werden bezogen auf die zu entwickelnden
Varianten vorgestellt. Zunächst wird das Demaq-System mit der DB2 und Saxon
(Kapitel 5.1) und anschließend das System, das die DB2 auch zur Regelauswertung verwendet (Kapitel 5.2), betrachtet.
5.1
Demaq mit der DB2 und Saxon
In der System-Variante von Demaq mit der DB2 als Nachrichtenspeicher und
Saxon als Regelauswerter werden neben allen Nachrichten, auch alle sonstigen
relevanten Daten, wie beispielsweise Properties oder Rules, in der DB2 gespeichert. Eine mögliche relationale Modellierung der Daten wird in diesem Kapitel
vorgestellt. Zu diesem Zweck wird das bereits entworfene ER-Diagramm (vgl.
Abschnitt 4.2.1) in ein logisches Schema (in DDL) überführt. Dafür schlägt [31]
vor, zunächst jede Entität und Beziehung als eigene Relation zu berücksichtigen.
Nachdem dies in Kapitel 5.1.1 erfolgt ist, werden in Abschnitt 5.1.2 Verfeinerungen an dem Schema vorgenommen, um überflüssige Relationen und Redundanzen
zu bereinigen. Anschließend wird in Abschnitt 5.1.3 das verfeinerte Schema teilweise noch einmal überarbeitet, um es den Gegebenheiten im aktuellen DemaqSystem anzupassen.
In Kapitel 5.1.4 werden verschiedene Varianten für die Abbildung der
Nachrichten-Warteschlangen des Demaq-Systems auf ein relationales Model vorgestellt. Die Möglichkeiten bei der Umsetzung sind allerdings sehr umfangreich,
so dass kein Anspruch auf Vollständigkeit erhoben werden kann. Vielmehr sollen die vorgestellten Varianten verschiedene Denkansätze illustrieren und somit
mögliche Richtungen für Weiterentwicklungen aufzeigen.
39
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Nachdem die Datenmodellierung abgehandelt wurde, werden in Kapitel 5.1.6
die Änderungen des Quelltextes im Demaq-Kern besprochen. Da in dieser SystemVariante NATIX weiterverwendet wird (vgl. Abschnitt 4.2.3), befasst sich Abschnitt 5.1.7 mit den Erweiterungen im NATIX-Code, die notwendig sind, um
mithilfe der NATIX-Konzepte (vgl. Kapitel 2.2.1) auf Daten in der DB2 zugreifen zu können. Abschließend beleuchtet Kapitel 5.1.8 die Implementierung der
DB2-Fassade, die unabhängig von Demaq und NATIX umgesetzt wird (vgl. Abschnitt 4.2.4).
5.1.1
Überführung des ER-Diagramms in ein logisches Schema
Anhand des modellierten ER-Diagramms (vgl. Abbildung 8 auf Seite 33) werden
alle Entitäten und Beziehungen in Relationen überführt. Es ergeben sich hieraus
die im Folgenden dargelegten Tabellen-Definitionen für Daten im Demaq-System.
5.1.1.1
Regeln Regeln bestehen aus einem eindeutigen Namen, über den
sie identifiziert werden, sowie einem gültgen XQuery-Ausdruck. Der XQueryAusdruck ist hierbei nicht in seiner Länge beschränkt. Deshalb wird für diesen
der Datentyp CLOB gewählt.
1 create table r u l e s (
name
3
varchar ( 2 5 5 )
expression
clob
not null ,
not null ,
primary key ( name )
5 );
5.1.1.2
Warteschlangen Warteschlangen werden durch ihren Namen iden-
tifiziert. Des Weitern kann ihnen eine Priorität zugeordnet werden, die derzeit
noch nicht im Demaq-System berücksichtigt wird. Der mode einer Warteschlange
ist entweder transient oder persistent, wobei aktuell alle Queues persistenziert
werden. Der Typ der Warteschlange wird im Attribut kind festgehalten. Er kann
40
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
entweder basic, incoming oder outgoing sein. Der port ist die Anschlussadresse,
die die Kommunikation über ein Netzwerk mit der Warteschlange erlaubt (nur bei
den Gateway-Typen incoming und outgoing). Das interface legt für GatewayQueues das zugehörige Protokoll für die Kommunikation über ein Netzwerk fest,
möglich sind beispielsweise SMTP oder HTTP.
1 create table queues (
name
3
varchar ( 2 5 5 )
not null ,
p r i o r i t y smallint not null default 0 ,
−− mode : 0= p e r s i s t e n t ,1= t r a n s i e n t
5
mode
smallint not null default 0
check ( mode in ( 0 , 1 ) ) ,
−− k i n d : 0=b a s i c ,1= incoming ,2= o u t g o i n g
7
9
kind
smallint not null default 0
port
int
check ( kind in ( 0 , 1 , 2 ) ) ,
not null check ( p o r t between 1024 and 6 5 5 3 5 ) ,
interface
varchar ( 5 1 2 )
not null default ’ h t t p : / / ’ ,
primary key ( name )
11 ) ;
5.1.1.3
Nachrichten Nachrichten können über eine ID eindeutig über alle
Warteschlangen hinweg identifiziert werden. Die Nachricht selbst wird im XMLFormat gespeichert. Ihr Zustand (state) kann entweder enqueued oder deleted
sein, da im Modus Persistent Nachrichten nur als gelöscht markiert, aber nicht
tatsächlich physisch gelöscht werden.
1 create table me ssa g es (
3
i d int
not null ,
message
xml
not null ,
−− s t a t e : 0=enqueued ,1= d e l e t e d
5
s t a t e smallint not null default 0
primary key ( i d )
7 );
41
check ( s t a t e in ( 0 , 1 ) ) ,
5.1 Demaq mit der DB2 und Saxon
5.1.1.4
Feinentwurf
Eigenschaften Eigenschaften (Properties) zeichnen sich durch einen
eindeutigen Namen aus und haben einen Typ, der einem Datentyp des XQuery
Datenmodells [10] entspricht. Falls nicht explizit ein Datentyp für eine Eigenschaft
angegeben wird, wird der Typ implizit auf xs:anyType gesetzt.
1 create table p r o p e r t i e s (
3
name
varchar ( 2 5 5 )
not null ,
type
varchar ( 2 5 5 )
not null default ’ xs : anyType ’ ,
primary key ( name )
5 );
5.1.1.5
Slicings Slicings werden über einen eindeutigen Namen gekennzeich-
net.
1 create table s l i c i n g s (
s l i c i n g n a m e varchar ( 2 5 5 )
3
not null ,
primary key ( s l i c i n g n a m e )
);
5.1.1.6
Schemata Ein XML-Schema wird durch seine zugewiesene eindeuti-
ge URI identifiziert. Das eigentliche Schema ist im XML-Format speicherbar.
create table schema (
2
uri
varchar ( 5 1 2 )
schema
4
xml
not null ,
not null ,
primary key ( u r i )
);
5.1.1.7
Beziehung Warteschlangen-Regel Jeder Warteschlange können
mehrere Regeln zugeordnet werden. Eine Regel kann aber nur einer Queue zugeordnet sein. Regeln und Warteschlangen werden jeweils durch ihre Namen repräsentiert.
42
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
1 create table q u e u e r u l e (
rulename varchar ( 2 5 5 )
3
queuename
not null ,
varchar ( 2 5 5 )
not null ,
primary key ( rulename , queuename )
5 );
5.1.1.8
Beziehung Slicing-Regeln Jedem Slicing können mehrere Regeln
zugeordnet werden. Umgekehrt kann eine Regel aber nur einem Slicing zugeordnet sein. Außerdem kann eine Regel nur entweder auf einer Queue oder einem
Slicing definiert sein. In der Beziehung Slicing-Regeln werden Regeln und Slicings
jeweils durch ihren Namen repräsentiert.
1 create table q u e u e r u l e (
rulename varchar ( 2 5 5 )
3
not null ,
s l i c i n g n a m e varchar ( 2 5 5 )
not null ,
primary key ( rulename , queuename )
5 );
5.1.1.9
Beziehung
Warteschlange
zu
Antwort-Warteschlange
Gateway-Queues haben maximal genau eine Antwort-Warteschlange, so dass
requestqueue als Primärschlüssel verwendet werden kann. Eine Antwort-Queue
kann nur einmal als solche verwendet werden. Deshalb muss responsequeue
eindeutig (unique) sein.
1 create table r e s p o n s e q u e u e (
3
requestqueue
varchar ( 2 5 5 )
not null ,
responsequeue
varchar ( 2 5 5 )
not null ,
primary key ( r e q u e s t q u e u e ) ,
5
unique
( responsequeue )
);
43
5.1 Demaq mit der DB2 und Saxon
5.1.1.10
Feinentwurf
Beziehung -Warteschlange zu Regeln Zu jeder Regel kann eine
Queue zur Behandlung von Errors bestimmt werden. Eine Error-Warteschlange
kann aber zu mehreren Regeln zugeordnet sein. Deshalb kann der Regelname in
dieser Beziehung als Primärschlüssel verwendet werden.
create table h a n d l e e r r o r (
2
rulename varchar ( 2 5 5 )
queuename
4
not null ,
varchar ( 2 5 5 )
not null ,
primary key ( rulename )
);
5.1.1.11
Beziehung Schema zu Warteschlangen Diese Beziehung stellt
eine optionale Zuordnung eines Schemas zur Nachrichten-Validierung einer oder
mehrerer Warteschlangen dar.
1 create table queue schema (
3
schemauri
varchar ( 2 5 5 )
not null ,
queuename
varchar ( 2 5 5 )
not null ,
primary key ( queuename )
5 );
5.1.1.12
Beziehung Nachricht-Warteschlange Jede Nachricht muss ge-
nau einer Warteschlange zugeordnet sein. Hieraus folgt, dass msgid als Primärschlüssel eingesetzt werden kann.
1 create table msg queue (
3
msgid int
not null ,
queuename
varchar ( 2 5 5 )
not null ,
primary key ( msgid )
5 );
5.1.1.13
Beziehung Eigenschaftswerte-Nachricht Nachrichten können
keine, eine oder mehrere Properties besitzen. Für jede Nachricht werden alle Ei44
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
genschaftswerte in dieser Tabelle gespeichert. Da der Wert für jede Nachricht
anders sein kann, wiederholen sich die Eigenschaftsnamen häufig. Demnach existiert keine Spalte, die eindeutig ist. Als Primärschlüssel eignen sich aber die
Spalten propertyname und msgid. Der Wert einer Eigenschaft kann atomar oder
vom Typ XML sein und ist grundsätzlich nicht beschränkt. Deshalb wird für
zugehörige Spalte der Datentyp CLOB gewählt.
1 create table m s g p r o p e r t y (
propertyname
3
5
varchar ( 2 5 5 )
msgid int
not null ,
value clob
not null ,
not null ,
primary key ( propertyname , msgid )
);
5.1.1.14
Beziehung Eigenschaften-Warteschlangen Die Definitionen für
Eigenschaften, welche die Auswertung der Werte für einzelne Nachrichten bestimmen, werden in dieser Tabelle gespeichert. Dabei können die Eigenschaften
mit gleichem Namen und unterschiedlichen Definitionen verschiedenen Warteschlangen zugeordnet sein. Deshalb kommen als Primärschlüssel nur die Spalten
queuename und propertyname gemeinsam in Frage.
Die valueexpression ist ein XQuery-Ausdruck, der definiert, wie der Wert
der Eigenschaft auszuwerten ist. Dieser XQuery-Ausdruck ist in der Länge nicht
beschränkt. Aus diesem Grund wird für die Spalte valueexpression der Datentyp CLOB gewählt.
create table q u e u e p r o p e r t y (
2
queuename
varchar ( 2 5 5 )
propertyname
4
valueexpression
not null ,
varchar ( 2 5 5 )
not null ,
clob not null ,
−− f i x e d : 0= f a l s e ,1= t r u e
6
f i x e d smallint not null default 0
−− i n h e r i t e d : 0= f a l s e ,1= t r u e
45
check ( f i x e d in ( 0 , 1 ) ) ,
5.1 Demaq mit der DB2 und Saxon
8
inherited
Feinentwurf
smallint not null default 0
check ( i n h e r i t e d in ( 0 ,
1) ) ,
primary key ( queuename , propertyname )
10 ) ;
5.1.1.15
Beziehung Eigenschaft-Slicing Einem Slicing muss genau ein
Property aus der Tabelle queue_property als Slicing-Property zugeordnet werden.
create table s l i c i n g p r o p e r t y (
2
s l i c i n g n a m e varchar ( 2 5 5 )
propertyname
4
not null ,
varchar ( 2 5 5 )
not null ,
primary key ( s l i c i n g n a m e )
);
5.1.2
Verfeinerung der DDL
Relationen können unter bestimmten Bedingung zusammengefasst werden [31].
Die daraus resultierenden Verfeinerungen für die Tabellen-Definitionen werden
in diesem Kapitel dargestellt. Auf Tabellen, die nicht weiter verfeinert werden
können, wird im Folgenden nicht weiter eingegangen.
5.1.2.1
Zusammenfassung Regeln und Error-Queues
Da für jede Regel
nur eine oder keine Error-Queue definiert ist, können die beiden betreffenden
Tabellen zusammengefasst werden. Die Tabelle handle_error fällt demnach weg
bzw. wird in die Tabelle rules integriert:
1 create table r u l e s (
name
3
varchar ( 2 5 5 )
expression
clob
not null ,
not null ,
errorqueuename varchar ( 2 5 5 ) ,
5
primary key ( name )
);
46
5.1 Demaq mit der DB2 und Saxon
5.1.2.2
Zusammenfassung
Feinentwurf
Warteschlangen
mit
der
Queue-
Resonsequeue-Beziehung Da es zu jeder Warteschlange maximal eine
Antwort-Warteschlange gibt, kann die Tabelle für die Zuordnung der AntwortWarteschlange in die Warteschlangentabelle integriert werden:
create table queues (
2
name
varchar ( 2 5 5 )
not null ,
p r i o r i t y smallint not null default 0 ,
−− mode : 0= p e r s i s t e n t ,1= t r a n s i e n t
4
mode
smallint not null default 0
check ( mode in ( 0 , 1 ) ) ,
−− k i n d : 0=b a s i c ,1= incoming ,2= o u t g o i n g
6
8
kind
smallint not null default 0
port
int
check ( p o r t between 1024 and 6 5 5 3 5 ) ,
interface
10
check ( kind in ( 0 , 1 , 2 ) ) ,
varchar ( 5 1 2 ) ,
responsequeue
varchar ( 2 5 5 ) ,
primary key ( name )
12 ) ;
5.1.2.3
Zusammenfassung
Nachrichten
und
Nachricht-
Warteschlange-Beziehung Jede Nachricht, repräsentiert durch ihre eindeutige ID, kann nur in genau einer Warteschlange enthalten sein. Wird sie in eine
weitere Warteschlange eingereiht, bekommt sie eine neue eindeutige ID. Auf
diese Weise kann sie immer genau einer Warteschlange zugeordnet werden.
create table me ssa g es (
2
i d int
not null ,
queuename
4
message
varchar ( 2 5 5 )
xml
not null ,
not null ,
−− s t a t e : 0=enqueued ,1= p r o c e s s e d
6
s t a t e smallint not null default 0
primary key ( i d )
8 );
47
check ( s t a t e in ( 0 , 1 ) ) ,
5.1 Demaq mit der DB2 und Saxon
5.1.2.4
Zusammenfassung
von
Feinentwurf
Slicings
und
Slicing-Property-
Beziehung Jedes Slicing in Demaq ist genau auf einem Property definiert.
Deshalb ist keine eigenständige Beziehung für die Zuordnung der Slicings zu
Properties notwendig. Die Tabellen slicings und slicing_property können
so zu folgender Tabelle zusammengefasst werden:
create table s l i c i n g s (
2
s l i c i n g n a m e varchar ( 2 5 5 )
propertyname
4
varchar ( 2 5 5 )
not null ,
not null ,
primary key ( s l i c i n g n a m e )
);
5.1.2.5
Wegfall Schemata und Schema-Queue-Beziehung Eine Validie-
rung von eingereihten Nachrichten anhand eines Schemas wird von Demaq derzeit
noch nicht unterstützt. Außerdem gibt es in der DB2 das XML Schema Repository, das die Validierung von XML-Daten mithilfe eines XML-Schemas automatisch
vornehmen kann [27]. So kann eine Validierung von Nachrichten auf einfache Weise erfolgen, ohne eine eigene Verwaltung implementieren zu müssen. Die Tabellen
zur Schema-Validierung können deshalb wegfallen.
5.1.3
Weitere Anpassungen des logischen Designs
In diesem Abschnitt werden noch einmal Änderungen am logischen Design vorgenommen. Zum einen sind Anpassungen an Gegebenheiten des bisherigen DemaqSystems notwendig (Abschnitt 5.1.3.1). Zum anderen sind Besonderheiten mit
der DB2 als Nachrichtenspeicher zu beachten (Abschnitt 5.1.3.2).
5.1.3.1
Anpassungen an das Demaq-Ausführungssystems Einige Da-
ten, die im ER-Diagramm als Attribute modelliert wurden und somit als DatenSpalte in einer der Relationen definiert wurden, werden im aktuellen DemaqAusführungssystem als Properties gespeichert. Demnach können folgende Spalten
48
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
weggelassen werden:
Tabelle Warteschlangen: Die Daten in den Spalten priority, kind,
port, interface und responsequeue werden in der Tabelle queue_property
als Property einer Warteschlange gespeichert.
Tabelle
Regeln: Die
Regeln
und
die
Zuordnungen
von
Error-
Warteschlangen zu Regeln werden als Properties gespeichert. Deshalb kann
die Tabelle Regeln weggelassen werden. Ebenso wird die Tabelle queue_rule
überflüssig.
5.1.3.2
Anpassungen an DB2
Um eine Nachricht aus der DB2 zu laden,
muss bekannt sein, welche Länge diese Nachricht hat, da die Verbindung standardmäßig einen Buffer mit begrenzter Größe (32767) verwendet [33]. Ist die
Nachricht länger als diese Standardgröße, so wird sie ohne Fehlermeldung nur
zum Teil übertragen. Deshalb muss die Größe des Buffer s ab einer bestimmten
Nachrichtenlänge explizit vergrößert werden.
Die Länge von XML-Daten kann von DB2 allerdings nicht festgestellt werden,
ohne diese zu serialisieren. Da dies ein hoher Aufwand ist, wird die Länge jeder
Nachricht bereits beim übertragen an die Datenbank in einer zusätzlichen Spalte
messagesize in der messages-Tabelle gespeichert.
5.1.4
Varianten der Warteschlangenabbildung
In Demaq werden Warteschlangen (Queues) nach dem FIFO-Prinzip bearbeitet.
Eine Einhaltung des Prinzips wird aber nicht garantiert, um dem System bei
der Ausführung Freiheitsgrade zur Optimierung einzuräumen. Auf diese Weise
muss das System nicht auf die abschließende Abarbeitung einer Nachricht warten,
sondern kann schon mit der Bearbeitung der nächsten Nachricht beginnen.
49
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 10: Implementierung einer Warteschlange [9]. (a) Implementierung in einem Array.
(b) Implementierung als verkettete Liste
Warteschlangen können auf verschiedene Art und Weise implementiert werden. Beispielsweise schlägt [9] die Implementierung in einem Array oder als verkettete Liste vor (vgl. Abbildung 10). Allerdings können derartige native Datenstrukturen in einem relationalen DBMS nicht verwendet werden. Folglich stellt
sich die Frage, ob ähnliche Datenstrukturen über Relationen nachzubilden ist
oder ob es besser ist, einen grundsätzlich abweichenden Ansatz zu wählen.
Das Ziel dieser Diplomarbeit ist es, die DB2 in das Demaq-Ausführungssystem
zu integrieren. Dabei spielt das Leistungsverhalten eine wichtige Rolle (vgl. Abschnitt 3.3.3). Aus diesem Grund soll eine effiziente Abbildung für Warteschlangen in einer relationalen Datenbank gefunden werden. Dementsprechend werden
in diesem Kapitel beispielhaft mehrere unterschiedliche Abbildungsmöglichkeiten vorgestellt. Auf der Grundlage von theoretischen Bewertungsaspekten wird
eine Auswahl der Abbildungsvarianten getroffen, die in geeigneten Experimenten innerhalb des Demaq-Ausführungssystems auf ihre Leistungsfähigkeit getestet
werden sollen (siehe Kapitel 7.2). Die Varianten mit ihren Bewertungsaspekten
werden in einer tabellarischen Übersicht in Kapitel 5.1.4.8 zusammengefasst.
Aufgrund der besseren Übersichtlichkeit werden die vorgestellten Möglichkeiten der Warteschlangenabbildung in den Abschnitten auf physischer Ebene opti-
50
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
miert. Obwohl die physische Optimierung über eine logische Betrachtung hinausgeht, soll auf diese Weise die Lesbarkeit gewahrt bleiben, indem eine allzu Große
Fragmentierung vermieden wird. Dieses Kapitel fällt somit im Hinblick auf die
Gesamtstruktur dieser Arbeit aus dem Rahmen.
5.1.4.1
Variante 1: Einfache Relation Die erste Variante ist die einfachste
Implementierung, um Warteschlangen in einem relationalen DBMS abzubilden.
Dabei wird die Abbildung mithilfe einer einfachen Relation umgesetzt, in der alle
Daten der Warteschlangen gespeichert werden.
Logischer Entwurf: In der Tabelle, in der die Daten der Warteschlangen gespeichert werden, wird eine Spalte mit einer Identifikation (ID) benötigt,
mit der eine Nachricht eindeutig (über alle Warteschlangen hinweg) identifiziert
werden kann. Aus diesem Grund können alle eingehenden Nachrichten unter Zuhilfenahme einer Sequence durchnummeriert werden. Gleichzeitig kann hierdurch
die zeitliche Reihenfolge des Eingangs der Nachrichten festgehalten werden, da
die Sequence die IDs in aufsteigender Reihenfolge vergibt. Die Nachricht mit der
kleinsten ID ist also diejenige, die am längsten in einer Warteschlange ist und
demnach als nächstes verarbeitet werden muss. Auf diese Weise kann eine zusätzliche Spalte mit einem timestamp eingespart werden.
Des Weiteren wird eine Spalte benötigt, um in ihr den aktuellen Status (enqueued oder processed ) einer Nachricht zu speichern. Denn in dem derzeitigen
Demaq-Ausführungssystem wird nur der Modus ”persistent“ unterstützt, bei dem
verabeitete Nachrichten nicht gelöscht, sondern nur als verarbeitet (processed )
markiert werden.
Um mehrere Warteschlangen in einer Relation abzubilden, bedarf es einer
weiteren Spalte, um die Warteschlangenzugehörigkeit zu speichern. Dies kann
mit einer Spalte für den Warteschlangenname erreicht werden. Das SQL-DDLStatement zum Erzeugen der Tabelle sieht wie folgt aus:
51
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
1 create table me ssa g es (
i d int
3
not null ,
queuename
message
varchar ( 2 5 5 )
xml
not null ,
not null ,
−− s t a t e : 0=enqueued ,1= p r o c e s s e d
5
s t a t e smallint not null default 0
7
check ( s t a t e in ( 0 , 1 ) ) ,
primary key ( i d )
);
Abbildung 11: Warteschlangen als einfache Relation
Wie in Abbildung 11 dargestellt, können die Funktionen enqueue und dequeue als einfache SQL-Statements ausgedrückt werden. Dabei ist es wichtig,
dass die Funktionen isoliert voneinander ausgeführt werden, damit nicht z.B.
zwischen Schritt 1 und 2 der dequeue-Funktion in der Abbildung 11 eine andere Transaktion die gleiche Nachrichten-ID als Minimum wählt. Ansonsten wäre
es möglich, dass Nachrichten mehrmals abgearbeitet werden. Aus diesem Grund
dürfen keine dequeue-Funktionen nebenläufig auf einer Tabelle ausgeführt werden. Zu Erreichen ist dies z.B. durch die Umsetzung als Prozedur mit einem
zusammengesetzten atomaren SQL-Statement (vgl. beispielsweise [47]).
52
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Physischer Entwurf: Um den direkten Zugriff auf eine Nachricht zu beschleunigen, wird ein Index auf der Spalte für die Nachrichten-ID benötigt. In
der DB2 wird auf dem Primärschlüssel einer Relation immer implizit ein Index
angelegt [34], so dass kein Index explizit erzeugt werden muss, da die Spalte id
bereits als Primärschlüssel gekennzeichnet ist.
Um die Funktion dequeue möglichst performant auszuführen, müsste auf der
Spalte state ein Index erzeugt werden, der die Spalten queuename und id in
dieser Reihenfolge inkludiert [17]. Dies ist aber aus zwei Gründen nicht möglich
und bei genauerer Betrachtung auch nicht sinnvoll. Erstens ist die Spalte state
nicht eindeutig, so dass auf ihr kein Index definiert werden kann, der andere
Spalten inkludiert. Zweitens rechtfertigt der Aufwand zur Pflege des Index auf
der state-Spalte den Einsatz nicht. Denn bei jedem Zugriff mit dequeue auf eine
Nachricht wird deren Status von enqueued auf processed geändert und der Index
muss umstrukturiert werden.
Ein sinnvoller Index für diese Variante sollte auf der Spalte queuename erzeugt werden. Da sich die Spalte queuename für eine Nachricht nie ändert und
über sie ein Großteil der Nachrichten gefiltert werden kann, bleibt diese als beste
Alternative, um darauf einen Index zu erzeugen:
create index queuenamendx
2
on me ssa g es ( queuename ) ;
Mit jedem insert wird ein exklusiver Lock bei den enqueue-Operationen
gehalten. Obwohl die neu eingefügte Zeile nicht in der dequeue-Operation berücksichtigt werden muss, blockiert sie die Ausführung der Operation, da der
Ausdruck ”SELECT min(id)...“ auf die Freigabe der Sperre warten muss. Dies
kann verhindert werden, indem die DB2 Option DB2_SKIPINSERTED=on gewählt
wird [43]. Damit werden inserts, die noch nicht mit commit bestätigt wurden,
behandelt als würden sie nicht existieren.
In der DB2 Version für z/OS kann zusätzlich der Zusatz ”SKIP LOCKED DATA“
53
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 12: Warteschlangen als einfache Relation (optimiert)
in der dequeue-Funktion verwendet werden. Dadurch werden Datenzeilen, die
durch Update-Operationen exklusiv gesperrt sind, ignoriert und die Nebenläufigkeit kann erhöht werden [29].
Eine weitere Optimierung auf der Ebene der einzelnen SQL-Statements ist
dadurch möglich, dass diese in ein zusammengefasstes Statement überführt werden. Abbildung 12 zeigt wie die Funktionen dequeue und enqueue jeweils in
einem SQL-Ausdruck implementiert werden können. Auf diese Weise kann der
Anfrage-Optimierer der DB2 über alle Einzelausdrücke hinweg eine Optimierung
vornehmen [3].
Theoretische Bewertung: Nachteilig ist in dieser Variante, dass durch
die Update-Operation innerhalb der dequeue-Funktion auf der state-Spalte ein
exklusiver Lock gehalten wird. Dadurch wird verhindert, dass mehrere Transaktionen gleichzeitig Nachrichten mit dequeue entnehmen können. Denn ein zweiter
dequeue-Aufruf würde wieder ein Minimum selektieren, das aber nicht selektiert
werden kann, solange die exklusive Sperre besteht. Zur Lösung dieses Problems
54
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
darf an dieser Stelle kein Uncommited Read zugelassen werden. Ansonsten werden Nachrichten gelesen, die gerade mit enqueue von einer anderen Transaktion
eingefügt werden und noch nicht mit commit bestätigt wurden. In diesem Fall
würden Nachrichten weiterverarbeitet, die später potenziell durch ein rollback
wieder entfernt werden und deshalb nicht hätten weiterverarbeitet werden dürfen.
In der DB2 Version für z/OS könnte das Problem des Locks allerdings umgangen werden, indem der Zusatz ”SKIP LOCKED DATA“ verwendet wird [29].
5.1.4.2
Variante 2: Mehrere Einfache Relationen Um das Problem der
exklusiven Sperre der Variante in Kapitel 5.1.4.1 teilweise zu umgehen, können die
Sperren auf einzelne Queues beschränkt werden, indem für jede Warteschlange
eine eigene Tabelle verwendet wird.
Abbildung 13: Warteschlangen als mehrere einzelne Relationen
Logischer Entwurf: Der logische Entwurf für die Tabellen einzelner Warteschlangen entspricht im Wesentlichen dem der Variante in Kapitel 5.1.4.1, nur
55
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
dass die Spalte queuename überflüssig wird. Das SQL-DDL-Statement sieht, beispielsweise für eine Warteschlange mit dem Namen ”queue1“, wie folgt aus:
create table queue1 (
2
i d int
not null ,
message
xml
not null ,
−− s t a t e : 0=enqueued ,1= p r o c e s s e d
4
s t a t e smallint not null default 0
6
check ( s t a t e in ( 0 , 1 ) ) ,
primary key ( i d )
);
Damit auf Nachrichten nur mithilfe ihrer ID zugegriffen werden kann, muss
eine zusätzliche Tabelle verwaltet werden, in der gespeichert wird, in welcher
Warteschlange sich die Nachricht mit einer spezifischen ID befindet. Diese Tabelle
muss nur zwei Spalten enthalten: Eine für die Nachrichten-ID und eine, die den
Tabellennamen der Warteschlange enthält.
1 create table message queue (
i d int
3
queuename
not null ,
varchar ( 2 5 5 )
not null ,
primary key ( i d )
5 );
Der Zugriff mit den Funktionen enqueue und dequeue muss für jede Warteschlange individualisiert sein. Abbildung 13 zeigt wie dies durch einzelne SQLStatements umgesetzt werden kann.
Physischer Entwurf: Wie in dem physischen Entwurf der Variante in Kapitel 5.1.4.1 bereits diskutiert, muss kein zusätzlicher Index erzeugt werden, da die
einzige in Frage kommende Spalte queuename hier nicht existiert. Durch die Deklaration der Nachrichten-ID als Primärschlüssel in der Warteschlangen-Tabelle
und der Tabelle message_queue wird implizit ein Index von DB2 generiert [34].
Wie bereits in der Variante in Kapitel 5.1.4.1 ausführlich beschrieben, kann
mit der DB2 Option DB2_SKIPINSERTED=on verhindert werden, dass inserts
56
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 14: Warteschlangen als mehrere einzelne Relationen (optimiert)
blockierend wirken [43]. So können enqueue- und dequeue-Operationen nebenläufig ausgeführt werden. Allgemeiner kann mit der DB2 Version für z/OS der
Ausdruck ”SKIP LOCKED DATA“ bei der dequeue-Funktion verwendet werden [29].
Ein Uncommited Read kann aber auch in dieser Variante nicht zugelassen
werden, da ansonsten Nachrichten aus nicht abschließend mit commit bestätigten
enqueue-Operationen weiterverarbeitet werden können.
Die einzelnen SQL-Statements in den Funktionen enqueue und dequeue können wieder zusammengefasst werden (siehe Abbildung 14), um eine bessere automatische Optimierung zu erreichen [3].
Theoretische Bewertung: Der Vorteil bei der Verwaltung jeder Warteschlange in einer eigenen Tabelle ist, dass eine Filterung über den Queue-Namen
entfällt. Jedoch muss es ein zusätzliches Mapping von Nachrichten-IDs zu Warteschlangen bzw. Tabellen geben, da der eindeutige Identifikator einer Nachricht
57
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 15: enqueue und dequeue auf paarweisen Relationen
keinen Aufschluss darüber gibt, in welcher Queue sie zu finden ist. Letztendlich kann diese Variante dennoch von Vorteil sein, da erstens eine Selektion des
Minimums ausschließlich über den Index des Primärschlüssels erfolgen kann und
deshalb keine Datenseiten geladen werden müssen, um die nächste zu bearbeitende Nachricht zu finden; und zweitens eine exklusive Sperre nur eine Warteschlange
(anstatt alle Warteschlangen wie in der Variante in Kapitel 5.1.4.1) blockiert und
demnach mehrere dequeue-Operationen gleichzeitig ohne Probleme ausgeführt
werden können.
5.1.4.3
Variante 3: Paarweise Relationen Um bei dequeue-Operationen
Uncommitted Reads zu erlauben, dürfen auf der betroffenen Tabelle gleichzeitig keine enqueue-Operationen möglich sein. Eine mögliche Lösung ist, dass die
Warteschlangen auf zwei Tabellen verteilt werden (in Anlehnung an eine Idee
von [37]). Auf diese Weise können auf der einen Tabelle die enqueue- und auf
der anderen die dequeue-Operationen unabhängig voneinander ausgeführt wer-
58
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
den. Sobald keine Nachrichten mehr in der Tabelle mit den dequeue-Operationen
enthalten sind, rotieren beide Tabellen, so dass dann die leere Tabelle aufgefüllt
und die gefüllte abgearbeitet wird. Das Prinzip dieser Variante wird in Abbildung
15 veranschaulicht.
Logischer Entwurf: Eine der Tabellen könnte als Kopfteil der Warteschlange genutzt werden und die andere als Rumpf. Da beide Tabellen während
der Laufzeit ihre Eigenschaft als Kopf- bzw. Rumpfteil tauschen (Rotation), werden die Tabellennamen mit dem neutralen Zusatz ”L“ bzw. ”R“ gekennzeichnet.
Die Definition beider Tabellen entspricht der Variante in Kapitel 5.1.4.2:
1 create table queue1 L (
3
i d int
not null ,
message
xml
not null ,
−− s t a t e : 0=enqueued ,1= p r o c e s s e d
5
s t a t e smallint not null default 0
check ( s t a t e in ( 0 , 1 ) ) ,
primary key ( i d )
7 );
create table queue1 R (
9
i d int
not null ,
message
xml
not null ,
−− s t a t e : 0=enqueued ,1= p r o c e s s e d
11
s t a t e smallint not null default 0
13
check ( s t a t e in ( 0 , 1 ) ) ,
primary key ( i d )
);
Ebenso wie in der Variante in Kapitel 5.1.4.2 muss eine zusätzliche Tabelle
das Mapping der Nachrichten zu den Warteschlangen speichern, damit auf Nachrichten ausschließlich über deren ID zugegriffen werden kann. Eine Sicht auf die
gesamte Warteschlange kann mithilfe einer View erzeugt werden:
create view queue1 ( id , message , s t a t e ) as
2
s e l e c t id , message , s t a t e
from queue1 L
59
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 16: Warteschlange als paarweise Relationen
4 union a l l
s e l e c t id , message , s t a t e
6
from queue1 R
Die Zuordnung von Tabellen-Kopfteil und -Rumpf, kann im Hauptspeicher
verwaltet werden.
Physischer Entwurf: Außer den implizit erzeugten Indizes auf den
Nachrichten-IDs werden keine weiteren Indizes erzeugt.
Abbildung 16 skizziert den Entwurf der Variante mit paarweisen Relationen.
Für jede Warteschlange müssen nicht nur zwei Tabellen angelegt werden, sondern für jede dieser Tabellen müssen für die dequeue- und enqueue-Operationen
individuelle SQL-Statements erzeugt werden.
Abbildung 17 zeigt eine optimierte Version dieser Variante, in der die getrennten SQL-Statements zu atomaren Ausdrücken zusammengefasst wurden, um eine
verbesserte automatische Optimierung zu erreichen [3]. Alle Statements der de-
60
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 17: Warteschlange als paarweise Relationen (optimiert)
queue-Operation können außerdem mit dem Zusatz ”WITH UR“ ausgeführt werden, durch den die Ausdrücke als Uncommitted Read ausgeführt werden. Die Abbildung 17 zeigt außerdem die Tabellenzuordnung nach der Rotation, während
Abbildung 16 die Zuordnung vor der Rotation abbildet.
Abbildung 18: Warteschlange als paarweise Relationen blockiert vor der Rotation
61
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Theoretische Bewertung: Ein Vorteil bei dieser Variante ist, dass die
Funktionen enqueue und dequeue auf unterschiedlichen Tabellen ausgeführt
werden. Dadurch kann die Nebenläufigkeit erhöht werden, indem die dequeueFunktion mit einem Zusatz als Uncommitted Read ausgeführt werden kann. Auf
diese Weise können keine Nachrichten gelesen werden, die gerade mit enqueue
eingefügt, aber noch nicht mit commit bindend bestätigt wurden.
Sobald die Rumpf-Tabelle leer ist, kann sie mit der Kopftabelle vertauscht
werden (Rotation). Ein Nachteil dabei ist, dass der Tausch erst dann erfolgen
darf, wenn alle eingefügten Nachrichten im Kopfteil mit commit bestätigt wurden. Da nicht alle Transaktionen gleichzeitig beginnen und enden, ergeben sich
Leerlaufzeiten, in denen Transaktionen warten müssen (vgl. Abbildung 18).
Abbildung 19: Warteschlangen als einfache Relation mit Pointern
62
5.1 Demaq mit der DB2 und Saxon
5.1.4.4
Feinentwurf
Variante 4: Einfache Relation mit Pointern Wie von [9] vorge-
schlagen und in Abbildung 10 veranschaulicht, können Warteschlangen mit Hilfe
von Head - und Tail-Pointern und einem Array implementiert werden. Innerhalb
eines relationalen DBMS gibt es keine Array-Datenstruktur. Jedoch kann eine
Tabelle in ähnlicher Weise benutzt werden, indem die Zeilen als Speicherzellen
aufgefasst werden, für die der Primärschlüssel der Tabelle als deren ”Speicheradresse“ verwendet wird.
Logischer Entwurf: Die Tabelle für die Warteschlangen unterscheidet sich
nicht von der Definition der Variante in Kapitel 5.1.4.2:
create table queue1 (
2
i d int
not null ,
message
xml
not null ,
−− s t a t e : 0=enqueued ,1= p r o c e s s e d
4
s t a t e smallint not null default 0
6
check ( s t a t e in ( 0 , 1 ) ) ,
primary key ( i d )
);
Zusätzlich wird wieder eine message_queue-Tabelle angelegt, welche die
Nachrichten-IDs den Tabellen der Warteschlangen zuordnet (vgl. Kapitel 5.1.4.2).
Für jede Queue wird zusätzlich eine Relation mit zwei Zeilen verwaltet: In einer
Zeile wird der Head -, in der anderen der Tail-Pointer gespeichert. Die Pointer Tabelle kann wie folgt definiert werden (hier am Beispiel einer Warteschlange mit
dem Namen ”queue1“):
1 create table q u e u e 1 p o i n t e r (
type char ( 4 ) not null ,
3
value int ,
primary key ( type )
5 );
Abbildung 19 visualisiert die Implementierung, die der Umsetzung einer Warteschlange in einem Array ähnelt.
63
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Physischer Entwurf: Außer den implizit erzeugten Indizes auf den
Nachrichten-IDs und der Spalte type in der Pointer -Tabelle, werden keine weiteren Indizes erzeugt (vgl. Diskussion bei Variante 1).
Abbildung 20: Warteschlangen als einfache Relation mit Pointern (optimiert)
Da die Pointer eher flüchtige Daten darstellen, die aus den übrigen Daten
abgeleitet werden können (z.B. nach einem Systemabsturz), bedeutet eine Persistenzierung einen Overhead. Eine Speicherung der Daten in einer temporären
Tabelle [20] ist allerdings nicht möglich, da diese immer nur für eine Connection
bzw. Session gültig ist. Deshalb müsste sie für mehrere nebenläufige Verbindungen synchronisiert werden. Da dies nur durch großen Aufwand möglich ist, bringen
temporäre Tabellen in diesem Fall keinen Vorteil.
Den Tail-Pointer in der Pointer -Tabelle zu speichern, ist überflüssig, da auf
das Ende der Warteschlange nur zugegriffen wird, wenn eine neue Nachricht eingefügt wird. In diesem Fall kann der Tail-Pointer durch eine Sequence ersetzt
64
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
werden, da keine Zeile zum Speichern Vorallokiert wird. Denn im Gegensatz zu
einem Array, das eine feste Größe hat, wird eine Tabelle in einem relationalen
DBMS dynamisch vergrößert. Auf diese Weise können alle Update-Operationen
auf dem Tail-Pointer eingespart werden.
Die Selektion der nächsten Nachricht durch ein SQL-Statement darf nicht
mit dem Zusatz ”WITH UR“ als Uncommitted Read ausgeführt werden. Ansonsten
könnten Nachrichten weiterverarbeitet werden, die eingefügt, aber noch nicht mit
commit bestätigt wurden.
Wie auch bei den bisherigen Varianten können die SQL-Statements zusammengefasst werden (vgl. Abbildung 20), um die automatische Optimierung zu
verbessern [3].
Theoretische Bewertung: Im ersten Moment erscheint diese Umsetzung
vorteilhaft, da für die Wahl der nächsten Nachricht kein Minimum selektiert
werden muss. Ein einfacher Join genügt zum Selektieren. Allerdings muss der
Head-Pointer anschließend auf die nächste Nachricht gesetzt werden, wodurch
eine zusätzliche Update-Operation ausgeführt wird. Diese Update-Operation auf
der Pointer -Tabelle belegt diese mit einem exklusiven Lock bis zum Ende der
Transaktion. Auf diese weise wird eine nebenläufige Ausführung verhindert.
Ebenso darf der ”SELECT min(id)...“-Ausdruck in keinem Fall als Uncommitted Read ausgeführt werden, da ansonsten möglicherweise Nachrichten weiterverarbeitet werden, die noch nicht mit commit bestätigt wurden.
Letztendlich zeichnet sich diese Variante durch eine hohe Komplexität aus,
ohne besonders erkennbare Vorteile zu bieten.
5.1.4.5
Variante 5: Einfache Relation mit Verkettung Die Implemen-
tierung einer Warteschlange als verkettete Liste ist eine weitere Variante, die [9]
vorschlägt und die in Abbildung 10 unter (b) veranschaulicht ist. In einem relationalen DBMS gestaltet sich die Nachbildung einer solchen verketteten Liste als
65
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 21: Warteschlangen als einfache Relation mit Verkettung
schwierig. Dennoch soll an dieser Stelle ein Vorschlag zur Umsetzung vorgestellt
werden. Dabei wird die Nachrichten-ID wieder ähnlich wie eine Speicheradresse
aufgefasst.
Logischer Entwurf: Die Warteschlangen werden in einzelne Tabellen abgebildet. Hier eine beispielhafte Definition für eine Warteschlange mit dem Namen
”queue1“:
1 create table queue1 (
i d int
3
next
not null ,
int default null ,
message
5
xml
not null ,
−− s t a t e : 0=enqueued ,1= p r o c e s s e d
s t a t e smallint not null default 0
7
primary key ( i d )
66
check ( s t a t e in ( 0 , 1 ) ) ,
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
);
Zusätzlich wird für jede Warteschlange eine Tabelle angelegt, in welcher der
Head - und der Tail-Pointer verwaltet werden. Die Pointer -Tabelle passend zu
obigem Beispiel sieht wie folgt aus:
create table q u e u e 1 p o i n t e r (
2
type char ( 4 ) not null ,
value int ,
4
primary key ( type )
);
Abbildung 21 stellt eine mögliche Implementierung einer Warteschlange als
verkettete Liste in einem relationalen Datenbanksystem dar.
Physischer Entwurf: Außer den implizit erzeugten Indizes auf den
Nachrichten-IDs in der Warteschlangentabelle und type-Spalte in der Pointer Tabelle werden keine weiteren Indizes erzeugt.
Wie auch bei den bisherigen Varianten können die SQL-Statements zusammengefasst werden, um die automatische Optimierung zu verbessern [3].
Theoretische Bewertung: Die Update-Operationen auf der Pointer Tabelle sperren exklusiv die Einträge bis zum Ende der Transaktion. Die Pointer können nicht als Uncommited Read gelesen werden, da eine neu eingereihte
Nachricht, die noch nicht abschließend mit commit bestätigt wurde, den HeadPointer geändert haben könnte. Dann würde die nächste dequeue-Operation, die
als Uncommited Read ausgeführt wird, diese Nachricht weiterverarbeiten, was
nicht zulässig ist.
Insgesamt hat diese Variante der Warteschlangenabbildung keine signifikanten Vorteile zu bieten, außer dass kein Minimum mehr selektiert werden muss.
Außerdem ist sie im Vergleich zu den anderen Varianten überdurchschnittlich
kompliziert.
67
5.1 Demaq mit der DB2 und Saxon
5.1.4.6
Feinentwurf
Variante 6: Trennung von Daten und Statusinformationen
Abgearbeitete Nachrichten werden im Demaq-System nicht gelöscht, sondern nur
als bearbeitet markiert. Darum erschweren diese bereits abgearbeiteten Nachrichten in den vorhergehenden Varianten die Selektion der nächsten Nachricht, da der
notwendige Tablescan 3 alle Daten (auch die bereits abgearbeiteten) einer Warteschlangentabelle durchlaufen muss. Deshalb wird in dieser Variante versucht, die
Nachrichtendaten von den relevanten Informationen der Warteschlangenbearbeitung zu trennen.
Logischer Entwurf: Zunächst wird eine Relation definiert, um die Nachrichten aller Warteschlangen zu speichern. Allerdings werden die Statusinformationen, d.h. die Spalte state, weggelassen:
1 create table me ssa g es (
i d int
3
not null ,
queuename
message
5
varchar ( 2 5 5 )
xml
not null ,
not null ,
primary key ( i d )
);
Wenn obige Tabelle isoliert betrachtet wird, ist nicht ersichtlich, welche der
Nachrichten bereits bearbeitet wurden und welche nicht. Deshalb wird eine weitere Tabelle benötigt, in der die IDs der Nachrichten gespeichert werden, die noch
nicht bearbeitet wurden:
create table u n p r o c m e s s a g e s (
2
i d int
not null ,
primary key ( i d )
4 );
3
Wie bei Variante in Kapitel 5.1.4.1 bereits ausführlich diskutiert, ist es nicht sinnvoll einen
Index zu verwenden, um die bearbeiteten Nachrichten von den nicht bearbeiteten zu trennen.
Deshalb müssen die Datensätze tatsächlich gelesen werden, wenn der SQL-Ausdruck ”WHERE
state=0“ auftaucht.
68
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 22: Warteschlange mit Statusinformationen in Form einer extra Tabelle
Sobald eine neue Nachricht in die Tabelle messages eingefügt wird, muss ihre
ID auch in die Tabelle unproc_messages eingefügt werden. Wird eine Nachricht
bearbeitet, muss ihre ID in der Tabelle unproc_messages gelöscht werden. Der
Datensatz der Nachricht in der Tabelle messages bleibt hingegen unverändert.
Abbildung 22 veranschaulicht die beschriebene Variante und zeigt eine mögliche Implementierung der dequeue- und enqueue-Funktionen.
Physischer Entwurf: Die Selektion der nächsten Nachricht erfolgt über
einen Join der beiden Tabellen unproc_messages und messages über den
Primärschlüssel. Desweiteren wird die Selektion über den Ausdruck ”WHERE
m.queuename=qname“ (vgl. Abbildung 22) auf eine bestimmte Warteschlange eingeschränkt, so dass für die – durch den Join vorselektierten – Tabellenzeilen die
69
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 23: Warteschlange mit Statusinformationen in Form einer extra Tabelle (optimiert)
Datenseiten von der Festplatte geladen werden. Da der Index für den Primärschlüssel auf der Spalte id der messages-Tabelle eindeutig ist, könnte die Spalte
queuename in den Index inkludiert werden [17]. Auf diese Weise kann die Selektion der nächsten Nachricht ausschließlich über die Indizes erfolgen [14], ohne dass
zusätzlich Datenseiten geladen werden. Für die Definition der Tabelle bedeutet
dies, dass kein Primärschlüssel festgelegt wird. Stattdessen wird ein angepasster
Index explizit definiert:
create table me ssa g es (
2
i d int
not null ,
queuename
4
message
varchar ( 2 5 5 )
xml
not null ,
not null
);
6 create unique index messagesndx
on me ssa g es ( i d )
8
i n c l u d e ( queuename ) ;
70
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
In der neu definierten Tabelle unproc_messages werden keine Updates mehr
ausgeführt. Es werden nur Inserts für neu eingereihte Nachrichten durchgeführt
und Deletes für verarbeitete. In der Standardkonfiguration der DB2 würden diese
Operationen die Tabelle blockieren, wenn das nächste Minimum selektiert wird,
obwohl die neu eingefügten und die gelöschten Zeilen für die Selektion des Minimums nicht relevant sind. Die Nachrichten, die eingefügt, aber noch nicht mit
commit bestätigt wurden, dürfen noch nicht weiterverarbeitet werden, genauso
wie Nachrichten, die bereits in Weiterverarbeitung sind. Deshalb kann mit den
Optionen DB2_SKIPINSERTED=ON und DB2_SKIPDELETED=ON veranlasst werden,
dass DB2 gelöschte und eingefügte Zeilen, die noch nicht mit commit bestätigt
wurden, ignoriert, so dass keine Blockierung durch diese stattfindet [43].
Die einzelnen SQL-Statements der dequeue- und enqueue-Operation können
wieder zusammengefasst werden, so dass die automatische Optimierung der DB2
effizienter arbeiten kann [3]. Abbildung 23 stellt eine derart optimierte Version
dar.
Theoretische Bewertung: Durch die getrennte Speicherung der IDs der
noch nicht verarbeiteten Nachrichten kann die nächste Nachricht einer Queue
wesentlich effizienter selektiert werden. Erstens, weil mit einem schnellen IndexJoin die meisten Nachrichten ausgeschlossen werden können; und zweistens, weil
mit den Optionen DB2_SKIPINSERTED=ON und DB2_SKIPDELETED=ON beliebig viele dequeue- und enqueue-Operationen nebenläufig auf die Tabellen zugreifen können, ohne sich gegenseitig zu blockieren. Außerdem ist die nächste Nachricht ausschließlich über die Indizes bestimmbar, wenn die Spalte queuename in den Index
der Tabelle messages inkludiert wird. Damit ist diese Variante theoretisch eine
der Effizientesten.
5.1.4.7
Variante 7: Einfache Relation mit redundanter Queue im
Hauptspeicher In vorhergehenden Diskussionen wurde ausgeführt, dass die
71
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Warteschlangenimplementierung mit einer Sicht, die sich auf die relationale Datenbank beschränkt, nicht optimal ist. Dies ist damit zu begründen, dass sich
flüchtige Daten, wie die Pointer in Abschnitt 5.1.4.4 und 5.1.4.5, nur schlecht
in einem DBMS verwalten lassen. Letztlich bedeutet die Persistenzierung dieser
Daten einen Overhead, da sie sich aus den übrigen Daten rekonstruieren lassen.
So könnte der aktuelle Zustand ohne persistenzierte Pointer auch nach einem
System-Absturz leicht wieder hergestellt werden.
Werden andererseits keine Pointer verwendet, muss die nächste Nachricht
aus den Daten der Tabellen extrahiert werden. Dies bedeutet einen zusätzlichen
Aufwand, z.B. durch ein ”SELECT min(id)..“-Statement oder einen Join.
Aus diesem Grund muss das Sichtfeld bei der Implementierung der Warteschlangen auf die gesamte Applikation erweitert werden. Dabei wäre es Vorteilhaft, wenn mit dem Aufruf von dequeue bereits bekannt ist, welche Nachricht
mit welcher ID als nächstes abgearbeitet wird. Dann könnte diese ID der Datenbank in einem Select-Statement übergeben werden, so dass nur noch ein einfacher
Indexscan zum Auffinden der Nachricht ausreicht.
Logischer Entwurf: Da in dieser Variante der ”SELECT min(id)...“Ausdruck, der zum bestimmen der nächsten Nachrichten-ID nötig war, wegfällt,
werden keine Sperren mehr auf Ebene der ganzen Tabelle gesetzt. Daher kann
für alle Warteschlangen eine einzige Tabelle gewählt werden:
create table me ssa g es (
2
i d int
not null ,
queuename
4
message
varchar ( 2 5 5 )
xml
not null ,
not null ,
−− s t a t e : 0=enqueued ,1= p r o c e s s e d
6
s t a t e smallint not null default 0
primary key ( i d )
8 );
72
check ( s t a t e in ( 0 , 1 ) ) ,
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 24: Warteschlange mit Informationsverwaltung im Hauptspeicher
Damit die ID der nächsten Nachricht beim Aufruf der dequeue-Funktion bereits bekannt ist, muss im Demaq-System eine redundante Warteschlange im
Hauptspeicher gehalten werden. In dieser sind lediglich die IDs der noch nicht
verarbeiteten Nachrichten vorzuhalten. Deshalb weist die Datenmenge im Hauptspeicher ein niedriges Fluktuationsniveau auf. Die Nachrichten selbst werden weiterhin im relationalen DBMS gespeichert. Bei einem System-Absturz kann die
Warteschlange im Hauptspeicher aus den Daten in der DB2 leicht rekonstruiert
werden. Abbildung 24 skizziert die Implementierung einer solchen Warteschlangenverwaltung im Hauptspeicher und Datenhaltung in der DB2.
Physischer Entwurf: Außer dem implizit erzeugten Index auf der
Nachrichten-ID wird kein weiterer Index benötigt, da der einzige Zugriff auf die
Messages-Tabelle über die ID erfolgt.
Die Implementierung der Queue kann im Demaq-System mithilfe des Queue73
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Abbildung 25: Warteschlange mit Informationsverwaltung im Hauptspeicher (optimiert)
Schedulers vorgenommen werden. Dort wird bereits im aktuellen System jede
Nachrichten-ID zusammen mit dem Queue-Namen eingereiht. Bei der Auswertung durch den RuleExecutor wird allerdings nur der Queue-Name weiterverwendet, während die Nachrichten-ID unbeachtet bleibt. Durch wenige Anpassungen kann die ID an dieser Stelle an den RuleProcessor weitergegeben und an die
eigentliche dequeue-Funktion als Parameter übergeben werden. Auf diese Weise
können die bestehenden Module verwendet werden, um mit wenig Aufwand eine
redundante Queue im Hauptspeicher abzubilden.
Wie in Abbildung 25 dargestellt, können die einzelnen SQL-Statements aus
Abbildung 24 zusammengefasst werden, um der automatischen Optimierung in
der DB2 mehr Spielraum zu lassen [3].
Theoretische Bewertung: Mit Blick auf die nebenläufige Verarbeitung
treten mit dieser Variante keine Probleme auf. Da die dequeue-Funktion bei dieser
Variante nur direkt mit der ID auf Nachrichten zugreift, wird die Tabelle, in der
74
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
die Nachrichten liegen, nie komplett blockiert. Denn beim Standard-IsolationsLevel Cursor Stability in der DB2 wird nur die Zeile gesperrt, die auch tatsächlich gelesen oder geändert wird [43]. Der Zugriff auf alle anderen Zeilen bleibt
weiter möglich. Auch können neue Zeilen nebenläufig eingefügt werden. Ebenso
hätte eine exklusive Sperre einer einzelnen Zeile keine negativen Auswirkungen,
da durch die synchronisierte Warteschlange im Hauptspeicher garantiert wird,
dass jede Zeile nur von einem Thread bearbeitet wird. Auf diese Weise können
beliebig viele dequeue- und enqueue-Operationen nebenläufig auf die Daten in
der DB2 zugreifen, ohne sich gegenseitig zu blockiern. Außerdem besteht keine
Gefahr, dass Nachrichten, die schon eingefügt, aber noch nicht mit commit bestätigt wurden, weiterverarbeitet werden, weil diese erst nach dem commit dem
QueueScheduler bekannt werden.
Durch das Selektieren ausschließlich über die Nachrichten-ID kann über einen
IndexScan auf dem Primärschlüssel schnellstmöglich auf den Datensatz zugegriffen werden. Insgesamt gehört diese Variante in theoretischer Hinsicht zu den
Effizientesten.
5.1.4.8
Tabellarische Übersicht der Varianten In Tabelle 3 wird die Be-
wertung der verschiedenen Varianten der Warteschlangenabbildung auf ein relationales DBMS nochmals zusammenfassend dargestellt. Dabei werden die zuvor
ausgeführten Aspekte ”Nebenläufigkeit“, ”Zugriffskosten für Selektionen“, ”Zugriffskosten für Updates“ und die ”Handhabung“ berücksichtigt. Die Bewertung
erfolgt qualitatv mit ”+“ (positiv), ”0“ (neutral) oder ”-“ (negativ).
Insgesamt haben die Varianten 6 und 7 in der theoretsichen Bewertung, insbesondere im Bezug auf die Effizienz, die höchsten Werte erreicht. Aus diesem
Grund werden diese Varianten in dem Experiment, welches in Kapitel 7.2.4 beschrieben wird, getestet.
75
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Tabelle 3: Übersicht der Varianten der Warteschlangenabbildung in einem relationalen DBMS
5.1.5
DB2-Datenbankmodul: Varianten der Abbildung von Slices
Slices können in einer relationalen Datenbank auf unterschiedliche Weise implementiert werden. Die möglichen Varianten können im Rahmen der vorliegenden
Arbeit nicht vollständig vorgestellt werden. Entscheidend für eine native Implementierung von Slices (vgl. Kapitel 4.2.5) ist, dass die Nachrichten, die den gleichen Wert für das Slicing-Property haben, möglichst effizient selektiert werden
können. Im Folgenden werden beispielhaft drei mögliche Implementierungen vorgestellt.
5.1.5.1
Slicing Zugriffe über einen Index Mithilfe einer separaten
Slicing-Property-Tabelle können Slicings in einem relationalen DBMS mit wenig
Aufwand implementiert werden. Die Tabelle wird durch folgendes DDL-Statement
definiert:
create table m s g s l i c i n g p r o p e r t y (
2
propertyname
msgid int
4
varchar ( 2 5 5 )
not null ,
not null ,
value varchar ( 5 1 2 ) not null
);
76
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Um Nachrichten-IDs zu ermitteln, die zu einem spezifischen Slicing gehören,
kann eine Selektion auf der Slicing-Property-Tabelle durchgeführt werden. Folgender SQL-Ausdruck könnte hierfür benutzt werden:
1 SELECT msgid
FROM m s g s l i c i n g p r o p e r t y
3
WHERE propertyname= ’ m y S l i c i n g ’
AND value= ’ 42 ’ ;
Um dieses SQL-Statement auszuwerten, wird ein Tablescan der gesamten Tabelle msg_slicing_property durchgeführt. Durch eine Indizierung der Spalte
propertyname oder der Spalte value ist hierbei eine zusätzliche Beschleunigung
möglich. Eine alleinige Selektion von Nachrichten-IDs über einen Index ist allerdings nicht möglich, da beide genannten Spalten keine eindeutigen Werte enthalten. Deshalb kann kein Index erzeugt werden, der andere Spalten enthält [17]. Da
davon ausgegangen werden kann, dass in den meisten Fällen die Variation der
value-Spalte größer ist als die der propertyname-Spalte, erscheint ein Index auf
der value-Spalte vorteilhafter:
create index s l i c i n g n d x on m s g s l i c i n g p r o p e r t y ( value ) ;
5.1.5.2
Slicings mit Materialized Views Eine weitere Variante der Imple-
mentierung von Slices kann mit Hilfe von Materialized Views umgesetzt werden.
Hierzu wird die Property-Tabelle der gewöhnlichen Nachrichten-Properties auch
für die Slicing-Properties verwendet.
Für jedes Slicing-Property wird eine eigene Materialized View angelegt. Das
Statement zum Erzeugen der View sieht wie folgt aus:
1 create table q s s l i c e m y s l i c i n g as
(SELECT msgid , value as key
3
FROM m s g p r o p e r t y
WHERE propertyname= ’ m y S l i c i n g ’ )
5
data i n i t i a l l y d e f e r r e d r e f r e s h immediate ;
77
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
set i n t e g r i t y f o r q s s l i c e m y s l i c i n g immediate checked not
incremental ;
Das folgende Beispiel verdeutlicht, wie über eine Materialized View bei der
Regelauswertung auf ein Slicing zugegriffen werden kann:
create r u l e g e t s l i c i n g c o n t e n t f o r m y s l i c i n g
2
enqueue message <r e s u l t >
{ qs : s l i c e ( ’ 42 ’ , ’ m y s l i c i n g ’ ) }
4
</ r e s u l t > into r e s p o n s e q u e u e ;
Der Aufruf qs:slice(’42’,’myslicing’) wird für die Auswertung mit der
DB2 in ein SQL-Statement umgewandelt:
SELECT message
2
FROM me ssa g es m, q s s l i c e m y s l i c i n g s
WHERE s . key= ’ 42 ’
4
AND s . msgid=m. i d ;
5.1.5.3
Slicings als eigene Tabellen Eine andere Alternative stellt die
Möglichkeit dar, für jedes Slicing-Property eine eigene Tabelle anzulegen. Mit
dem Slicing-Namen als Tabellenname kann beim System-Start von Demaq für
jedes Slicing eine Tabelle erzeugt werden. Beispielsweise wird für das Slicing
”mySlicing“ folgende Tabelle angelegt:
create table q s s l i c e m y s l i c i n g (
2
key varchar ( 5 1 2 ) ,
msgid int not null
4 );
Wird zur Laufzeit des Demaq-Systems eine Nachricht mit dem SlicingProperty ”myslicing“ eingefügt, wird der Wert nicht in die Tabelle msg_property
oder msg_slicing_property eingetragen, sondern in die speziell für das Slicing
angelegte Tabelle qs_slice_myslicing.
78
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Um die Effizienz der Selektion auf der speziellen Slicing-Tabelle zu steigern,
wird zusätzlich ein Index auf der Spalte key angelegt:
create index q s s l i c e m y s l i c i n g n d x
2
on q s s l i c e m y s l i c i n g ( key ) ;
Auch bei dieser Variante kann keine ausschließliche Selektion der NachrichtenIDs über den Index erfolgen. Die Auswahl erfolgt aber nur über eine Spalte und
die Slicing-Tabelle enthält weniger Einträge als bei der Variante in Kapitel 5.1.5.1,
da sich die Werte der Slicing-Properties auf mehrere Tabellen verteilen. Deshalb
erscheint diese Variante aus theoretischer Sicht effizienter und wird aus diesem
Grund im Rahmen dieser Diplomarbeit implementiert.
Anhand des folgenden Beispiels soll verdeutlicht werden, wie in dieser Variante
der Zugriff auf ein Slicing bei der Regelauswertung abläuft:
create r u l e g e t s l i c i n g c o n t e n t f o r m y s l i c i n g
2
enqueue message <r e s u l t >
{ qs : s l i c e ( ’ 42 ’ , ’ m y s l i c i n g ’ ) }
4
</ r e s u l t > into r e s p o n s e q u e u e ;
Der Aufruf qs:slice(’42’,’myslicing’) wird für die Auswertung mit der
DB2 zu einem SQL-Statement aufgelöst:
SELECT message
2
FROM me ssa g es m, q s s l i c e m y s l i c i n g s
WHERE s . key= ’ 42 ’
4
AND s . msgid=m. i d ;
5.1.6
Änderung des Demaq-Codes
Um DB2 als Nachrichtenspeicher zu verwenden, müssen einige Umstrukturierungen vorgenommen werden, die vor Allem der Modularisierung der Komponenten
für zukünftige Erweiterungen Rechnung tragen (vgl. die Anforderungen in Kapitel 3.3.2). Zusätzlich müssen neue C++-Klassen eingeführt werden, welche die
79
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Schnittstellen zum Nachrichtenspeicher bilden (vgl. Abschnitt 4.1.3).
5.1.6.1
Umstrukturierungen In dem Ordner src/infra/gateway waren
bisher die Dateien natixgateway.hh und -.cc zu finden. Um das NatixGateway
austauschbar zu machen, werden in diesem Ordner zwei Unterordner natix und
db2 angelegt und die Dateien natixgateway.hh und -.cc werden in den natix-Ordner verschoben. Im Unterodner db2 werden die Dateien db2gateway.hh
und -.cc für die Klasse DB2Gateway angelegt. Entsprechend den Überlegungen in
Kapitel 4.2.2 wird im Ordner src/infra/gateway die Datei messagestoregateway.hh angelegt. In dieser Datei wird ein typedef für den Typ MessageStoreGateway entweder für die Klasse NatixGateway oder DB2Gateway definiert, je
nachdem wie die Einstellungen in der Datei configure.ac vorgenommen werden.
Die Umstrukturierungen für die austauschbare Gateway-Klasse betreffen auch
den übrigen Quelltext des Demaq-Systems. Zunächst müssen alle VariablenDeklarationen und Objekt-Erzeugungen der ehemaligen Gateway-Klasse durch
den neutralen Typ MessageStoreGateway ersetzt werden. Außerdem muss der
NATIX-spezifische Code aus den unspezifischen Klassen des Demaq-Kerns in
die Gateway-Klassen verschoben werden. Beispielsweise wird in der Datei demaq.cc in der Funktion reconstructSchedulerContentFromQueue() NATIXspezifischer Code verwendet, um den letzten System-Zustand nach einem Absturz wieder herzustellen. Um die Systemwiederherstellung neutral, d.h. mit jedem Nachrichtenspeicher kompatibel, zu gestalten, wird in den Gateway-Klassen
die zusätzliche Funktion getUnprocessedMessagesTimestampList() implementiert, in die der vom Nachrichtenspeicher abhängige Code verschoben wird. In
der Funktion reconstructSchedulerContentFromQueue() wird anschließend die
neutrale Funktion der Gateway-Klassen verwendet. Eine Reihe weiterer solcher
Code-Verlagerungen in die Gateway-Klassen wird durchgeführt, die an dieser Stelle nicht weiter aufgeführt werden sollen.
In dem Ordner src/demaq werden Umstrukturierungen für die Klasse Demaq80
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Config vorgenommen. Zunächst wird ein Unterodner config angelegt, in dem die
Ordner natix und db2 erzeugt werden. Die ehemaligen Dateien demaqconfig.hh
und -.cc werden umbenannt in natixconf.hh und -.cc. Außerdem werden sie in
den natix-Ordner verschoben. Dementsprechend werden die Dateien db2conf.hh
und -.cc im Unterordner db2 angelegt. In dem neuen Ordner config wird die
Datei demaqconf.hh dazu verwendet, um den neutralen Typ DemaqConfig mithilfe eines typedefs entweder als NatixConfig oder als DB2Config zu definieren.
Gesteuert wird dies über die gleiche Einstellung in der Datei configure.ac, die
auch den typedef des MessageStoreGateway steuert. Dadurch kann eine unterschiedliche Konfigurationsklasse für das System verwendet werden, je nachdem
mit welchem Nachrichtenspeicher das System kompiliert wird.
Durch die vorgenommenen Umstrukturierungen lassen sich in Zukunft andere Nachrichtenspeicher mit wenig Aufwand in das System integrieren. Dazu
müssen nur in den Ordnern src/infra/gateway und src/demaq passende Unterordner mit zusätzlichen Gateway- bzw. DemaqConfig-Klassen angelegt werden.
Diese werden dann als typedef in die Dateien messagestoregateway.hh und demaqconf.hh hinzugefügt. Schließlich wird eine zusätzliche Makro-Variable in der
Datei configure.ac definiert, welche die Kompilierung mit den neuen Klassen
optional zulässt.
5.1.6.2
Neue C++ Klassen Folgende neue Klassen entstehen im Demaq-
Kern:
DB2Gateway Die Klasse DB2Gateway bildet die neue Schnittstelle zur DB2 als
Nachrichtenspeicher. Die Signatur der Klasse ist identisch mit der der NatixGateway-Klasse.
NatixGateway Die Klasse NatixGateway ist durch Umbenennung aus der alten
Gateway-Klasse entstanden.
DB2DemaqConfig Die Klasse enthält Konfigurations-Einstellungen, die speziell
81
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
für das System mit der DB2 benötigt werden. Ein Objekt der Klasse wird
beim Erzeugen der Demaq-Instanz an diese übergeben, die dann ein individuell konfiguriertes System startet.
NatixDemaqConfig Analog zu der Klasse DB2DemaqConfig enthält die Klasse
NatixDemaqConfig spezifische Einstellungsparameter für ein zu startendes
Demaq-System mit NATIX. Diese Klasse ist durch Umbenennung und Verschiebung der ehemaligen DemaqConfig-Klasse entstanden.
5.1.7
Erweiterung des NATIX-Codes
Wenn das Demaq-System mit der DB2 als Nachrichtenspeicher und Saxon als
Regelauswerter kompiliert wird, kontrolliert NATIX weiterhin den Regelauswertungsmechanismus (vgl. Kapitel 4.2.3). Deshalb muss es NATIX ermöglicht werden auf XML-Dokumente zugreifen zu können, die in der DB2 gespeichert sind.
5.1.7.1
nur
Umstrukturierungen Die
an
wird
typ
einer
erzeugt.
Stelle:
Dort
DB2Document
und
-.cc,
in
Der
werden
den
Ordnerstruktur
Ordner
die
sich
src/schema/physical/db2document
Handler
Dateien
ändert
für
den
neuen
Fragment-
db2documentdescriptormanager.hh
db2documentmetadataviewfactory.cc
und
-.cc
und
db2documentstreamviewfactory.cc und -.cc hinzugefügt.
Um steuern zu können, ob NATIX mit der DB2-Funktionalität kompiliert
wird, muss eine zusätzliche Compiler -Option hinzugefügt werden. Dazu wird eine
neue Datei mit dem Namen db2 in den Ordner abusy/configs angelegt, in der die
Umgebungsvariable CONFIG_DB2_SPECIALS=y gesetzt wird. Diese Variable kann
in den Imakefiles dazu benutzt werden, die DB2-spezifische Funktionalität nur
zu kompilieren, wenn die Variable auf ”y“ gesetzt ist. Der Aufruf, um NATIX mit
der DB2 -Funktionalität zu kompilieren, lautet dann beispielsweise:
abusy −−c o n f i g n a t i x g c c debug demaq db2
82
5.1 Demaq mit der DB2 und Saxon
5.1.7.2
Feinentwurf
Änderungen des bestehenden Codes Wie in Kapitel 4.2.3 be-
schrieben, müssen die Callback-Services in NATIX angepasst werden, damit aus
Demaq-Regeln heraus auf Daten in der DB2 zugegriffen werden kann. Zu diesem Zweck wird die Datei saxonxqueryquerystreamviewfactory.cc im Ordner
src/schema/physical/query/saxon angepasst. In dieser Datei wird die Anfragenbearbeitung der Callback-Services definiert. Jede Anfrage wird durch einen
String-Vergleich identifiziert und dann entsprechend auf dem Nachrichtenspeicher
ausgeführt. Da mit der DB2 ein weiterer optionaler Nachrichtenspeicher hinzukommt, muss der ausführende Code entweder für NATIX als Speicher oder die
DB2 kompiliert sein. Deshalb wird für jede mögliche Anfrage mit einem #ifdef
CONFIG_DB2_SPECIALS definiert, für welchen Nachrichtenspeicher der Callback Mechanismus kompiliert wird. Ist CONFIG_DB2_SPECIALS=y gesetzt, werden die
Services für die DB2 kompiliert.
Der neue Fragmenttyp für XML-Dokumente, die in der DB2 gespeichert sind,
wird in der Datei types.xml im Ordner src/control/request/spec hinzugefügt. Die Definition in der XML-Datei genügt aus, damit der notwendige Code
beim Kompilieren von NATIX automatisch generiert wird.
5.1.7.3
Neue C++ Klassen In NATIX werden folgende neuen C++-
Klassen definiert:
DB2DocumentDescriptorManager Die DB2DocumentDescriptorManager-Klasse
ist dafür zuständig, ein Descriptor -Objekt für ein Dokument, das in
der DB2 gespeichert ist, zu erzeugen. Angefordert wird dies mit einem
OpenDB2Document-Request.
Außerdem deligiert die DB2DocumentDescriptorManager-Klasse einen
OpenView-Request an die richtige Factory-Klasse, wenn dieser mit einem
DB2-FragmentDescriptor erzeugt wird.
Um NATIX den DB2DocumentDescriptorManager als Handler für DB283
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
FragmentDescriptoren bekannt zu machen, wird in der SchemaManagerKlasse in den Dateien src/schema/physical/repository/schemamanager.hh und -.cc ein DB2DocumentDescriptorManager als Objekt-Variable
hinzugefügt. Damit auf diese Variable zugegriffen werden kann, muss zusätzlich noch die Funktion getDB2DocumentDescriptor() ergänzt werden.
DB2Document-Stream-View-Factory Die
Stream-View-Factory
für
DB2-
FragmentDescriptoren generiert aus einem in der DB2 gespeicherten XMLDokument einen Stream. Beauftragt wird sie von einem OpenView-Request,
der vom DB2DocumentDescriptorManager weitergeleitet wurde und einen
DB2-FragmentDescriptor enthält. Durch den Descriptor weiß die FactoryKlasse welches Dokument als Stream geöffnet werden soll.
DB2Document-Metadata-View-Factory Die
Metadata-View-Factory-Klasse
ist dafür zuständig, für ein Dokument, das in der DB2 gespeichert
ist, Metadaten zusammenzustellen. Zu diesem Zweck wird ein entsprechender OpenView-Requests von dem DB2DocumentDescriptorManager
weitergeleitet, der einen DB2-FragmentDescriptor enthält. Durch den
DB2-FragmentDescriptor erhält die Factory-Klasse die Information, für
welches Dokument sie die Metadaten zusammenstellen soll.
OpenDB2Document Die Klasse OpenDB2Document ist ein neuer Request (vgl. Kapitel 2.2.1). Mit diesem Request kann ein FragmentDescriptor des Typs
DB2Document erzeugt und an den Aufrufer zurückgegeben werden. Dieser
Request wird in der XML-Datei opendb2document.xml im Pfad src/control/request/spec/schema definiert. Der C++-Code wird hieraus beim
Kompilieren vom NATIX-Build -System automatisch generiert.
84
5.1 Demaq mit der DB2 und Saxon
5.1.8
Feinentwurf
DB2-Fassade
Die Vorüberlegungen zu der Integration der Funktionalität der DB2 betreffen drei
Punkte:
1. Die Integration der Funktionalität der DB2: Wie und wo kann man diese
am besten integrieren? (Vgl. hierzu Abschnitt 4.2.4),
2. die benutzte Technik: Wie kann man mit der DB2 eine Verbindung herstellen?
3. wie diese Technik benutzt wird: Wie lässt sich die benutzte Technik am
besten implementieren?.
Die beiden letzten Punkte werden in den Unterabschnitten 5.1.8.1 und 5.1.8.2
behandelt.
Die DB2-Fassade kapselt nicht nur die Verbindung und Funktionalität der Datenbank, sondern dient auch zur Verwaltung der Datenbanktransaktionen, die eng
an eine Verbindung gekoppelt sind [26]. Denn sobald eine Anfrage über eine Verbindung an die DB2 übermittelt wird, wird implizit eine Transaktion gestartet,
die dieser Verbindung im DBMS zugeordnet ist. Abgeschlossen wird eine Transaktion, indem ein explizit commit gesendet wird. Der Zeitpunkt zum Abschluss
einer Transaktion durch commit, und damit die Steuerung der Transaktion, wird
vom Demaq-System-Kern übernommen. Da die DB2-Fassade die Verbindungen
verwaltet, verwaltet sie implizit auch die Transaktionen.
Die wichtigste Klasse der DB2-Fassade ist die DB2Transaction-Klasse aufgrund der engen Bindung an eine Transaktion bzw. Verbindung. Diese enthält
allerdings mehr als nur die Funktionalität einer Transaktion bzw. Verbindung:
Während die Gateway-Klasse die Außenschnittstelle des Demaq-Systems ist, stellt
die DB2Transaction-Klasse die Außenschnittstelle der DB2 für Demaq dar. Auf
diese Weise ist der Zugriff auf die DB2 einfach zu handhaben. Die implementierten
Klassen der Fassade werden in Kapitel 5.1.8.3 detailliert erläutert.
85
5.1 Demaq mit der DB2 und Saxon
5.1.8.1
Feinentwurf
Kommunikationstechnik Als Technik zur Kommunikation mit der
DB2 wird CLI benutzt. Grundsätzlich stehen folgende Techniken zur Auswahl
[8]:
• JDBC
• .NET Data Provider
• Embedded SQL
• CLI (ODBC)
JDBC kommt für das Demaq-System nicht in Frage, da Java langsamer ist
als C/C++. Ansonsten bietet JDBC keine signifikanten Vorteile gegenüber den
sonstigen Varianten [8]. Gleichermaßen ungeeignet ist der .NET Data Provider,
da dieser nicht primär für Linux-Systeme entworfen worden ist und ebenfalls keine
zusätzlichen Vorteile bietet.
Embedded SQL wird nicht als eingesetzte Kommunikationstechnik gewählt,
da es einige entscheidende Nachteile hat: Es können nicht ohne weiteres mehrere
Verbindungen und Transaktionen gleichzeitig von demselben Programm gestartet
werden [13], was aber Grundvoraussetzung für die Nebenläufigkeit (vgl. Kapitel
3.4.4) ist. Außerdem benötigt Embedded SQL einen Precompiler und ist sehr
unflexibel, da das Programm von der gebundenen Datenbank abhängig ist.
Mit CLI sind parallele Abläufe mit mehreren gleichzeitig agierenden Transaktionen kein Problem. Zudem baut es auf dem internationalen Standard SQL/CLI
und ODBC auf, was eine hohe Flexibilität bedeutet.
5.1.8.2
Implementierung Die Implementierung der DB2-Fassade mit Hilfe
von CLI wird mit der Template Library OTL umgesetzt. Mit OTL kann mit dem
Setzen einer Makro-Variable der Code ebenso für die Oracle 11g, MS Sql Server
oder einigen anderen Datenbanken kompiliert werden. Damit wird CLI vergleichbar flexibel wie ODBC, ohne dass ein Driver-Manager benötigt wird [15]. Die
86
5.1 Demaq mit der DB2 und Saxon
Feinentwurf
Flexibilität kommt zukünftigen Vorhaben zugute, wie es in der Anforderung in
Kapitel 3.3.2 gefordert wird. Außerdem nutzt OTL wiederverwendbare Streams,
so dass ein Großteil der verwendeten SQL-Statements bereits beim System-Start
vorbereitet wird. Hierdurch kann die Effizienz der Zugriffe mittels SQL erhöht
werden.
5.1.8.3
Neue C++ Klassen Folgende neue Klassen gehören zu der DB2-
Fassade:
DB2Transaction Die Klasse DB2Transaction ist die Hauptklasse der DB2Fassade. Über sie laufen sämtliche Zugriffe auf die DB2. Zudem bietet sie
Transaktionsfunktionalitäten mit ihren Funktionen abort() und commit().
ConnectionPool Die Zeit für den Verbindungsaufbau zur DB2 ist nicht konstant.
Wenn eine Verbindung erst beim Starten einer Transaktion aufgebaut wird,
führt das zu erheblichen Verzögerungen. Deshalb werden in der ConnectionPool-Klasse Verbindungen auch nach dem Abschluss einer Transaktion
gehalten. Beim System-Start wird eine Anzahl an Verbindungen aufgebaut,
indem DB2Transaction-Objekte erzeugt und gestartet werden. Die Anzahl
kann über die Datei settings.hh im include-Ordner des Projektes gesteuert werden.
Wird vom Demaq-System oder NATIX eine DB2Transaction benötigt, so
wird diese über die statische Factory-Funktion getDB2Transaction() der
DB2Transaction-Klasse angefordert. Die Funktion greift auf den ConnectionPool zu und liefert eine unbenutzte Verbindung zurück. Um eine Verbindung zur weiteren Verwendung an den ConnectionPool zurückzugeben, wird explizit die statische Funktion freeTransaction() der Klasse
DB2Transaction aufgerufen werden.
Intern werden die unbenutzten Verbindungen im ConnectionPool mit Hilfe
87
5.2 Demaq mit der DB2
Feinentwurf
eines Stack s verwaltet. Mit freeTransaction() freigegebene Transaktionen werden auf den Stack zurückgelegt.
5.2
Demaq mit der DB2
Die System-Variante von Demaq mit der DB2 als Nachrichtenspeicher und Regelauswerter baut im Wesentlichen auf der Variante mit der DB2 und Saxon auf
(Kapitel 5.1). Die entscheidenden Veränderungen, die notwendig sind, um DB2
im Demaq-Ausführungssystem auch als Regelauswerter zu verwenden, werden in
diesem Kapitel im Detail beleuchtet.
5.2.1
Änderung des Demaq-Kerns
Zunächst werden einige Veränderungen an der Ordnerstruktur im Demaq-System
vorgenommen, die in Kapitel 5.2.1.1 erläutert werden. Diese zielen auf die Erweiterbarkeit für die Zukunft und die Modularisierung ab (vgl. Anforderungen
in Kapitel 3.3.2). Änderungen an bestehendem Demaq-Code werden in Kapitel
5.2.1.2 beschrieben. Neu hinzukommenden C++-Klassen betreffen die Regelauswertung und die Abarbeitung der resultierenden Pending Action List und werden
in Kapitel 5.2.1.3 erläutert.
5.2.1.1
Umstrukturierungen In dem Ordner src/core werden die neuen
Unterordner queryresults, ruleprocessors und actioninterpreters angelegt, in denen jeweils die Unterordner natix und db2 erzeugt werden. Die bisherigen Dateien ruleprocessor.hh und -.cc, queryresult.hh und -.cc bzw.
actioninterpreter.hh und -.cc werden in die Ordner src/core/ruleprocessors/natix, src/core/queryresults/natix bzw. src/core/actioninterpreters/natix verschoben. Außerdem werden sie umbenannt in natixruleprocessor.hh und -.cc, natixqueryresult.hh und -.cc bzw. natixactioninterpreter.hh und -.cc. Die entsprechenden Dateien für die DB2 werden in den db2-
88
5.2 Demaq mit der DB2
Feinentwurf
Unterordnern angelegt.
In der Datei configure.ac im Wurzelverzeichnis des Demaq-Projektes kann
gesteuert werden, mit welchem Haupt-Regelauswerter das Demaq-System kompiliert werden soll. Durch die Implementierung der Klassen RuleProcessor, QueryResult und Actioninterpreter über eine Vererbungshierarchie, anstatt mithilfe
eines typedef, können in Zukunft, mit wenigen zusätzlichen Anpassungen, verschiedene Regelauswerter in der gleichen System-Instanz betrieben werden. Auf
diese Weise kann z.B. ein Fallback -Mechanismus implementiert werden, um Regeln, die von der DB2 nicht ausgewertet werden können, mit Hilfe von Saxon
auszuwerten (vgl. Kapitel 4.1.4).
5.2.1.2
Änderungen des bestehenden Codes Die XQuery-Engine der
DB2 kann nicht derart erweitert werden, dass Demaq-spezifische Funktionen,
wie beispielsweise qs:queue(), direkt von der Datenbank interpretiert werden
können (vgl. Kapitel 2.3.2.2). Dazu müssten Funktionen deklariert bzw. Module
importiert werden, was von der DB2 nicht unterstützt wird.
Deshalb müssen diese speziellen QRL-Funktionen beim Import eines DQLFiles von Demaq während des System-Starts mit Hilfe von Rewrites wegkompiliert werden. Die Rewrites werden für die wichtigsten Demaq-Funktionen in
der Tabelle 4 aufgelistet. Diese gelten allerdings nur für eine WarteschlangenAbbildung nach dem Vorschlag in Kapitel 5.1.4.1 und eine Slice-Abbildung nach
Kapitel 5.1.5.3. Allerdings sind nur wenige Anpassungen notwendig, um die vorgestellten Rewrites in den übrigen Varianten verwenden zu können.
Die Rewrites werden implementiert, indem die Dateien transformation.hh
und -.cc im Ordner src/xqlparser angepasst werden.
4
Die Variable $
demaq contextmsgid wird bei der Vorbereitung einer Regel zur Auswer-
tung automatisch auf die ID der Kontext-Nachricht gesetzt. Die Variable $
wird mit der Kontext-Nachricht initialisiert.
89
demaq contextmsg
5.2 Demaq mit der DB2
Feinentwurf
QRL
Rewrite für die DB2
qs:message()
$___demaq_contextmsg
qs:queue(”qname”)
db2-fn:sqlquery(’select message from
4
messages where queuename=parameter(1)’,
”qname”)
qs:property(”pname”)
db2-fn:sqlquery(’select value from
msg_property where msgid=parameter(1)
and propertyname=parameter(2)’,
$___demaq_contextmsgid, ”pname”)
qs:slice(”skey”,”sname”)
4
db2-fn:sqlquery(’select m.message from
messages m,qs_slice_sname s where
s.key=parameter(1) and s.msgid=m.id’,
”skey”)
qs:slicekey(”sname”)
db2-fn:sqlquery(’select
key from qs_slice_sname
where msgid=parameter(1)’,
$___demaq_contextmsgid)
4
Tabelle 4: Rewrites für Demaq-spezifische Funktionen
5.2.1.3
Neue C++ Schnittstellen Folgende neue C++-Klassen werden
implementiert, damit die DB2 als alternativer Regelauswerter eingesetzt werden
kann:
DB2RuleProcessor Der DB2RuleProcessor bereitet für eine bestimmte Nachricht die Regelauswertung vor, übergibt die vorbereitete Regel zur
Ausführung an die DB2-Fassade und generiert aus dem Ergebnis ein
DB2QueryResult.
NatixRuleProcessor Der NatixRuleProcessor greift zur Regelauswertung auf
90
5.2 Demaq mit der DB2
Feinentwurf
NATIX zu. Aus dem Ergebnis der Auswertung generiert er ein NatixQueryResult. Diese Klasse ist durch Umbenennung der ehemaligen RuleProcessor-Klasse entstanden.
DB2QueryResult Die DB2-spezifische Implementierung der Pending Action List,
die das Ergebnis einer Regelauswertung mit der DB2 darstellt.
NatixQueryResult Die NatixQueryResult-Klasse verkörpert eine Pending Action List als Resultat einer Regelauswertung mit NATIX und Saxon. Diese
Klasse ist durch Umbenennung der ehemaligen QueryResult-Klasse entstanden.
DB2Actioninterpreter Die
DB2Actioninterpreter-Klasse
kann
ein
DB2QueryResult interpretieren und die beinhalteten Aktionen optimiert für die DB2 ausführen.
NatixActioninterpreter Der NatixActioninterpreter kann entsprechend
ein NatixQueryResult abarbeiten und die enthaltenen Aktionen optimiert
für NATIX ausführen. Diese Klasse ist durch Umbenennung der ehemaligen
Actioninterpreter-Klasse entstanden.
5.2.2
Erweiterung der DB2-Fassade
Um die Regelauswertung mit der DB2 zu ermöglichen, wird die Klasse DB2Transaction der DB2-Fassade um die Funktion execQueryMsg() erweitert. Der Funktion wird als Parameter die ID der Kontext-Nachricht
(<<context_msg_id>>) und die auszuführende Regel (<<query>>) als String
übergeben.
In der Funktion wird die Regelauswertung mithilfe eines SQL/XMLStatements vorbereitet. Beispielsweise wird die XQuery Variable $___demaq_contextmsgid mit der ID der Kontext-Nachricht initialisiert. Diese Variable
ist insbesondere für Zugriffe aus der Regel auf den Nachrichtenspeicher wichtig,
91
5.2 Demaq mit der DB2
Feinentwurf
die durch SQL-Anfragen mit der Funktion db2-fn:sqlquery() erfolgen (vgl.
Abschnitt 5.2.1.2). Auf diese Weise wird folgender SQL-Ausdruck erzeugt:
1 SELECT XMLQUERY( ’<<query>> ’
PASSING ’<<c o n t e x t m s g i d >> ’ AS ”
d e m a q c o n t e x t m s g i d ”)
3 FROM sysibm . sysdummy1 ;
Es wäre an dieser Stelle auch möglich XQuery direkt, d.h. ohne es in
SQL/XML einzubetten, mit der DB2 auszuführen, indem das Schlüsselwort xquery vor die Regel gesetzt wird und beides an die DB2 übertragen wird. Dies wäre
allerdings mit dem Nachteil verbunden, dass der XQuery-Ausdruck nicht parametrisiert werden könnte, wie beispielsweise durch die <<context_msg_id>> in
obigem Ausdruck.
Eine weitere Anpassung ist notwendig, da die DB2 bei der direkten Ausführung von XQuery kein Kontext-Dokument hat. Das bedeutet, dass der Punkt, der
in XQuery auf das context-item verweist [5], im äußersten Kontext eines XQueryAusdrucks nicht definiert ist. Im Gegensatz dazu ist in Demaq das context-item
als die Kontext-Nachricht definiert, so dass es in der DB2 zu einem Fehler kommt,
wenn in einer Regel der Punkt verwendet wird. Aus diesem Grund muss für die
DB2 das context-item explizit gesetzt werden. Dies kann nur durch einen XPathAusdruck geschehen. Der SQL/XML-Ausdruck zur Regelauswertung wird deshalb wie folgt erweitert:
1 SELECT XMLQUERY( ’ $
demaq contextmsg/(<<query >>) ’
PASSING
3
(SELECT message FROM me ssa g es WHERE i d= ’<<c o n t e x t m s g i d >> ’ )
AS ”
5
’<<c o n t e x t m s g i d >> ’ AS ”
demaq contextmsg ” ,
d e m a q c o n t e x t m s g i d ”)
FROM sysibm . sysdummy1 ;
Mit der Variable $___demaq_contextmsg wird nicht nur in der Regel
(<<query>>) das context-item gesetzt, sondern auf sie wird auch zugegriffen,
wenn in der DQL-Anwendung die Funktion qs:message() verwendet wird (vgl.
92
5.2 Demaq mit der DB2
Feinentwurf
Tabelle 4 auf Seite 90).
93
Implementierung
6
Implementierung
In den vorangehenden Kapiteln wurden zunächst die Ziele und Anforderungen
formuliert (Kapitel 3), die zu implementierenden System-Varianten konzeptuell
entworfen (Kapitel 4) und anschließend auf logischer Ebene verfeinert (Kapitel 5).
In diesem Kapitel wird nun das verfeinerte Design auf physischer Ebene optimiert.
Die physische Optimierung wird zunächst für den Nachrichtenspeicher (Abschnitt 6.1) und anschließend für die Regelauswertung mit der DB2 (Abschnitt
6.2) vorgenommen.
6.1
Optimierung der DB2 als Nachrichtenspeicher
In diesem Kapitel wird dargestellt, inwiefern eine physische Optimierung mit DB2
als Nachrichtenspeicher möglich ist.
6.1.1
Indizes
Grundsätzlich wird von DB2 bei jeder Relation für die Spalten im Primärschlüssel
implizit ein Index angelegt [34]. Deshalb ist für folgende Tabellen keine explizite Erzeugung eines Index notwendig, da der Zugriff ausschließlich über diesen
Schlüssel erfolgt:
• queues (Definition der Warteschlangen)
• properties (Definition der Attribute)
• msg_property (Zuordnung: Nachrichten zu Eigenschaftswert)
• queue_property (Zuordnung: Queue zu Eigenschaftsdefinition)
Die Indizes für die Tabellen der Nachrichten-Warteschlangen wurden bereits
im Kapitel 5.1.4 vorgestellt. Ebenso wurden die Indizes der Slices im Kapitel
4.2.5 erläutert. Ansonsten sind keine weiteren Indizes für Tabellen in der DB2
anzulegen.
94
6.1 Optimierung der DB2 als Nachrichtenspeicher
6.1.2
Implementierung
Datenblöcke für große XML-Nachrichten
Die Größe der Datenblöcke (pagesize) in der DB2 ist standardmäßig 4KB. Wenn
einzelne Daten in Spalten größer sind als 4KB, werden sie in 4KB große Teile zerlegt und auf mehreren Datenseiten gespeichert [36]. Dadurch leidet das Leistungsverhalten, da die Daten bei jedem Lesevorgang aus vielen verteilten Teilstücken
rekonstruiert werden müssen.
Eine Optimierungsmöglichkeit hierfür besteht darin, einen Tablespace mit zugehörigem Bufferpool mit größeren Datenblöcken (max. 32KB) anzulegen. Zusätzlich wird ein Tablespace mit zugehörigem Bufferpool mit kleinen Datenblöcken
(min. 4KB) erzeugt. Die relationalen Daten, die gewöhnlich wenig Platz in Anspruch nehmen, werden in dem Tablespace mit kleinen Datenblöcken gespeichert
und die großen XML- bzw. LOB-Daten in dem mit großen Datenblöcken.
In Frage kommt diese Art der Optimierung für die Tabelle msg_property,
queue_property und die Tabelle, in der die Nachrichten im XML-Format gespeichert werden. Das zugehörige Statement zum Erzeugen der Tabelspaces und
zum Auslagern der Daten sieht wie folgt aus (vgl. [36]):
create b u f f e r p o o l bp4k
2
p a g e s i z e 4k ;
create b u f f e r p o o l bp32k
4
p a g e s i z e 32 k ;
create t a b l e s p a c e r e l D a t a
6
p a g e s i z e 4K
managed by a u t o m a t i c s t o r a g e
8
b u f f e r p o o l bp4k ;
create t a b l e s p a c e xmlData
10
p a g e s i z e 32K
managed by a u t o m a t i c s t o r a g e
12
b u f f e r p o o l bp32k ;
create table me ssa g es (
14
id bigint
message
not null ,
xml
not null ,
95
6.1 Optimierung der DB2 als Nachrichtenspeicher
16
−− s t a t e : 0=enqueued ,1= d e l e t e d
s t a t e smallint not null default 0
18
Implementierung
check ( s t a t e in ( 0 , 1 ) ) ,
primary key ( i d )
) in r e l D a t a
20 l o n g in xmlData ;
Abbildung 26: Durch räumlich getrennt gespeicherte Daten verlängern sich die I/O-Phasen,
weil der Lesekopf der Festplatte umpositioniert werden muss
Ein Nachteil dieser Lösung ist, dass die Daten einer Tabellenzeile räumlich
getrennt voneinander in unterschiedlichen Tablespaces und damit in unterschiedlichen Containern auf der Festplatte gespeichert werden. Durch die physische
Trennung der Daten auf der Festplatte muss der Lesekopf zum Lesen der ganzen Datenzeile mindestens einmal neu positioniert werden (vgl. Abbildung 26),
wodurch sich die I/O-Phase durch die erhöhte Seek Time verlängert [31]. Dementsprechend ist die oben vorgeschlagene Lösung nur optimal, wenn tatsächlich große
XML-Nachrichten (> 3KB) verarbeitet werden. Sollte die zu speichernde Nachricht kleiner als 3KB sein, wird sie entfernt von den zugehörigen Daten gespeichert, obwohl sie auf die Datenseite der Zeile passen würde. Um diesem Nachteil
entgegenzuwirken, wird für XML-Daten eine Inline-Option hinzugefügt [18]. Das
96
6.1 Optimierung der DB2 als Nachrichtenspeicher
Implementierung
zugehörige Create Table-Statement verändert sich damit wie folgt (vgl. [36]):
create table me ssa g es (
2
id bigint
message
4
not null ,
xml
not null i n l i n e l e n g t h 3 0 0 0 ,
−− s t a t e : 0=enqueued ,1= d e l e t e d
s t a t e smallint not null default 0
6
check ( s t a t e in ( 0 , 1 ) ) ,
primary key ( i d )
) in r e l D a t a
8 l o n g in xmlData ;
Der obige Zusatz ”inline length 3000“ besagt, dass XML-Daten bis zu einer
Länge von 3KB zusammen mit den anderen Daten der Tabellenzeile auf der
gleichen Datenseite gespeichert werden. Nur wenn eine Nachricht größer als 3KB
ist, wird diese auf den Tablespace mit der größeren pagesize von 32KB ausgelagert.
Diese Inline ist nur für den XML-Datentyp vorhanden, so dass für die LOBDaten eine andere Lösung gefunden werden muss. Optimal für die Tabellen
msg_property und queue_property ist es, keine Daten auf den Tablespace mit
der pagesize von 32KB auszulagern. Denn in den meisten Fällen wird die Größe der Property-Definitionen und der Property-Werte 3KB nicht überschreiten,
so dass nur in Ausnahmefällen längere Daten auf mehrere Datenseiten aufgeteilt
werden.
6.1.3
Parallelisierung von Lese- und Schreibzugriffen
Parallelität zu erreichen stellt eine wichtige Möglichkeit zur Optimierung des Leistungsverhaltens im Demaq-System dar. NATIX unterstützt Parallelität in der
Speicherverwaltung derzeit nicht explizit. Anders bei der DB2, mit der Parallelität bei der Ausführung per se automatisch erreicht werden kann, z.B. auf einem
Server mit mehr als einem Prozessor. Beim Speichern von Daten kann mit der
DB2 ebenso Parallelität genutzt werden. Diese muss allerdings explizit konfiguriert werden. Ist sie eingerichtet, so wird die parallelisierte Speicherverwaltung
97
6.1 Optimierung der DB2 als Nachrichtenspeicher
Implementierung
von der Datenbank automatisch verwaltet.
Lese- und Schreibzugriffe auf Festplatten stellen einen Engpass in gängigen
Computersystemen dar. Im Gegensatz hierzu ist das Lesen aus dem Hauptspeicher oder Caches um ein Vielfaches schneller. Eine Möglichkeit, um dieses Problematik abzumildern, ist es, die Daten in mehrere kleine Teile zu zerlegen und
jeweils auf unterschiedlichen Festplatten parallel zu speichern. Dadurch wird die
zu speichernde bzw. lesende Datenmenge je Festplatte reduziert, so dass sich Leseund Schreibvorgänge verkürzen (vgl. Abbildung 27). Dieses Prinzip wird von der
DB2 unterstützt und kann automatisch verwaltet werden [41].
Um alle Tablespaces automatisch per default von dem DBMS auf mehrere
Festplatten verteilen zu lassen, muss die Datenbank mit mehreren Zielpfaden
erzeugt werden:
create d a t a b a s e demaq
2
automatic s t o r a g e yes
on /mnt/ d i s k 2 / dknochen ,
4
/mnt/ d i s k 3 / dknochen ,
/mnt/ d i s k 4 / dknochen ,
6
/mnt/ d i s k 5 / dknochen
dbpath on /mnt/ d i s k 6 / dknochen ;
Mit obigem Statement wird eine Datenbank demaq erzeugt, deren Daten automatisch auf fünf Festplatten verteilt werden [19]. Auf der ersten Festplatte
befindet sich das Betriebssystem sowie der Programm-Code von Demaq und der
DB2. Die Festplatten zwei bis fünf werden ausschließlich für die Daten-Container
der Tablespaces verwendet. Der Datenbankpfad ist in diesem Beispiel auf der
sechsten Festplatte. Hier werden einige Steuerdateien von dem DBMS für die
Datenbank abgelegt. Mit dieser Beispielkonfiguration, die in den Tests in Kapitel
7.2 verwendet wird, kann eine hoher Grad an Parallelität erreicht werden.
98
6.1 Optimierung der DB2 als Nachrichtenspeicher
Implementierung
Abbildung 27: Automatische Speicherverwaltung über mehrere Festplatten (adaptiert von [41]).
(a) Engpass bei der Speicherung auf einer Festplatte durch lange I/O-Zyklen. (b) Speicherung
auf mehreren Festplatten und Verkürzung der I/O-Zyklen durch Parallelisierung
6.1.4
Nebenläufige Verarbeitung von Nachrichten
Das Realisierungsvorhaben der Nebenläufigkeit wird dadurch erleichtert, dass der
Quelltext des Demaq-Ausführungssystems bereits alles Notwendige enthält, um
die nebenläufige Verarbeitung von Nachrichten zu ermöglichen: Innerhalb eines
Dispatchers (vgl. Kapitel 2.1.2.2) können beliebig viele ProcessingThreads gestartet werden. Jedoch wird im aktuellen System immer nur ein Prozess pro
Dispatcher gestartet, da mit NATIX als Nachrichtenspeicher keine nebenläufigen Verarbeitungen möglich sind. Die Anzahl der gestarteten Threads kann
mit der DB2 als Nachrichtenspeicher erhöht werden, indem die Funktion Dis99
6.2 Optimierung der Regelauswertung mit der DB2
Implementierung
patcher::increaseThreadCount() beliebig oft vor dem Start eines Dispatchers
aufgerufen wird. Damit sind die Anpassungen für die Realisierung der Nebenläufigkeit mit der DB2 trivial.
6.2
Optimierung der Regelauswertung mit der DB2
In diesem Kapitel werden Möglichkeiten dargestellt, mit denen die Regelauswertung mithilfe der DB2 optimiert werden kann.
6.2.1
Vermeidung von Serialisier- und Parsingvorgängen
XML-Dokumente werden von der DB2 ausschließlich in serialisierter Textform
an aufrufende Applikationen zurückgegeben (vgl. Kapitel 2.3.2). Ebenso können
sie nur in serialisierter Form an die DB2 übermittelt werden. Aus diesem Grund
ist der Aufwand für Parsing- und Serialisierungs-Vorgänge umso höher, je mehr
Nachrichten zwischen der DB2 und einer anderen Komponente ausgetauscht werden.
Abbildung 28 stellt exemplarisch die Interaktion von Saxon als Regelauswerter, DB2 als Nachrichtenspeicher und Demaq dar. Die Anwendung ist so definiert,
dass eine Nachricht, die über eine HTTP-Verbindung kommt, in einer GatewayQueue vom Typ Incoming gespeichert wird. Anschließend wird sie an eine interne
Warteschlange vom Typ Basic weitergeleitet. Diese zwei enqueue-Aufrufe bedingen fünf Parsing- und vier Serialisierungsvorgänge im System. Durch die Übergänge zwischen den verschiedenen Komponenten im Demaq-System entsteht ein
Overhead an redundanten Parsing- und Serialisierungs-Operationen. Aus diesem
Grund ist zu erwarten, dass die Tests zum Leistungsverhalten dieser SystemVariante eher negativ ausfallen.
Verbessert werden kann diese Situation, wenn statt Saxon DB2 zur Regelauswertung eingesetzt wird. Durch diese Änderung fallen die KomponentenÜbergänge zwischen Nachrichtenspeicher und Regelauswerter weg und damit
100
6.2 Optimierung der Regelauswertung mit der DB2
Implementierung
Abbildung 28: Serialisierungs- und Parsing-Vorgänge in einer Beipsiel-Anwendung im DemaqSystem mit der DB2 und Saxon
auch überflüssige Parsing- und Serialisierungs-Vorgänge. Gegenüber der in Abbildung 28 schematisierten Beispielanwendung kann auf diese Weise einer von
fünf Parsing-Vorgängen und eine von vier Serialisierungs-Operationen eingespart
werden (vgl. Abbildung 29).
Eine weitere Einsparung ist möglich, indem Nachrichten, die mit enqueue in
eine andere interne Warteschlange eingereiht werden, nicht erst an den DemaqKern zurückgegeben werden. Denn bisher werden Nachrichten im QueryResult
als Ergebnis einer Regelauswertung an den Demaq-Kern übergeben, damit dort
die enthaltenen Aktionen interpretiert und mit den Nachrichten ausgeführt werden können. Soll eine Nachricht in einer Aktion nicht an eine Gateway-Queue,
101
6.2 Optimierung der Regelauswertung mit der DB2
Implementierung
Abbildung 29: Serialisierungs- und Parsing-Vorgänge in einer Beipsiel-Anwendung im DemaqSystem mit der DB2 als Nachrichtenspeicher und Regelauswerter
sondern an eine interne Basic-Queue übermittelt werden, wird sie unverändert
an die DB2 zurückgegeben und löst auf diese Weise einen zusätzlichen Parsingund Serialisierungs-Vorgang aus.
Nachrichten, die intern weitergeleitet werden, sollten direkt in der DB2 mit
enqueue eingereiht werden. Wird die Regelauswertung derart verändert, müssen
diese Nachrichten später nicht noch einmal geparst werden (vgl. Abbildung 30).
Statt der kompletten Nachrichten werden dem Demaq-Kern nur die IDs der intern
neu eingereihten Nachrichten mitgeteilt, damit der Actioninterpreter diese bei
der Generierung der ConsequenceList berücksichtigen kann. Der Actioninterpreter muss demnach angepasst werden, so dass er interne enqueues nicht noch
einmal ausführt.
102
6.2 Optimierung der Regelauswertung mit der DB2
Implementierung
Abbildung 30: Serialisierungs- und Parsing-Vorgänge in einer Beipsiel-Anwendung im DemaqSystem mit der DB2 als Nachrichtenspeicher und Regelauswerter (optimiert)
6.2.2
Implementierung der Regelauswertung mit DB2
In Kapitel 5.2.2 wurde beschrieben, wie sich die Regelauswertung in der DB2 auf
logischer Ebene umsetzen läßt. Darauf aufbauend wurde in Kapitel 6.2.1 erläutert, wie der Ablauf in der Auswertung der Regeln optimiert werden kann. Zur
Umsetzung des sich ergebenden Mechanismus der Regelauswertung bieten sich
zwei Alternativen an. Zum einen können Stored Procedures für die Auswertung
von Regeln verwendet werden. Zum anderen kann ein SQL-Statement zusammengesetzt werden, dass als Seiteneffekte die enqueues ausführt und ein QueryResult
zurückliefert. Beide Varianten werden in den beiden folgenden Abschnitten 6.2.2.1
und 6.2.2.2 detailliert vorgestellt.
103
6.2 Optimierung der Regelauswertung mit der DB2
Implementierung
Entsprechend der vorhergehenden Diskussionen (vgl. Kapitel 5.2.2 und 6.2.1)
sind folgende Arbeitsschritte in beiden Varianten auszuführen:
1. Die XQuery-basierte Regel muss wie bisher auf die Kontext-Nachricht angewandt und zu einer Aktionenliste im XML-Format evaluiert werden.
2. Alle internen enqueues müssen direkt in der DB2 ausgeführt werden.
3. Die Aktionenliste muss geändert werden, so dass bei den internen enqueueAktionen nur die ID der neu eingereihten Nachrichten enthalten ist und
nicht die komplette Nachricht selbst.
4. Die modifizierte Aktionenliste muss als Ergebnis der Regelauswertung zurückgegeben werden.
6.2.2.1
Regelauswertung mit Stored Procedures In Stored Procedures
können sowohl SQL- als auch SQL/XML- und XQuery-Ausdrücke verwendet
werden [38]. Außerdem können mehrere einzelne Statements zu einem atomaren Block zusammengefasst werden [47]. Zunächst wird für jede Regel eine eigene
Stored Procedure mit dem Präfix qs_rule_ und dem Namen <<rulename>>
wie folgt erzeugt, damit mit dieser die Aktionenliste bei der Regelauswertung
generiert werden kann:
1 CREATE PROCEDURE q s r u l e <<rulename>> ( IN msgid int ,OUT p a l xml )
LANGUAGE SQL
3 READS SQL DATA
NO EXTERNAL ACTION
5 P1 : BEGIN
SET p a l=XMLQUERY( ’ $
7
demaq contextmsg/(<<query >>) ’
PASSING
(SELECT message FROM me ssa g es WHERE i d=msgid )
9
AS ”
msgid AS ”
demaq contextmsg ” ,
d e m a q c o n t e x t m s g i d ”) ;
11 END P1
104
6.2 Optimierung der Regelauswertung mit der DB2
Implementierung
In obiger Vorlage wird anstelle von <<query>> der XQuery-Ausdruck, in
den die Regel vom XQL-Parser [46] umgewandelt wurde, eingefügt. Die auf diese Weise erzeugte Stored Procedure wird nicht direkt vom DB2RuleProcessor
aufgerufen, da sie die Aktionenliste liefert, welche noch die Aktionen für interne
enqueues enthält.
Damit die internen enqueues bereits innerhalb der DB2 ausgeführt werden
und nicht an den Demaq-Kern zurückgegeben werden, wird eine weitere Stored
Procedure mit dem Namen ruleexecutor generiert, die zur Regelauswertung vom
DB2RuleProcessor aufgerufen wird. Dieser Prozedure wird der Regelname von
der Regel übergeben, die ausgeführt werden soll. Mit Hilfe von dem Regelnamen
weiß die ruleexecutor-Prozedur, welche Regel-Prozedur sie aufrufen muss, um
für die Regel die Aktionenliste zu bekommen. Die von der Regel-Prozedur erhaltene Aktionenliste wird dann weiterverarbeitet, um die internen enqueues direkt
auszuführen (vgl. Kapitel 6.2.1).
Die Umsetzung der Stored Procedure ruleexecutor wird im Folgenden dargestellt:
1 CREATE PROCEDURE r u l e e x e c u t o r ( IN msgid int , IN rulename varchar
( 2 5 6 ) ,OUT q r e s u l t CLOB )
LANGUAGE SQL
3 MODIFIES SQL DATA
NO EXTERNAL ACTION
5 P1 : BEGIN
DECLARE p a l XML;
7 DECLARE i n s e r t e d XML;
DECLARE stmt varchar ( 1 0 0 0 ) ;
9 DECLARE newidsxml XML;
DECLARE m o d i f i e d p a l XML;
11
SET stmt= ’ c a l l q s r u l e ’ c o n c a t rulename c o n c a t ’ ( ? , ? ) ’ ;
13 PREPARE s 1 FROM stmt ;
105
6.2 Optimierung der Regelauswertung mit der DB2
Implementierung
15 −− 1 . R e g e l zu e i n e r A k t i o n e n l i s t e e v a l u i e r e n :
EXECUTE s 1 into p a l USING msgid ;
17
−− 2 . I n t e r n e e n q u e u e s d e r r e s u l t i e r e n d e n A k t i o n e n l i s t e
19 −− d i r e k t a u s f u e h r e n und d i e neuen N a c h r i c h t e n −IDs z u r u e c k g e b e n :
SELECT
21
XMLELEMENT (NAME ”msgids ” ,
XMLAGG ( XMLELEMENT ( NAME ” i d ” , i d )
23
ORDER BY i d )
)
25 INTO P1 . newidsxml
FROM new table (
27
INSERT INTO me ssa g es ( id , queuename , message , m e s s a g e s i z e , s t a t e )
SELECT n e x t v a l f o r MESSAGE ID SEQ , enq . t a r g e t , enq . message ,
l e n g t h ( x m l s e r i a l i z e ( enq . message as clob ) ) as l e n g t h , 0
29
FROM XMLTABLE( ’ $ p a l / enqueue ’ PASSING
P1 . p a l AS ” p a l ”
31
COLUMNS
”MESSAGE” XML PATH ’ document { . / message / ∗ [ 1 ] } ’ ,
33
”TARGET” varchar ( 2 5 5 ) PATH ’ . / @ t a r g e t ’ ,
”POSITION” int PATH ’ . / p o s i t i o n ( ) ’
35
) AS enq
ORDER BY enq . position
37
)
GROUP BY s t a t e ;
39
−− 3 . Die u r s p r u e n g l i c h e A k t i o n e n l i s t e v e r a e n d e r n und a n s t e l l e
41 −− d e r N a c h r i c h t e n d i e neuen IDs e i n f u e g e n :
SET m o d i f i e d p a l=XMLQUERY( ’ copy $new := $ p a l
43
modify
f o r $ e n q u e u e p o s i t i o n i n $new/ enqueue / p o s i t i o n ( )
l e t $newmsgid := $newmsgids / i d [ p o s i t i o n ( )=$ e n q u e u e p o s i t i o n ]
45
l e t $enqueue := $new/ enqueue [ p o s i t i o n ( )=$ e n q u e u e p o s i t i o n ]
r e t u r n do r e p l a c e $enqueue / message with <message msgid =”{
$newmsgid }”/>
106
6.2 Optimierung der Regelauswertung mit der DB2
47
Implementierung
r e t u r n $new ’
PASSING
49
P1 . p a l AS ” p a l ” ,
P1 . newidsxml AS ”newmsgids ”
51 ) ;
53 −− 4 . Die m o d i f i z i e r t e A k t i o n e n l i s t e z u r u e c k l i e f e r n :
SET q r e s u l t=XMLSERIALIZE( m o d i f i e d p a l as clob ) ;
55 END P1
Die Ausführung der internen enqueues wird mit einem SELECT-Statement mit
Seiteneffekt durchgeführt [3]. Mit dem Konstrukt ”new table(INSERT...)“ wird
aus den eingefügten Datensätzen eine temporäre Tabelle erzeugt, auf die in einem
äußeren SELECT-Statement zugegriffen werden kann. Auf diese Weise können die
INSERT-Statements ausgeführt und gleichzeitig die neu eingefügten NachrichtenIDs zurückgegeben werden.
Im dritten Schritt (siehe Kommentare im Code) wird die ursprüngliche Aktionenliste mithilfe eines XQuery-Update-Statements (”do replace“) verändert,
indem die Nachrichten-IDs der neu eingefügten Nachrichten an die Stelle der
Nachrichten selbst gesetzt wird.
6.2.2.2
Regelauswertung durch ein atomares SQL-Statement Etwas
komplizierter als die Umsetzung mit Stored Procedures ist die Regelauswertung
bei Ausführung eines einzelnen SQL-Statements. Hierbei werden die einzelnen
SQL-Statements, wie sie in Kapitel 6.2.2.1 vorgestellt wurden, zu einem einzigen
Ausdruck zusammengefasst. Dementsprechend werden die Zwischenergebnisse
nicht in Variablen, sondern in temporären Tabellen mithilfe des WITH-Statements
[23] zwischengespeichert.
Das sich daraus ergebende Statement sieht wie folgt aus:
1 with
−− 1 . E v a l u i e r e A k t i o n e n l i s t e
107
6.2 Optimierung der Regelauswertung mit der DB2
3
a c t i o n s ( p a l ) AS (
SELECT XMLQUERY( ’ $
5
Implementierung
demaq contextmsg/(<<query >>) ’
PASSING
(SELECT message FROM me ssa g es WHERE i d= ’<<c o n t e x t m s g i d >> ’ )
7
AS ”
demaq contextmsg ” ,
’<<c o n t e x t m s g i d >> ’ AS ”
9
d e m a q c o n t e x t m s g i d ”)
FROM sysibm . sysdummy1 ) ,
11 −− 2 . Fuehre i n t e r n e e n q u e u e s d i r e k t aus
newmsgids ( id , group ) AS (
13
SELECT id , ’dummy ’ ”
FROM new t a b l e (
15
INSERT INTO m essa g es ( id , queuename , message , m e s s a g e s i z e ,
state )
SELECT n e x t v a l f o r MESSAGE ID SEQ , enq . t a r g e t , enq .
message , l e n g t h ( x m l s e r i a l i z e ( enq . message a s c l o b ) ) , 0
17
FROM XMLTABLE( ’ $ p a l / enqueue ’ PASSING
(SELECT p a l FROM a c t i o n s FETCH FIRST 1 ROW ONLY) AS ”
pal ”
19
COLUMNS
”MESSAGE” XML PATH ’ document { . / message / ∗ [ 1 ] } ’ ,
21
”TARGET” v a r c h a r ( 2 5 5 ) PATH ’ . / @target ’ ,
”POSITION” i n t PATH ’ . / p o s i t i o n ( ) ’
23
) AS enq
ORDER BY enq . p o s i t i o n
25
)
),
27
−− G ru p p ie r e d i e neu e i n g e r e i h t e n N a chric hten −IDs
29
i n s e r t e d ( i d s ) AS (
SELECT XMLELEMENT(NAME ”msgids ” ,
31
XMLAGG (XMLELEMENT (NAME ” i d ” , n . i d ) ORDER BY n . i d ) ”
)
33
FROM newmsgids n
108
6.2 Optimierung der Regelauswertung mit der DB2
Implementierung
GROUP BY n . group
35
),
37 −− 3 . Passe d i e A k t i o n e n l i s t e an : e r s e t z t d i e b e r e i t s e i n g e r e i h t e n
−− N a c h r i c h t e n durch i h r e i d s
39
t o b e r e t u r n e d ( p a l ) AS (
SELECT xmlquery ( ’ copy $new := $ p a l
41
modify f o r $ e n q u e u e p o s i t i o n i n $new/ enqueue / p o s i t i o n ( )
l e t $newmsgid := $newmsgids / i d [ p o s i t i o n ( )=
$enqueueposition ]
43
l e t $enqueue := $new/ enqueue [ p o s i t i o n ( )=$ e n q u e u e p o s i t i o n
]
r e t u r n do r e p l a c e $enqueue / message with <message msgid
=”{$newmsgid }”/>
45
r e t u r n $new ’
PASSING (SELECT p a l FROM a c t i o n s FETCH FIRST 1 ROW ONLY) AS
”pal ” ,
47
( Select i d s from i n s e r t e d FETCH FIRST 1 ROW ONLY) AS ”
newmsgids ”
)
49
FROM sysibm . sysdummy1
)
51
−− 4 . Gebe d i e a n g e p a s s t e A k t i o n e n l i s t e a l s E r g e b n i s z u r u e c k
53 SELECT p a l
FROM t o b e r e t u r n e d ;
Der obige SQL-Code besteht aus einem einzigen zusammengesetzten Statement. Zur besseren Lesbarkeit sind die einzelnen Schritte zur Regelauswertung
jeweils kommentiert.
Der Vorteil dieser Variante ist, dass Regeln jeweils dynamisch in ein SQLStatement eingebunden werden und dass die DB2 über alle Teilausdrücke des
SQL-Statements hinweg eine automatische Optimierung vornehmen kann [3].
109
6.2 Optimierung der Regelauswertung mit der DB2
6.2.3
Implementierung
Steuerung der Weiterverarbeitung von Nachrichten mit Triggern
Ein Feature der DB2, das zum Umsetzen von Demaq-Funktionalität in der DB2
in Betracht gezogen werden kann, sind Trigger. Beispielsweise kann erwogen werden, Trigger zu verwenden, um nach dem Einfügen einer neuen Nachricht die
Regelauswertung auf dieser zu starten.
Hierbei treten allerdings zwei Probleme auf, die einen Einsatz von Triggern
zu diesem Zweck unmöglich machen. Das eine Problem ist, dass es nicht möglich
ist, die Ausführung eines Triggers zu verzögern, bis eine eingefügte Nachricht mit
commit bestätigt wurde. D.h. Trigger würden immer sofort zum Zeitpunkt des
Einfügens einer Nachricht ausgeführt, so dass auf diese Weise Nachrichten weiterverarbeitet würden, die potenziell durch ein rollback wieder gelöscht werden
könnten.
Das zweite Problem geht mit dem Ersten einher: Trigger laufen immer im
Kontext ihrer aufrufenden Transaktion ab. Es ist nicht möglich innerhalb eines Triggers eine Transaktion zu beenden und eine neue Transaktion zu starten
[25]. Auch darf in einem Trigger keine Prozedur aufgerufen werden, die ein commit auslöst [24]. Da aber die Verarbeitung einer neu eingefügten Nachricht laut
Spezifikation des Demaq-Systems [6, 46] in den Kontrollabschnitt einer eigenen
Transaktion fällt, ist der Einsatz von Triggern auch aus diesem Grund nicht
möglich.
110
Evaluation
7
Evaluation
Die bisherigen Betrachtungen haben sich mit der Analyse, dem Design sowie der
Implementation der zu entwickelnden Demaq-System-Varianten beschäftigt. In
diesem Kapitel werden die entwickelten System-Varianten evaluiert. Zum einen
wird das System qualitativ überprüft (Abschnitt 7.1). Zum anderen wird es quantitativ mittels definierter Testanwendungen experimentell untersucht (Abschnitt
7.2).
7.1
Qualitative Evaluation
Die qualitative Evaluation bewertet die entwickelten System-Varianten anhand
der Anforderungen aus Kapitel 3.3.
7.1.1
Korrektheit
Zum Überprüfen der Korrektheit wurden Testfälle definiert. Wichtig hierbei war,
dass sowohl das System mit NATIX, als auch das mit der DB2 zu den gleichen Ergebnissen kommen. Die definierten Testanwendungen sind im Anhang in Kapitel
A.1.1 aufgelistet.
Die Testfälle wurden zudem verwendet, um peu a peu die lauffähige Funktionalität im System mit ausgetauschtem Nachrichtenspeicher und im späteren
Verlauf mit der ausgetauschten Regelauswertung zu vervollständigen. Deshalb
wurden die Tests derart definiert, dass sie sich sukzessiv in der Komplexität steigern und somit mehr Funktionen des Demaq-Systems abdecken. Auf diese Weise
konnten nach dem Vorbild der agilen Software-Entwicklung (”Working software
is the primary measure of progress.“ [2]) zunächst die wichtigsten Funktionalitäten, wie beispielsweise ”create queue“ oder ”create rule“, implementiert sowie
getestet werden. Anschließend wurden nach und nach weitere Features, wie z.B.
”qs:slice“ oder ”qs:slicekey“, ergänzt.
111
7.1 Qualitative Evaluation
Evaluation
Eine Einschränkung der System-Varianten mit der DB2 als Nachrichtenspeicher hat sich bei den Tests gezeigt und bleibt als offenes Problem bestehen: Es
kann nur auf Properties und Slicekeys der aktuell bearbeiteten Nachricht zugegriffen werden. Dieses Problem ist darauf zurückzuführen, dass von der XMLRepräsentation einer Nachricht nicht auf ihre ID im Nachrichtenspeicher geschlossen werden kann, da die Spalte message in der Tabelle messages nicht eindeutig
ist. Für den Zugriff auf Properties oder den Slicekey einer beliebigen Nachricht,
wird die ID aber zwingend benötigt. Im System mit NATIX wird hierzu eine Processing Instruction verwendet, die an jede Nachricht angefügt die Nachrichten-ID
enthält. Dies wurde nicht implementiert.
7.1.2
Modularisierung
Eine Modularisierung konnte im Rahmen dieser Diplomarbeit umgesetzt werden.
Auf den Nachrichtenspeicher wird nun ausschließlich über die NatixGatewaybzw. die DB2Gateway-Klasse zugegriffen, so dass ein Austausch des Nachrichtenspeichers allein durch Implementierung einer passenden Gateway-Klasse erfolgen
kann.
Ähnlich verhält es sich beim Austausch der Regelauswertung. Hierzu werden
die modularisierten Klassen NatixRuleprocessor, NatixQueryResult und NatixActioninterpreter ersetzt. Im Rahmen dieser Arbeit ist dies geschehen mit
den Klassen DB2Ruleprocessor, DB2QueryResult und DB2Actioninterpreter.
7.1.3
Leistungsverhalten
In dieser Diplomarbeit wurde gezeigt, dass eine Integration der relationalen Datenbank DB2 als Nachrichtenspeicher in das Demaq-System möglich ist. Die Optimierung des Leistungsverhaltens war über die Machbarkeit hinaus eine wichtige
Anforderung. Aus diesem Grund wurden zahlreiche Optimierungsmöglichkeiten
sowohl auf logischer als auch auf physischer Ebene vorgeschlagen. Letztendlich
112
7.2 Quantitative Evaluation
Evaluation
konnte eine Optimierung hauptsächlich nur auf theoretischer Basis durchgeführt
werden, so dass ein Vergleich für viele Varianten nicht vorliegt. Außerdem wurde
bei der Implementierung auf eine zu frühe Optimierung verzichtet, weshalb das
derzeitige Leistungsverhalten qualitativ bewertet als steigerungsfähig einzustufen
ist.
7.2
Quantitative Evaluation
Wesentlicher Bestandteil dieser Diplomarbeit ist die Bearbeitung von zwei Teilproblemen, die bereits in Kapitel 3.4.2 kurz beschrieben wurden. Demgemäß werden zur quantitativen Evaluation zwei unabhängige Experimentreihen für die
Teilprobleme durchgeführt: Zum einen wird das Leistungsverhalten verschiedener Abbildungen von Warteschlangen in einem relationalen DBMS untersucht
und zu der nativen Implementierung in NATIX in Vergleich gesetzt. Zum anderen wird die Veränderung im Leistungsverhalten des Demaq-Ausführungssystems
betrachtet, nachdem zur Regelauswertung die DB2 XQuery Engine anstelle von
Saxon verwendet wird.
Um wissenschaftliche Fragestellungen zu untersuchen, gibt es eine Vielzahl an
möglichen Methoden. Demzufolge muss die Frage beantwortet werden, warum ein
formales Experiment die geeignete Wahl ist. Da aber im Rahmen dieser Arbeit
ein funktionales Softwaresystem geschlossen untersucht wird, ohne Benutzer oder
andere äußere Umstände in der Betrachtung zu berücksichtigen, erscheint die
wissenschaftliche Methode des formalen Experiments als offensichtliche Wahl.
Dennoch werden die formalen Anforderungen für ein Experiment in Kapitel 7.2.1
zur Vollständigkeit kurz überprüft. Darüber hinaus sollen die Experimente wie
folgt definiert und durchgeführt werden [39]:
1. Überprüfung der Anforderungen für formale Experimente (Kapitel 7.2.1)
2. Konzeption (Kapitel 7.2.2)
113
7.2 Quantitative Evaluation
Evaluation
3. Design (Kapitel 7.2.3, 7.2.4 und 7.2.5)
4. Vorbereitung (Kapitel 7.2.7)
5. Durchführung (Kapitel 7.2.8)
6. Analyse (Kapitel 7.2.9).
7.2.1
Erfüllung der Anforderungen für formale Experimente
In Tabelle 5 sind die Anforderungen aufgelistet, die laut [39] zu erfüllen sind,
damit ein formales Experiment die richtige Methode für eine Untersuchung darstellt.
Eigenschaft
Experiment
Grad der Kontrolle
Hoch
Schwierigkeit der Kontrolle
Niedrig
Grad der Wiederholbarkeit
Hoch
Aufwand der Wiederholung
Niedrig
Tabelle 5: Eigenschaften, welche die Durchführung eines Experiments rechtfertigen (vgl. [39])
Die wissenschaftliche Methode des formalen Experiments ist für die vorliegende Aufgabenstellung der Diplomarbeit die geeignete Wahl. Dementsprechend
sind die formalen Anforderungen wie folgt erfüllt:
Grad der Kontrolle Der Grad der Kontrolle ist hoch. Es gibt kaum Einflussfaktoren, die nicht kontrollierbar sind, wie z.B. menschliches Verhalten.
Faktoren wie die Laufzeitumgebung können frei festgelegt und konstant gehalten werden.
Schwierigkeit der Kontrolle Die Schwierigkeit der Kontrolle ist niedrig. Die
Laufzeitumgebung wird nicht verändert. Das System kann über KompilierOptionen gesteuert werden und mit Hilfe von Logdateien überprüft werden.
114
7.2 Quantitative Evaluation
Evaluation
Grad der Wiederholbarkeit Die Untersuchung kann beliebig oft mit definierten Testfällen wiederholt werden.
Aufwand der Wiederholung Ein Testdurchlauf wird mit einem einzelnen
Shellskriptaufruf gestartet.
7.2.2
Konzeption der Experimente
Die Konzeption eines Experiments beinhaltet die Festlegung des Ziels, bzw. der
Ziele [39]. Idealerweise wird eine Fragestellung formuliert, die nach der Durchführung des Experiments beantwortet wird. Deshalb werden in folgenden Unterkapiteln 7.2.2.1 bzw. 7.2.2.2 die Ziele festgelegt und entsprechende Fragestellungen
formuliert. Zur Vereinfachung wird nachfolgend vom ”Experiment Warteschlange“, bzw. ”Experiment Regelauswertung“ gesprochen. Gemeint sind die Experimente, die das entsprechende Problem, wie es in Kapitel 3.4.2 vorgestellt wurde,
bearbeiten.
7.2.2.1
Ziele des Experiments Warteschlange Ziel dieses Experiments
ist es, innerhalb des Demaq-Systems eine effiziente Warteschlangen-Abbildung in
einem relationalen Datenbanksystem (im Speziellen in der DB2) zu finden. Diese
Abbildung soll die effiziente Ausführung der enqueue- und dequeue-Funktionen
sowie sonstige Operationen auf Warteschlangen im Demaq-System unterstützen.
Zu diesem Zweck wurden in Kapitel 5.1.4 bereits einige Alternativen für mögliche
Abbildungen diskutiert, von denen die Varianten 1, 6 und 7 (vgl. Kapitel 5.1.4.1,
5.1.4.6 und 5.1.4.7) auf ihre Leistungsfähigkeit hin überprüft werden.
Die zu beantwortende Frage ist: Welche der untersuchten Abbildungen für
Warteschlangen im relationalen Datenbanksystem bedingt eine schnellstmögliche Abarbeitung der Elemente? Und als zweite sich anschließende Frage: Wie
gut ist das Leistungsverhalten dieser Abbildung im Gegensatz zu der nativen
Warteschlangen-Implementierung des NATIX-Systems?
115
7.2 Quantitative Evaluation
Evaluation
Abbildung 31: Übersicht der Testanwendungen für die Experimente und deren benutzte DemaqFeatures
7.2.2.2
Ziele des Experiments Regelauswertung Ziel dieses Experi-
ments ist es zunächst, zu überprüfen, ob eine Regelauswertung mit der XQueryEngine der DB2 möglich ist. Dabei ist es wichtig, dass die Demaq-spezifischen
Funktionen möglichst vollständig und vor allem korrekt ausgeführt werden können. Ein weiteres Ziel ist es, das Leistungsverhalten der Regelauswertung mit der
DB2 mit der Saxon-basierten Regelauswertung in Relation zu setzen.
Die zu beantwortenden Fragen lauten demnach: Läßt sich die DemaqRegelauswertung vollständig und korrekt mit der DB2 umsetzen? Und des Weiteren: Wie steht das Leistungsverhalten dieser Regelauswertung im Verhältnis zur
Regelauswertung mit Saxon?
7.2.3
Testanwendungen
Die Testanwendungen sind mit unterschiedlicher Komplexität definiert und legen
ihren Fokus auf unterschiedliche Demaq-Features (vgl. Abbildung 31). Auf diese
Weise kann einerseits eine hohe Allgemeingültigkeit erreicht werden, da Anwendungsfelder in allen Komplexitätsstufen für Demaq denkbar sind. Andererseits
116
7.2 Quantitative Evaluation
Evaluation
Abbildung 32: Testanwendung 1 und 2: Simulation mit einem Server und mehreren Clients
können so Zusammenhänge zwischen bestimmten Features von Demaq, wie z.B.
der Zugriff auf Slices oder Properties, und dem Leistungsverhalten hergestellt
werden. Beispielsweise könnte der Zugriff auf Properties im relationalen DBMS
sehr effizient sein, während das Abfragen von Slices eher uneffizient ist. Welche
Aussagen dieser Art am Ende getroffen werden können, ist offen, weshalb die
Testanwendungen möglichst wenig antizipativ sein sollen.
In den Versuchsanwendungen sollte möglichst keine Kommunikation nach außen erfolgen, so dass keine Indeterminismen im Kommunikationsaufbau über das
Betriebssystem auftreten können. Demnach wird pro Anwendung nur für die
Start- und Antwort-Nachricht ein externer Kommunikationskanal verwendet.
Außerdem muss es in jeder Anwendung ein Terminierungs-Charakteristikum
geben, das nicht an ein zufälliges Ereignis gekoppelt ist. Dadurch wird bei jedem
Durchlauf der Test-Applikation eine gleichbleibende Menge an Arbeit garantiert.
Beispielsweise könnte in einem deterministischen Ablauf eine festgelegte Anzahl
an Nachrichten die Terminierung bewirken.
Die Testapplikationen sollen typische Anwendungsparadigmen im Bereich der
117
7.2 Quantitative Evaluation
Evaluation
Business-Processes simulieren. Sie stellen aber isoliert betrachtet keine realistischen Anwendungsbeispiele dar.
7.2.3.1
Testanwendung 1: Client/Server-Simulation In dieser Testan-
wendung tauschen mehrere Client-Warteschlangen Nachrichten mit einer Server Warteschlange aus. Die Server -Warteschlange wird überdurchschnittlich ausgelastet und stellt somit einen Engpass dar. Das Ziel der Clients ist es, 1000 Nachrichten mit dem Server hin und her zu wechseln. Die Anzahl der gewechselten
Nachrichten wird innerhalb des Wurzelelementes einer Nachricht in dem Attribut
msgcount vermerkt. Die Nachrichten werden ansonsten unverändert retourniert.
Variantenname
Anzahl der Clients
Größe der Nachricht
A1
5
1KB
A2
11
1KB
A3
21
1KB
B1
5
10KB
B2
11
10KB
B3
21
10KB
C1
5
100KB
C2
11
100KB
C3
21
100KB
Tabelle 6: Varianten der Testanwendungen 1 und 2
Hat einer der Clients 1000 Nachrichten mit dem Server gewechselt, meldet er
dies, indem er eine Nachricht an die report-Warteschlange schickt. Die reportWarteschlange wartet bis alle Clients eine Beendigungs-Nachricht gesendet haben
und schickt dann eine Antwort-Nachricht, mit der die Anwendung beendet wird.
Tabelle 6 listet Variationen auf, die mit dieser Anwendung untersucht werden.
Auf diese Weise soll ein breites Spektrum an Komplexitäten abgedeckt werden.
118
7.2 Quantitative Evaluation
Evaluation
Abbildung 33: Testanwendung 3: Prozesskette mit Überkreuzung
Für die Variante A1 ist der DQL-Code im Anhang A.1.2.1 angefügt. Abbildung
32 stellt die Testapplikation ”Client/Server-Simulation“ schematisch dar.
7.2.3.2
Testanwendung 2: Client/Server-Simulation mit qs:queue()
Die Testanwendung ”Client/Server-Simulation mit qs:queue()“ ist identisch zu
der ersten Testanwendung, außer dass die Clients nur 100 Nachrichten mit dem
Server austauschen sowie dass die Anzahl der gewechselten Nachrichten nicht
mehr in einem Attribut vermerkt wird. Stattdessen wird die aktuelle Anzahl der
gewechselten Nachrichten darüber bestimmt, wie viele Nachrichten in einer Client-Warteschlange vorhanden sind. Zu diesem Zweck wird die Demaq-Funktion
qs:queue() und die XQuery-Standard-Funktion fn:count() verwendet. Die Varianten dieser Testanwendung sind ebenfalls in Tabelle 6 aufgeführt. Beispielhaft
für die Variante A1 ist der DQL-Code im Anhang A.1.2.2 angefügt.
7.2.3.3
Testanwendung 3: Prozesskette mit Überkreuzung Bei dieser
Anwendung werden in mehreren Testreihen (vgl. Tabelle 7) unterschiedlich viele Prozessketten mittels Nachrichten gleichzeitig durch eine zirkulär angeordnete
Reihe von Warteschlangen geschickt. Die Warteschlangen sind dabei derart an119
7.2 Quantitative Evaluation
Evaluation
geordnet, dass sie von zwei Seiten an die gleiche Warteschlange senden und somit
eine virtuelle Acht formen. Damit die Nachrichten an der Überkreuzung richtig
weitergeleitet werden, wird für sie ein Property verwaltet, in dem vermerkt wird,
ob sie sich im Prozessverlauf auf der großen Schleife befinden und folglich auf die
Kleine weitergeleitet werden müssen oder umgekehrt. Abbildung 33 visualisiert
den Aufbau dieser Testanwendung.
Variantenname
Anzahl gleichzeitiger Größe der
Prozessketten
Nachrichten
A1
5
1KB
A2
20
1KB
A3
40
1KB
B1
5
10KB
B2
20
10KB
B3
40
10KB
C1
5
100KB
C2
20
100KB
C3
40
100KB
Tabelle 7: Varianten der Testanwendung 3
Die Prozesse werden durch eine Start-Nachricht von außen gestartet und jede Nachricht muss 50 mal die Prozesskette durchlaufen. Die Anzahl der Durchläufe wird in einem Property gespeichert. Sobald eine Nachricht 50 Durchgänge
absolviert hat, wird dies durch eine Nachricht an die Warteschlange report gemeldet. Die report-Warteschlange wartet bis alle Prozesse abgeschlossen sind.
Dann schickt sie eine Antwort-Nachricht an die ursprünglich aufrufende GatewayQueue, wodurch die Anwendung beendet wird.
120
7.2 Quantitative Evaluation
Evaluation
Abbildung 34: Testanwendung 4: Prozess-Simulation Split/Join
7.2.3.4
Testanwendung 4: Prozess-Simulation Split/Join In dieser
Testanwendung laufen mehrere Prozesse gleichzeitig ab. Jeder Prozess wird an
einer Stelle (split) auf zwei verschiedene Warteschlangen (child1 und child2)
aufgeteilt. Anschließend wird eine der beiden Nachrichten mithilfe eines Slice (choose) auf die forward-Warteschlange weitergeleitet, während die andere
Nachricht ignoriert wird. Welche Nachricht von den beiden weitergeleitet wird,
wird durch das Attribut superior festgelegt, in dem per Zufall entweder true
oder false gespeichert ist. Auf diese Weise soll ein Prozess simuliert werden, in
dem an einer Stelle zwei Alternativen zur Auswahl stehen, von denen die bessere
ausgewählt und weiterverarbeitet wird.
Insgesamt wird die Split/Join-Simulation pro Nachricht 500 mal durchlaufen, wobei die Anzahl der absolvierten Durchläufe in dem Attribut processcount vermerkt wird. Sollte eine Nachricht die forward-Warteschlange zum
500. Mal passieren, wird diese in die report-Warteschlange umgeleitet. Die report-Warteschlange wartet bis alle Abläufe beendet sind und schickt anschließend
die Antwort-Nachricht an die ursprünglich aufrufende Gateway-Queue. Damit
wird die Anwendung terminiert.
121
7.2 Quantitative Evaluation
Variantenname
Evaluation
Anzahl gleichzeitiger Größe der
Prozesse
Nachrichten
A1
5
1KB
A2
20
1KB
A3
40
1KB
B1
5
10KB
B2
20
10KB
B3
40
10KB
C1
5
100KB
C2
20
100KB
C3
40
100KB
Tabelle 8: Varianten der Testanwendung 4
Die Tests werden mit unterschiedlich großen Nachrichten und verschieden vielen parallelen Prozessen durchgeführt. Eine Übersicht der Varianten der Tests ist
in Tabelle 8 aufgelistet. Für die Variante A1 ist der DQL-Code im Anhang in
Abschnitt A.1.2.4 angefügt.
7.2.4
Design des Experiments Warteschlange
Die Ziele dieses Experiments wurden bereits in Kapitel 7.2.2.1 festgelegt. Ebenfalls wurden die dazugehörigen wissenschaftlichen Fragestellungen formuliert. Für
das Experiment Warteschlange sind zwei Fragen von Interesse. Dementsprechend
unterteilt sich das in diesem Unterkapitel vorgestellte Experiment in zwei Teile (Teilexperimente A und B). Zunächst soll eine möglichst effiziente Abbildung
für Warteschlangen in der DB2 gefunden werden. Die Abbildung, die sich als
am geeignetsten erweist, soll dann in Vergleich gesetzt werden zu der nativen
Implementierung in NATIX.
Wie in Kapitel 5.1.4 ausführlich behandelt, existiert eine unbeschränkte Zahl
122
7.2 Quantitative Evaluation
Evaluation
möglicher Abbildungen von Warteschlangen auf ein relationales System. Aus diesem Grund können in diesem Experiment nicht alle Möglichkeiten erschöpfend
untersucht werden, so dass nach der theoretischen Vorauswahl (vgl. die Übersicht
in Kapitel 5.1.4.8) lediglich die Varianten 6 (vgl. Abschnitt 5.1.4.6) und 7 (vgl.
Abschnitt 5.1.4.7) untersucht werden.
7.2.4.1
Unabhängige Variable Die unabhängige Variable in einem Expe-
riment ist diejenige Variable, welche verändert wird, um die Auswirkungen der
Veränderungen zu untersuchen [39].
Teilexperiment A: Die unabhängige Variable ist die jeweilig gewählte Art
der Abbildung von Warteschlangen in der DB2. Es werden die Varianten 6 und
7 der Abschnitte 5.1.4.6 und 5.1.4.7 getestet.
Teilexperiment B: Die unabhängige Variable ist der gewählte Nachrichtenspeicher, in dem die Warteschlangen verwaltet werden. Zwei Alternativen werden untersucht:
1. native Implementierung in NATIX oder
2. relationale Abbildung in der DB2.
Für die Abbildung der Warteschlange in der DB2 wird diejenige gewählt,
welche aus dem Teilexperiment A als die Effizienteste hervorgeht.
7.2.4.2
Abhängige Variablen Die abhängigen Variablen sind diejenigen
Variablen, deren Veränderung in Abhängigkeit von der unabhängigen Variable
interessiert [39].
Teilexperiment A und B: Die abhängige Variable ist das gemessene Leistungsverhalten. Es wird von dem Zeitpunkt des Sendens der ersten Nachricht bis
123
7.2 Quantitative Evaluation
Evaluation
zum Erhalt der Antwort-Nachricht gemessen. Außerdem werden durchschnittliche Loop-Zeiten gemessen (siehe Erläuterungen in Kapitel 7.2.7). Weder die Startnoch die Endphase des Demaq-Ausführungssystems wird in der Messung berücksichtigt.
7.2.4.3
Andere konstante Faktoren Die konstanten Faktoren des Expe-
riments dürfen nicht verändert werden, um einen Einfluss auf das Ergebnis der
Experimente ausschließen zu können [39]. Die folgenden Faktoren werden aus
diesem Grund in allen Teil-Experimenten konstant gehalten:
Das System:
• OpenSUSE Linux 10.2 (Kernel release 2.6.22.5-31)
• DualCore Processor (i686)
• Hardware Platform i386
• NATIX
• IBM DB2 Express-C v9.5
• 6 Festplatten:
– SEAGATE ST373207LC (10K-RPM, ”/local“)
– FUJITSU MAS3367NC (15K-RPM, ”/mnt/disk2“)
– FUJITSU MAS3367NC (15K-RPM, ”/mnt/disk3“)
– FUJITSU MAS3367NC (15K-RPM, ”/mnt/disk4“)
– FUJITSU MAS3367NC (15K-RPM, ”/mnt/disk5“)
– FUJITSU MAP3367NC (10K-RPM, ”/mnt/disk6“)
124
7.2 Quantitative Evaluation
Evaluation
Testanwendungen für die Experimente: Die Messung erfolgt mit vorab
definierten Anwendungen, die ein breites Spektrum an Komplexitäten abdecken.
Die Testanwendungen wurden in Kapitel 7.2.3 ausführlich vorgestellt.
7.2.4.4
Hypothesen Die in diesem Abschnitt formulierten Hypothesen spie-
geln die theoretische Erwartung über den Ausgang der Experimente wider [39].
Gleichzeitig präzisieren die Hypothesen die Ziele der Experimente.
Hypothese zum Teilexperiment A: Von den zu testenden Varianten
ist die Implementierung der Warteschlangen in der DB2 innerhalb des DemaqSystems mit Variante 7 (vgl. Abschnitt 5.1.4.7) am effizientesten.
Hypothese zum Teilexperiment B: Die Implementierung der Warteschlangen im Demaq-System ist in der DB2 weniger effizient als die native Warteschlangenimplementierung in NATIX.
7.2.4.5
Beschränkungen Eine Allgemeingültigkeit der Experimente kann
nicht gewährleistet werden. Zu diesem Zweck müssten alle denkbaren DemaqAnwendungen getestet werden, deren Zahl unbegrenzt ist. Deshalb wird es Anwendungen geben, bei denen die Tests zu einem anderen Ergebnis führen. Da
allerdings auf ein möglichst breites Anwendungsspektrum geachtet wurde, kann
von einer angemessen hohen Allgemeingültigkeit ausgegangen werden.
7.2.5
Design des Experiments Regelauswertung
Es wurden zwei Ziele für das Experiment Regelauswertung definiert (vgl. Kapitel 7.2.2.2). Zum einen soll überprüft werden, ob eine Regelauswertung mit der
DB2 im Demaq-System möglich ist. Dies wird als gegeben angesehen, wenn das
System mit der DB2 lauffähig ist und die Ergebnisse der Testanwendungen mit
den Ergebnissen des aktuellen Systems übereinstimmen. Ist dies der Fall, soll
125
7.2 Quantitative Evaluation
Evaluation
zum anderen das Leistungsverhalten des Systems mit der DB2 in Bezug zu der
bisherigen Implementierung mit NATIX als Nachrichtenspeicher und Saxon als
Regelauswerter gesetzt werden. Da die in Unterkapitel 7.2.3 definierten Testanwendungen das Demaq-spezifische Funktionsspektrum variantenreich abdecken,
kann eine ausreichende Allgemeingültigkeit angenommen werden.
7.2.5.1
Unabhängige Variable Die unabhängige Variable ist die gewählte
System-Variante, entweder mit der DB2 als Nachrichtenspeicher und Regelauswerter oder mit NATIX als Nachrichtenspeicher und Saxon als Regelauswerter.
7.2.5.2
Abhängige Variablen In Abhängigkeit von der unabhängigen Va-
riable wird das Leistungsverhalten des Gesamtsystems untersucht.
7.2.5.3
Andere konstante Faktoren Es wird dasselbe System benutzt, das
bereits in Abschnitt 7.2.4.3 beschrieben wurde. Die verwendeten Testanwendungen wurden in Unterkapitel 7.2.3 definiert.
7.2.5.4
Hypothese Davon ausgehend, dass eine Umsetzung des Demaq-
Systems mit der DB2 als Nachrichtenspeicher und Regelauswerter machbar ist,
wird folgende Hypothese formuliert:
Das Demaq-System ist mit NATIX und Saxon effizienter als mit der DB2.
7.2.6
Beschränkungen
Auch für dieses Experiment kann eine Allgemeingültigkeit nicht gewährleistet
werden. D.h. es existieren Anwendungen, bei denen die Tests zu einem anderen
Resultat führen. Wie allerdings bereits zuvor erwähnt, wurde ein möglichst breites Anwendungsspektrum berücksichtigt, so dass von einer angemessen hohen
Allgemeingültigkeit ausgegangen werden kann.
126
7.2 Quantitative Evaluation
7.2.7
Evaluation
Vorbereitung der Experimente
Die Vorbereitung der Experimente beinhaltete die Implementierung eines Logging-Mechanismus zur Speicherung der Messwerte. Hierzu wurde im ProcessingThread im Dispatcher zusätzlicher Code eingefügt, der die Messwerte über
den Standard-Output-Stream ausgibt. Auf diese Weise konnten die Messdaten
über die Konsole in eine Datei umgeleitet werden. Der Umfang der gemessenen
Arbeitseinheit umfasst dabei einen Loop. Ein Loop wird definiert durch folgende
Arbeitsschritte für eine neu eingereihte Nachricht in einer Warteschlange:
1. Hole alle definierten Regeln für die Warteschlange.
2. Führe alle Regeln auf der Nachricht aus.
3. Interpretiere alle Aktionen in dem QueryResult und führe diese aus.
Der Start einer Testanwendung wurde mittels eines Testdrivers ermöglicht.
Der Testdriver wurde in C++ geschrieben und ist dafür verantwortlich, dass für
eine Testanwendung die notwendige Demaq-Instanz erzeugt und gestartet wird.
Außerdem löst dieser die Verarbeitung innerhalb einer Testanwendung mit dem
Senden einer Start-Nachricht aus. Innerhalb des Testdrivers wurde zusätzlich zu
der bereits beschriebenen Messung der Loops die Messung der Gesamtlaufzeit
einer Testanwendung implementiert.
Die DQL-Dateien für die Testanwendungen wurden mit Hilfe von XSLStylesheets automatisch in den verschiedenen Varianten erzeugt (vgl. Varianten
der Anwendungen in den Tabellen 6, 7 und 8).
7.2.8
Durchführung der Experimente
Die Durchführung der Experimente wurde mit Hilfe von Shell -Skripten gesteuert und ausgeführt. Auf diese Weise konnten alle Testanwendungen automatisiert
hintereinander gestartet werden. Zunächst wurden jedoch alle Warteschlangen
127
7.2 Quantitative Evaluation
Evaluation
mit jeweils 100.000 Nachrichten befüllt, um ein realistisches Anwendungsszenario zu schaffen. Ausgenommen hiervon war die Testanwendung ”Client/ServerSimulation mit qs:queue()“ (vgl. Abschnitt 7.2.3.2). Erste Tests hatten bei dieser
ein außergewöhnlich schlechtes Leistungsverhalten offenbart, aufgrund dessen eine Verwendung dieser Testanwendung nur ohne das vorherige Befüllen möglich
war.
Die Experimente wurden mit allen Testanwendungen für folgende DemaqSystem-Varianten durchgeführt:
1. Demaq mit NATIX als Nachrichtenspeicher und Saxon zur Regelauswertung.
2. Demaq mit der DB2 als Nachrichtenspeicher und Saxon zur Regelauswertung. In der DB2 wurde die Warteschlangen-Abbildung in der Variante 6
(vgl. Kapitel 5.1.4.6) verwendet.
3. Demaq mit der DB2 als Nachrichtenspeicher und Saxon zur Regelauswertung. In der DB2 wurde die Warteschlangen-Abbildung in der Variante 7
(vgl. Kapitel 5.1.4.7) verwendet.
4. Demaq mit der DB2 als Nachrichtenspeicher und zur Regelauswertung. Die
Regelauswertung wurde mit Hilfe von automatisch erzeugten Stored Procedures (vgl. Kapitel 6.2.2.1) umgesetzt.
Bei allen Tests mit der DB2 wurde die native Unterstützung von Slices, wie
sie in Kapitel 5.1.5.3 beschrieben wurde, verwendet.
7.2.9
Analyse der Ergebnisse
In diesem Kapitel werden die Ergebnisse der Experimente mit den Testanwendungen aus Kapitel 7.2.3 evaluiert. Die Ergebnisse werden für das Experiment
Warteschlange (Abschnitt 7.2.9.1) und das Experiment Regelauswertung (Abschnitt 7.2.9.2) getrennt betrachtet.
128
7.2 Quantitative Evaluation
7.2.9.1
Evaluation
Ergebnisse des Experiments Warteschlange In diesem Ab-
schnitt werden zunächst die Ergebnisse für die untersuchten Abbildungen der
Warteschlangen evaluiert (Teilexperiment A). Anschließend wird die effizienteste
Abbildung mit der nativen Warteschlangenimplementierung in NATIX verglichen
(Teilexperiment B).
Teilexperiment A Im Durchschnitt aller Testergebnisse hat Variante 7
(vgl. Abschnitt 5.1.4.7) die Testanwendungen um 4,3% schneller bewältigt als
Variante 6 (vgl. Abschnitt 5.1.4.6). Werden allerdings die Ergebnisse der Anwendungen mit kleinen XML-Nachrichten (Varianten A1, A2, A3) isoliert betrachtet,
so ist Variante 6 im Schnitt 2% schneller als Variante 7.
Während bei den eher einfachen Anwendungen der beiden Client/ServerSimulationen Variante 7 deutlich überlegen ist (9,1 bzw. 8,5% schneller), zeigt
sich Variante 6 bei der Verwendung von Slices effizienter (2,3% schneller). Die
Testergebnisse des Teilexperiments A sind in der Tabelle 9 auf Seite 131 sowie in
Tabelle 10 auf Seite 132 detailliert aufgelistet.
Teilexperiment B Die Testergebnisse von Teilexperiment B zeigen, dass
das Demaq-System, wenn es Saxon zur Regelauswertung verwendet, mit NATIX
im Schnitt 614,35% schneller ist als mit der DB2 als Nachrichtenspeicher. Interessant ist, dass NATIX bei den C-Varianten mit großen Nachrichten (100Kb)
nur 112,07% effizienter ist als die DB2. Bei den C-Varianten der Testanwendung
”Client/Server-Simulation mit qs:queue()“ ist die DB2 sogar schneller (13,25%).
Die detaillierten Ergebnisse des Teilexperiments B werden in der Tabelle 11
auf Seite 133 und in Tabelle 12 auf Seite 134 detailliert dargestellt.
7.2.9.2
Ergebnisse des Experiments Regelauswertung Das Experiment
Regelauswertung hat sehr gemischte Ergebnisse geliefert. Demnach ist die Regelauswertung mit NATIX und Saxon insgesamt im Schnitt 76,67% effizienter
129
7.2 Quantitative Evaluation
Evaluation
bei den Testanwendungen. Bei genauerer Betrachtung ist die Regelauswertung
mit der DB2 bei den Anwendungen ”Client/Server-Simulation mit qs:queue()“
und ”Prozess-Simulation Split/Join“ um 32,13% schneller, während NATIX und
Saxon bei den Anwendungen ”Client/Server-Simulation“ und ”Prozesskette mit
Überkreuzung“ im Schnitt um 185,46% effizienter ist.
Zu beachten bleibt in jedem Fall, dass das System mit der DB2 im Multithreading-Modus verwendet wurde.
Die detaillierten Ergebnisse des Experiments Regelauswertung werden in Tabelle 13 auf Seite 135 und in Tabelle 14 auf Seite 136 vorgestellt.
7.2.10
Zusammenfassung der Ergebnisse
Für eine schnellstmögliche Abarbeitung der Elemente einer Warteschlange, die
in der DB2 implementiert ist, eignet sich von den untersuchten Abbildungen
Variante 7 (vgl. Abschnitt 5.1.4.7) am besten. Das Ergebnis ist mit 4,3% allerdings
nicht deutlich und diese Variante unterliegt in bestimmten Anwendungen der
Variante 6 (vgl. Abschnitt 5.1.4.6). Insgesamt konnte damit jedoch die Hypothese
aus Kapitel 7.2.4.4 für Teilexperiment A bestätigt werden.
Im Vergleich zu NATIX ist die DB2 in der bisherigen Form als Nachrichtenspeicher unterlegen, wenn zur Regelauswertung Saxon verwendet wird. Im Schnitt
ist NATIX hierbei um 614,35% effizienter. Damit ist erwartungsgemäß auch die
Hypothese für Teilexperiment B (vgl. Abschnitt 7.2.4.4) bestätigt worden.
Das Ergebnis des Experiments Regelauswertung ist nicht eindeutig. Bei einem
Teil der Anwendungen zeigte sich die DB2 effizienter (32,13%), bei der anderen
Hälfte der Anwendungen waren NATIX und Saxon jedoch deutlich überlegen
(185,46%). Damit ist das System mit NATIX und Saxon insgesamt im Schnitt
76,67% schneller als die Regelauswertung mit der DB2. Allerdings kann die Hypothese für das Experiment Regelauswertung (vgl. Abschnitt 7.2.5.4) nicht eindeutig
bestätigt werden und muss differenziert betrachtet werden.
130
7.2 Quantitative Evaluation
Evaluation
Tabelle 9: Testergebnisse Teilexperiment A: Erster Teil
131
7.2 Quantitative Evaluation
Evaluation
Tabelle 10: Testergebnisse Teilexperiment A: Zweiter Teil
132
7.2 Quantitative Evaluation
Evaluation
Tabelle 11: Testergebnisse Teilexperiment B: Erster Teil
133
7.2 Quantitative Evaluation
Evaluation
Tabelle 12: Testergebnisse Teilexperiment B: Zweiter Teil
134
7.2 Quantitative Evaluation
Evaluation
Tabelle 13: Testergebnisse Experiment Regelauswertung: Erster Teil
135
7.2 Quantitative Evaluation
Evaluation
Tabelle 14: Testergebnisse Experiment Regelauswertung: Zweiter Teil
136
Zusammenfassung und Ausblick
8
Zusammenfassung und Ausblick
In diesem Kapitel werden die zuvor erarbeiteten Ergebnisse zusammengefasst
(Abschnitt 8.1). Außerdem wird ein Ausblick auf zukünftige Untersuchungen und
Weiterentwicklungsmöglichkeiten des Demaq-Systems gegeben (Abschnitt 8.2).
8.1
Zusammenfassung
Im Rahmen dieser Diplomarbeit wurde am Beispiel der DB2 gezeigt, wie ein relationales DBMS in das Demaq-Ausführungssystem integriert werden kann. Als
Resultat kann Demaq nun flexibler eingesetzt werden. Die im Verlauf der vorliegenden Diplomarbeit erarbeiteten Ergebnisse sollen im Folgenden kurz zusammenfassend dargestellt werden.
In Kapitel 3 wurden zunächst die Anforderungen für das zu entwickelnde System analysiert. Als besonders wichtig wurde die korrekte Funktionsweise des
implementierten Systems herausgestellt. Ebenso stand die Modularisierung im
Mittelpunkt, um das System für zukünftige Untersuchungen flexibel und anpassungsfähig zu gestalten. Schließlich sollte das Leistungsverhalten optimiert werden, sobald die generelle Machbarkeit feststand.
Anschließend folgte in Kapitel 4 eine grob konzeptuelle Vorstellung der Architekturen der zu entwickelnden System-Varianten. Insgesamt wurden drei SystemVarianten präsentiert. Zunächst wurde das aktuelle System, das NATIX als Nachrichtenspeicher und Saxon zur Regelauswertung verwendet, schematisch aufbereitet. Als zweite Variante wurde ein System mit der DB2 als Nachrichtenspeicher
und Saxon als Regelauswerter vorgestellt, in dem Teile von NATIX weiterverwendet werden. Schließlich folgte die dritte Variante, in welcher das Demaq-System
mit der DB2 als Nachrichtenspeicher und zur Regelauswertung konzipiert wurde.
Die Schwierigkeit bei der Architektur war es, eine Modularisierung umzusetzen,
bei der verschiedenste Schnittstellen miteinander in Einklang gebracht werden
mussten.
137
8.1 Zusammenfassung
Zusammenfassung und Ausblick
Darauf aufbauend fand in Kapitel 5 eine detaillierte Verfeinerung des Designs
auf logischer Ebene statt. Wichtig waren in diesem Abschnitt die Abbildungen der
Warteschlangen und Slices auf das relationale Modell. Dementsprechend folgte
die Vorstellung und Diskussion diverser möglicher Abbildungen. Für die Regelauswertung mit der DB2 wurden in diesem Abschnitt zudem die Grundlagen
gelegt. Hierzu wurden für die Demaq-spezifischen Funktionen Rewrites definiert,
welche die Funktionen in SQL-Statements überführen.
In Kapitel 6 stand daraufhin die Implementation im Mittelpunkt, wobei eine
Optimierung auf physischer Ebene verfolgt wurde. Für die DB2 als Nachrichtenspeicher wurde eine Optimierung der Datenseiten und eine Parallelisierung
der Speicherverwaltung vorgeschlagen. Die Regelauswertung mit der DB2 konnte
durch einen Mechanismus verbessert werden, der interne enqueue Operationen
direkt in der Datenbank ausführt, ohne die Nachrichten an den Demaq-Kern zurückzuliefern. Außerdem wurde eine Ausführung der Regeln mit Hilfe von Stored
Procedures vorgeschlagen.
In Kapitel 7.1 wurden die implementierten Systemvarianten qualitativ auf
Grundlage der Anforderungen evaluiert. Den Schluss bildete eine quantitative
Evaluation der implementierten System-Komponenten mittels breit angelegter
Experimente mit Testanwendungen. Dabei zeigte sich, dass das Demaq-System
mit NATIX und Saxon insgesamt deutlich effizienter ist als das System mit der
DB2 als Nachrichtenspeicher und Saxon als Regelauswerter (im Durchschnitt
614,35%). Im Vergleich zu dem System, das die DB2 als Nachrichtenspeicher
und zur Regelauswertung verwendet, ist die ursprüngliche Demaq-Variante im
Schnitt ebenfalls effizienter (76,67%). Hierbei sind die Ergebnisse allerdings nicht
eindeutig, weshalb dieses Resultat differenziert zu betrachten ist.
138
8.2 Ausblick
8.2
Zusammenfassung und Ausblick
Ausblick
In diesem Kapitel wird ein Ausblick gegeben, wie das im Rahmen dieser Diplomarbeit entwickelte System kurz- bis mittelfristig verbessert werden kann.
8.2.1
Konvertierungen vermeiden
In dem in der vorliegenden Diplomarbeit implementierten System sind die
Schnittstellen nicht optimal implementiert, da häufig Konvertierungen zwischen
verschiedenen Datentypen vorgenommen werden. Sofern eine Vereinheitlichung
möglich ist, können diese Konvertierungen vermieden werden und so Leistungssteigerungen erzielt werden.
8.2.2
Auf Properties und Slicekeys beliebiger Nachrichten zugreifen
Wie sich bei den Tests zur Überprüfung der Korrektheit in Kapitel 7.1.1 gezeigt
hat, kann im System mit der DB2 als Nachrichtenspeicher und Regelauswerter
derzeit nur auf Properties und Slicekeys der aktuellen Kontextnachricht zugegriffen werden. Im System mit NATIX bzw. Saxon wurde dies mit Hilfe von
Processing-Instructions gelöst, welche die Nachrichten-ID enthalten. Dieser Mechanismus konnte aus zeitlichen Gründen nicht implementiert werden.
8.2.3
Nebenläufigkeit
Die Experimente mithilfe der Testanwendungen mit der DB2 als Regelauswerter
bei der Verwendung mehrerer Threads verliefen nicht ohne Komplikationen. Im
Besonderen hat sich die Verwendung von Slices als problematisch herausgestellt.
So kommt es bei der Verarbeitung häufig zu Deadlocks. Wie die Deadlocks genau
zustande kommen und ob sie eventuell vermieden werden können, muss noch
untersucht werden.
Zudem werden Deadlocks von der DB2 automatisch aufgelöst, indem eine oder
mehrere der beteiligten Transaktionen zurückgesetzt werden. Das Demaq-System
139
8.2 Ausblick
Zusammenfassung und Ausblick
bekommt hierüber keinen Bescheid und kann die Anwendung in diesem Fall nicht
ordnungsgemäß ausführen. Demnach muss die nebenläufige Verarbeitung noch
verbessert werden.
8.2.4
Untersuchung der Slicing-Abbildungen
In Kapitel 5.1.5 wurden diverse Varianten der Abbildung von Slices auf das relationale Modell vorgeschlagen. Diese sollten auf ihre Effizienz hin untersucht
werden.
8.2.5
Parallelisierung der Aktionen
Die Abarbeitung der Aktionen eines QueryResults wird derzeit seriell im Processing Thread durchgeführt. Wie die Abarbeitung parallelisiert werden kann, ist
ein Thema für zukünftige Untersuchungen.
8.2.6
Abgleich
der
Verbindungen
der
DB2-Fassade
mit
den
Processing-Threads
In dem implementierten System wird in der DB2-Fassade in der Datei include/settings.hh die Anzahl der zu erzeugenden Verbindungen zur DB2 für
den ConnectionPool festgelegt. Im Demaq-Kern wird die Anzahl der ProcessingThreads deklariert, die somit unabhängig von den Verbindungen gesteuert
werden. Dies sollte vereinheitlicht werden, da jeder ProcessingThread immer
genau zwei Verbindungen gleichzeitig verwendet, so dass in Abhängigkeit von der
Anzahl der gestarteten ProcessingThreads die Anzahl der Verbindungen zur
DB2 determiniert werden kann.
8.2.7
Nachrichten-Validierung
Die Validierung von XML-Dokumenten in der DB2 könnte zu einem besseren
Leistungsverhalten bei Parsing-Vorgängen führen. Eine Queue-abhängige Vali-
140
8.2 Ausblick
Zusammenfassung und Ausblick
dierung von Nachrichten könnte zukünftig mittels XML-Schemata in der DB2
implementiert werden. Die Möglichkeiten zur Steigerung des Leistungsverhaltens
sind dementsprechend zu untersuchen.
8.2.8
Rewrites für die DB2
In dem implementierten System werden die Rewrites für die DB2 als Regelauswerter in der Transformation-Klasse in den Dateien xqlparser/transformation.hh und -.cc umgesetzt. Dies ist nicht optimal, da die Rewrites auf diese
Weise nicht bei der AST-Generierung berücksichtigt und geprüft werden. Außerdem wird die Steuerung derzeit über eine Makrovariable gesteuert und nicht
über den Rewrite-Mechanismus, der zu diesem Zweck in der Traversal-Klasse
in Demaq implementiert wurde.
141
LITERATUR
LITERATUR
Literatur
[1] Rav Ahuja.
Introducing db2 9, part 4: Autonomic and other en-
hancements in db2 9.
Technical report, IBM, Jun 2006.
Retrie-
ved on 14.07.2008 http://www.ibm.com/developerworks/db2/library/
techarticle/dm-0606ahuja2.
[2] Kent Beck, Mike Beedle, Arie van Bennekum, Alistair Cockburn, Ward Cunningham, Martin Fowler, James Grenning, Jim Highsmith, Andrew Hunt,
Ron Jeffries, Jon Kern, Brian Marick, Robert C. Martin, Steve Mellor,
Ken Schwaber, Jeff Sutherland, and Dave Thomas. Principles of agile software. http://www.agilemanifesto.org/principles.html, 2001. Retrieved on
17.07.2008 http://www.agilemanifesto.org/principles.html.
[3] Andreas Behm, Serge Rielau, and Richard Swagerman. Returning modified
rows - select statements with side effects. In VLDB ’04: Proceedings of the
Thirtieth international conference on Very large data bases, pages 987–997.
VLDB Endowment, 2004.
[4] Anjul Bhambhri. Firing up the hybrid engine. IBM Database Magazine, 3,
Jul 2005.
[5] Scott Boag, Don Chamberlin, Mary F. Fernandez, Daniela Florescu, Jonathan Robie, and Jerome Simeon. Xquery 1.0: An xml query language, Jan 2007.
Retrieved on 23.04.2008 http://www.w3.org/TR/2007/
REC-xquery-20070123/.
[6] A. Böhm, C-C. Kanne, and G. Moerkotte. Demaq: A foundation for declarative xml message processing. In Proc. 3. Biennial Conference on Innovative
Data Systems Research (CIDR), 2007.
[7] Donald D. Chamberlin and Raymond F. Boyce. Sequel: A structured english
query language. In FIDET ’74: Proceedings of the 1974 ACM SIGFIDET
142
LITERATUR
LITERATUR
(now SIGMOD) workshop on Data description, access and control, pages
249–264, New York, NY, USA, 1974. ACM Press.
[8] Whei-Jen Chen, John Chun, Naomi Ngan, Rakesh Ranjan, and Manoj K.
Sardana. Db2 express-c: The developer handbook for xml, php, c/c++,
java, and .net.
Technical report, IBM Redbooks, Sep 2006.
Retrie-
ved on 14.04.2008 http://www.redbooks.ibm.com/redpieces/abstracts/
SG247301.html.
[9] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford
Stein. Introduction to Algorithms, Second Edition. McGraw-Hill Science/Engineering/Math, Jul 2001.
[10] Mary F. Fernandez, Ashok Malhotra, Jonathan Marsh, Marton Nagy,
and Norman Walsh.
Jan 2007.
Xquery 1.0 and xpath 2.0 data model (xdm),
Retrieved on 24.04.2008 http://www.w3.org/TR/2007/
REC-xpath-datamodel-20070123/.
[11] Thorsten Fiebig, Sven Helmer, Carl-Christian Kanne, Guido Moerkotte, Julia Neumann, Robert Schiele, and Till Westmann. Anatomy of a native xml
base management system. VLDB Journal, 11(4):292–314, 2002.
[12] Colleen Graham, Dan Sommer, and Bhavish Sood. Market share: Relational database management systems by operating system, worldwide, 2006.
Gartner Dataquest, Jun 2007.
[13] IBM. DB2 Information Center - Advantages of DB2 CLI over embedded
SQL, Mar 2006. Retrieved on 10.05.2008 http://publib.boulder.ibm.
com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/
ad/c0005890.htm.
[14] IBM.
lationalen
DB2 Information Center - Tipps zur Planung von reIndizes,
Oct
2006.
Retrieved
143
on
12.06.2008
http:
LITERATUR
LITERATUR
//publib.boulder.ibm.com/infocenter/db2luw/v9/topic/com.ibm.
db2.udb.admin.doc/doc/c0005054.htm.
[15] IBM.
DB2 Information Center - Comparison of DB2 CLI and
Microsoft
ODBC,
Mar
2008.
Retrieved
on
12.05.2008
http:
//publib.boulder.ibm.com/infocenter/db2luw/v9r5/topic/com.
ibm.db2.luw.apdv.cli.doc/doc/c0000670.html.
[16] IBM.
DB2 Information Center - CREATE FUNCTION (SQL Sca-
lar, Table, or Row) statement, Aug 2008.
Retrieved on 07.08.2008
http://publib.boulder.ibm.com/infocenter/db2luw/v9r5/topic/
com.ibm.db2.luw.sql.ref.doc/doc/r0003493.html.
[17] IBM.
DB2 Information Center - Create Index Statement, Mar 2008.
Retrieved on 12.06.2008 http://publib.boulder.ibm.com/infocenter/
db2luw/v9r5/index.jsp?topic=/com.ibm.db2.luw.sql.ref.doc/doc/
r0000919.html.
[18] IBM. DB2 Information Center - Create Table Statement, Mar 2008. Retrieved on 10.06.2008 http://publib.boulder.ibm.com/infocenter/db2luw/
v9r5/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000927.html.
[19] IBM. DB2 Information Center - Datenbanken mit dynamischem Speicher,
Mar 2008.
Retrieved on 10.08.2008 http://publib.boulder.ibm.com/
infocenter/db2luw/v9r5/topic/com.ibm.db2.luw.admin.dbobj.doc/
doc/c0012278.html.
[20] IBM.
DB2 Information Center - Declaring global temporary tables,
Mar 2008.
Retrieved on 13.06.2008 http://publib.boulder.ibm.com/
infocenter/db2luw/v9r5/topic/com.ibm.db2.luw.admin.dbobj.doc/
doc/t0020127.html.
144
LITERATUR
LITERATUR
[21] IBM. DB2 Information Center - Einschränkungen bei pureXML, Mar 2008.
Retrieved on 21.05.2008 http://publib.boulder.ibm.com/infocenter/
db2luw/v9r5/topic/com.ibm.db2.luw.xml.doc/doc/r0022679.html.
[22] IBM. DB2 Information Center - Funktion ’sqlquery’, Mar 2008. Retrieved on 13.05.2008 http://publib.boulder.ibm.com/infocenter/db2luw/
v9r5/topic/com.ibm.db2.luw.xml.doc/doc/xqrfnsqq.html.
[23] IBM.
DB2 Information Center - Select-statement, Mar 2008.
Retrie-
ved on 05.08.2008 http://publib.boulder.ibm.com/infocenter/db2luw/
v9r5/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000879.html.
[24] IBM.
DB2 Information Center - SQL Nachrichten: SQL0751N, Mar
2008.
Retrieved on 23.08.2008 http://publib.boulder.ibm.com/
infocenter/db2luw/v9r5/topic/com.ibm.db2.luw.messages.sql.doc/
doc/msql00751n.html.
[25] IBM.
DB2 Information Center - SQL Nachrichten: SQL1157N, Mar
2008.
Retrieved on 23.08.2008 http://publib.boulder.ibm.com/
infocenter/db2luw/v9r5/topic/com.ibm.db2.luw.messages.sql.doc/
doc/msql01157n.html.
[26] IBM. DB2 Information Center - Transaction Processing, Mar 2008. Retrieved on 28.08.2008 http://publib.boulder.ibm.com/infocenter/db2luw/
v9r5/topic/com.ibm.db2.luw.apdv.cli.doc/doc/c0008003.html.
[27] IBM. DB2 Information Center - XML-Schemarepository, Mar 2008. Retrieved on 25.08.2008 http://publib.boulder.ibm.com/infocenter/db2luw/
v9r5/index.jsp?topic=/com.ibm.db2.luw.xml.doc/doc/c0022720.
html.
[28] IBM.
DB2 Information Center - XQuery Prolog, Mar 2008.
145
Retrie-
LITERATUR
LITERATUR
ved on 13.05.2008 http://publib.boulder.ibm.com/infocenter/db2luw/
v9r5/topic/com.ibm.db2.luw.xml.doc/doc/xqrprologs.html.
[29] IBM. DB2 Version 9.1 for z/OS - SQL Reference, Feb 2008. Retrieved
on 13.07.2008 http://publib.boulder.ibm.com/infocenter/dzichelp/
v2r2/topic/com.ibm.db29.doc.sqlref/dsnsqk13.pdf?noframes=true.
[30] Michael H. Kay.
Saxonica - xslt and xquery processing.
Retrieved on
13.07.2008 http://www.saxonica.com/introducing.html.
[31] Alfons Kemper and André Eickler. Datenbanksysteme - Eine Einführung, 6.
Auflage. Oldenbourg, 2006.
[32] Sergei
Kuchin.
Oracle,
http://otl.sourceforge.net,
Jun
odbc
2008.
and
db2-cli
template
Retrieved
on
library.
10.04.2008
http://otl.sourceforge.net.
[33] Sergei Kuchin. Oracle, odbc and db2-cli template library documentation
– otl connect class. http://otl.sourceforge.net/otl3 connect class.htm, Apr
2008. Retrieved on 10.04.2008 http://otl.sourceforge.net.
[34] Alexander Kuznetsov. Essential facts about index covering in db2 universal
database. Technical report, IBM, Chicago, IL, USA, Mar 2003. Retrieved on 23.07.2008 http://www.ibm.com/developerworks/db2/library/
techarticle/0303kuznetsov/0303kuznetsov.html.
[35] Roger Miller. Large objects get bigger. IBM Database Magazine, 3, Jul 2005.
[36] Matthias Nicola. 15 best practices for purxml. Technical report, IBM, Oct
2006. Retrieved on 27.07.2008 http://www.ibm.com/developerworks/db2/
library/techarticle/dm-0610nicola.
[37] Chris Okasaki. Simple and efficient purely functional queues and deques.
Journal of Functional Programming, 5(4):583–592, 1995.
146
LITERATUR
LITERATUR
[38] Rex Oliva. Use xml in db2 sql stored procedures. Technical report, IBM,
Jan 2007. Retrieved on 14.08.2008 http://www.ibm.com/developerworks/
db2/library/techarticle/dm-0701oliva/index.html.
[39] Shari Lawrence Pfleeger. Experimental design and analysis in software engineering. Annals of Software Engineering, 1(1):219–253, 1995.
[40] Axel Pols, Klaus Fuest, and Christian Krys. Zukunft digitale wirtschaft.
Studie, BITKOM Bundesverband Informationswirtschaft, Telekommunikation und neue Medien e.V., Berlin, Germany, 2007.
[41] Aamer Sachedina, Matt Huras, and Kelly Schlamb. Db2 9: Simplify database
management with automatic storage, Nov 2006. DB2 Chat with the Lab Retrieved on 23.07.2008 ftp://ftp.software.ibm.com/software/data/db2/
9/labchats/20061114-slides.pdf.
[42] Douglas C. Schmidt. Wrapper facade: a structural pattern for encapsulated
functions within classes. C++ Rep., 11(2):40–50, 1999.
[43] Werner Schuetz. Lock avoidance in db2 udb v8. Technical report, IBM, Sep
2005. Retrieved on 23.06.2008 http://www-128.ibm.com/developerworks/
db2/library/techarticle/dm-0509schuetz.
[44] Sun Microsystems, Inc., Santa Clara, CA, USA. Multithreaded Programming Guide, May 2002. Retrieved on 16.05.2008 http://docs.sun.com/
app/docs/doc/802-1949/802-1949.
[45] Universität Mannheim - Database Research Group. Natix Manual. Retrieved
on 16.08.2008 http://db.informatik.uni-mannheim.de/natixdoc/.
[46] Universität Mannheim - Database Research Group. A brief introduction to
the Demaq system, Mar 2008.
147
LITERATUR
[47] Paul Yip.
LITERATUR
Advanced sql scripting pl.
Technical report, IBM, Mar
2002. Retrieved on 13.06.2008 http://www.ibm.com/developerworks/db2/
library/techarticle/0203yip/0203yip.html.
148
Mannheim, den 17. Oktober 2008
Ich, Dennis Knochenwefel (Student der Wirtschaftsinformatik an der Universität Mannheim, Matrikelnummer 0947788),
versichere an Eides statt, dass ich die vorliegende Diplomarbeit
selbstständig verfasst und keine anderen als die angegebenen Hilfsmittel verwendet habe. Die Arbeit wurde in dieser oder ähnlicher
Form noch keiner Prüfungskommission vorgelegt.
Dennis Knochenwefel
149
Anhang
A
Anhang
A.1
Quellcodes der Tests
In dieser Diplomarbeit wurden Testfälle zu verschiedenen Zwecken definiert. In
Abschnitt A.1.1 werden die Testfälle aufgezeigt, die während der Entwicklungsphase zur sukzessiven Vervollständigung der Funktionalität und Überprüfung der
Korrekheit verwendet wurden (vgl. Kapitel 7.1). In Abschnitt A.1.2 werden die
Quelltexte der Testanwendungen der Experimente aufgeführt (vgl. Kapitel 7.2.3).
A.1.1
Testfälle Entwicklungsphase / Korrektheitsüberprüfung
Alle im Folgenden aufgeführten Testanwendungen sind vollständige, gültige
Demaq-Anwendungen, auch wenn es für diese keine tatsächlichen Anwendungsszenarien gibt. Die an Komplexität zunehmenden Anwendungen wurden in der
angegebenen Reihenfolge zur Überprüfung der Korrektheit der im Rahmen dieser
Diplomarbeit entwickelten System-Varianten verwendet.
A.1.1.1
demaqTestcase1.dql
c r e a t e queue i n d e f a u l t
2
kind b a s i c
mode p e r s i s t e n t ;
A.1.1.2
demaqTestcase2.dql
1 c r e a t e queue i n d e f a u l t
kind incoming
3
i n t e r f a c e ”h t t p : / / l o c a l h o s t ”
p o r t ”8080 ”
5
mode p e r s i s t e n t ;
150
A.1 Quellcodes der Tests
A.1.1.3
Anhang
demaqTestcase3.dql
1 import module namespace qs = ”h t t p : / /www. demaq . n e t / d q l ”
a t ”/ l o c a l / dknochen /demaq/ s r c / xquery / d e m a q l i b r a r y . x q l ” ;
3
c r e a t e queue i n d e f a u l t
5
kind incoming
i n t e r f a c e ”h t t p : / / l o c a l h o s t ”
7
p o r t ”8080 ”
response outdefault
9
mode p e r s i s t e n t ;
11 c r e a t e r u l e s i m p l e a n s w e r f o r i n d e f a u l t
enqueue message . i n t o o u t d e f a u l t ;
A.1.1.4
demaqTestcase4.dql
import module namespace qs = ”h t t p : / /www. demaq . n e t / d q l ”
2
a t ”/ l o c a l / dknochen /demaq/ s r c / xquery / d e m a q l i b r a r y . x q l ” ;
4 c r e a t e queue i n d e f a u l t
kind incoming
6
i n t e r f a c e ”h t t p : / / l o c a l h o s t ”
p o r t ”8080 ”
8
response outdefault
mode p e r s i s t e n t ;
10
c r e a t e r u l e simpleanswer for i n d e f a u l t
12
l e t $msgcount := count ( qs : queue ( ) )
return enqueue message
14
<r e s p o n s e >
<queue>i n d e f a u l t </queue>
16
<msgcount >{$msgcount}</msgcount>
151
A.1 Quellcodes der Tests
Anhang
</r e s p o n s e > i n t o o u t d e f a u l t ;
A.1.1.5
demaqTestcase5.dql
1 import module namespace qs = ”h t t p : / /www. demaq . n e t / d q l ”
a t ”/ l o c a l / dknochen /demaq/ s r c / xquery / d e m a q l i b r a r y . x q l ” ;
3
(:∗∗
5
∗ This s i m p l e example i s used t o t e s t t h e i m p l e m e n t a t i o n
∗ o f t h e demaq s p e c i f i c f u n c t i o n s :
7
∗
∗ qs : queue ( )
9
∗ qs : queue ( qname )
∗ qs : message ( )
11
∗ qs : p r o p e r t y ( pname )
∗ qs : p r o p e r t y ( qs : m e s s a g e i d p r o p e r t y )
13
∗ qs : p r o p e r t y ( qs : m e s s a g e q u e u e s t a t u s p r o p e r t y , message )
∗ qs : s l i c e ( s l i c e k e y , s l i c e n a m e )
15
∗ qs : s l i c e k e y ( name )
∗:)
17
c r e a t e queue i n d e f a u l t
19
kind incoming
i n t e r f a c e ”h t t p : / / l o c a l h o s t ”
21
p o r t ”8080 ”
response outdefault
23
mode p e r s i s t e n t ;
25 c r e a t e queue l o g g e r
kind b a s i c
27
mode p e r s i s t e n t ;
29 c r e a t e p r o p e r t y now
152
A.1 Quellcodes der Tests
Anhang
queue i n d e f a u l t
31
v a l u e //Now/ t e x t ( ) ;
33 c r e a t e s l i c i n g p r o p e r t y sametime
queue i n d e f a u l t , l o g g e r
35
v a l u e //Now/ t e x t ( ) ;
37 c r e a t e r u l e l o g f o r i n d e f a u l t
enqueue message qs : message ( ) i n t o l o g g e r ;
39
c r e a t e r u l e simpleanswer for i n d e f a u l t
41
l e t $msgcount1 := count ( qs : queue ( ) )
l e t $msgcount2 := count ( qs : queue ( ” o u t d e f a u l t ”) )
43
l e t $ s l i c e c o u n t :=
count ( qs : s l i c e ( qs : message ( ) //Now/ t e x t ( ) , ”sametime ”) )
45
l e t $ l a s t s l i c e m e s s a g e :=
qs : s l i c e ( qs : message ( ) //Now/ t e x t ( ) , ”sametime ”) [ $ s l i c e c o u n t ]
47
return enqueue message
<r e s p o n s e >
49
<queue>
indefault
51
</queue>
<msgcount f u n c t i o n=”qs : queue ( ) ”>
53
{ $msgcount1 }
</msgcount>
55
<msgcount f u n c t i o n=”qs : queue ( o u t d e f a u l t ) ”>
{ $msgcount2 }
57
</msgcount>
<p r o p e r t y f u n c t i o n=”qs : p r o p e r t y ( now ) ”>
59
{ qs : p r o p e r t y ( ”now ”) }
</p r o p e r t y >
61
<c o n t e x t I t e m f u n c t i o n=”qs : message ( ) ”>
{ qs : message ( ) }
63
</c o n t e x t I t e m >
153
A.1 Quellcodes der Tests
Anhang
<s l i c e m s g c o u n t f u n c t i o n=”qs : s l i c e ( . / / Now/ t e x t ( ) , sametime ) ”>
{ $slicecount }
65
</ s l i c e m s g c o u n t >
67
< s l i c e k e y f u n c t i o n=”qs : s l i c e k e y ( sametime ) ”>
{ qs : s l i c e k e y ( ”sametime ”) }
69
</ s l i c e k e y >
<msgid f u n c t i o n=”qs : p r o p e r t y ( qs : m e s s a g e i d p r o p e r t y ) ”>
{ qs : p r o p e r t y ( ”qs : m e s s a g e i d p r o p e r t y ”) }
71
</msgid>
73
<m s g s t a t e f u n c t i o n=
”qs : p r o p e r t y ( $ l a s t s l i c e m e s s a g e ,
75
qs : m e s s a g e q u e u e s t a t u s p r o p e r t y ) ”>
{ qs : p r o p e r t y ( $ l a s t s l i c e m e s s a g e ,
”qs : m e s s a g e q u e u e s t a t u s p r o p e r t y ”) }
77
</msgstate >
79
</r e s p o n s e > i n t o o u t d e f a u l t ;
A.1.2
Testanwendungen Experimente
Die Testanwendungen werden jeweils in der Variante A1 gezeigt (vgl. hierzu das
Kapitel 7.2.3).
A.1.2.1
test1ClientServer.dql
1 import module namespace qs = ”h t t p : / /www. demaq . n e t / d q l ”
a t ”/home/ dknochen / demaq orig / s r c / xquery / d e m a q l i b r a r y . x q l ” ;
3
(:∗∗
5
∗ s t a r t queue
∗:)
7 c r e a t e queue incoming
kind incoming
9
i n t e r f a c e ”h t t p : / / l o c a l h o s t ”
154
A.1 Quellcodes der Tests
Anhang
p o r t ”8080 ”
11
response incoming response
mode p e r s i s t e n t ;
13
(:∗∗
15
∗ the re po r t that w i l l stop the a p p l i c a t i o n
∗:)
17 c r e a t e queue r e p o r t
kind b a s i c
19
mode p e r s i s t e n t ;
21 ( : ∗ ∗
∗ the s e r v e r
23
∗:)
c r e a t e queue s e r v e r
25
kind b a s i c
mode p e r s i s t e n t ;
27
(:∗∗
29
∗ a l l other c l i e n t s
∗:)
31 c r e a t e queue c l i e n t 1
kind b a s i c
33
mode p e r s i s t e n t ;
35 c r e a t e queue c l i e n t 2
kind b a s i c
37
mode p e r s i s t e n t ;
39 c r e a t e queue c l i e n t 3
kind b a s i c
41
mode p e r s i s t e n t ;
43 c r e a t e queue c l i e n t 4
155
A.1 Quellcodes der Tests
Anhang
kind b a s i c
45
mode p e r s i s t e n t ;
47 ( : ∗ ∗
∗ enqueue s t a r t message
49
∗:)
c r e a t e r u l e s t a r t u p f o r incoming
51
l e t $msg := .
return enqueue message
53
<r o o t kind=” s t a r t u p ”>
<body>
{$msg/ c h i l d : ∗ }
55
</body>
57
</r o o t > i n t o s e r v e r ;
59 ( : ∗ ∗
∗ enqueue r e s p o n s e message
61
∗:)
c r e a t e r u l e stop for r e p o r t
63
l e t $msg := .
return
65
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
return
67
i f ( ( count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] ) =4) and
( count ( qs : queue ( ’ i n c o m i n g r e s p o n s e ’ ) [ // @ s e s s i o n i d=$ s e s s i o n i d
] ) =0) )
69
then enqueue message
<r o o t kind=” s t o p ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
71
<msgs>
{ count ( qs : queue ( ) ) }
73
</msgs>
<s e s s i o n m s g s >
75
{ count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] ) }
</s e s s i o n m s g s >
156
A.1 Quellcodes der Tests
77
Anhang
</r o o t > i n t o i n c o m i n g r e s p o n s e
else () ;
79
81 ( : ∗ ∗
∗ server
83
∗:)
c r e a t e r u l e masterping for s e r v e r
85
l e t $msg := qs : message ( )
return i f ( $msg// r o o t / @kind=”s t a r t u p ”)
87
then
l e t $ s e s s i o n i d := count ( qs : queue ( ’ r e p o r t ’ ) )
89
return
( : p i n g i n i t i a l message t o a l l o t h e r s : )
91
(
enqueue message
< c l i e n t 1 msgcount=”1 ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
93
{$msg// r o o t / body }
95
</ c l i e n t 1 > i n t o c l i e n t 1 ,
enqueue message
< c l i e n t 2 msgcount=”1 ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
97
{$msg// r o o t / body }
99
</ c l i e n t 2 > i n t o c l i e n t 2 ,
enqueue message
< c l i e n t 3 msgcount=”1 ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
101
{$msg// r o o t / body }
103
</ c l i e n t 3 > i n t o c l i e n t 3 ,
enqueue message
< c l i e n t 4 msgcount=”1 ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
105
{$msg// r o o t / body }
107
</ c l i e n t 4 > i n t o c l i e n t 4
)
109
else
( : i n c r e a s e msgcount by 1 . then
157
A.1 Quellcodes der Tests
111
Anhang
check where t h e pong came from and
p i n g i t back : )
113
l e t $msgcount := f n : number ( $msg// @msgcount )+1
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
115
return
i f ( $msg/ c l i e n t 1 )
117
then enqueue message
< c l i e n t 1 msgcount=”{ $msgcount } ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
{$msg// body }
119
</ c l i e n t 1 > i n t o c l i e n t 1
121
e l s e i f ( $msg/ c l i e n t 2 )
then enqueue message
< c l i e n t 2 msgcount=”{ $msgcount } ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
123
{$msg// body }
125
</ c l i e n t 2 > i n t o c l i e n t 2
e l s e i f ( $msg/ c l i e n t 3 )
127
then enqueue message
< c l i e n t 3 msgcount=”{ $msgcount } ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
{$msg// body }
129
</ c l i e n t 3 > i n t o c l i e n t 3
131
e l s e i f ( $msg/ c l i e n t 4 )
then enqueue message
< c l i e n t 4 msgcount=”{ $msgcount } ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
133
{$msg// body }
135
</ c l i e n t 4 > i n t o c l i e n t 4
else () ;
137
(:∗∗
139
∗ common c l i e n t s
∗:)
141 c r e a t e r u l e pong1 f o r c l i e n t 1
l e t $msg := qs : message ( )
143
l e t $msgcount := f n : number ( $msg/ c h i l d : ∗ / @msgcount )
return i f ( $msgcount <1000)
158
A.1 Quellcodes der Tests
145
Anhang
then
( : pong t o s e r v e r : )
147
enqueue message $msg i n t o s e r v e r
else
149
( : g i v e up : )
enqueue message $msg i n t o r e p o r t ;
151
c r e a t e r u l e pong2 f o r c l i e n t 2
153
l e t $msg := qs : message ( )
l e t $msgcount := f n : number ( $msg/ c h i l d : ∗ / @msgcount )
155
return i f ( $msgcount <1000)
then
157
( : pong t o s e r v e r : )
enqueue message $msg i n t o s e r v e r
159
else
( : g i v e up : )
161
enqueue message $msg i n t o r e p o r t ;
163 c r e a t e r u l e pong3 f o r c l i e n t 3
l e t $msg := qs : message ( )
165
l e t $msgcount := f n : number ( $msg/ c h i l d : ∗ / @msgcount )
return i f ( $msgcount <1000)
167
then
( : pong t o s e r v e r : )
169
enqueue message $msg i n t o s e r v e r
else
171
( : g i v e up : )
enqueue message $msg i n t o r e p o r t ;
173
c r e a t e r u l e pong4 f o r c l i e n t 4
175
l e t $msg := qs : message ( )
l e t $msgcount := f n : number ( $msg/ c h i l d : ∗ / @msgcount )
177
return i f ( $msgcount <1000)
then
159
A.1 Quellcodes der Tests
179
Anhang
( : pong t o s e r v e r : )
enqueue message $msg i n t o s e r v e r
181
else
( : g i v e up : )
183
enqueue message $msg i n t o r e p o r t ;
A.1.2.2
test2ClientServer2.dql
1 import module namespace qs = ”h t t p : / /www. demaq . n e t / d q l ”
a t ”/home/ dknochen / demaq orig / s r c / xquery / d e m a q l i b r a r y . x q l ” ;
3
(:∗∗
5
∗ s t a r t queue
∗:)
7 c r e a t e queue incoming
kind incoming
9
i n t e r f a c e ”h t t p : / / l o c a l h o s t ”
p o r t ”8080 ”
11
response incoming response
mode p e r s i s t e n t ;
13
(:∗∗
15
∗ the re po r t that w i l l stop the a p p l i c a t i o n
∗:)
17 c r e a t e queue r e p o r t
kind b a s i c
19
mode p e r s i s t e n t ;
21 ( : ∗ ∗
∗ the s e r v e r
23
∗:)
c r e a t e queue s e r v e r
25
kind b a s i c
160
A.1 Quellcodes der Tests
Anhang
mode p e r s i s t e n t ;
27
(:∗∗
29
∗ a l l other c l i e n t s
∗:)
31 c r e a t e queue c l i e n t 1
kind b a s i c
33
mode p e r s i s t e n t ;
35 c r e a t e queue c l i e n t 2
kind b a s i c
37
mode p e r s i s t e n t ;
39 c r e a t e queue c l i e n t 3
kind b a s i c
41
mode p e r s i s t e n t ;
43 c r e a t e queue c l i e n t 4
kind b a s i c
45
mode p e r s i s t e n t ;
47 ( : ∗ ∗
∗ enqueue s t a r t message
49
∗:)
c r e a t e r u l e s t a r t u p f o r incoming
51
l e t $msg := .
return enqueue message
53
<r o o t kind=” s t a r t u p ”>
<body>
55
{$msg/ c h i l d : ∗ }
</body>
57
</r o o t > i n t o s e r v e r ;
59 ( : ∗ ∗
161
A.1 Quellcodes der Tests
Anhang
∗ enqueue r e s p o n s e message
61
∗:)
c r e a t e r u l e stop for r e p o r t
63
l e t $msg := .
return
65
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
return i f ( ( count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] ) =4) and
67
( count (
qs : queue ( ’ i n c o m i n g r e s p o n s e ’ ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] ) =0) )
69
then enqueue message
<r o o t kind=” s t o p ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
71
<msgs>
{ count ( qs : queue ( ) ) }
73
</msgs>
<s e s s i o n m s g s >
{ count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] ) }
75
</s e s s i o n m s g s >
77
</r o o t > i n t o i n c o m i n g r e s p o n s e
else () ;
79
(:∗∗
81
∗ server
∗:)
83 c r e a t e r u l e m a s t e r p i n g f o r s e r v e r
l e t $msg := qs : message ( )
85
return i f ( $msg// r o o t / @kind=”s t a r t u p ”)
then
87
l e t $ s e s s i o n i d := count ( qs : queue ( ’ r e p o r t ’ ) )
return
89
( : p i n g i n i t i a l message t o a l l o t h e r s : )
(
91
enqueue message
< c l i e n t 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
93
{$msg// r o o t / body }
162
A.1 Quellcodes der Tests
Anhang
</ c l i e n t 1 > i n t o c l i e n t 1 ,
95
enqueue message
< c l i e n t 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
{$msg// r o o t / body }
97
</ c l i e n t 2 > i n t o c l i e n t 2 ,
99
enqueue message
< c l i e n t 3 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
{$msg// r o o t / body }
101
</ c l i e n t 3 > i n t o c l i e n t 3 ,
103
enqueue message
< c l i e n t 4 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
{$msg// r o o t / body }
105
</ c l i e n t 4 > i n t o c l i e n t 4
107
)
else
109
( : i n c r e a s e msgcount by 1 . then
check where t h e pong came from and
111
p i n g i t back : )
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
113
return
i f ( $msg/ c l i e n t 1 )
115
then enqueue message
< c l i e n t 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
117
{$msg// body }
</ c l i e n t 1 > i n t o c l i e n t 1
119
e l s e i f ( $msg/ c l i e n t 2 )
then enqueue message
121
< c l i e n t 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
{$msg// body }
123
</ c l i e n t 2 > i n t o c l i e n t 2
e l s e i f ( $msg/ c l i e n t 3 )
125
then enqueue message
< c l i e n t 3 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
127
{$msg// body }
163
A.1 Quellcodes der Tests
Anhang
</ c l i e n t 3 > i n t o c l i e n t 3
129
e l s e i f ( $msg/ c l i e n t 4 )
then enqueue message
< c l i e n t 4 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
131
{$msg// body }
133
</ c l i e n t 4 > i n t o c l i e n t 4
else () ;
135
(:∗∗
137
∗ common c l i e n t s
∗:)
139 c r e a t e r u l e pong1 f o r c l i e n t 1
l e t $msg := qs : message ( )
141
return
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
143
return
l e t $msgcount := count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] )
145
return i f ( $msgcount <100)
then
147
( : pong t o s e r v e r : )
enqueue message $msg i n t o s e r v e r
149
else
( : g i v e up : )
151
enqueue message $msg i n t o r e p o r t ;
153 c r e a t e r u l e pong2 f o r c l i e n t 2
l e t $msg := qs : message ( )
155
return
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
157
return
l e t $msgcount := count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] )
159
return i f ( $msgcount <100)
then
161
( : pong t o s e r v e r : )
164
A.1 Quellcodes der Tests
Anhang
enqueue message $msg i n t o s e r v e r
163
else
( : g i v e up : )
165
enqueue message $msg i n t o r e p o r t ;
167 c r e a t e r u l e pong3 f o r c l i e n t 3
l e t $msg := qs : message ( )
169
return
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
171
return
l e t $msgcount := count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] )
173
return i f ( $msgcount <100)
then
175
( : pong t o s e r v e r : )
enqueue message $msg i n t o s e r v e r
177
else
( : g i v e up : )
179
enqueue message $msg i n t o r e p o r t ;
181 c r e a t e r u l e pong4 f o r c l i e n t 4
l e t $msg := qs : message ( )
183
return
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
185
return
l e t $msgcount := count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] )
187
return i f ( $msgcount <100)
then
189
( : pong t o s e r v e r : )
enqueue message $msg i n t o s e r v e r
191
else
( : g i v e up : )
193
enqueue message $msg i n t o r e p o r t ;
165
A.1 Quellcodes der Tests
A.1.2.3
Anhang
test3ProcessChain.dql
1 import module namespace qs = ”h t t p : / /www. demaq . n e t / d q l ”
a t ”/home/ dknochen / demaq orig / s r c / xquery / d e m a q l i b r a r y . x q l ” ;
3
(:∗∗
5
∗ s t a r t queue
∗:)
7 c r e a t e queue incoming
kind incoming
9
i n t e r f a c e ”h t t p : / / l o c a l h o s t ”
p o r t ”8080 ”
11
response incoming response
mode p e r s i s t e n t ;
13
(:∗∗
15
∗ t h e r e p o r t queue t h a t w i l l s t o p t h e a p p l i c a t i o n
∗:)
17 c r e a t e queue r e p o r t
kind b a s i c
19
mode p e r s i s t e n t ;
21 ( : ∗ ∗
∗ the s t a r t / f i n i s h
23
∗:)
c r e a t e queue s t a r t f i n i s h
25
kind b a s i c
mode p e r s i s t e n t ;
27
(:∗∗
29
∗ t h e complex p r o c e s s s t e p
∗:)
31 c r e a t e queue complex
kind b a s i c
166
A.1 Quellcodes der Tests
33
Anhang
mode p e r s i s t e n t ;
35 ( : ∗ ∗
∗ the big c y c l e
37
∗:)
c r e a t e queue s i m p l e 1
39
kind b a s i c
mode p e r s i s t e n t ;
41 c r e a t e queue s i m p l e 2
kind b a s i c
43
mode p e r s i s t e n t ;
c r e a t e queue s i m p l e 3
45
kind b a s i c
mode p e r s i s t e n t ;
47
(:∗∗
49
∗ the small c y c l e
∗:)
51 c r e a t e queue s i m p l e 4
kind b a s i c
53
mode p e r s i s t e n t ;
c r e a t e queue s i m p l e 5
55
kind b a s i c
mode p e r s i s t e n t ;
57
(:∗∗
59
∗ cycle property
∗ i n d i c a t e s from which c y c l e t h e p r o c e s s
61
∗ a c t u a l l y comes from
∗:)
63 c r e a t e p r o p e r t y c y c l e
queue s t a r t f i n i s h , s i m p l e 1 , s i m p l e 2 , s i m p l e 3 , s i m p l e 4 , s i m p l e 5 , complex
65
value ”” ;
167
A.1 Quellcodes der Tests
Anhang
67 ( : ∗ ∗
∗ p r o p e r t y t o count t h e f i n i s h e d p r o c e s s e s
69
∗:)
create property processcount
71
queue s t a r t f i n i s h , s i m p l e 1 , s i m p l e 2 , s i m p l e 3 , s i m p l e 4 , s i m p l e 5 , complex
value 0;
73
(:∗∗
75
∗ enqueue s t a r t message
∗:)
77 c r e a t e r u l e s t a r t u p f o r incoming
l e t $msg := .
79
return enqueue message
<r o o t kind=” s t a r t u p ”>
81
<body>
{$msg/ c h i l d : ∗ }
83
</body>
</r o o t > i n t o s t a r t f i n i s h ;
85
(:∗∗
87
∗ enqueue r e s p o n s e message
∗:)
89 c r e a t e r u l e s t o p f o r r e p o r t
l e t $msg := .
91
return
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
93
return i f ( ( count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] ) =5) and
( count ( qs : queue ( ’ i n c o m i n g r e s p o n s e ’ ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] )
=0) )
95
then enqueue message
<r o o t kind=” s t o p ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
97
<msgs>
{ count ( qs : queue ( ) ) }
99
</msgs>
168
A.1 Quellcodes der Tests
Anhang
<s e s s i o n m s g s >
{ count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] ) }
101
</s e s s i o n m s g s >
103
</r o o t > i n t o i n c o m i n g r e s p o n s e
else () ;
105
107 ( : ∗ ∗
∗ s t a r t and f i n i s h
109
∗:)
c r e a t e r u l e s t a r t r u n f i n i s h for s t a r t f i n i s h
111
l e t $msg := qs : message ( )
return i f ( $msg// r o o t / @kind=”s t a r t u p ”)
113
then
l e t $ s e s s i o n i d := count ( qs : queue ( ’ r e p o r t ’ ) )
115
return
( : s t a r t the race : )
117
(
enqueue message
119
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
{$msg// r o o t / body }
121
</p r o c e s s 1 > i n t o s i m p l e 1
with c y c l e v a l u e ” b i g c y c l e ”
123
with p r o c e s s c o u n t v a l u e 1 ,
enqueue message
125
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
{$msg// r o o t / body }
127
</p r o c e s s 2 > i n t o s i m p l e 1
with c y c l e v a l u e ” b i g c y c l e ”
129
with p r o c e s s c o u n t v a l u e 1 ,
enqueue message
131
<p r o c e s s 3 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
{$msg// r o o t / body }
133
</p r o c e s s 3 > i n t o s i m p l e 1
169
A.1 Quellcodes der Tests
Anhang
with c y c l e v a l u e ” b i g c y c l e ”
135
with p r o c e s s c o u n t v a l u e 1 ,
enqueue message
<p r o c e s s 4 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
137
{$msg// r o o t / body }
139
</p r o c e s s 4 > i n t o s i m p l e 1
with c y c l e v a l u e ” b i g c y c l e ”
141
with p r o c e s s c o u n t v a l u e 1 ,
enqueue message
<p r o c e s s 5 s e s s i o n i d=”{ $ s e s s i o n i d } ” >
143
{$msg// r o o t / body }
145
</p r o c e s s 5 > i n t o s i m p l e 1
with c y c l e v a l u e ” b i g c y c l e ”
147
with p r o c e s s c o u n t v a l u e 1
)
149
else
( : i n c r e a s e p r o c e s s c o u n t by 1 . then
151
s t a r t t h e next p r o c e s s c h a i n : )
l e t $ p r o c e s s c o u n t := f n : number ( qs : p r o p e r t y ( ” p r o c e s s c o u n t ”) )
153
return i f ( $ p r o c e s s c o u n t <50)
then
155
enqueue message $msg i n t o s i m p l e 1
with c y c l e v a l u e ” b i g c y c l e ”
157
with p r o c e s s c o u n t v a l u e ( $ p r o c e s s c o u n t +1)
else
159
enqueue message $msg i n t o r e p o r t ;
161 ( : ∗ ∗
∗ big cycle
163
∗:)
c r e a t e r u l e s i m p l e 1 r u l e for simple1
165
l e t $msg := qs : message ( )
l e t $ p r o c e s s c o u n t := f n : number ( qs : p r o p e r t y ( ” p r o c e s s c o u n t ”) )
167
return
170
A.1 Quellcodes der Tests
Anhang
enqueue message $msg i n t o s i m p l e 2
169
with c y c l e v a l u e ” b i g c y c l e ”
with p r o c e s s c o u n t v a l u e $ p r o c e s s c o u n t ;
171
c r e a t e r u l e s i m p l e 2 r u l e for simple2
173
l e t $msg := qs : message ( )
l e t $ p r o c e s s c o u n t := f n : number ( qs : p r o p e r t y ( ” p r o c e s s c o u n t ”) )
175
return
enqueue message $msg i n t o s i m p l e 3
177
with c y c l e v a l u e ” b i g c y c l e ”
with p r o c e s s c o u n t v a l u e $ p r o c e s s c o u n t ;
179
c r e a t e r u l e s i m p l e 3 r u l e for simple3
181
l e t $msg := qs : message ( )
l e t $ p r o c e s s c o u n t := f n : number ( qs : p r o p e r t y ( ” p r o c e s s c o u n t ”) )
183
return
enqueue message $msg i n t o complex
185
with c y c l e v a l u e ” b i g c y c l e ”
with p r o c e s s c o u n t v a l u e $ p r o c e s s c o u n t ;
187
(:∗∗
189
∗ small cycle
∗:)
191 c r e a t e r u l e s i m p l e 4 r u l e f o r s i m p l e 4
l e t $msg := qs : message ( )
193
l e t $ p r o c e s s c o u n t := f n : number ( qs : p r o p e r t y ( ” p r o c e s s c o u n t ”) )
return
195
enqueue message $msg i n t o s i m p l e 5
with c y c l e v a l u e ” s m a l l c y c l e ”
197
with p r o c e s s c o u n t v a l u e $ p r o c e s s c o u n t ;
199 c r e a t e r u l e s i m p l e 5 r u l e f o r s i m p l e 5
l e t $msg := qs : message ( )
201
l e t $ p r o c e s s c o u n t := f n : number ( qs : p r o p e r t y ( ” p r o c e s s c o u n t ”) )
171
A.1 Quellcodes der Tests
Anhang
return
203
enqueue message $msg i n t o complex
with c y c l e v a l u e ” s m a l l c y c l e ”
205
with p r o c e s s c o u n t v a l u e $ p r o c e s s c o u n t ;
207 c r e a t e r u l e c o m p l e x r u l e f o r complex
l e t $msg := qs : message ( )
209
l e t $ p r o c e s s c o u n t := f n : number ( qs : p r o p e r t y ( ” p r o c e s s c o u n t ”) )
l e t $ c y c l e := qs : p r o p e r t y ( ” c y c l e ”)
211
return
i f ( $ c y c l e=” b i g c y c l e ”)
213
then
enqueue message $msg i n t o s i m p l e 4
215
with c y c l e v a l u e ” s m a l l c y c l e ”
with p r o c e s s c o u n t v a l u e $ p r o c e s s c o u n t
217
else
enqueue message $msg i n t o s t a r t f i n i s h
219
with c y c l e v a l u e ” b i g c y c l e ”
with p r o c e s s c o u n t v a l u e $ p r o c e s s c o u n t ;
A.1.2.4
test4SplitJoin.dql
import module namespace qs = ”h t t p : / /www. demaq . n e t / d q l ”
2
a t ”/home/ dknochen / demaq orig / s r c / xquery / d e m a q l i b r a r y . x q l ” ;
4 (:∗∗
∗ s t a r t queue
6
∗:)
c r e a t e queue incoming
8
kind incoming
i n t e r f a c e ”h t t p : / / l o c a l h o s t ”
10
p o r t ”8080 ”
response incoming response
172
A.1 Quellcodes der Tests
12
Anhang
mode p e r s i s t e n t ;
14 ( : ∗ ∗
∗ t h e r e p o r t −queue t h a t w i l l s t o p t h e a p p l i c a t i o n
16
∗:)
c r e a t e queue r e p o r t
18
kind b a s i c
mode p e r s i s t e n t ;
20
(:∗∗
22
∗ t h e s p l i t t i n g queue
∗:)
24 c r e a t e queue s p l i t
kind b a s i c
26
mode p e r s i s t e n t ;
28 ( : ∗ ∗
∗ the f i r s t c h i l d p r o c e s s
30
∗:)
c r e a t e queue c h i l d 1
32
kind b a s i c
mode p e r s i s t e n t ;
34
(:∗∗
36
∗ the second c h i l d p r o c e s s
∗:)
38 c r e a t e queue c h i l d 2
kind b a s i c
40
mode p e r s i s t e n t ;
42 ( : ∗ ∗
∗ t h e f o r w a r d queue
44
∗:)
c r e a t e queue f o r w a r d
173
A.1 Quellcodes der Tests
46
Anhang
kind b a s i c
mode p e r s i s t e n t ;
48
(:∗∗
50
∗ the choose s l i c e
∗ t h i s s l i c e i s used t o c h o o s e
52
∗ the s u p e r i o r of the c h i l d p r o c e s s e s
∗:)
54 c r e a t e s l i c i n g p r o p e r t y c h o o s e
queue c h i l d 2 , c h i l d 1
56
v a l u e . // @ p r o c e s s i d ;
58 ( : ∗ ∗
∗ enqueue s t a r t message
60
∗:)
c r e a t e r u l e s t a r t u p f o r incoming
62
l e t $msg := .
return enqueue message
64
<r o o t kind=” s t a r t u p ”>
<body>
{$msg/ c h i l d : ∗ }
66
</body>
68
</r o o t > i n t o s p l i t ;
70 ( : ∗ ∗
∗ enqueue r e s p o n s e message
72
∗:)
c r e a t e r u l e stop for r e p o r t
74
l e t $msg := .
return
76
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
return i f ( ( count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] ) =5) and
78
( count ( qs : queue ( ’ i n c o m i n g r e s p o n s e ’ ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] )
=0) )
174
A.1 Quellcodes der Tests
Anhang
then enqueue message
<r o o t kind=” s t o p ” s e s s i o n i d=”{ $ s e s s i o n i d } ” >
80
<msgs>
{ count ( qs : queue ( ) ) }
82
</msgs>
84
<s e s s i o n m s g s >
{ count ( qs : queue ( ) [ // @ s e s s i o n i d=$ s e s s i o n i d ] ) }
86
</s e s s i o n m s g s >
</r o o t > i n t o i n c o m i n g r e s p o n s e
88
else () ;
90 ( : ∗ ∗
∗ split processes
92
∗:)
c r e a t e r u l e s p l i t t i n g for s p l i t
94
l e t $msg := qs : message ( )
return i f ( $msg// r o o t / @kind=”s t a r t u p ”)
96
then
l e t $ s e s s i o n i d := count ( qs : queue ( ’ r e p o r t ’ ) )
98
return
( : s p l i t t h e f i r s t time : )
100
(
l e t $random sup := b o o l e a n ( number (
102
s e c o n d s −from−dateTime ( c u r r e n t −dateTime ( ) ) ) mod 2 )
l e t $ p r o c e s s i d := c o n c a t ( $ s e s s i o n i d , ” 1 1 ”)
104
return (
enqueue message
106
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{
$random sup } ” p r o c e s s i d=”{ $ p r o c e s s i d } ” p r o c e s s c o u n t
=”1 ” >
{$msg// r o o t / body }
108
</p r o c e s s 1 > i n t o c h i l d 1 ,
enqueue message
110
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{ not (
175
A.1 Quellcodes der Tests
Anhang
$random sup ) } ” p r o c e s s i d=”{ $ p r o c e s s i d } ”
p r o c e s s c o u n t=”1 ” >
{$msg// r o o t / body }
112
</p r o c e s s 2 > i n t o c h i l d 2 ) ,
l e t $random sup := b o o l e a n ( number ( s e c o n d s −from−dateTime (
c u r r e n t −dateTime ( ) ) ) mod 2 )
114
l e t $ p r o c e s s i d := c o n c a t ( $ s e s s i o n i d , ” 1 2 ”)
return (
116
enqueue message
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{
$random sup } ” p r o c e s s i d=”{ $ p r o c e s s i d } ” p r o c e s s c o u n t
=”1 ” >
118
{$msg// r o o t / body }
</p r o c e s s 1 > i n t o c h i l d 1 ,
120
enqueue message
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{ not (
$random sup ) } ” p r o c e s s i d=”{ $ p r o c e s s i d } ”
p r o c e s s c o u n t=”1 ” >
122
{$msg// r o o t / body }
</p r o c e s s 2 > i n t o c h i l d 2 ) ,
124
l e t $random sup := b o o l e a n ( number ( s e c o n d s −from−dateTime (
c u r r e n t −dateTime ( ) ) ) mod 2 )
l e t $ p r o c e s s i d := c o n c a t ( $ s e s s i o n i d , ” 1 3 ”)
126
return (
enqueue message
128
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{
$random sup } ” p r o c e s s i d=”{ $ p r o c e s s i d } ” p r o c e s s c o u n t
=”1 ” >
{$msg// r o o t / body }
130
</p r o c e s s 1 > i n t o c h i l d 1 ,
enqueue message
132
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{ not (
$random sup ) } ” p r o c e s s i d=”{ $ p r o c e s s i d } ”
p r o c e s s c o u n t=”1 ” >
176
A.1 Quellcodes der Tests
Anhang
{$msg// r o o t / body }
134
</p r o c e s s 2 > i n t o c h i l d 2 ) ,
l e t $random sup := b o o l e a n ( number ( s e c o n d s −from−dateTime (
c u r r e n t −dateTime ( ) ) ) mod 2 )
136
l e t $ p r o c e s s i d := c o n c a t ( $ s e s s i o n i d , ” 1 4 ”)
return (
138
enqueue message
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{
$random sup } ” p r o c e s s i d=”{ $ p r o c e s s i d } ” p r o c e s s c o u n t
=”1 ” >
140
{$msg// r o o t / body }
</p r o c e s s 1 > i n t o c h i l d 1 ,
142
enqueue message
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{ not (
$random sup ) } ” p r o c e s s i d=”{ $ p r o c e s s i d } ”
p r o c e s s c o u n t=”1 ” >
144
{$msg// r o o t / body }
</p r o c e s s 2 > i n t o c h i l d 2 ) ,
146
l e t $random sup := b o o l e a n ( number ( s e c o n d s −from−dateTime (
c u r r e n t −dateTime ( ) ) ) mod 2 )
l e t $ p r o c e s s i d := c o n c a t ( $ s e s s i o n i d , ” 1 5 ”)
148
return (
enqueue message
150
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{
$random sup } ” p r o c e s s i d=”{ $ p r o c e s s i d } ” p r o c e s s c o u n t
=”1 ” >
{$msg// r o o t / body }
152
</p r o c e s s 1 > i n t o c h i l d 1 ,
enqueue message
154
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{ not (
$random sup ) } ” p r o c e s s i d=”{ $ p r o c e s s i d } ”
p r o c e s s c o u n t=”1 ” >
{$msg// r o o t / body }
156
</p r o c e s s 2 > i n t o c h i l d 2 )
177
A.1 Quellcodes der Tests
Anhang
)
158
else
( : i n c r e a s e p r o c e s s c o u n t by 1 . then s p l i t a g a i n : )
160
l e t $ p r o c e s s c o u n t :=number ( $msg// @ p r o c e s s c o u n t )+1
l e t $ s e s s i o n i d :=$msg// @ s e s s i o n i d
162
return
(: split :)
164
(
l e t $random sup := b o o l e a n ( number ( s e c o n d s −from−dateTime (
c u r r e n t −dateTime ( ) ) ) mod 2 )
166
l e t $ p r o c e s s i d := c o n c a t ( $ s e s s i o n i d , ” ” , $ p r o c e s s c o u n t , ” 1 ”)
return (
168
enqueue message
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{
$random sup } ” p r o c e s s i d=”{ $ p r o c e s s i d } ” p r o c e s s c o u n t
=”{ $ p r o c e s s c o u n t } ” >
170
{$msg// r o o t / body }
</p r o c e s s 1 > i n t o c h i l d 1 ,
172
enqueue message
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{ not (
$random sup ) } ” p r o c e s s i d=”{ $ p r o c e s s i d } ”
p r o c e s s c o u n t=”{ $ p r o c e s s c o u n t } ” >
174
{$msg// r o o t / body }
</p r o c e s s 2 > i n t o c h i l d 2 ) ,
176
l e t $random sup := b o o l e a n ( number ( s e c o n d s −from−dateTime (
c u r r e n t −dateTime ( ) ) ) mod 2 )
l e t $ p r o c e s s i d := c o n c a t ( $ s e s s i o n i d , ” ” , $ p r o c e s s c o u n t , ” 2 ”)
178
return (
enqueue message
180
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{
$random sup } ” p r o c e s s i d=”{ $ p r o c e s s i d } ” p r o c e s s c o u n t
=”{ $ p r o c e s s c o u n t } ” >
{$msg// r o o t / body }
182
</p r o c e s s 1 > i n t o c h i l d 1 ,
178
A.1 Quellcodes der Tests
Anhang
enqueue message
184
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{ not (
$random sup ) } ” p r o c e s s i d=”{ $ p r o c e s s i d } ”
p r o c e s s c o u n t=”{ $ p r o c e s s c o u n t } ” >
{$msg// r o o t / body }
186
</p r o c e s s 2 > i n t o c h i l d 2 ) ,
l e t $random sup := b o o l e a n ( number ( s e c o n d s −from−dateTime (
c u r r e n t −dateTime ( ) ) ) mod 2 )
188
l e t $ p r o c e s s i d := c o n c a t ( $ s e s s i o n i d , ” ” , $ p r o c e s s c o u n t , ” 3 ”)
return (
190
enqueue message
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{
$random sup } ” p r o c e s s i d=”{ $ p r o c e s s i d } ” p r o c e s s c o u n t
=”{ $ p r o c e s s c o u n t } ” >
192
{$msg// r o o t / body }
</p r o c e s s 1 > i n t o c h i l d 1 ,
194
enqueue message
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{ not (
$random sup ) } ” p r o c e s s i d=”{ $ p r o c e s s i d } ”
p r o c e s s c o u n t=”{ $ p r o c e s s c o u n t } ” >
196
{$msg// r o o t / body }
</p r o c e s s 2 > i n t o c h i l d 2 ) ,
198
l e t $random sup := b o o l e a n ( number ( s e c o n d s −from−dateTime (
c u r r e n t −dateTime ( ) ) ) mod 2 )
l e t $ p r o c e s s i d := c o n c a t ( $ s e s s i o n i d , ” ” , $ p r o c e s s c o u n t , ” 4 ”)
200
return (
enqueue message
202
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{
$random sup } ” p r o c e s s i d=”{ $ p r o c e s s i d } ” p r o c e s s c o u n t
=”{ $ p r o c e s s c o u n t } ” >
{$msg// r o o t / body }
204
</p r o c e s s 1 > i n t o c h i l d 1 ,
enqueue message
206
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{ not (
179
A.1 Quellcodes der Tests
Anhang
$random sup ) } ” p r o c e s s i d=”{ $ p r o c e s s i d } ”
p r o c e s s c o u n t=”{ $ p r o c e s s c o u n t } ” >
{$msg// r o o t / body }
208
</p r o c e s s 2 > i n t o c h i l d 2 ) ,
l e t $random sup := b o o l e a n ( number ( s e c o n d s −from−dateTime (
c u r r e n t −dateTime ( ) ) ) mod 2 )
210
l e t $ p r o c e s s i d := c o n c a t ( $ s e s s i o n i d , ” ” , $ p r o c e s s c o u n t , ” 5 ”)
return (
212
enqueue message
<p r o c e s s 1 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{
$random sup } ” p r o c e s s i d=”{ $ p r o c e s s i d } ” p r o c e s s c o u n t
=”{ $ p r o c e s s c o u n t } ” >
{$msg// r o o t / body }
214
</p r o c e s s 1 > i n t o c h i l d 1 ,
216
enqueue message
<p r o c e s s 2 s e s s i o n i d=”{ $ s e s s i o n i d } ” s u p e r i o r=”{ not (
$random sup ) } ” p r o c e s s i d=”{ $ p r o c e s s i d } ”
p r o c e s s c o u n t=”{ $ p r o c e s s c o u n t } ” >
{$msg// r o o t / body }
218
</p r o c e s s 2 > i n t o c h i l d 2 )
220
);
222 ( : ∗ ∗
∗ choose the s u p e r i o r p r o c e s s
224
∗:)
c r e a t e r u l e c h o o s e r u l e for choose
226
l e t $msg := .
l e t $ s l i c e=qs : s l i c e ( )
228
l e t $ s u p e r i o r := $ s l i c e / c h i l d : ∗ [ @ s u p e r i o r=true ( ) ]
return i f ( $msg/∗ / @ s u p e r i o r=f n : t r u e ( ) )
230
then
( : l e t the superior through : )
232
enqueue message $ s u p e r i o r i n t o f o r w a r d
else () ;
180
A.1 Quellcodes der Tests
Anhang
234
create r u l e forwardrule f o r forward
236
l e t $msg := q s : message ( )
l e t $ p r o c e s s c o u n t := f n : number ( $msg // @ p r o c e s s c o u n t )
238
r e t u r n i f ( $ p r o c e s s c o u n t <100)
then
240
( : s t a r t t h e n e x t p r o c e s s round : )
enqueue message $msg i n t o s p l i t
242
else
(: report :)
244
enqueue message $msg i n t o r e p o r t ;
181
Herunterladen