All Products
Search
Document Center

PolarDB:Migrasi data

Last Updated:Aug 08, 2026

Panduan ini menyediakan langkah-langkah terperinci dan praktik terbaik untuk memigrasikan data dari Amazon DynamoDB ke edisi PolarDB yang kompatibel dengan DynamoDB. PolarDB menyediakan rangkaian alat migrasi khusus yang menggabungkan sinkronisasi penuh dan inkremental untuk membantu Anda mencapai migrasi data yang lancar dengan downtime minimal.

Ikhtisar migrasi

Migrasi terdiri dari lima tahap, yang diatur oleh tiga alat inti: nimo-shake (untuk sinkronisasi data, termasuk sinkronisasi penuh dan inkremental), nimo-full-check (untuk pemeriksaan konsistensi data), dan PolarDBBackSync (untuk sinkronisasi balik).

  1. Sinkronisasi penuh

    • Alat: nimo-shake

    • Proses: Alat ini secara otomatis membuat skema tabel yang sesuai di kluster PolarDB target. Kemudian, alat ini membaca semua data dari database sumber secara konkuren menggunakan operasi Scan dan menuliskannya ke kluster target dalam batch menggunakan BatchWriteItem (secara default, data ditulis langsung melalui protokol PostgreSQL. Untuk informasi lebih lanjut, lihat Sinkronisasi penuh dalam mode tulis langsung PostgreSQL pada Langkah 1).

  2. Sinkronisasi inkremental

    • Alat: nimo-shake

    • Proses: Setelah sinkronisasi penuh, alat ini menggunakan AWS DynamoDB Streams untuk menangkap perubahan data (penyisipan, penghapusan, dan modifikasi) dari sumber sejak migrasi dimulai. Alat ini kemudian menyinkronkan perubahan tersebut ke kluster target untuk memastikan konsistensi data akhirnya. Proses ini mendukung transfer yang dapat dilanjutkan kembali.

  3. Pemeriksaan konsistensi

    • Alat: nimo-full-check

    • Proses: Anda dapat menjalankan alat ini kapan saja selama atau setelah sinkronisasi data. Alat ini membaca data secara konkuren dari sumber dan target, membandingkannya berdasarkan primary key, dan menghasilkan laporan perbedaan terperinci untuk memverifikasi integritas data.

  4. (Opsional) Sinkronisasi balik

    • Alat: PolarDBBackSync.jar (berbasis Realtime Compute for Apache Flink)

    • Proses: Setelah memverifikasi konsistensi data, Anda dapat membuat tautan sinkronisasi balik dari PolarDB for PostgreSQL ke DynamoDB sumber sebagai perlindungan untuk rollback bisnis. Alat ini menggunakan Flink untuk menangkap perubahan data real-time dari PolarDB dan memanggil operasi API DynamoDB PutItem atau DeleteItem untuk menyinkronkan pembaruan tersebut.

  5. Cutover bisnis

    • Proses: Ketika latensi data inkremental minimal dan pemeriksaan konsistensi tidak menunjukkan perbedaan, Anda dapat menghentikan sementara penulisan bisnis. Setelah semua data tersinkronisasi, alihkan koneksi aplikasi Anda ke kluster PolarDB untuk menyelesaikan migrasi.

Catatan

  • Dampak performa: Migrasi data, terutama selama sinkronisasi penuh, memberikan beban baca dan tulis yang tinggi pada database sumber dan target. Kami merekomendasikan melakukan migrasi selama jam sepi dan menilai kapasitas database Anda terlebih dahulu.

  • Konfigurasi keamanan: Sebelum cutover bisnis, batasi izin tulis pada kluster PolarDB target. Berikan akses tulis hanya kepada akun sinkronisasi data untuk mencegah korupsi data yang tidak disengaja.

Prasyarat

Sebelum memulai migrasi, pastikan Anda telah menyelesaikan persiapan berikut:

  1. Dapatkan toolkit:

    1. Toolkit migrasi: NimoShake-20260807.zip. Paket ini berisi tiga alat: nimo-shake, nimo-full-check, dan nimo-repair.

    2. (Opsional) Toolkit migrasi balik: PolarDBBackSync.jar.

  2. PolarDB kluster:

    1. Untuk kluster yang sudah ada atau baru, aktifkan kompatibilitas DynamoDB, dapatkan titik akhir DynamoDB, dan buat akun DynamoDB khusus untuk mendapatkan kredensial akses guna akses API.

    2. (Opsional) Konfigurasi parameter: Jika Anda perlu mengonfigurasi sinkronisasi balik, Anda harus mengubah parameter wal_level kluster PolarDB menjadi logical. Mengubah parameter ini memerlukan restart kluster, sehingga kami merekomendasikan menyelesaikan langkah ini sebelum memulai migrasi.

  3. AWS DynamoDB:

    1. Dapatkan kredensial akses (ID AccessKey dan Secret Access Key) untuk AWS DynamoDB.

  4. Lingkungan runtime: Siapkan instance ECS atau server lain yang memiliki konektivitas ke kluster PolarDB dan AWS DynamoDB untuk menjalankan toolkit migrasi.

Prosedur

Langkah 1: Konfigurasikan dan mulai sinkronisasi data

  1. Ekstrak NimoShake.zip, masuk ke direktori NimoShake, dan edit file konfigurasi bersama conf/nimo.conf. Alat nimo-shake, nimo-full-check, dan nimo-repair berbagi file ini, dan masing-masing alat hanya membaca parameter yang diperlukannya. Berikut adalah parameter konfigurasi inti yang diperlukan untuk memulai sinkronisasi:

    Parameter

    Deskripsi

    Contoh nilai

    sync_mode

    Mode sinkronisasi: all menunjukkan sinkronisasi penuh dan inkremental, sedangkan full hanya sinkronisasi penuh.

    all

    source.access_key_id

    ID AccessKey AWS DynamoDB sumber.

    AKIAIOSFODNN7...

    source.secret_access_key

    Secret access key AWS DynamoDB sumber.

    wJalrXUtnFEMI...

    source.region

    Wilayah tempat AWS DynamoDB sumber berada.

    cn-north-1

    target.endpoint_url

    Titik akhir akses DynamoDB kluster PolarDB target (termasuk nomor port).

    http://pe-xxx.rwlb.rds...

    target.access_key_id

    ID AccessKey akun DynamoDB untuk kluster PolarDB target.

    your-polardb-access-key

    target.secret_access_key

    Secret access key akun DynamoDB untuk kluster PolarDB target.

    your-polardb-secret-key

    filter.collection.white

    Daftar putih untuk penyaringan tabel. Pisahkan beberapa nama tabel dengan titik koma (;). Parameter ini tidak dapat digunakan bersama parameter daftar hitam.

    c1;c2

    filter.collection.black

    Daftar hitam untuk penyaringan tabel. Pisahkan beberapa nama tabel dengan titik koma (;). Parameter ini tidak dapat digunakan bersama parameter daftar putih.

    c1;c2

    Untuk menggunakan mode pemeriksaan berbasis snapshot S3 yang direkomendasikan (lihat Langkah 2), Anda juga harus mengonfigurasi parameter koneksi PostgreSQL native berikut:

    Parameter

    Deskripsi

    Contoh nilai

    s3.export_state_file

    Jalur ke file status ekspor. File ini ditulis oleh nimo-shake dan dibaca oleh nimo-full-check.

    ../nimo-shake-s3-exports.json

    s3.export_bucket

    Nama bucket S3 target untuk ekspor data DynamoDB.

    my-export-bucket

    s3.export_prefix

    Awalan jalur S3 yang digunakan untuk mengatur file yang diekspor.

    exports/my-project/

    target.pg.endpoint_url

    Alamat port native PolarDB for PostgreSQL (format host:port).

    pc-xxx.pg.polardb.rds...:5432

    target.pg.user

    Username untuk PolarDB for PostgreSQL (juga digunakan sebagai nama skema).

    Catatan

    Akun DynamoDB pada dasarnya adalah akun database standar. Secret access key-nya (SK) dihasilkan dengan mengenkripsi password yang Anda tetapkan menggunakan algoritma yang kompatibel. Oleh karena itu, target.pg.user dan target.access_key_id merujuk pada akun yang sama. target.pg.password adalah password kustom Anda, dan SK adalah kunci yang diturunkan dari password tersebut.

    your-username

    target.pg.password

    Password untuk PolarDB for PostgreSQL.

    your-password

    target.pg.check_database

    Nama database khusus yang menyimpan tabel pemeriksaan inkremental.

    Selama fase sinkronisasi inkremental, nimo-shake menulis primary key dari catatan yang berubah ke tabel pemeriksaan inkremental di database ini agar dapat dibaca oleh mode pemeriksaan s3 atau incr. Anda harus membuat database ini secara manual sebelum startup, dan nimo-shake serta nimo-full-check harus dikonfigurasi dengan nilai yang sama.

    Catatan

    target.pg.check_database mengarah ke database khusus yang menyimpan tabel pemeriksaan inkremental. Sebelum memulai sinkronisasi, gunakan Privileged Account untuk membuat database secara manual dan atur pemiliknya menjadi **target.pg.user** (akun DynamoDB yang dijelaskan di atas). Dengan demikian, akun tersebut memiliki izin untuk membuat skema dan tabel pemeriksaan inkremental di database tersebut.

    nimoshake_check

    (Opsional) Sinkronisasi penuh dalam mode tulis langsung PostgreSQL

    Secara default, sinkronisasi penuh menggunakan mode tulis langsung PostgreSQL native untuk menulis data langsung ke PolarDB menggunakan protokol PostgreSQL standar, melewati lapisan API kompatibilitas DynamoDB untuk performa yang lebih tinggi. Untuk kembali ke lapisan API DynamoDB (BatchWriteItem, yang menulis maksimal 25 item sekaligus), Anda dapat mengubah parameter ini secara manual menjadi dynamodb. Anda dapat mengonfigurasi parameter berikut di bagian [SHAKE] file conf/nimo.conf:

    Parameter

    Deskripsi

    Default

    full.write_protocol

    Protokol yang digunakan untuk penulisan data penuh.

    • postgresql (default): mode tulis langsung PostgreSQL berkinerja tinggi.

    • dynamodb: lapisan API DynamoDB (BatchWriteItem, maksimal 25 item per batch).

    postgresql

    full.document.write.batch

    Jumlah dokumen yang ditulis dalam setiap batch. Saat menggunakan mode tulis langsung PostgreSQL, ukuran batch tidak dibatasi hingga 25 dokumen. Anda dapat meningkatkan nilai ini untuk lebih meningkatkan throughput tulis. Jika Anda kembali ke protokol dynamodb, ubah nilai ini kembali menjadi 25.

    1000

    full.document.concurrency

    Jumlah thread tulis konkuren per tabel. Dalam mode tulis langsung PostgreSQL, alat secara otomatis mengatur ukuran kolam koneksi berdasarkan nilai ini untuk memastikan korespondensi satu-ke-satu antara thread dan koneksi.

    4

    Catatan
    • Mode tulis langsung PostgreSQL juga mengharuskan Anda mengonfigurasi empat parameter target.pg.*. Kumpulan konfigurasi ini dibagi dengan mode pemeriksaan s3 / incr, sehingga Anda tidak perlu memasukkannya lagi.

    • Mode ini hanya memengaruhi jalur tulis selama fase sinkronisasi penuh. Sinkronisasi inkremental selalu menulis data melalui lapisan API yang kompatibel dengan DynamoDB.

  2. (Opsional) Perlindungan Stream Buffer untuk sinkronisasi penuh berdurasi panjang

    AWS DynamoDB Streams hanya menyimpan catatan perubahan selama 24 jam. Ketika tabel sumber berukuran besar dan sinkronisasi penuh diperkirakan memakan waktu lebih dari 24 jam, perubahan inkremental yang dihasilkan selama fase penuh mungkin secara otomatis dibuang oleh AWS jika tetap berada di Streams lebih dari 24 jam, menyebabkan kehilangan data dalam sinkronisasi inkremental. Untuk mengatasi hal ini, Anda dapat mengaktifkan Stream Buffer: pendengar inkremental menulis catatan perubahan Streams ke buffer lokal secara real-time sejak awal sinkronisasi penuh, melewati batas retensi 24 jam. Setelah sinkronisasi penuh selesai, perubahan yang dibuffer dikonsumsi dan diputar ulang dari buffer lokal untuk memastikan tidak ada perubahan yang hilang. Fitur ini dinonaktifkan secara default dan hanya boleh diaktifkan ketika durasi perkiraan sinkronisasi penuh mendekati atau melebihi 24 jam. Konfigurasikan parameter berikut di conf/nimo.conf:

    Parameter

    Deskripsi

    Default

    incr.stream_buffer.enable

    Sakelar utama untuk Stream Buffer.

    false

    incr.stream_buffer.dir

    Direktori file buffer. Jika dibiarkan kosong, default ke direktori saudara dari checkpoint (<workdir>/<id>-buffer).

    Kosong

    incr.stream_buffer.max_seg_size_mb

    Ukuran maksimum (MB) file segmen buffer tunggal. Melebihi nilai ini memicu rotasi.

    64

    incr.stream_buffer.max_seg_count

    Jumlah maksimum catatan per segmen buffer. Melebihi nilai ini memicu rotasi.

    10000

    incr.stream_buffer.max_seg_duration_sec

    Interval waktu (detik) untuk rotasi segmen paksa.

    300

    incr.stream_buffer.max_size_mb

    Kuota disk global (MB), dibagi oleh semua shard dan tabel (bukan per-shard). Rencanakan berdasarkan ruang disk yang tersedia di mesin.

    51200 (50 GB)

    incr.stream_buffer.quota_backoff_sec

    Ketika buffer melebihi kuota global, penulis mencatat ERROR setiap 30 detik untuk meminta operasi memperluas ruang disk atau mempercepat sinkronisasi penuh. Setelah durasi yang ditentukan oleh quota_backoff_sec berlalu, program sinkronisasi secara otomatis dihentikan.

    1800

    • Kapasitas disk dapat diperkirakan secara kasar dengan rumus: Disk yang diperlukan (MB) ≈ Durasi sinkronisasi penuh (detik) × Tulisan puncak (catatan/detik) × (Rata-rata byte per catatan / 3) / 1 MB × 1.5. Selalu sediakan ruang disk lebih daripada kurang.

    • Selama sinkronisasi penuh, pembaca tidak mengonsumsi buffer. Oleh karena itu, begitu buffer melebihi max_size_mb, buffer tidak dapat dikosongkan sendiri. Dalam kasus ini, proses crash setelah backoff. Anda harus menambah ruang disk atau meningkatkan kecepatan sinkronisasi penuh sebelum memulai ulang.

  3. Jalankan file biner untuk sistem operasi Anda untuk memulai sinkronisasi.

    Catatan

    Kami merekomendasikan menjalankan tugas dengan nohup di latar belakang untuk mencegah tugas sinkronisasi terganggu jika sesi terminal terputus.

    # Jalankan di direktori NimoShake
    nohup ./bin/nimo-shake.linux.amd64 -conf=./conf/nimo.conf > /dev/null 2>&1 &

    Program pertama-tama melakukan sinkronisasi penuh. Setelah sinkronisasi penuh selesai, program secara otomatis beralih ke fase sinkronisasi inkremental dan terus berjalan.

Langkah 2: Periksa konsistensi data

  1. nimo-full-check dan nimo-shake berbagi file conf/nimo.conf yang sama, sehingga Anda tidak perlu mengganti direktori atau mengedit file konfigurasi tambahan. Pilih mode pemeriksaan menggunakan parameter mode:

    • scan: Melakukan pemindaian real-time untuk membandingkan data antara sumber dan target. Mode ini paling mudah dikonfigurasi dan tidak memerlukan infrastruktur tambahan, tetapi terus-menerus mengonsumsi kapasitas baca DynamoDB selama pemeriksaan.

    • s3 (Direkomendasikan): Ketika sinkronisasi penuh selesai, nimo-shake secara otomatis mengekspor data sumber ke S3 dan membuat snapshot point-in-time. nimo-full-check menggunakan snapshot ini sebagai garis dasar untuk pemeriksaan, yang menghindari pemindaian ulang DynamoDB sumber. Ini memerlukan parameter terkait S3 dari Langkah 1.

    • incr (Gunakan dengan mode s3): Selama fase sinkronisasi inkremental, nimo-shake menulis primary key dari setiap catatan yang berubah ke tabel pemeriksaan inkremental (ct_{user}_{table}) di PolarDB. nimo-full-check membaca tabel pemeriksaan inkremental dan hanya memeriksa catatan yang berubah.

    • Perbandingan dua metode pemeriksaan

      Scan Mode

      Mode S3 / incr

      Downtime yang diperlukan

      Lebih lama. Penulisan bisnis harus dihentikan selama pemeriksaan untuk mencegah data sumber berubah selama pemindaian.

      Lebih singkat. Pemeriksaan berdasarkan snapshot. Setelah menghentikan penulisan, Anda hanya perlu memastikan bahwa data inkremental telah tersusul sebelum cutover.

      Dampak pada sumber

      Terus-menerus mengonsumsi kapasitas baca DynamoDB.

      Pemeriksaan penuh berdasarkan snapshot S3 dan tidak mengonsumsi kapasitas DynamoDB. Pemeriksaan inkremental (mode incr) hanya mengkueri catatan yang berubah, sehingga mengonsumsi lebih sedikit kapasitas.

      Kompleksitas konfigurasi

      Rendah.

      Lebih tinggi. Memerlukan konfigurasi tambahan untuk S3 dan koneksi PolarDB for PostgreSQL.

  2. (Opsional) Verifikasi kontinu inkremental (mode drain, dinonaktifkan secara default): Secara default, mode incr melakukan verifikasi satu kali terhadap semua catatan perubahan yang terakumulasi di tabel pemeriksaan inkremental selama jendela downtime cutover. Ketika sinkronisasi inkremental berjalan dalam periode panjang (jam hingga hari), tabel pemeriksaan inkremental mengakumulasi banyak primary key tertunda, sehingga verifikasi akhir saat cutover memakan waktu lama. Setelah Anda mengaktifkan verifikasi kontinu inkremental (drain), nimo-full-check mode=incr berjalan sebagai proses berumur panjang: selama sinkronisasi inkremental, proses ini terus-menerus memverifikasi dan mengonsumsi catatan yang telah dikonfirmasi konsisten dari tabel pemeriksaan inkremental, menjaga ukuran tabel tersebut tetap kecil sebelum cutover. Saat cutover, hanya jumlah minimal catatan yang tersisa yang perlu diverifikasi akhir, sehingga secara signifikan mengurangi waktu verifikasi dalam jendela downtime. Fitur ini dinonaktifkan secara default dan tidak memengaruhi perilaku yang ada. Aktifkan hanya ketika periode inkremental panjang dan downtime cutover sangat kritis.

    Penting
    • Sakelar check_drain.enable berlaku untuk nimo-shake dan nimo-full-check. Kedua alat berbagi file conf/nimo.conf yang sama, sehingga satu konfigurasi berlaku untuk keduanya.

    • Sebelum mengaktifkan fitur ini di produksi, kami merekomendasikan menyelesaikan verifikasi lalu lintas penuh pada instance pengujian.

    Konfigurasikan parameter berikut di conf/nimo.conf (tidak perlu perubahan secara default):

    Parameter

    Deskripsi

    Default

    check_drain.enable

    Sakelar utama untuk verifikasi kontinu inkremental (drain). Berlaku untuk nimo-shake dan nimo-full-check. Ketika diatur ke false (default), perilakunya identik dengan perilaku default (mode incr dijalankan sekali lalu keluar).

    false

    check_drain.finalize_flag_file

    Jalur ke file sentinel finalisasi. Saat cutover, operasi menjalankan touch pada file ini, dan proses verifikasi berumur panjang memasuki fase verifikasi akhir pada siklus berikutnya, menghasilkan laporan perbedaan otoritatif, lalu keluar. Diperlukan ketika enable=true.

    Kosong

    check_drain.check_qps

    Maksimum permintaan BatchGetItem per detik untuk verifikasi drain (batas independen untuk sumber dan target). Parameter ini membatasi tekanan drain pada sumber dan target untuk menghindari persaingan dengan sumber daya sinkronisasi inkremental. Tingkatkan nilai ini jika verifikasi terlalu lambat.

    20

    Catatan
    • Selain parameter yang tercantum di atas, conf/nimo.conf juga berisi parameter tuning lanjutan seperti check_drain.cycle_interval_sec, check_drain.settle_sleep_ms, dan check_drain.consistent_read. Pertahankan nilai default dalam kebanyakan kasus. Lihat komentar inline di file konfigurasi untuk detailnya.

    • Setelah Anda mengaktifkan drain, fase cutover tidak lagi memerlukan menjalankan nimo-full-check lagi. Sebagai gantinya, jalankan touch pada file sentinel finalisasi untuk memicu proses berumur panjang menyelesaikan verifikasi akhir dan menghasilkan laporan perbedaan akhir. Untuk informasi lebih lanjut, lihat Lakukan cutover bisnis - Pemeriksaan konsistensi terakhir.

    • Proses berumur panjang untuk mode incr harus dimulai setelah verifikasi garis dasar s3 selesai. Proses verifikasi yang tersisa sama dengan default.

  3. Mulai tugas pemeriksaan.

    nohup ./bin/nimo-full-check.linux.amd64 -conf=./conf/nimo.conf > /dev/null 2>&1 &

    Alat pemeriksaan menyimpan log terperinci dan laporan perbedaan data di direktori default logs/ dan nimo-full-check-diff/, masing-masing. Berikut adalah contoh output dari pemeriksaan yang berhasil:

    [INFO] documentChecker[0] with table[{nimo-shake src2}] [success: 91, fail: 0] item matches!
    [INFO] documentChecker[2] with table[{nimo-shake src1}] [success: 96, fail: 0] item matches!
    [INFO] documentChecker[0] with table[{nimo-shake src2}] [success: 92, fail: 0] item matches!
    [INFO] documentChecker[2] with table[{nimo-shake src1}] [success: 97, fail: 0] item matches!
    [INFO] documentChecker[0] with table[{nimo-shake src2}] [success: 93, fail: 0] item matches!
    [INFO] documentChecker[0] with table[{nimo-shake src2}] [success: 94, fail: 0] item matches!
    [INFO] documentChecker[2] with table[{nimo-shake src1}] [success: 98, fail: 0] item matches!
    [INFO] documentChecker[0] with table[{nimo-shake src2}] [success: 95, fail: 0] item matches!
    [INFO] documentChecker[2] with table[{nimo-shake src1}] [success: 99, fail: 0] item matches!
    [INFO] documentChecker[0] with table[{nimo-shake src2}] [success: 96, fail: 0] item matches!
    [INFO] documentChecker[2] with table[{nimo-shake src1}] [success: 100, fail: 0] item matches!
    [INFO] documentChecker[2] with table[{nimo-shake src1}] check completed. real total count: 100
    [INFO] documentChecker[2] with table[{nimo-shake src1}] close executor
    [INFO] documentChecker[2] finishes checking table[src1]
    [INFO] documentChecker[0] with table[{nimo-shake src2}] [success: 97, fail: 0] item matches!
    [INFO] documentChecker[0] with table[{nimo-shake src2}] [success: 98, fail: 0] item matches!
    [INFO] documentChecker[0] with table[{nimo-shake src2}] [success: 99, fail: 0] item matches!
    [INFO] documentChecker[0] with table[{nimo-shake src2}] [success: 100, fail: 0] item matches!
    [INFO] documentChecker[0] with table[{nimo-shake src2}] check completed. real total count: 100
    [INFO] documentChecker[0] with table[{nimo-shake src2}] close executor
    [INFO] documentChecker[0] finishes checking table[src2]
    [INFO] all documentCheckers finish
    [INFO] checker finishes!
    [INFO] full-check completes!
  4. (Opsional) Perbaiki data yang tidak konsisten:

    1. Ketika data di DynamoDB sumber tidak konsisten dengan data di kluster PolarDB for PostgreSQL target, tabel yang tidak konsisten tercantum di direktori diff yang ditentukan. Contoh:

      Catatan

      Direktori diff default adalah nimo-full-check-diff. Anda dapat mengonfigurasinya di conf/nimo.conf menggunakan parameter diff_output_file.

      nimo-full-check-diff/
        └── testtable-0
        └── testtable-1
    2. Jalankan tugas perbaikan:

      nohup ./bin/nimo-repair.linux.amd64 -conf=./conf/nimo.conf > /dev/null 2>&1 &

Langkah 3: (Opsional) Konfigurasikan sinkronisasi balik

Sebelum cutover bisnis, Anda dapat mengonfigurasi tautan sinkronisasi balik dari PolarDB for PostgreSQL ke DynamoDB sumber. Tautan ini diaktifkan selama pergantian resmi ke PolarDB untuk mengaktifkan aliran data balik dan menyediakan perlindungan untuk rollback bisnis. Prosedur konfigurasinya adalah sebagai berikut:

Persiapan lingkungan

  1. Pastikan parameter PolarDB wal_level diatur ke logical.

  2. Buat akun istimewa dan berikan izin:

    1. (Opsional) Jika Anda belum membuat akun istimewa, buka Konsol PolarDB, lalu di halaman kluster Settings and Management > Accounts, buat akun istimewa.

  3. Buat slot replikasi logis dan berikan izin: Hubungkan ke database polardb_internal_dynamodb menggunakan akun istimewa. Jalankan perintah SQL berikut untuk membuat slot replikasi logis dan memberikan izin replikasi kepada DynamoDB Account. Anda kemudian dapat melihat status slot replikasi logis yang dibuat.

    -- Buat slot replikasi logis. Nama 'flink_slot' harus sesuai dengan nama slot yang ditentukan dalam konfigurasi Flink Anda selanjutnya.
    SELECT * FROM pg_create_logical_replication_slot('flink_slot', 'pgoutput');
    
    -- Berikan izin REPLICATION kepada akun pengguna DynamoDB khusus yang Anda buat sebelumnya.
    -- Ganti <your_dynamodb_user> dengan nama akun pengguna DynamoDB khusus Anda.
    ALTER ROLE <your_dynamodb_user> REPLICATION;
    
    -- Periksa status slot replikasi. Pada tahap ini, status aktif 'flink_slot' seharusnya f (false).
    SELECT * FROM pg_replication_slots;
  4. Aktifkan dan konfigurasikan Flink:

    1. Aktifkan Realtime Compute for Apache Flink dan buat ruang kerja Flink.

      Penting

      Ruang kerja Flink harus berada di VPC yang sama dengan kluster PolarDB.

    2. Konfigurasikan akses jaringan publik untuk ruang kerja Flink Anda agar dapat terhubung ke AWS DynamoDB.

  5. Konfigurasikan daftar putih alamat IP kluster PolarDB:

    1. Di Konsol Flink, klik tombol View Details untuk ruang kerja, lalu di halaman Workspace Details, dapatkan informasi CIDR Block-nya.

    2. Buka Konsol PolarDB. Di halaman kluster Settings and Management > Cluster Whitelists, klik Add Whitelist dan tambahkan Blok CIDR Flink.

  6. Verifikasi konektivitas antara kluster PolarDB dan ruang kerja Flink:

    1. Di Konsol Flink, buka ruang kerja dan klik ikon Network Probe di pojok kanan atas.

    2. Masukkan titik akhir pribadi dan port node primer kluster PolarDB, lalu klik Probe.

    3. Pesan pop-up yang bertuliskan Network Probe Connection Successful menunjukkan bahwa daftar putih alamat IP kluster telah dikonfigurasi dengan benar.

Terapkan pekerjaan Flink

  1. Unduh alat sinkronisasi balik: PolarDBBackSync.jar.

  2. Buat file konfigurasi bernama application.yaml dengan konten berikut:

    snapshot:
      mode: never
    
    source:
        # Titik akhir pribadi node primer PolarDB
        hostname: pc-xxx.pg.polardb.rds.aliyuncs.com
        # Port pribadi node primer PolarDB
        port: 5432
        # Nama slot replikasi logis yang dibuat sebelumnya
        slotName: flink_slot
    
    target:
      # Wilayah AWS DynamoDB target
      region: cn-north-1
    
    # (Opsional) Konfigurasi penyaringan tabel. Anda dapat mendeklarasikan whiteTableSet atau blackTableSet.
    filter:
      # whiteTableSet: tabel yang akan disinkronisasi balik
      # blackTableSet: tabel yang tidak akan disinkronisasi balik
      whiteTableSet:
      blackTableSet:
    
    # Interval checkpoint untuk pekerjaan Flink, dalam milidetik
    checkpoint:
      interval: 3000
    
  3. Unggah file: Di Konsol Flink, buka ruang kerja target. Di halaman File Management, unggah PolarDBBackSync.jar dan application.yaml.

  4. Simpan kredensial dengan aman: Untuk menghindari paparan kunci dalam teks biasa, kami merekomendasikan menggunakan fitur Variable Management Flink untuk menyimpan informasi sensitif. Di halaman Variable Management, tambahkan empat variabel berikut:

    Parameter

    Nilai

    polardbusername

    Akun DynamoDB untuk PolarDB.

    polardbpassword

    Password asli akun DynamoDB untuk PolarDB. Ini bukan secret access key akun DynamoDB.

    dynamodbak

    ID AccessKey AWS DynamoDB.

    dynamodbsk

    Secret access key AWS DynamoDB.

    configfilename

    (Opsional) Nama file dependensi tambahan. Nilai default: application.yaml.

  5. Terapkan dan mulai pekerjaan:

    1. Buka halaman Job O&M, lalu pilih Deploy Job > JAR Job.

    2. Masukkan parameter utama berikut dan konfigurasikan parameter lain berdasarkan lingkungan bisnis Anda. Lalu, klik Deploy.

      Parameter

      Referensi

      Deployment Mode

      Atur ke Stream Mode.

      Deployment name

      Masukkan nama untuk penerapan pekerjaan, misalnya PolarDBBackSync.

      Engine Version

      Atur ke vvr-11.3-jdk11-flink-1.20.

      JAR URI

      Pilih PolarDBBackSync.jar yang telah diunggah.

      Entry point class

      Atur ke org.example.PolarDBCdcJob.

      Entry point main arguments

      Atur ke:

      --polardbusername ${secret_values.polardbusername}

      --polardbpassword ${secret_values.polardbpassword}

      --dynamodbak ${secret_values.dynamodbak}

      --dynamodbsk ${secret_values.dynamodbsk}

      (Opsional) --configfilename ${secret_values.configfilename}

      Additional dependency files

      Pilih application.yaml yang telah diunggah.

      Penting

      Jika password atau nilai parameter lain mengandung karakter khusus, pekerjaan Flink mungkin gagal mengurai parameter. Untuk mencegah masalah ini, setelah pekerjaan dibuat, buka Deployment Details > Run Parameter Configuration, klik Edit, lalu tambahkan konfigurasi berikut di Other Configurations: env.java.opts: -Dconfig.disable-inline-comment=true.

    3. Setelah penerapan berhasil, klik Start > Stateless Start.

Validasi dan pembersihan

  • Validasi: Setelah pekerjaan dimulai, gunakan akun istimewa untuk terhubung ke database polardb_internal_dynamodb kluster PolarDB dan jalankan SELECT * FROM pg_replication_slots;. Jika nilai bidang active untuk slot replikasi flink_slot berubah menjadi t (true), pekerjaan Flink telah terhubung. Anda kemudian dapat mulai mengarahkan trafik bisnis ke kluster PolarDB.

  • Pembersihan: Ketika sinkronisasi balik tidak lagi diperlukan, Anda dapat melakukan langkah-langkah berikut untuk melepaskan sumber daya terkait dan mengurangi biaya.

    • Realtime Compute for Apache Flink:

      • Hentikan pekerjaan: Buka Konsol Flink. Di ruang kerja target, buka halaman Job O&M, temukan pekerjaan target, lalu klik Stop.

      • Lepaskan instance: Kembali ke Konsol Flink, temukan ruang kerja target, lalu klik Release Resources.

    • PolarDB kluster: Gunakan akun istimewa untuk terhubung ke database polardb_internal_dynamodb dan jalankan perintah berikut untuk menghapus slot replikasi logis.

      SELECT pg_drop_replication_slot('flink_slot');

Langkah 4: Lakukan cutover bisnis

Setelah latensi sinkronisasi inkremental rendah dan pemeriksaan konsistensi data berhasil, Anda dapat merencanakan cutover bisnis. Ketika siap, ikuti langkah-langkah berikut:

  1. Pemeriksaan akhir: Sebelum jendela downtime yang direncanakan, jalankan alat pemeriksaan konsistensi berulang kali hingga Anda memastikan bahwa latensi sinkronisasi inkremental minimal dan jumlah ketidaksesuaian data nol atau dalam kisaran yang dapat diterima.

  2. Hentikan penulisan sumber: Pada awal jendela downtime, hentikan semua aplikasi dari menulis ke AWS DynamoDB sumber.

  3. Tunggu sinkronisasi selesai: Pantau log nimo-shake untuk memastikan tidak ada data inkremental baru yang perlu disinkronkan.

  4. Pemeriksaan konsistensi terakhir: Jalankan alat nimo-full-check lagi untuk memastikan data di sumber dan target sepenuhnya konsisten.

    Catatan

    Jika Anda telah mengaktifkan verifikasi kontinu inkremental (mode drain), Anda tidak perlu memulai nimo-full-check lagi pada langkah ini. Proses verifikasi berumur panjang telah terus-menerus memverifikasi dan mengonsumsi tabel pemeriksaan inkremental selama fase inkremental. Setelah Anda memastikan bahwa laju tulis inkremental nimo-shake telah turun ke nol (antrian telah dikosongkan), buat file sentinel finalisasi (file yang ditentukan oleh check_drain.finalize_flag_file, misalnya, touch /tmp/nimo-finalize). Proses berumur panjang secara otomatis memasuki fase verifikasi akhir, menghasilkan laporan perbedaan otoritatif, lalu keluar.

  5. Hentikan alat sinkronisasi: Setelah Anda memastikan data telah tersinkronisasi sepenuhnya, hentikan proses nimo-shake.

  6. Alihkan koneksi aplikasi: Hentikan aplikasi bisnis dan ubah konfigurasi koneksi database mereka dari titik akhir AWS DynamoDB ke titik akhir akses DynamoDB PolarDB.

  7. (Opsional) Mulai tugas sinkronisasi balik: Selama pergantian bisnis resmi ke PolarDB, mulai tugas sinkronisasi balik. Tugas ini menggunakan Realtime Compute for Apache Flink untuk mengimplementasikan replikasi data balik, yang menyediakan perlindungan untuk rollback bisnis.

  8. Mulai aplikasi bisnis: Mulai ulang aplikasi bisnis. Cutover selesai.

  9. (Opsional) Hentikan tugas sinkronisasi balik: Setelah cutover selesai dan bisnis berjalan stabil selama periode tertentu, Anda dapat menghentikan tugas sinkronisasi balik (yang mencakup menghentikan pekerjaan Flink dan melepaskan sumber dayanya).

Lampiran: Simulasikan trafik real-time

Untuk mensimulasikan migrasi dunia nyata dengan penulisan data kontinu di lingkungan pengujian, gunakan kode contoh Go berikut. Kode ini secara berkala menulis dan memperbarui data di tabel DynamoDB sumber.

Catatan

Langkah ini hanya untuk pengujian dan validasi proses migrasi. Jangan lakukan langkah ini dalam migrasi produksi.

package main

import (
	"context"
	"fmt"
	"log"
	"math/rand"
	"time"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/credentials"
	"github.com/aws/aws-sdk-go-v2/service/dynamodb"
	"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)

// --- Konfigurasi untuk AWS DynamoDB sumber Anda ---
var (
    region    = "cn-north-1"       // Wilayah AWS DynamoDB
    accessKey = "your-aws-access-key" // Access key AWS DynamoDB
    secretKey = "your-aws-secret-key" // Secret key AWS DynamoDB
)

// --- Fungsi pembantu untuk membuat klien DynamoDB ---
func createClient() (*dynamodb.Client, context.Context) {
    ctx := context.Background()
    sdkConfig, err := config.LoadDefaultConfig(ctx, config.WithRegion(region))
    if err != nil {
        log.Fatalf("Gagal memuat konfigurasi AWS: %v", err)
    }
    client := dynamodb.NewFromConfig(sdkConfig, func(o *dynamodb.Options) {
        o.Credentials = credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")
    })
    return client, ctx
}

// --- Fungsi untuk membuat tabel dan mengisi data awal ---
func initializeData(client *dynamodb.Client, ctx context.Context) {
    tableName := "src1" // Contoh nama tabel

    // Buat tabel jika belum ada
    _, err := client.CreateTable(ctx, &dynamodb.CreateTableInput{
        TableName: &tableName,

        AttributeDefinitions: [ ]types.AttributeDefinition{

            {AttributeName: aws.String("pk"), AttributeType: types.ScalarAttributeTypeS},
        },

        KeySchema: [ ]types.KeySchemaElement{

            {AttributeName: aws.String("pk"), KeyType: types.KeyTypeHash},
        },
        ProvisionedThroughput: &types.ProvisionedThroughput{
            ReadCapacityUnits:  aws.Int64(100),
            WriteCapacityUnits: aws.Int64(100),
        },
    })
    if err != nil {
		// Abaikan jika tabel sudah ada, gagal untuk error lain
        if _, ok := err.(*types.ResourceInUseException); !ok {
			log.Fatalf("CreateTable gagal untuk %s: %v", tableName, err)
		}
    }

    fmt.Printf("Menunggu tabel '%s' menjadi aktif...\n", tableName)
    waiter := dynamodb.NewTableExistsWaiter(client)
    err = waiter.Wait(ctx, &dynamodb.DescribeTableInput{TableName: &tableName}, 5*time.Minute)
    if err != nil {
        log.Fatalf("Waiter gagal untuk tabel %s: %v", tableName, err)
    }

    // Masukkan 100 item contoh
    for i := 0; i < 100; i++ {
        pk := fmt.Sprintf("%s_user_%03d", tableName, i)
        item := map[string]types.AttributeValue{
            "pk":  &types.AttributeValueMemberS{Value: pk},
            "val": &types.AttributeValueMemberN{Value: fmt.Sprintf("%d", i)},
        }
        client.PutItem(ctx, &dynamodb.PutItemInput{TableName: &tableName, Item: item})
    }
    fmt.Printf("Memasukkan 100 item awal ke '%s'.\n", tableName)
}

// --- Fungsi untuk mensimulasikan trafik bisnis kontinu ---
func simulateTraffic(client *dynamodb.Client, ctx context.Context) {
    tableName := "src1"
    fmt.Println("Memulai pembaruan berkala untuk mensimulasikan trafik. Tekan Ctrl+C untuk berhenti.")
    i := 0
    for {
        pk := fmt.Sprintf("%s_user_%03d", tableName, i%100)
        newValue := fmt.Sprintf("%d", rand.Intn(1000))
        _, err := client.UpdateItem(ctx, &dynamodb.UpdateItemInput{
            TableName: &tableName,
            Key: map[string]types.AttributeValue{
                "pk": &types.AttributeValueMemberS{Value: pk},
            },
            ExpressionAttributeValues: map[string]types.AttributeValue{
                ":newval": &types.AttributeValueMemberN{Value: newValue},
            },
            UpdateExpression: aws.String("SET val = :newval"),
        })
        if err != nil {
            fmt.Printf("Error pembaruan: %v\n", err)
        } else {
            fmt.Printf("Memperbarui pk=%s dengan val baru=%s\n", pk, newValue)
        }
        i++
        time.Sleep(1 * time.Second) // Perbarui satu catatan per detik
    }
}

func main() {
    client, ctx := createClient()
    initializeData(client, ctx)
    simulateTraffic(client, ctx)
}