Topik ini menjelaskan dukungan berbagai tipe topik untuk sinkronisasi perubahan data akibat operasi pada tabel sumber, strategi sharding untuk masing-masing tipe topik, format data, serta contoh pesan.
Dukungan berbagai tipe topik untuk sinkronisasi perubahan data yang disebabkan oleh operasi pada tabel sumber
| Tipe topik | Menulis pesan DML ke topik | Menulis pesan heartbeat hulu ke topik | Menulis pesan DDL ke topik | Mode pemetaan antara tabel sumber dan topik | Tipe data |
| TUPLE | Didukung | Tidak didukung | Tidak didukung | Satu tabel ke satu topik | Tipe data yang didukung oleh DataHub |
| BLOB | Didukung | Didukung | Didukung | Satu database (beberapa tabel) ke satu topik | Data BLOB |
- Setelah membuat topik TUPLE, bidang yang telah didefinisikan dalam skema topik tidak dapat dimodifikasi. Oleh karena itu, topik TUPLE cocok untuk skenario di mana skema tabel sumber bersifat tetap dan tidak terdapat operasi DDL yang mengubah skema tabel—seperti ADD COLUMN atau DROP COLUMN—pada tabel sumber. Topik TUPLE tidak dapat menyinkronkan pesan DDL maupun pesan heartbeat dari tabel sumber, sehingga pesan tersebut tidak dapat ditransmisikan secara transparan ke tujuan. Pemetaan antara tabel sumber dan topik bersifat satu-ke-satu. Jika Anda ingin menulis data dari banyak tabel sumber ke DataHub, Anda harus membuat jumlah topik yang sama di DataHub, yang menyulitkan konsumsi data oleh pihak tujuan.
- Topik BLOB tidak memiliki skema dan hanya menyimpan data BLOB. Topik BLOB dapat menyinkronkan pesan DDL dan pesan heartbeat dari tabel sumber, serta memungkinkan pesan tersebut dikonsumsi oleh tujuan. Pemetaan antara tabel sumber dan topik bersifat banyak-ke-satu, yaitu beberapa tabel dalam satu database dipetakan ke satu topik. Anda hanya perlu membuat satu topik untuk beberapa tabel sumber yang ingin dibaca datanya, sehingga memudahkan konsumsi data oleh tujuan. Kami merekomendasikan penggunaan topik BLOB dalam skenario di mana DataHub berperan sebagai antrian pesan perantara untuk migrasi seluruh data dalam sebuah database.
Strategi sharding untuk berbagai tipe topik
Shard adalah saluran konkuren yang digunakan untuk mentransmisikan data dalam suatu topik. Laju penulisan pesan ke topik oleh satu shard dibatasi. Anda dapat menambahkan beberapa shard untuk meningkatkan kinerja penulisan. Namun, DataHub hanya dapat menjamin urutan konsumsi pesan jika hanya satu shard yang digunakan. Urutan konsumsi pesan antar shard tidak dapat dijamin ketika terdapat lebih dari satu shard. Tabel berikut menjelaskan strategi sharding untuk masing-masing tipe topik guna mencapai tiga tujuan sekaligus: peningkatan kinerja penulisan melalui penambahan shard, jaminan urutan konsumsi pesan antar shard, serta pencegahan kesenjangan data (data skew).
| Skenario | TUPLE | BLOB |
| Kunci primer tersedia. Anda dapat menentukan kunci primer kustom. | Pesan di-shard berdasarkan kunci primer. | Pesan di-shard berdasarkan kunci primer. |
| Urutan konsumsi pesan perlu dijamin. | Pesan dengan nilai kunci primer yang sama dikonsumsi secara berurutan. | Pesan dengan nilai kunci primer yang sama dikonsumsi secara berurutan. |
| Tidak ada kunci primer. | Pesan di-shard berdasarkan kolom acak. | Pesan di-shard berdasarkan nama tabel. |
| Urutan konsumsi pesan perlu dijamin. | Urutan konsumsi pesan tidak dapat dijamin. | Pesan yang berasal dari tabel yang sama dikonsumsi secara berurutan. |
Format data
- TUPLESaat Anda membuat topik di Data Integration, kolom metadata tertentu ditambahkan secara otomatis:
_sequence_id_,_excute_time_,_source_table_,_before_image_, dan_after_image_Parameter Deskripsi _sequence_id_ ID unik setiap pesan. Nilai parameter bertipe STRING dan terdiri atas angka. ID pesan sama untuk operasi update before dan update after. _excute_time_ Waktu saat data dihasilkan. _source_table_ Nama tabel sumber. _before_image_ Pre-image. Nilai parameter adalah Y untuk operasi delete atau update before. Nilai parameter adalah N untuk operasi insert atau update after. _after_image_ Post-image. Nilai parameter adalah N untuk operasi delete atau update before. Nilai parameter adalah Y untuk operasi insert atau update after. _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 - BLOBPesan topik BLOB berupa data biner yang dihasilkan dari konversi string berformat JSON. Contoh kode berikut menunjukkan string berformat JSON:
{ "schema": { // Metadata tempat perubahan dilakukan. Hanya nama kolom dan tipe data kolom yang ditentukan. "dataColumn": [// Kolom tempat perubahan dilakukan. Data di tabel tujuan diperbarui secara otomatis. { "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// ID urutan unik setiap pesan yang dihasilkan setelah data inkremental dan data penuh digabungkan. Nilai parameter bertipe STRING. "op": "INSERT/UPDATE/DELETE/TRANSACTION_BEGIN/TRANSACTION_END/CREATE/ALTER/ERASE/QUERY/TRUNCATE/RENAME/CINDEX/DINDEX/GTID/XACOMMIT/XAROLLBACK/MHEARTBEAT..."// Operasi yang dilakukan. Nilai parameter bersifat case-sensitive. "timestamp": { "eventTime": 1,// Wajib. Waktu saat operasi dilakukan. Nilai parameter adalah timestamp 13 digit dalam milidetik. "systemTime": 2,// Opsional. Waktu sistem yang harus Anda tentukan untuk sumber data tertentu seperti Oracle. "checkpointTime": 3// Opsional. Waktu checkpoint yang harus Anda tentukan untuk sumber data tertentu seperti ApsaraDB for OceanBase. }, "ddl": { "text": "ADD COLUMN ...", "ddlMeta": "[SQLStatement serialized binary, expressed in base64 string]" } }, "version":"1.0.0" }- Deskripsi bidang untuk topik BLOBPenting Tipe data berikut didukung untuk bidang dalam pesan: BOOLEAN, DOUBLE, DATE, BYTES, LONG, dan STRING.
BOOLEAN: Nilai valid untuk bidang bertipe data ini adalah true dan false. DATE: Nilai bidang bertipe data ini adalah timestamp 13 digit dalam milidetik. BYTES: Nilai bidang bertipe data ini adalah string yang di-encode Base64. Encode dan decode Base64 diimplementasikan dengan memanggil operasi API yang disediakan oleh java.util.Base64. String text = "Test text123"; // Encode Base64.getEncoder().encodeToString(text.getBytes("UTF-8")) // Decode Base64.getDecoder().decode(encodedText)Bidang level-1 Bidang level-2 Deskripsi schema dataColumn Nama dan tipe data kolom. Nilainya bertipe JSONArray. dataColumn mencatat nama dan tipe data kolom yang diperbarui di sumber. Operasi perubahan dapat berupa penambahan, penghapusan, atau modifikasi data, atau perubahan skema tabel di sumber. - name: nama kolom.
- type: tipe data kolom.
primaryKey Informasi tentang kunci primer. Nilainya bertipe List. pk: nama kunci primer.
source Informasi tentang sumber atau tabel sumber. Nilainya bertipe Object. - dbType: tipe sumber. Nilainya bertipe STRING.
- dbVersion: versi sumber. Nilainya bertipe STRING.
- dbName: nama sumber. Nilainya bertipe STRING.
- schemaName: nama skema. Anda harus menentukan bidang ini untuk sumber seperti PostgreSQL dan SQL Server. Nilainya bertipe STRING.
- tableName: nama tabel sumber. Nilainya bertipe STRING.
payload before Data sebelum perubahan. Nilainya bertipe JSONObject. Misalnya, jika database MySQL adalah sumber dan data di sumber ini diperbarui, bidang before mencatat data sebelum pembaruan. - Setelah pesan pembaruan atau penghapusan data dibaca dari sumber, bidang before ditentukan dalam catatan penulisan.
- dataColumn: informasi kolom. Nilainya bertipe JSONObject. Nilai bidang dalam format Nama kolom:Nilai kolom. Nama kolom adalah string. Jika tipe data yang ditentukan untuk kolom adalah BYTES, nilai kolom adalah string yang di-encode Base64. Jika tipe data yang ditentukan untuk kolom adalah DATE, nilai kolom adalah timestamp 13 digit bertipe LONG.
after Data setelah perubahan. Bidang after mencatat data setelah perubahan dalam format data yang sama dengan bidang before. Catatan Bidang ini wajib ditentukan saat operasi update atau insert dilakukan.op Tipe operasi. Nilai valid: - INSERT: menyisipkan data.
- UPDATE_BEFOR: memperbarui data (sebelum).
- UPDATE_AFTER: memperbarui data (setelah).
- DELETE: menghapus data.
- TRANSACTION_BEGIN: memulai transaksi sumber data.
- TRANSACTION_END: mengakhiri transaksi sumber data.
- CREATE: membuat tabel di sumber data.
- ALTER: memodifikasi tabel di sumber data.
- QUERY: menanyakan perubahan data di database dengan mengeksekusi pernyataan SQL yang menyebabkan perubahan data tersebut.
- TRUNCATE: menghapus semua baris dari tabel di sumber data.
- RENAME: mengganti nama tabel di sumber data.
- CINDEX: membuat indeks.
- DINDEX: menghapus indeks.
- MHEARTBEAT: pesan heartbeat. Pesan ini menunjukkan bahwa node sinkronisasi berjalan sebagaimana mestinya ketika tidak ada data baru yang dihasilkan di sumber.
timestamp Timestamp catatan data. Nilainya bertipe JSONObject. - eventTime: waktu saat data di sumber berubah. Nilainya adalah timestamp 13 digit dalam milidetik dan bertipe LONG.
- systemTime: waktu saat node sinkronisasi membaca pesan perubahan. Nilainya adalah timestamp 13 digit dalam milidetik dan bertipe LONG.
- checkpointTime: waktu tertentu saat offset sinkronisasi diatur ulang. Nilainya adalah timestamp 13 digit dalam milidetik dan bertipe LONG. Dalam kebanyakan kasus, nilai bidang ini sama dengan nilai bidang eventTime.
ddl Bidang ini ditentukan hanya jika skema tabel di sumber diubah. Nilainya null ketika operasi DDL, seperti penambahan, penghapusan, atau modifikasi data, dilakukan di sumber. - text: teks pernyataan DDL di sumber. Nilainya bertipe STRING.
- ddlMeta: data biner yang diperoleh dengan melakukan serialisasi objek pernyataan SQL yang dihasilkan setelah Anda menggunakan FastSQL untuk mengurai pernyataan DDL. Data biner disimpan sebagai string yang di-encode Base64. Nilai ddlMeta bertipe STRING.
Setelah Anda mengaktifkan dukungan DDL, tujuan melakukan deserialisasi objek pernyataan SQL yang telah diserialisasi untuk memulihkan objek tersebut menjadi pernyataan DDL yang dapat dieksekusi di topik.
version Tidak ada Versi data dalam format JSON. - Deskripsi serialisasi untuk data BLOB
Dalam topik ini, pesan dipetakan ke objek JSON yang terdiri atas pasangan kunci-nilai. Nilai parameter value dalam setiap pasangan kunci-nilai dapat berupa objek JSON, array JSON, atau nilai tipe data tertentu sesuai format pesan.
Tipe data penyimpanan untuk setiap bidang dalam objek JSON mengacu pada deskripsi bidang di atas. Anda dapat melakukan serialisasi objek JSON menjadi string menggunakan metode toJSONString yang disediakan oleh Fastjson, lalu mengonversi string tersebut ke dalam bentuk byte[] menggunakan metode getBytes(Charsets.UTF_8) dengan set karakter UTF-8.
- Deskripsi bidang untuk topik BLOB
Data JSON contoh untuk pesan terkait
- INSERT:
{ "schema": { "dataColumn": [ { "name": "id", "type": "LONG" }, { "name": "name", "type": "STRING" }, { "name": "comment", "type": "STRING" } ], "source": { "dbName": "yunshi_db", "dbType": "MySQL", "tableName": "t_shiyu_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" } - UPDATE BEFORE:
{ "schema": { "dataColumn": [ { "name": "id", "type": "LONG" }, { "name": "name", "type": "STRING" }, { "name": "comment", "type": "STRING" } ], "source": { "dbName": "yunshi_db", "dbType": "MySQL", "tableName": "t_shiyu_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" } - UPDATE AFTER:
{ "schema": { "dataColumn": [ { "name": "id", "type": "LONG" }, { "name": "name", "type": "STRING" }, { "name": "comment", "type": "STRING" } ], "source": { "dbName": "yunshi_db", "dbType": "MySQL", "tableName": "t_shiyu_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" } - DELETE:
{ "schema": { "dataColumn": [ { "name": "id", "type": "LONG" }, { "name": "name", "type": "STRING" }, { "name": "comment", "type": "STRING" } ], "source": { "dbName": "yunshi_db", "dbType": "MySQL", "tableName": "t_shiyu_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": "yunshi_db", "dbType": "MySQL", "tableName": "t_shiyu_nopk" } }, "payload": { "op": "ALTER", "sequenceId": "1605339516000000035", "ddl": { "text": "alter table t_shiyu_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+ABJwcHBwcHBwcHBwc3IAMmNvbS5hbGliYWJhLmZhc3RzcWwuc3FsLmFzdC5leHByLlNRTElkZW50aWZpZXJFeHBy3DXH1zvWbgkCAARKAApoYXNoQ29kZTY0TAAEbmFtZXEAfgABTAAOcmVzb2x2ZWRDb2x1bW5xAH4ADkwAE3Jlc29sdmVkT3duZXJPYmplY3RxAH4ADnhyACdjb20uYWxpYmFiYS5mYXN0c3FsLnNxbC5hc3QuU1FMRXhwckltcGxs2ypmFJxWrQIAAHhxAH4ACwAAAAAAAAAAcHBwQCnxzH5tIDl0AARob2xvcHBwcPBwcHBwcHBweHBweHBzcQB+ABQAAAAAdwQAAAAAeHNxAH4AFAAAAAB3BAAAAAB4c3IAOGNvbS5hbGliYWJhLmZhc3RzcWwuc3FsLmFzdC5zdGF0ZW1lbnQuU1FMRXhwclRhYmxlU291cmNlRHD7eYJ4eswCAAVMAAdjb2x1bW5zcQB+AAZMAARleHBycQB+AB5MAApwYXJ0aXRpb25zcQB+AAZMAAhzYW1wbGluZ3QAOExjb20vYWxpYmFiYS9mYXN0c3FsL3NxbC9hc3Qvc3RhdGVtZW50L1NRTFRhYmxlU2FtcGxpbmc7TAAMc2NoZW1hT2JqZWN0dAAxTGNvbS9hbGliYWJhL2Zhc3RzcWwvc3FsL3JlcG9zaXRvcnkvU2NoZW1hT2JqZWN0O3hyADhjb20uYWxpYmFiYS5mYXN0c3FsLnNxbC5hc3Quc3RhdGVtZW50LlNRTFRhYmxlU291cmNlSW1wbAqEMenTm5zUAgAESgAPYWxpYXNIYXNoQ29kZTY0TAAFYWxpYXNxAH4AAUwACWZsYXNoYmFja3EAfgAeTAAFaGludHNxAH4ABnhxAH4ACwAAAAAAAAAAcHBwAAAAAAAAAABwcHBwc3EAfgAqAAAAAAAAAABwcHEAfgA0NH7o4UvP9Dt0AAx0X3NoaXl1X25vcGtwcHBwcA==" }, "timestamp": { "eventTime": 1605342109000, "systemTime": 1605342109259, "checkpointTime": 1605342109000 } }, "version": "0.0.1" }