Verteilung persistenter Objekte auf die Pages der Datenbank - Clustering
Der Datentransfer zwischen dem ObjectStore Datenbank-Server und den Clients ist page-orientiert. Deshalb bestimmt die Anordnung der Objekte in der Datenbank in hohem Maße die Performance der Anwendungen.
Objekte auf der gleichen Page werden zusammen geladen - vom Zeitaufwand gesehen erhält man sie "umsonst" mit, aber sie unterliegen auch gemeinsam dem Locking beim Schreiben.
Der Object-Manager des ClassiX®-Systems steuert beim Erzeugen neuer persistenter Objekte an welcher Position in der Datenbank diese gespeichert werden - das Clustering.
Clustering Strategien können stufenweise aktiviert bzw. deaktiviert werden.
Unter dem Aspekt des Clustering ist ein Objekt entweder ein Master- oder Slave-Objekt:
Ein Masterobjekt wird in einem für seine Klasse festgelegtem Segment der Datenbank gespeichert; möglicherweise wird für das Masterobjekt ein Cluster angelegt. Die Information über das Segment und ein eventuell anzulegende Cluster sind im Datenbank-Layout (File CLASSIX.ODB) beschrieben.
Wenn das Clustering vollständig deaktiviert ist gibt es nur Masterobjekte – dies ist die Standardannahme im ClassiX®-System.
Die Position eines Slaveobjektes in der Datenbank bestimmt ein anderes, bereits in der Datenbank gespeichertes Objekt, mit dem es verbunden wird. Die Erzeugung solch eines Objekts mit CreatePersObject oder CopyPersObject muss verzögert werden bis zu dem Zeitpunkt, wenn eine Relation zu einem bereits in der Datenbank existierenden Objekt aufgebaut wird. Die genannten InstantView®-Befehle erzeugen deshalb zunächst ein (transientes) Objekt der Klasse CX_LAZY_CREATOR. Das persistente Objekt entsteht wenn mit Link eine Relation zu einem anderen persistenten Objekt aufgebaut wird.
Ein Master-Objekt ist über Eintrage in mindestens einer Root Entry Point Collection direkt erreichbar, ein Slave-Objekt nur indirekt über Referenzen von anderen Objekten.
Slave-Objekte können dadurch definiert werden, dass es
- keinen Eintrag in einer Root Entry Point Collection gibt oder
- kein Segment definiert ist, wo das Objekt gespeichert werden soll: in der Storage Beschreibung fehlt die erste Segmentangabe.
Bedingung 1. und 2. allein sind aber nicht hinreichend. Für das Clustering der Slave-Objekte wird ein Fine-Tuning über die Environment-Variable CX_CLUSTERING bzw. die Methode SetClusteringMode unterstützt.
Parameter ist eine Zahl 0 ≤ n ≤ 255. Die Bits von n steuern folgende Funktionalität:
Bit | Wert | Kategorie | Klassen | betrifft Regel |
---|---|---|---|---|
0 | 1 | elementare Datentypen |
CX_STRING..., CX_NUMERIC..., CX_VECTOR_AMOUNT..., CX_TERM..., CX_FORMULA, CX_FCONDITION, CX_NAMED_FCONDITION, CX_CONDITIONED_BAG aber nicht CX_NAMED_FORMULA |
1. kein Eintrag in eine Root Entry Point Collection |
1 | 2 | Objekte mit Gültigkeit | CX_VALIDITY... | |
2 | 4 | Wrapper | CX_DESCRIPTIVE_REF, CX_OVERWRITING_REF | |
3 | 8 | Definition Slave-Segment | alle | 2. kein Segment definiert |
4 | 16 | Attribute | CX_ATTRIBUTE_SET... | 1. kein Eintrag in eine Root Entry Point Collection |
5 | 32 | Model-Klassen | CX_PASSWORD..., CX_GENERAL_TERMS..., CX_CONDITION..., CX_ACCESS... | |
6 | 64 | Transaktionen | CX_TRANSACTION..., CX_ALLOCATION... | |
7 | 128 | Monitore | CX_DATA_CUBE, CX_LOG_CUBE, CX_ACCOUNT aber nicht CX_STATE_MONITOR |
wobei Klasse . . . auch alle abgeleiteten Klassen einschließt, z.B. steht CX_NUMERIC... auch für CX_PERCENT, CX_VALUE und CX_VALUE_PER
Wohin das Slave-Objekt letztendlich gespeichert wird, bestimmt das (erste) Master-Objekt, mit dem es eine Relation eingeht:
wo gespeichert in Datenbank | Bedingung | Beschreibung | |
---|---|---|---|
so nah wie möglich beim Master-Objekt | so nah wie möglich beim Master-Objekt, auf der gleichen Page | Master definiert weder eigenes Cluster noch Slave-Segment, | Class(Master, 12345, store, MasterBase) File(store) Storage(store, objectSegment, ...) |
keinesfalls auf der Page des Masters | im Default Cluster eines vom Master vorgegeben (Slave-)Segments | Master definiert ein Slave-Segment | Class(Master, 12345, store, MasterBase) File(store) Storage(store, Seg(objectSegment, slaveSegment), ...) |
in eigenem Cluster im vom Master vorgegeben Slave-Segment | Master definiert ein Slave-Segment mit Flag AUTO | Class(Master, 12345, store, MasterBase) File(store) Storage(store, Seg(objectSegment, slaveSegment), ...) Segment(slaveSegment, AUTO) |
|
in eigenem Cluster im vom Master vorgegeben (Object-)Segment |
Master definiert eigenes Cluster |
Class(Master, 12345, store, MasterBase, Cluster(1)) File(store) Storage(store, objectSegment, ...) |
Oder als Graph: