Este apéndice describe las operaciones compatibles, las estrategias de sharding, los formatos de datos y los ejemplos de mensajes para los distintos tipos de datos de DataHub.
Operaciones compatibles para distintos tipos de datos
Un topic es la unidad básica para la suscripción y publicación de datos en DataHub, y representa una colección de datos de streaming. DataHub admite dos tipos de datos: TUPLE y BLOB.
|
Tipo de DataHub |
Escritura de mensajes DML |
Escritura de mensajes de heartbeat ascendentes |
Escritura de mensajes DDL |
Asignación de origen a topic |
Tipo |
|
TUPLE |
Compatible |
No compatible |
No compatible |
Una tabla a un topic |
Tipos admitidos por DataHub |
|
BLOB |
Compatible |
Compatible |
Compatible |
Una base de datos (varias tablas) a un topic |
Datos binarios BLOB |
Los topics TUPLE tienen un esquema fijo que no se puede modificar después de su creación. Son adecuados para escenarios donde el esquema de la tabla de origen es estable y no implica operaciones DDL como
ADD COLUMNoDROP COLUMN. Los topics TUPLE no admiten el reenvío de mensajes DDL ni de mensajes de heartbeat desde el origen hacia los consumidores descendentes. Esta asignación uno a uno puede resultar inconveniente para el consumo descendente si tiene muchas tablas de origen, ya que debe crear un topic correspondiente para cada una.Los topics BLOB no tienen un esquema predefinido y almacenan únicamente datos binarios sin procesar, lo que les brinda mayor flexibilidad. Admiten el reenvío de mensajes DDL y de heartbeat desde el origen hacia los consumidores descendentes. Asignan varias tablas de una sola base de datos a un único topic. Esto permite usar un solo topic para todas las tablas de origen y simplifica el consumo descendente. Este tipo es ideal para escenarios donde DataHub actúa como una cola de mensajes intermedia para la migración completa de una base de datos.
Estrategias de sharding para distintos tipos de datos
Un shard es un canal concurrente para la transmisión de datos dentro de un topic de DataHub. Aunque un solo shard tiene un throughput de escritura limitado, puede usar varios shards para incrementarlo. DataHub garantiza el consumo en orden únicamente dentro de un mismo shard, no entre varios shards. Para mejorar el rendimiento de escritura con múltiples shards y, al mismo tiempo, mantener el orden de los mensajes y evitar la dispersión de datos, DataHub ofrece las siguientes estrategias de sharding para los tipos de datos TUPLE y BLOB.
|
Escenario |
TUPLE |
BLOB |
|
Con clave primaria (incluidas claves primarias personalizadas) |
Sharding por clave primaria |
Sharding por clave primaria |
|
Garantía de orden |
Los mensajes con la misma clave primaria se procesan en orden |
Los mensajes con la misma clave primaria se procesan en orden |
|
Sin clave primaria |
Sharding aleatorio |
Sharding por nombre de tabla |
|
Garantía de orden |
No se garantiza el orden |
Los mensajes de la misma tabla se procesan en orden |
Formatos de datos
-
TUPLE
El formato TUPLE utiliza tipos de datos admitidos de forma nativa por DataHub. Data Integration agrega varias columnas de metadatos cuando crea un topic. El esquema del formato TUPLE contiene tanto columnas de metadatos como columnas de datos de negocio. Los campos que comienzan con un guion bajo, como
_sequence_id_y_operation_type_, son columnas de metadatos. Los campos restantes son columnas de datos de negocio. Las columnas de metadatos incluyen_sequence_id_,_excute_time_,_source_table_,_before_image_y_after_image_.Parámetro
Descripción
_sequence_id_
Un ID de mensaje único de tipo STRING, compuesto por dígitos. Las operaciones UPDATE_BEFOR y UPDATE_AFTER de la misma actualización comparten un ID de secuencia.
_excute_time_
La hora en que se generaron los datos.
_source_table_
El nombre de la tabla de origen.
_before_image_
La imagen previa. El valor es
Ypara una operación UPDATE_BEFOR o DELETE, yNpara una operación UPDATE_AFTER o INSERT._after_image_
La imagen posterior. El valor es
Npara una operación UPDATE_BEFOR o DELETE, yYpara una operación UPDATE_AFTER o INSERT.Ejemplo: La siguiente tabla muestra los datos sincronizados en DataHub después de ejecutar sentencias INSERT, UPDATE y DELETE.
_sequence_id_
_operation_type_
_excute_time_
_before_image_
_after_image_
1649991610688000000
I
1649991726000
N
Y
1649991610688000001
U
1649991756000
Y
N
1649991610688000001
U
1649991756000
N
Y
1649991610688000002
D
1649991774000
Y
N
-
BLOB
Un mensaje BLOB consiste en datos binarios creados mediante la conversión de una cadena JSON. El formato JSON correspondiente es el siguiente:
{ "schema": { // Metadata about the change, specifying only column names and types. "dataColumn": [ // Information about the changed data columns, used to update records in the destination table. { "name": "id", "type": "LONG" }, { "name": "name", "type": "STRING" }, { "name": "binData", "type": "BYTES" }, { "name": "ts", "type": "DATE" } ], "primaryKey": [ "pkName1", "pkName2" ], "source": { "dbType": "mysql", "dbVersion": "1.0.0", "dbName": "myDatabase", "schemaName": "mySchema", "tableName": "tableName" } }, "payload": { "before": { "dataColumn":{ "id": 111, "name":"scooter", "binData": "[base64 string]", "ts": 1590315269000 } }, "after": { "dataColumn":{ "id": 222, "name":"donald", "binData": "[base64 string]", "ts": 1590315269000 } }, "sequenceId":XXX, // A string used for data ordering when merging full and incremental data. "op": "INSERT/UPDATE/DELETE/TRANSACTION_BEGIN/TRANSACTION_END/CREATE/ALTER/ERASE/QUERY/TRUNCATE/RENAME/CINDEX/DINDEX/GTID/XACOMMIT/XAROLLBACK/MHEARTBEAT...", // Case-sensitive. "timestamp": { "eventTime": 1, // Required. The time of the record change. A 13-digit timestamp with millisecond precision. "systemTime": 2, // Optional. Exists for some data sources like Oracle CDC. "checkpointTime": 3 // Optional. Included for some data sources like OceanBase. }, "ddl": { "text": "ADD COLUMN ...", "ddlMeta": "[SQLStatement serialized binary, expressed in base64 string]" } }, "version":"1.0.0" }-
Campos BLOB
ImportanteLos tipos de datos de todos los campos del mensaje los define StreamX e incluyen
BOOLEAN,DOUBLE,DATE,BYTES,LONGySTRING.BOOLEAN: The value is `true` or `false`. DATE: The value is a 13-digit integer representing a timestamp with millisecond precision. BYTES: Stores byte arrays as a Base64-encoded string. Use the `java.util.Base64` APIs for Base64 encoding and decoding: String text = "text123"; // Encode Base64.getEncoder().encodeToString(text.getBytes("UTF-8")) // Decode Base64.getDecoder().decode(encodedText)Elemento de nivel superior
Elemento de segundo nivel
Descripción
schema
dataColumn
Un JSONArray que contiene la información de tipos de las columnas de datos. dataColumn registra todas las columnas y sus tipos en un registro de cambio de datos ascendente. Una operación de cambio puede ser una modificación de datos (como inserción, eliminación o actualización) o una modificación de la estructura de la tabla.
name: El nombre de la columna.
type: El tipo de datos de la columna.
primaryKey
Una lista de cadenas que representan los nombres de las columnas de clave primaria.
pk: El nombre de la clave primaria.
source
Un objeto que contiene información sobre la base de datos o la tabla de origen.
dbType: Una cadena que representa el tipo de base de datos.
dbVersion: Una cadena que representa la versión de la base de datos.
dbName: Una cadena que representa el nombre de la base de datos.
schemaName: Una cadena que representa el nombre del esquema; es obligatoria para bases de datos como PostgreSQL y SQL Server.
tableName: Una cadena que representa el nombre de la tabla.
payload
before
Un JSONObject que contiene la imagen previa de los datos. Para una operación
UPDATEen un origen MySQL, el campobeforealmacena el contenido del registro antes de la actualización.Este campo se completa cuando se lee un mensaje de actualización o eliminación desde el origen.
dataColumn: Un parámetro de tipo JSONObject que representa la información de los datos. El formato es nombre de columna: valor de columna. El nombre de la columna es una cadena, y el valor de la columna depende de su tipo de datos: los valores de tipo BYTES se representan como cadenas Base64, los valores de tipo DATE se representan como marcas de tiempo de 13 dígitos de tipo long, y los valores de otros tipos se representan mediante sus tipos nativos.
after
La imagen posterior de los datos. El formato es el mismo que el del campo
before.NotaEste campo es obligatorio para las operaciones
UPDATEeINSERT.op
El tipo de operación. Valores válidos:
INSERT: Una inserción de datos.
UPDATE_BEFOR: La imagen previa de una actualización.
UPDATE_AFTER: La imagen posterior de una actualización.
DELETE: Una eliminación de datos.
TRANSACTION_BEGIN: El inicio de una transacción de base de datos.
TRANSACTION_END: El fin de una transacción de base de datos.
CREATE: Una creación de tabla.
ALTER: Una modificación de tabla.
QUERY: La sentencia SQL original del cambio en la base de datos.
TRUNCATE: Un truncamiento de tabla.
RENAME: Un cambio de nombre de tabla.
CINDEX: Una creación de índice.
DINDEX: Una eliminación de índice.
MHEARTBEAT: Un mensaje de heartbeat que indica que la tarea de sincronización se ejecuta correctamente incluso cuando no hay datos nuevos desde el origen.
timestamp
Un JSONObject que contiene las marcas de tiempo relacionadas con este registro de datos.
eventTime: Un valor Long que representa la hora en que ocurrió el cambio en la base de datos de origen. Es una marca de tiempo de 13 dígitos con precisión de milisegundos.
systemTime: Un valor Long que representa la hora en que la tarea de sincronización procesó este mensaje de cambio. Es una marca de tiempo de 13 dígitos con precisión de milisegundos.
checkpointTime: Un valor Long que representa la hora utilizada para restablecer el desplazamiento de sincronización. Este valor suele ser igual a
eventTime. Es una marca de tiempo de 13 dígitos con precisión de milisegundos.
ddl
Este campo se completa únicamente para operaciones DDL que cambian la estructura de la tabla. Para operaciones DML como inserción, eliminación y modificación de datos, el campo ddl es nulo.
text: Una cadena (String) que contiene el texto de la sentencia DDL de la base de datos.
ddlMeta: Una cadena (String) que contiene la representación binaria de un objeto SQLStatement, codificada en Base64. El objeto SQLStatement se genera al analizar sintácticamente la sentencia DDL con FastSQL.
Si habilita la compatibilidad con DDL, el sistema pasa el objeto SQLStatement serializado. El componente descendente puede entonces deserializar este objeto para reconstruir la sentencia DDL en la base de datos de destino y aplicar el cambio.
version
N/A
El número de versión del formato.
-
Serialización BLOB
En este formato JSON, cada mensaje corresponde a un único JSONObject. La estructura de este JSONObject, que puede incluir objetos y matrices anidados, define el formato del mensaje.
Para serializar el mensaje, convierta el JSONObject a una cadena (por ejemplo, mediante el método
toJSONStringde fastjson) y luego convierta la cadena a una matriz de bytes con el métodoString.getBytes(Charsets.UTF_8).
-
Ejemplos de mensajes JSON
-
Inserción:
{ "schema": { "dataColumn": [ { "name": "id", "type": "LONG" }, { "name": "name", "type": "STRING" }, { "name": "comment", "type": "STRING" } ], "source": { "dbName": "example_db", "dbType": "MySQL", "tableName": "example_table_pk" }, "primaryKey": [ "id", "name" ] }, "payload": { "op": "INSERT", "after": { "dataColumn": { "name": "joe", "comment": "comment", "id": 1 } }, "sequenceId": "1605339516000000004", "timestamp": { "eventTime": 1605339932000, "systemTime": 1605339932736, "checkpointTime": 1605339932000 } }, "version": "0.0.1" } -
Actualización previa:
{ "schema": { "dataColumn": [ { "name": "id", "type": "LONG" }, { "name": "name", "type": "STRING" }, { "name": "comment", "type": "STRING" } ], "source": { "dbName": "example_db", "dbType": "MySQL", "tableName": "example_table_pk" }, "primaryKey": [ "id", "name" ] }, "payload": { "op": "UPDATE_BEFOR", "before": { "dataColumn": { "name": "joe", "comment": "comment", "id": 1 } }, "sequenceId": "1605339516000000005", "timestamp": { "eventTime": 1605339934000, "systemTime": 1605339934951, "checkpointTime": 1605339934000 } }, "version": "0.0.1" } -
Actualización posterior:
{ "schema": { "dataColumn": [ { "name": "id", "type": "LONG" }, { "name": "name", "type": "STRING" }, { "name": "comment", "type": "STRING" } ], "source": { "dbName": "example_db", "dbType": "MySQL", "tableName": "example_table_pk" }, "primaryKey": [ "id", "name" ] }, "payload": { "op": "UPDATE_AFTER", "after": { "dataColumn": { "name": "joe", "comment": "com1", "id": 1 } }, "sequenceId": "1605339516000000005", "timestamp": { "eventTime": 1605339934000, "systemTime": 1605339934951, "checkpointTime": 1605339934000 } }, "version": "0.0.1" } -
Eliminación:
{ "schema": { "dataColumn": [ { "name": "id", "type": "LONG" }, { "name": "name", "type": "STRING" }, { "name": "comment", "type": "STRING" } ], "source": { "dbName": "example_db", "dbType": "MySQL", "tableName": "example_table_pk" }, "primaryKey": [ "id", "name" ] }, "payload": { "op": "DELETE", "before": { "dataColumn": { "name": "joe", "comment": "com1", "id": 1 } }, "sequenceId": "1605339516000000006", "timestamp": { "eventTime": 1605339937000, "systemTime": 1605339937671, "checkpointTime": 1605339937000 } }, "version": "0.0.1" } -
Heartbeat:
{ "schema": {}, "payload": { "op": "MHEARTBEAT", "timestamp": { "eventTime": 1605339953629, "checkpointTime": 1605339953629 } }, "version": "0.0.1" } -
DDL:
{ "schema": { "source": { "dbName": "example_db", "dbType": "MySQL", "tableName": "example_table_nopk" } }, "payload": { "op": "ALTER", "sequenceId": "1605339516000000035", "ddl": { "text": "alter table example_table_nopk add column holo text", "ddlMeta": "rO0ABXNyACljb20uYWxpYmFiYS5kaS5wbHVnaW4uY2VudGVyLm1ldGEuRERMTWV0YQLb5Cx/YWXtAgACTAAHZGRsVGV4dHQAEkxqYXZhL2xhbmcvU3RyaW5nO0wACXN0YXRlbWVudHQAKkxjb20vYWxpYmFiYS9mYXN0c3FsL3NxbC9hc3QvU1FMU3RhdGVtZW50O3hwdAAtYWx0ZXIgdGFibGUgdF9zaGl5dV9ub3BrIGFkZCBjb2x1bW4gaG9sbyB0ZXh0c3IAPGNvbS5hbGliYWJhLmZhc3RzcWwuc3FsLmFzdC5zdGF0ZW1lbnQuU1FMQWx0ZXJUYWJsZVN0YXRlbWVudBQPP3vMUl2cAgAPSQAHYnVja2V0c1oABmlnbm9yZVoAF2ludmFsaWRhdGVHbG9iYWxJbmRleGVzWgAPbWVyZ2VTbWFsbEZpbGVzWgAHb2ZmbGluZVoABm9ubGluZVoADnJlbW92ZVBhdGl0aW5nWgATdXBkYXRlR2xvYmFsSW5kZXhlc1oAD3VwZ3JhZGVQYXRpdGluZ0wAC2NsdXN0ZXJlZEJ5dAAQTGphdmEvdXRpbC9MaXN0O0wABWl0ZW1zcQB+AAZMAAlwYXJ0aXRpb250ACxMY29tL2FsaWJhYmEvZmFzdHNxbC9zcWwvYXN0L1NRTFBhcnRpdGlvbkJ5O0wACHNvcnRlZEJ5cQB+AAZMAAx0YWJsZU9wdGlvbnNxAH4ABkwAC3RhYmxlU291cmNldAA6TGNvbS9hbGliYWJhL2Zhc3RzcWwvc3FsL2FzdC9zdGF0ZW1lbnQvU1FMRXhwclRhYmxlU291cmNlO3hyACxjb20uYWxpYmFiYS5mYXN0c3FsLnNxbC5hc3QuU1FMU3RhdGVtZW50SW1wbEOxUUDVCJMGAgADWgAJYWZ0ZXJTZW1pTAAGZGJUeXBldAAcTGNvbS9hbGliYWJhL2Zhc3RzcWwvRGJUeXBlO0wACWhlYWRIaW50c3EAfgAGeHIAKWNvbS5hbGliYWJhLmZhc3RzcWwuc3FsLmFzdC5TUUxPYmplY3RJbXBs5LvqLFggFVECAAVJAAxzb3VyY2VDb2x1bW5JAApzb3VyY2VMaW5lTAAKYXR0cmlidXRlc3QAD0xqYXZhL3V0aWwvTWFwO0wABGhpbnR0ACxMY29tL2FsaWJhYmEvZmFzdHNxbC9zcWwvYXN0L1NRTENvbW1lbnRIaW50O0wABnBhcmVudHQAJ0xjb20vYWxpYmFiYS9mYXN0c3FsL3NxbC9hc3QvU1FMT2JqZWN0O3hwAAAAAAAAAABwcHAAfnIAGmNvbS5hbGliYWJhLmZhc3RzcWwuRGJUeXBlAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAFbXlzcWxwAAAAAAAAAAAAAAAAc3IAE2phdmEudXRpbC5BcnJheUxpc3R4gdIdmcdhnQMAAUkABHNpemV4cAAAAAB3BAAAAAB4c3EAfgAUAAAAAXcEAAAAAXNyADxjb20uYWxpYmFiYS5mYXN0c3FsLnNxbC5hc3Quc3RhdGVtZW50LlNRTEFsdGVyVGFibGVBZGRDb2x1bW4l5T6CFe//BAIABloAB2Nhc2NhZGVaAAVmaXJzdEwAC2FmdGVyQ29sdW1udAAlTGNvbS9hbGliYWJhL2Zhc3RzcWwvc3FsL2FzdC9TUUxOYW1lO0wAB2NvbHVtbnNxAH4ABkwAC2ZpcnN0Q29sdW1ucQB+ABhMAAhyZXN0cmljdHQAE0xqYXZhL2xhbmcvQm9vbGVhbjt4cQB+AAsAAAAAAAAAAHBwcQB+AA8AAHBzcQB+ABQAAAABdwQAAAABc3IAOWNvbS5hbGliYWJhLmZhc3RzcWwuc3FsLmFzdC5zdGF0ZW1lbnQuU1FMQ29sdW1uRGVmaW5pdGlvbst0gLKZ0qAtAgAmWgANYXV0b0luY3JlbWVudFoADGRpc2FibGVJbmRleFoAB3ByZVNvcnRJAAxwcmVTb3J0T3JkZXJaAAZzdG9yZWRaAAd2aXJ0dWFsWgAHdmlzaWJsZUwACGFubkluZGV4dAApTGNvbS9hbGliYWJhL2Zhc3RzcWwvc3FsL2FzdC9TUUxBbm5JbmRleDtMAAZhc0V4cHJ0ACVMY29tL2FsaWJhYmEvZmFzdHNxbC9zcWwvYXN0L1NRTEV4cHI7TAALY2hhcnNldEV4cHJxAH4AHkwADWNvbFByb3BlcnRpZXNxAH4ABkwAC2NvbGxhdGVFeHBycQB+AB5MAAdjb21tZW50cQB+AB5MAAtjb21wcmVzc2lvbnQALkxjb20vYWxpYmFiYS9mYXN0c3FsL3NxbC9hc3QvZXhwci9TUUxDaGFyRXhwcjtMAAtjb25zdHJhaW50c3EAfgAGTAAIZGF0YVR5cGV0AClMY29tL2FsaWJhYmEvZmFzdHNxbC9zcWwvYXN0L1NRTERhdGFUeXBlO0wABmRiVHlwZXEAfgAKTAALZGVmYXVsdEV4cHJxAH4AHkwACWRlbGltaXRlcnEAfgAeTAASZGVsaW1pdGVyVG9rZW5pemVycQB+AB5MAAZlbmFibGVxAH4AGUwABmVuY29kZXEAfgAfTAAGZm9ybWF0cQB+AB5MABBnZW5lcmF0ZWRBbGF3c0FzcQB+AB5MAAhpZGVudGl0eXQARExjb20vYWxpYmFiYS9mYXN0c3FsL3NxbC9hc3Qvc3RhdGVtZW50L1NRTENvbHVtbkRlZmluaXRpb24kSWRlbnRpdHk7TAASanNvbkluZGV4QXR0cnNFeHBycQB+AB5MAAhtYXBwZWRCeXEAfgAGTAAEbmFtZXEAfgAYTAAMbmxwVG9rZW5pemVycQB+AB5MAAhvblVwZGF0ZXEAfgAeTAAEcmVseXEAfgAZTAAMc2VxdWVuY2VUeXBldAAvTGNvbS9hbGliYWJhL2Zhc3RzcWwvc3FsL2FzdC9BdXRvSW5jcmVtZW50VHlwZTtMAARzdGVwcQB+AB5MAAdzdG9yYWdlcQB+AB5MAAl1bml0Q291bnRxAH4AHkwACXVuaXRJbmRleHEAfgAeTAAIdmFsaWRhdGVxAH4AGUwACXZhbHVlVHlwZXEAfgAeeHEAfgALAAAAAAAAAABwcHEAfgAaAAAAAAAAAAAAAHBwcHBwcHBzcQB+ABQAAAAAdwQAAAAAeHNyADpjb20uYWxpYmFiYS5mYXN0c3FsLnNxbC5hc3Quc3RhdGVtZW50LlNRTENoYXJhY3RlckRhdGFUeXBlqtJac/d+04cCAAVaAAloYXNCaW5hcnlMAAtjaGFyU2V0TmFtZXEAfgABTAAIY2hhclR5cGVxAH4AAUwAB2NvbGxhdGVxAH4AAUwABWhpbnRzcQB+AAZ4cgArY29tLmFsaWJhYmEuZmFzdHNxbC5zcWwuYXN0LlNRTERhdGFUeXBlSW1wbEWL29pc1gZFAgAJSgAObmFtZUhhc2hDb2RlNjRaAAh1bnNpZ25lZFoAEXdpdGhMb2NhbFRpbWVab25lWgAIemVyb2ZpbGxMAAlhcmd1bWVudHNxAH4ABkwABmRiVHlwZXEAfgAKTAAHaW5kZXhCeXEAfgAeTAAEbmFtZXEAfgABTAAMd2l0aFRpbWVab25lcQB+ABl4cQB+AAsAAAAAAAAAAHBwcQB+ACP6BPTvGZVAfgAAAHNxAH4AFAAAAAB3BAAAAAB4cHB0AAR0ZXh0cABwcHBwcQB+ABJwcHBwcHBwcHBwc3IAMmNvbS5hbGliYWJhLmZhc3RzcWwuc3FsLmFzdC5leHByLlNRTElkZW50aWZpZXJFeHBy3DXH1zvWbgkCAARKAApoYXNoQ29kZTY0TAAEbmFtZXEAfgABTAAOcmVzb2x2ZWRDb2x1bW5xAH4ADkwAE3Jlc29sdmVkT3duZXJPYmplY3RxAH4ADnhyACdjb20uYWxpYmFiYS5mYXN0c3FsLnNxbC5hc3QuU1FMRXhwckltcGxs2ypmFJxWrQIAAHhxAH4ACwAAAAAAAAAAcHBwQCnxzH5tIDl0AARob2xvcHBwcHBwcHBwcHBweHBweHBzcQB+ABQAAAAAdwQAAAAAeHNxAH4AFAAAAAB3BAAAAAB4c3IAOGNvbS5hbGliYWJhLmZhc3RzcWwuc3FsLmFzdC5zdGF0ZW1lbnQuU1FMRXhwclRhYmxlU291cmNlRHD7eYJ4eswCAAVMAAdjb2x1bW5zcQB+AAZMAARleHBycQB+AB5MAApwYXJ0aXRpb25zcQB+AAZMAAhzYW1wbGluZ3QAOExjb20vYWxpYmFiYS9mYXN0c3FsL3NxbC9hc3Qvc3RhdGVtZW50L1NRTFRhYmxlU2FtcGxpbmc7TAAMc2NoZW1hT2JqZWN0dAAxTGNvbS9hbGliYWJhL2Zhc3RzcWwvc3FsL3JlcG9zaXRvcnkvU2NoZW1hT2JqZWN0O3hyADhjb20uYWxpYmFiYS5mYXN0c3FsLnNxbC5hc3Quc3RhdGVtZW50LlNRTFRhYmxlU291cmNlSW1wbAqEMenTm5zUAgAESgAPYWxpYXNIYXNoQ29kZTY0TAAFYWxpYXNxAH4AAUwACWZsYXNoYmFja3EAfgAeTAAFaGludHNxAH4ABnhxAH4ACwAAAAAAAAAAcHBwAAAAAAAAAABwcHBwc3EAfgAqAAAAAAAAAABwcHEAfgA0NH7o4UvP9Dt0AAx0X3NoaXl1X25vcGtwcHBwcA==" }, "timestamp": { "eventTime": 1605342109000, "systemTime": 1605342109259, "checkpointTime": 1605342109000 } }, "version": "0.0.1" }