Replication

Dieser Dienst repliziert Daten aus einem RDBMS nach OpenSearch.

Automatische Migration der Replikationseinstellungen

Wird die BPC Version >= 3.1 zum ersten Mal gestartet, dann werden evtl. vorhandene Replikationseinstellungen automatisch für das neue Modul ‘Replication’ migriert. Wenn alle Replikationsjobs korrekt übernommen wurden, dann bitte - um Verwirrungen und Missverständnisse zu vermeiden - die beiden alten Replikations-Einstellungen (Core Services → Einstellungen) “Replication_Jobs” und “Replication_Threads” löschen. Diese sind dort mit orangen Balken markiert.

Auswirkung auf die System-Performance

Die Replikation hat direkten Einfluss auf die System-Performance. Dabei spielen insbesondere die Anzahl der Threads (Replication → Einstellungen → Replication_Threads) und der Intervall (replicationInterval) ein Rolle. Je mehr Jobs in kurzer Zeit laufen, desto höher ist die CPU Auslastung. Das gilt insbesondere, wenn viele Daten repliziert werden.

Die replicationBlockSize wirkt sich zwar positiv auf die Replikationsdauer aus, hat aber auch direkten Einfluss auf den Speicherbedarf von Apache Karaf.

Vorbereitung zur Datensatzaktualität

Vor der Einrichtung der Replikationen sollten ein paar Voraussetzungen geschaffen werden. Die Replikation benötigt für jede Tabelle (Log wie auch Childlog) eine Spalte mit ausschließlich anwachsenden Timestamps, da dieser Timestamp verwendet wird, um anschließend neuere/aktualisierte Datensätze zu finden. Loggen unterschiedliche Prozesse, Server, …​ also parallel in die DB und somit eventuell (auch nur um Millisekunden) zeitversetzt, kann es passieren, dass einzelne Datensätze nicht im BPC angezeigt werden, da diese mit einem Timestamp älter als dem neuesten replizierten committet werden.

Es empfiehlt sich daher:

  1. nicht die Serverzeit des loggenden, sondern die des DB-Servers zu loggen, da unterschiedliche Prozess-Server eventuell leicht abweichende Uhrzeiten haben

  2. sicherzustellen, dass wirklich bei jedem insert oder update diese Spalte neu geschrieben wird

Beides kann einfach über eine zusätzliche (versteckte) Spalte mit Default-Value und zugehörigem Trigger erfolgen. Das hat den Vorteil, dass sich für den Loggingprozess überhaupt nichts ändert)

Hinzufügen einer technischen TIMESTAMP Spalte für Replikation

Oracle

Für PM-Log und Childlog (ohne Prefix) unter Oracle sieht das Vorgehen zum Anlegen dann beispielsweise so aus:

--LOG:
--Spalte (mit 6Nachkommastellen Präzission) ergänzen, Defaultvalue für Inserts auf die aktuelle Uhrzeit in UTC setzen (damit ist keine Anpassung im Loggingprozess nötig)
ALTER TABLE LOG ADD (DB_UPDATE_TS TIMESTAMP DEFAULT SYSTIMESTAMP AT TIME ZONE 'UTC' NOT NULL);

--Bestehende Logeinsträge wieder "verteilen", sonst kommt die Replikation nicht gut klar:
--Entweder alle in einem Block (!besser nicht mit Tabellen > 1mio Einträge!):
UPDATE LOG SET DB_UPDATE_TS = TIMESTAMP;
Commit;

  --oder bei großen Datenmengen und Livesystemen, die auch noch was mit den Tabellen machen wollen, als anonymer PL/SQL-Block mit wenig Undo-Tablespacebedarf:
  --hierfür sollte zusätzlich ein Index auf der Timestamp-Spalte liegen um FullTableScans zu vermeiden!
    declare begin
      FOR counter IN 0 .. 3650 LOOP
        --dbms_output.put_line(to_char(to_date('2010-01-01', 'YYYY-MM-DD') + counter, 'YYYY-MM-DD') || ' - ' || to_char(to_date('2010-01-01', 'YYYY-MM-DD') + 1 + counter, 'YYYY-MM-DD'));
        --LOG:
        update log set DB_UPDATE_TS = TIMESTAMP where TIMESTAMP between to_date('2010-01-01', 'YYYY-MM-DD') + counter and to_date('2010-01-01', 'YYYY-MM-DD') + 1 + counter;
        commit;
        --CHILDLOG:
        update childlog set DB_UPDATE_TS = TIMESTAMP where TIMESTAMP between to_date('2010-01-01', 'YYYY-MM-DD') + counter and to_date('2010-01-01', 'YYYY-MM-DD') + 1 + counter;
        commit;
      END LOOP;
    end;

--Einen Trigger anlegen, der die Spalte bei jedem Update neu setzt (damit ist keine Anpassung im Loggingprozess nötig)
CREATE OR REPLACE
TRIGGER LOG_DB_UPDATE_TS
BEFORE UPDATE ON LOG
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
BEGIN
:NEW.DB_UPDATE_TS := SYSTIMESTAMP AT TIME ZONE 'UTC';
END;
/

--Index erstellen:
CREATE INDEX IDX_LOG_DBLU ON LOG(DB_UPDATE_TS) COMPUTE STATISTICS;


--Das ganze Geraffel noch mal für Childlog:
ALTER TABLE CHILDLOG ADD (DB_UPDATE_TS TIMESTAMP DEFAULT SYSTIMESTAMP AT TIME ZONE 'UTC' NOT NULL);

--Siehe ggf. PLSQL-Block oben!
UPDATE CHILDLOG SET DB_UPDATE_TS = TIMESTAMP;
commit;

CREATE OR REPLACE
TRIGGER CHILDLOG_DB_UPDATE_TS
BEFORE UPDATE ON CHILDLOG
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
BEGIN
:NEW.DB_UPDATE_TS := SYSTIMESTAMP AT TIME ZONE 'UTC';
END;
/

CREATE INDEX IDX_CHILDLOG_DBLU ON CHILDLOG(DB_UPDATE_TS) COMPUTE STATISTICS;
--Fertig

MSSQL

TIMESTAMP sollte in UTC gezogen werden, da sonst bei der Winterzeitumstellung ein blinder Fleck zwischen 2 und 3 Uhr entsteht! Der Code berücksichtigt dies noch nicht - evtl. verwenden Sie SYSUTCDATETIME statt SYSDATETIME - prüfen Sie jedoch das Verhalten im BPC.

Der Trigger für Childlog fehlt. Normalerweise wird dieser aber nicht benötigt, da die Einträge immer nur hinzugefügt und nicht aktualisiert werden.

/* Spalten hinzufügen. DATETIME2 für bessere Auflösung als DATETIME. Offensichtlich ist MSSQL nicht millisekundengenau, daher statt current_timestamp die Funktion SYSDATETIME() verwenden, diese ist nanosekundengenau. */
ALTER TABLE [LOG] ADD DB_UPDATE_TS DATETIME2 DEFAULT SYSDATETIME() NOT NULL;
GO

ALTER TABLE [CHILDLOG] ADD DB_UPDATE_TS DATETIME2 DEFAULT SYSDATETIME() NOT NULL;
GO

/* Spalten initial füllen */
BEGIN
    UPDATE [LOG] SET DB_UPDATE_TS = [timestamp];
END
GO

BEGIN
    UPDATE [CHILDLOG] SET DB_UPDATE_TS = [timestamp];
END
GO

/* Trigger */
CREATE TRIGGER LOG_DB_UPDATE_TS
  ON [LOG]
  AFTER UPDATE
  AS
BEGIN
    IF NOT UPDATE(DB_UPDATE_TS)
    BEGIN
        UPDATE t
            SET t.DB_UPDATE_TS = SYSDATETIME()
            FROM [LOG] AS t
            INNER JOIN inserted AS i
            ON t.PROCESSID = i.PROCESSID;
    END
END
GO

/* Indizes */
CREATE INDEX IDX_LOG_DBLU ON LOG (DB_UPDATE_TS);
CREATE INDEX IDX_CHILDLOG_DBLU ON CHILDLOG (DB_UPDATE_TS);

MySQL

und für MySQL ganz einfach:

# Fügt der Tabelle einen von der DB verwalteten ausreichend genauen Timestamp hinzu
ALTER TABLE LOG ADD DB_UPDATE_TS TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
ALTER TABLE CHILDLOG ADD DB_UPDATE_TS TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)

PostgreSQL

und für PostgreSQL auch über Trigger:

CREATE OR REPLACE FUNCTION update_db_update_ts_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.db_update_ts = timezone('UTC', now());
    RETURN NEW;
END;
$$ language 'plpgsql';

CREATE TRIGGER update_tc_log_db_update_ts BEFORE INSERT OR UPDATE ON tc_log FOR EACH ROW EXECUTE PROCEDURE  update_db_update_ts_column();
CREATE TRIGGER update_tc_childlog_db_update_ts BEFORE INSERT OR UPDATE ON tc_childlog FOR EACH ROW EXECUTE PROCEDURE  update_db_update_ts_column();

Konfiguration

Datenquellen

Datenquellen sind Verbindungen zu einzelnen Datenbanken. Die einzelnen Replikationsjobs verwenden/referenzieren diese dann. Diese werden unter Backend Connections vom Typ "data_source" eingerichtet und anhand der Komponenten ID referenziert.

Oberfläche

Für das Einrichten der einzelnen Replikation-Jobs steht eine eigene Oberfläche unter Einstellungen → Replication → Komponenten → Editor bereit. Über die Oberfläche können Einträge erzeugt, gelöscht, dupliziert und auch einzeln aktiviert/deaktiviert werden.

Konfigurationsparameter des Replication Moduls

Folgend werden die verschiedenen Parameter und damit verknüpften Funktionen beschrieben. Diese sind unter BPC Administration → Replication → Allgemein zu finden.

Name (Key) Datentyp Beschreibung

Replication_Threads
(replicatorThreadCount)

int

Anzahl der Threads die zur gleichzeitigen Ausführung der Replication Jobs verwendet werden.

Replication_Templates
(templates)

JSON

Zur Verfügungstellung von Vorlagen, welche bei den einzelnen Replikationsjobs dann ausgewählt werden können ("Template laden"). Um darüber dann zum Beispiel die Felder "Index Settings", "Index Mappings" und "Dynamic Templates" zu füllen.

Logs_Enabled
(replicationJobsLogEnabled)

boolean

Legt fest, ob die Durchläufe der Replication-Jobs (wenn dort aktiviert) in den speziellen OpenSearch Index 'bpc-replicationjobs-log' geloggt werden sollen oder nicht.

Logs_BulkWritePeriodInSeconds
(replicationJobsLogBulkWritePeriodInSeconds)

int

Angabe in Sekunden. Nach jedem Replikationsdurchlauf diese zu loggen würde sich negativ auf die Gesamtperformance des Systems auswirken. Deshalb werden die Logeinträge gesammelt und nach dieser Zeit im Bulk geschrieben.

Logs_CleanupPeriodInMinutes
(replicationJobsLogCleanupPeriodInMinutes)

int

Angabe in Minuten. Intervall in dem die Bereinigung des 'bpc-replicationjobs-log' Index erfolgen soll.

Logs_DeleteEntriesOlderThan
(replicationJobsLogDeleteEntriesOlderThan)

text

Angabe, wie lange Dokumente im 'bpc-replicationjobs-log' Index enthalten sein sollen. Kommt bei der Bereinigung zum Einsatz. Beispiel: 3 days ago

Konfigurationsparameter eines Replication Jobs

Folgend werden die verschiedenen Parameter und damit verknüpften Funktionen beschrieben. Diese sind unter BPC Administration → Replication → Komponenten zu finden. Es wird empfohlen, die spezialisierte Oberfläche zu verwenden: BPC Administration → Replication → Editor

Grundeinstellungen

Name (Key) Datentyp Beschreibung

Replication_Enabled
(replicationEnabled)

boolean

Den Replikationsjob aktivieren/deaktivieren

Replication_StartDate
(replicationStartDate)

String

Replikation von Datensätzen die neuer sind als dieser Zeitpunkt.
Datumsformat "yyyy-MM-dd' 'HH:mm:ss.SSS"

oder

als relativer Wert im Format:

1 second|minute|hour|day|week|month|year ago
n seconds|minutes|hours|days|weeks|months|years ago
Beispiele
1970-01-01 00:00:00.000
1 week ago
6 months ago
42 days ago

Quelle / Source

Name (Key) Datentyp Beschreibung

Source_DataSource
(rdmsDataSourceName)

String

Zu verwendende Datenquelle (ID der Backend Connections vom Typ data_source)

Source_Table
(sourceTable)

String

Tabellenname der Quelle

Source_Timezone
(sourceTimeZone)

String

Zeitzone der in der Quell-Datenbanktabelle verwendeten Datum-Felder (verwendet intern TimeZone.getTimeZone). Wird nur auf die eigentlichen Daten angewandt und nicht auf die der 'lastUpdateColumn'-Spalte.

Beispiele
UTC
GMT+1
GMT-8
America/Los_Angeles
Europe/Berlin
Etc/GMT
CET

Source_IdColumns
(idColumns)

String

Spalten für die Bildung eines eindeutigen Schlüssels im OpenSearch. Zum Beispiel: "PROCESSID,CHILDID"

Source_LastUpdateColumn
(lastUpdateColumn)

String

Diese Spalte wird für die Ermittlung des Alters des Datensatzes herangezogen

Es wird dringend empfohlen, in der Quelldatenbank auf diese Spalten einen Index anzulegen.

Source_LastUpdateColumnTimezone
(lastUpdateColumnTimeZone)

String

Zeitzone, welche in der Quell-Datenbanktabelle für die Daten in der lastUpdateColumn-Spalte verwendet wird.

Das Setting kommt nur im Zusammenspiel mit [adjustUpperDateLimitInSeconds] zur Anwendung.

Source_QueryTimeoutInSeconds
(sourceQueryTimeoutInSeconds)

Integer

Legt fest, wie lange der JDBC-Treiber auf eine Rückantwort der DB wartet. Siehe auch JDBC java.sql.Statement.setQueryTimeout()

Beispiele
UTC
GMT+1
GMT-8
America/Los_Angeles
Europe/Berlin
Etc/GMT
CET

Ziel / Target

Name (Key) Datentyp Beschreibung

Target_Index
(targetIndex)

String

Ziel-Index im OpenSearch.
Falls noch nicht vorhanden, wird der Index automatisch erstellt.

Target_CaseSensitivityOfFields
(targetIndexCaseSensitivityOfFields)

String

Legt fest, wie die Felder in OpenSearch angelegt werden sollen (Groß-/Kleinschreibung).

  • asSource = werden genauso angelegt wie sie von der Datenbank zurückgeliefert werden

  • lowerCase = Spaltennamen werden in Kleinschreibung umgewandelt

  • upperCase = Spaltennamen werden in Großschreibung umgewandelt

Target_IndexCreationSettings
(targetIndexCreationSettings)

JSON

Dem Ziel-Index bei Erstellung abweichende Settings vergeben.

  • Ist dieses Feld leer, dann werden wie gewohnt die Core Services Einstellung → Core_IndexCreationSettings verwendet.

  • Wenn es gesetzt ist, dann werden nur diese verwendet. Es müssen dann also die Einstellungen von Core_IndexCreationSettings per Copy&Paste als Grundlage verwendet werden.

Beispiel mit hinzugefügtem "Index Sorting"
{
   "number_of_shards": "5",
   "number_of_replicas": "1",
   "index": {
      "sort.field": "LASTUPDATE",
      "sort.order": "desc"
   },
   "analysis": {
      "normalizer": {
         "lowercaseNormalizer": {
            "filter": [
               "lowercase"
            ],
            "char_filter": [],
            "type": "custom"
         }
      }
   }
}

Soll das "Index Sorting" verwendet werden, dann müssen für die angegebenen Sortierungsfelder (LASTUPDATE in dem Beispiel) auch gleich OpenSearch-Mappings angelegt werden (siehe Target_IndexMappings).

Target_IndexMappings
(targetIndexMappings)

JSON

Dem Ziel-Index bei Erstellung ein Mapping vergeben. Sollte nur in bestimmten Fällen notwendig sein.

Das Mapping für das "Index Sorting" Beispiel von oben.
{
   "properties": {
      "LASTUPDATE": {
         "type": "date"
      }
   }
}

Target_IndexDynamicTemplates
(targetIndexDynamicTemplates)

JSON

Dem Ziel-Index ein maßgeschneidertes Mapping zuweisen. Ist dies gesetzt, dann wird das Globale (siehe Core Einstellung → Core_IndexDynamicTemplates) nicht verwendet.

In der Elasticsearch Dokumentation (Verweis bis die OpenSearch Dokumentation ebenbürtig ist) gibt es mehr Infos zu den Möglichkeiten der Dynamic Templates.

Bei dem folgenden Beispiel werden alle Felder die OpenSearch als Textfelder (Strings) erkennt mit einem Mapping versehen ("alle_textfelder") bei dem der Inhalt nicht analysiert wird (spart Speicherplatz und die Daten können trotzdem noch angezeigt werden). Plus einer Ausnahme ("spezialfall"): Für alle Textfelder welche den Namenspostfix 'name' haben wird unser Standard Mapping verwendet.

Beispiel
[
  {
    "spezialfall": {
      "match_mapping_type": "string",
      "match": "*name",
      "mapping": {
        "type": "text",
        "fields": {
          "lowercase": {
            "normalizer": "lowercaseNormalizer",
            "type": "keyword"
          },
          "raw": {
            "type": "keyword"
          }
        }
      }
    }
  },
  {
    "alle_textfelder": {
      "match_mapping_type": "string",
      "match": "*",
      "mapping": {
        "type": "keyword",
        "analyzer": false
      }
    }
  }
]

Erweiterte Einstellungen / Advanced

Name (Key) Datentyp Beschreibung

Replication_RestartWhereLeftOff
(restartReplicationWhereLeftOff)

boolean

Beim Start des Servers oder bei Änderung eines Jobs werden die Replikationsjobs neu gestartet und fangen wieder von vorne an zu replizieren (siehe replicationStartDate). Wenn diese Einstellung auf 'true' gesetzt ist, dann setzt die Replikation beim Datum des jüngsten Datensatzes der repliziert wurde wieder auf. Diese Zeitstempel werden als Metadaten im OpenSearch Index abgelegt.

Replication_Delay
(replicationDelay)

Integer

Verzögerung in Sekunden nach dem die Replikation gestartet wird

Replication_Interval
(replicationInterval)

Integer

Interval in Sekunden für die Replikation

Replication_BlockDayRange
(replicationBlockDayRange)

Integer

Anzahl der Tage (Block), die bei jedem Job-Durchlauf abgearbeitet werden sollen. Diesen Wert nicht zu hoch ansetzen, da dies dann bei der Quell-Datenbank eine erhöhte Last verursacht und auch OpenSearch/Lucene zu keiner Verschnaufpause kommt.

Beispiel 10 Tage: Der Job ist gerade beim 10.03.2015 angekommen, dann werden die Datensätze vom 10.03.2015 bis zum 20.03.2015 repliziert und beim folgenden Durchlauf vom 20.03.2015 bis zum 30.03.2015.

Replication_BlockSize
(replicationBlockSize)

Integer

Blockgröße für die Übertragung von DB nach OpenSearch. Anzahl der Datenbank-Sätze, die der JDBC-Treiber als Block einliest und im Speicher hält.

Es zeichnet sich aktuell ab, dass eine größere Blocksize besser ist. Siehe auch: Replikationsdauer. Aber bitte nicht übertreiben, da es andernfalls zu OutOfMemory Exceptions kommt. Eine Blockgröße von 2500 ist bei manchen Datenbanktabellen bereits zu hoch angesetzt.

Replication_SyncFiles
(replicationSyncFiles)

boolean

Synchronisation von BLOBs

Achtung eine nachträgliche Aktivierung ist aktuell nicht möglich.

Replication_UnzipSyncedFiles
(replicationUnzipSyncedFiles)

boolean

Entpackt synchronisierte Dateiinhalte automatisch.

Kommt nur zur Anwendung, wenn replicationSyncFiles aktiv ist.

Replication_AdjustUpperDateLimitInSeconds
(adjustUpperDateLimitInSeconds)

Integer

Umgehung eines Datenbankproblems, bei dem Satzaktualisierungen - welche durch einen Datenbank-Trigger initiiert werden - zu spät geschrieben und dadurch beim Replikationslauf nicht beachtet werden können (wir reden hier von 1-3 Sekunden).

Mit dieser Option werden die Sätze mit einem Aktualisierungstimestamp minus des festgelegten Wertes selektiert. In der Voreinstellung von 0, ist diese Möglichkeit deaktiviert und es wird wie bisher mit einem Timestamp in der Zukunft selektiert (replicationBlockDayRange). Da wir hierbei die Timestamp-Funktion der Datenbank verwenden, wird diese Möglichkeit momentan nur bei Oracle, MS SQL und MySQL angewendet.

Beispiel 3 Sekunden: Es werden die Sätze ab dem Timestamp des zuletzt replizierten Satzes bis zum aktuellen Timestamp der Datenbank minus 3 Sekunden selektiert. Klar sind dann nicht immer die aktuellsten Daten im BPC vorhanden, aber hoffentlich sind diese dann in einem konsistenten Zustand mit der Datenbank.

Replication_VamOrganizationId
(vamOrganizationId)

String

experimentell

Wenn nicht leer, dann werden Besonderheiten für die Replikation von Data-Management-Daten eingesetzt. Speziell werden nur die Daten der eingetragenen organizationId (wie in Data-Management-Konfiguration) repliziert

Replication_LoggingEnabled
(replicationLoggingEnabled)

boolean

Hier kann das Logging der Replikationsdurchläufe pro Replication Job aktiviert und deaktiviert werden.

Schattenkopien

Bei einer Schattenkopie werden zu dem festgelegten Zeitpunkt alle Dokumente (die nach dem festgelegten 'replicationStartDate' liegen) des OpenSearch-Index (siehe 'targetIndex') in einen neuen Index kopiert. Am Ende wird der Alias auf den neuen Index umgebogen und der bisherige Index gelöscht. Dies kann zum Beispiel einmal in der Woche durchgeführt werden, um wieder an einen schlanken Index zu kommen.

Zusatzhinweis: Die in OpenSearch als gelöscht markierten Dokumente (entweder selbst manuell gelöscht oder durch den Tail Sync) werden natürlich auch nicht mit in den neuen Index übernommen. Achtung: Der zugehörige Replikationslauf wird solange ausgesetzt, bis die Schattenkopie erstellt wurde.

Name (Key) Datentyp Beschreibung

ShadowCopy_Enabled
(replicationShadowCopyEnabled)

boolean

Erstellung von Schattenkopien aktivieren (shadow copy).

ShadowCopy_CronPattern
(replicationShadowCopyCronPattern)

String

Cron like Pattern zur Festlegung des Zeitpunktes wann die Schattenkopien erstellt werden sollen.

Beispiele
0 15 16 ? * SUN = Jeden Sonntag um 16:15 Uhr
0 */30 * * * ? = Alle 30 Minuten
30 59 11 ? * 1,2,3,4,5 = Am Montag, Dienstag, Mittwoch, Donnerstag und Freitag um 11:59:30 Uhr

Weitere Beispiele und die Dokumentation sind auf der Quartz-Scheduler Webseite zu finden.

ShadowCopy_KeepCopiesCount
(replicationShadowCopyKeepCopiesCount)

Integer

Anzahl der Schattenkopien die vorgehalten werden sollen.

0 = keine Schattenkopie wird vorgehalten

3 = Es werden 3 Schattenkopien vorgehalten (diese befinden sich im 'Close'-Status, um Ressourcen zu sparen)

Tail Sync

Der 'Tail Sync' arbeitet auf dem aktuellen Index (siehe 'targetIndex') und synchronisiert älterer Daten (neue/geänderte/gelöschte Datenbanksätze) mit OpenSearch, sodass diese wieder mit der Datenbank übereinstimmen. Dies kann z.B. jede Nacht einmal durchgeführt werden. Dokumente, die älter als das Startdatum der Replikation sind (siehe 'replicationStartDate'), werden erst einmal aus dem OpenSearch-Index gelöscht. Danach geht er Blockweise (Default 10 Tages-Schritte) die Datenbank durch und gleicht diese mit OpenSearch ab. Dabei werden neue/geänderte Datenbanksätze in den OpenSearch Index übernommen und Dokumente, die nicht mehr in der Datenbank existieren, werden in OpenSearch gelöscht. Der Tail Sync arbeitet nur mit den festgelegten 'idColumns' und 'lastUpdateColumn' Feldern (Hint: passender DB-Index hilft Wunder!). Die kompletten Daten werden nur bei neuen/geänderten Datenbanksätzen ausgelesen.

Der Sync läuft nicht bis zum aktuellen Datum (siehe [replicationTailSyncRelativeEndDate]), da diese Sätze auch weiterhin von unserer normalen Replikation abgearbeitet werden.

Name (Key) Datentyp Beschreibung

TailSync_Enabled
(replicationTailSyncEnabled)

boolean

Den 'Tail Sync' aktivieren

TailSync_CronPattern
(replicationTailSyncCronPattern)

String

Cron like Pattern zur Festlegung des Zeitpunktes wann der Tail Sync gestartet werden soll.

Beispiele
0 5 2 * * ? = Jede Nacht um 2:05 Uhr
0 35 21 ? * Sun = Jeden Sonntag um 21:35 Uhr
30 5 3 ? * 1,2,3,4,5 = Am Montag, Dienstag, Mittwoch, Donnerstag und Freitag um 3:05:30 Uhr

Weitere Beispiele und die Dokumentation sind auf der Quartz-Scheduler Webseite zu finden.

TailSync_BlockSize
(replicationTailSyncBlockSize)

Integer

Blockgröße des Datenbanktreibers. Beachte den Hinweis zu der Option replicationBlockSize.

TailSync_RelativeStartDate
(replicationTailSyncRelativeStartDate)

String

Das relativ angegebene Startdatum. Ab diesem Zeitpunkt soll dann synchronisiert werden. Daten, die vor dem Startdatum der Replikation liegen, werden auch weiterhin gelöscht. Dieses Datum wird nur verwendet, wenn es nach dem regulären Startdatum und vor dem Enddatum liegt.

1 second|minute|hour|day|week|month|year ago
n seconds|minutes|hours|days|weeks|months|years ago

Diese Option sollte nur in speziellen Fällen verwendet werden. Es kann zu Inkonsistenzen kommen, wenn in der Datenbank Sätze gelöscht werden, welche vor diesem relativen Startdatum liegen. Diese bleiben dann im OpenSearch-Index enthalten, obwohl sie nicht mehr in der Datenbank vorhanden sind.

TailSync_RelativeEndDate
(replicationTailSyncRelativeEndDate)

String

Das relativ angegebene Enddatum. Bis zu diesem Zeitpunkt soll dann synchronisiert werden und nicht weiter.

1 second|minute|hour|day|week|month|year ago
n seconds|minutes|hours|days|weeks|months|years ago

TailSync_BlockDayRange
(replicationTailSyncBlockDayRange)

Integer

Anzahl der Tage (Block) in denen die Daten abgearbeitet werden sollen. Siehe auch replicationBlockDayRange.

TailSync_RelativeDeleteOlderThanDate
(replicationTailSyncRelativeDeleteOlderThanDate)

String

Das relativ anzugebende Löschdatum. Alle Dokumente, die älter sind, werden gelöscht. Wird diese Option nicht gesetzt, dann wird sie auch nicht ausgeführt.

Consistency Check

Nach den Replikationsläufen wird ein einfacher Konsistenzcheck durchgeführt. Dabei werden die Anzahl Dokumente welche sich in der Quelle und dem Ziel befinden verglichen. Und zwar in dem Zeitraum 'replicationStartDate' und dem letzten Datum welches sich im Ziel (OpenSearch) befindet.

Bei vielen Daten (zig Millionen von Sätzen) kann es zu erhöhter Last auf dem System kommen und eine initiale Replikation extrem verlangsamt werden. Aktivieren Sie den Consistency Check nur, wenn Sie sicher sind, dass die Daten vollständig repliziert werden.

Name (Key) Datentyp Beschreibung

ConsistencyCheck_Frequency
(replicationConsistencyCheckFrequency)

Integer

Die Frequenz, mit welcher der Konsistenzcheck durchgeführt wird.

Beispiele:

  • 0 = wird nie durchgeführt

  • 1 = wird nach jedem Replikationslauf durchgeführt

  • 10 = wird nach jedem 10ten Replikationslauf durchgeführt

Lookup Joins

Können verwendet werden, um zu replizierende Dokumente mit zusätzlichen Daten anzureichern. Wenn z.B. in den zu replizierenden Daten nur eine Partner-ID steht und noch der Name des Partners etc. im Monitor benötigt wird.

Man verwendet unter OpenSearch eine Denormalisierung, das heißt, diese Daten werden mit in das Dokument übernommen und stehen wie alle anderen Daten zur Verfügung (performante Suche; Aggregation, …​). Voraussetzung: Die Lookup-"Tabellen" müssen als eigenständige Indexe zur Verfügung stehen und können z.B. über eine zusätzliche Replikation von einer DB-Tabelle übernommen werden.

Die Lookup-Daten können manuell ( BPC-Einstellungen → Übersicht → Status → Replikation → Jobs → Job → Lookup Joins synchronisieren ) sowie automatisch mithilfe unseres OpenSearch BPC Plugin (os-bpc-plugin) aktualisiert werden.

Es können mehrere Lookup-Tabellen referenziert werden, unten werden die möglichen Werte eines EINTRAGs beschrieben. Aufbau: "join": [ { EINTRAG }, { EINTRAG }, …​ ]

Damit der Wertevergleich funktioniert, müssen die Spaltentypen in den Datenbanktabellen identisch sein. Wenn es sich um String-Felder handelt, sollte "*.raw" als lookupKeyField verwendet werden, bei Zahlfeldern hingegen ohne das ".raw"

Lookup Joins Konfigurationsbeispiel
[
    {
        "keyField": "PARTNER",
        "lookupIndex": "lookup-partner",
        "lookupKeyField": "ID.raw",
        "resultFieldsPrefix": "partner_",
        "resultFieldsExcluded": [ "ID", "LASTUPDATE" ]
    },
    {
        "keyField": "MESSAGETYPE",
        "lookupIndex": "lookup-messagetype",
        "lookupKeyField": "ID.raw",
        "resultFieldsPrefix": "messagetype_",
        "resultFieldsExcluded": [ "ID", "LASTUPDATE" ]
    }
]
Feld Datentyp Beschreibung

keyField

String

Das Schlüsselfeld in der zu replizierenden Tabelle. Über den Wert des Feldes werden die Daten aus dem Lookup-Index übernommen.

Beispiel: PARTNER_ID
Hier steckt die ID des Partners und in dem angegebenen Lookup-Index die eigentlichen Daten des Partners, die übernommen werden sollen. (Hint: DB Foreign Key)

lookupIndex

String

Der OpenSearch Index mit den Lookup-Daten.

Beispiel: lookup-partner
In dem Beispiel die Detaildaten des Partners.

lookupKeyField

String

Beispiel: ID.raw
In diesem Feld wird nach dem Wert des 'keyField' (siehe oben) gesucht. (Hint: DB Primary Key)

resultFieldsPrefix

String

Die zu übernehmenden Felder aus dem Lookup-Index müssen mit einem eindeutigen Prefix versehen werden, sodass es zu keinem Konflikt mit existierenden Feldern kommt.

Beispiel: partner_

resultFieldsIncluded

String Array

Sollen nicht alle Felder aus dem Lookup-Index übernommen werden, können die zu übernehmenden Felder hier festgelegt werden.

Beispiel: [ "FIRST_NAME", "LAST_NAME" ]

resultFieldsExcluded

String Array

Sollen fast alle Felder übernommen werden, dann können hier die auszuschließenden festgelegt werden.

Beispiel: [ "ID", "UPDATED" ]

Replication Jobs Logging

Die Durchläufe der Replication Jobs können geloggt und zum Beispiel über den automatisch angelegten Monitor “Replication Jobs Monitor” angezeigt werden. Dieser Monitor wird beim Start angelegt, wenn er nicht vorhanden sein sollte. Er kann also nicht permanent gelöscht werden. Ebenso wird der verwendete Index ‘bpc-replicationjobs-log’ automatisch angelegt, wenn ein Durchlauf geloggt werden muss.

Das Logging kann global sowie je Replication Job an- und ausgeschalten werden (siehe entsprechende Einstellungen oben). Im Auslieferungszustand ist das Logging global aktiviert und das der Replication Jobs deaktiviert. Es wird also erst einmal nichts geloggt!

Die Log-Einträge werden im Bulk nach einiger Zeit in den erwähnten Index geschrieben. Das hat wenig Einfluss auf die Gesamtperformance des Systems. Allerdings können sehr viel Einträge in kürzester Zeit erzeugt werden (Millionen in ein paar Stunden), deshalb den Cleanup vielleicht nicht zu selten ausführen und ein Auge auf die Anzahl der darin enthaltenen Dokumente behalten: Einstellungen → Core Services → Indizes


Keywords: