PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Migrazione di PostgreSQL al cloud:confronto tra soluzioni di Amazon, Google e Microsoft

Da una prospettiva a volo d'uccello, sembrerebbe che quando si tratta di migrare i carichi di lavoro di PostgreSQL nel cloud, la scelta del provider di servizi cloud non dovrebbe fare alcuna differenza. Immediatamente, PostgreSQL semplifica la replica dei dati, senza tempi di inattività, tramite la replica logica, sebbene con alcune restrizioni. Al fine di rendere la loro offerta di servizi più attraente, i fornitori di servizi cloud possono elaborare alcune di queste restrizioni. Quando iniziamo a pensare alle differenze nelle versioni PostgreSQL disponibili, alla compatibilità, ai limiti, alle limitazioni e alle prestazioni, diventa chiaro che i servizi di migrazione sono fattori chiave nell'offerta complessiva di servizi. Non si tratta più di “lo offriamo, lo migriamo”. È diventato più come "lo offriamo, lo migriamo, con il minimo limite".

La migrazione è importante sia per le piccole che per le grandi organizzazioni. Non si tratta tanto delle dimensioni del cluster PostgreSQL, quanto dei tempi di inattività accettabili e dello sforzo post-migrazione.

Selezione di una strategia

La strategia di migrazione dovrebbe prendere in considerazione le dimensioni del database, il collegamento di rete tra l'origine e la destinazione, nonché gli strumenti di migrazione offerti dal provider cloud.

Hardware o software?

Proprio come l'invio di chiavi USB e DVD agli albori di Internet, nei casi in cui la larghezza di banda della rete non è sufficiente per trasferire i dati alla velocità desiderata, i cloud provider offrono soluzioni hardware in grado di per trasportare fino a centinaia di petabyte di dati. Di seguito sono riportate le soluzioni attuali di ciascuna delle tre grandi:

Una pratica tabella fornita da Google che mostra le opzioni disponibili:

L'appliance GCP è un'appliance di trasferimento

Un consiglio simile di Azure basato sulla dimensione dei dati rispetto alla larghezza di banda della rete:

L'appliance Azure è Data box

Verso la fine della sua pagina sulle migrazioni dei dati, AWS fornisce un assaggio di ciò che possiamo aspettarci, insieme alla raccomandazione della soluzione:

Nei casi in cui le dimensioni del database superano i 100 GB e la larghezza di banda di rete limitata, AWS suggerisce un soluzione hardware.

L'appliance AWS è Snowball Edge

Esportazione/Importazione dati

Le organizzazioni che tollerano i tempi di inattività possono trarre vantaggio dalla semplicità degli strumenti comuni forniti da PostgreSQL pronti all'uso. Tuttavia, durante la migrazione dei dati da un provider cloud (o hosting) a un altro provider cloud, fai attenzione al costo in uscita.

AWS

Per testare le migrazioni ho utilizzato un'installazione locale del mio database Nextcloud in esecuzione su uno dei miei server di rete domestica:

postgres=# select pg_size_pretty(pg_database_size('nextcloud_prod'));

pg_size_pretty

----------------

58 MB

(1 row)



nextcloud_prod=# \dt

                     List of relations

Schema |             Name | Type  | Owner

--------+-------------------------------+-------+-----------

public | awsdms_ddl_audit              | table | s9sdemo

public | oc_accounts                   | table | nextcloud

public | oc_activity                   | table | nextcloud

public | oc_activity_mq                | table | nextcloud

public | oc_addressbookchanges         | table | nextcloud

public | oc_addressbooks               | table | nextcloud

public | oc_appconfig                  | table | nextcloud

public | oc_authtoken                  | table | nextcloud

public | oc_bruteforce_attempts        | table | nextcloud

public | oc_calendar_invitations       | table | nextcloud

public | oc_calendar_reminders         | table | nextcloud

public | oc_calendar_resources         | table | nextcloud

public | oc_calendar_resources_md      | table | nextcloud

public | oc_calendar_rooms             | table | nextcloud

public | oc_calendar_rooms_md          | table | nextcloud

...

public | oc_termsofservice_terms       | table | nextcloud

public | oc_text_documents             | table | nextcloud

public | oc_text_sessions              | table | nextcloud

public | oc_text_steps                 | table | nextcloud

public | oc_trusted_servers            | table | nextcloud

public | oc_twofactor_backupcodes      | table | nextcloud

public | oc_twofactor_providers        | table | nextcloud

public | oc_users                      | table | nextcloud

public | oc_vcategory                  | table | nextcloud

public | oc_vcategory_to_object        | table | nextcloud

public | oc_whats_new                  | table | nextcloud

(84 rows)

The database is running PostgreSQL version 11.5:

postgres=# select version();

                                                version

------------------------------------------------------------------------------------------------------------

PostgreSQL 11.5 on x86_64-redhat-linux-gnu, compiled by gcc (GCC) 9.1.1 20190503 (Red Hat 9.1.1-1), 64-bit

(1 row)

Ho anche creato un utente PostgreSQL da utilizzare da AWS DMS, che è il servizio di Amazon per l'importazione di PostgreSQL in Amazon RDS:

postgres=# \du s9sdemo

            List of roles

Role name | Attributes |  Member of

-----------+------------+-------------

s9sdemo   |   | {nextcloud}

AWS DMS offre molti vantaggi, proprio come ci si aspetterebbe da una soluzione gestita nel cloud: 

  • ridimensionamento automatico (solo archiviazione, poiché l'istanza di calcolo deve avere le dimensioni corrette)
  •  provisioning automatico
  •  modello con pagamento in base al consumo
  •  failover automatico

Tuttavia, mantenere la coerenza dei dati per un database live è il massimo sforzo. Una coerenza del 100% si ottiene solo quando il database è in modalità di sola lettura, una conseguenza del modo in cui vengono acquisite le modifiche alle tabelle.

In altre parole, le tabelle hanno un cutover point-in-time diverso:

Proprio come per tutto nel cloud, c'è un costo associato al servizio di migrazione.

Per creare l'ambiente di migrazione, segui la guida introduttiva per configurare un'istanza di replica, un'origine, un endpoint di destinazione e una o più attività.

Istanza di replica

La creazione dell'istanza di replica è semplice per chiunque abbia familiarità con le istanze EC2 su AWS:

L'unica modifica rispetto alle impostazioni predefinite è stata la selezione di AWS DMS 3.3.0 o in seguito a causa del fatto che il mio motore PostgreSQL locale è 11.5:

Ed ecco l'elenco delle versioni AWS DMS attualmente disponibili:

Anche le installazioni di grandi dimensioni dovrebbero tenere conto dei limiti di AWS DMS:

C'è anche una serie di limitazioni che sono una conseguenza della replica logica di PostgreSQL restrizioni. Ad esempio, AWS DMS non eseguirà la migrazione degli oggetti secondari:

Vale la pena ricordare che in PostgreSQL tutti gli indici sono secondari e che non è una brutta cosa, come notato in questa discussione più dettagliata.

Endpoint di origine

Segui la procedura guidata per creare l'endpoint di origine:

Nello scenario di installazione Configurazione da una rete a un VPC Utilizzo di Internet my la rete domestica ha richiesto alcune modifiche per consentire all'indirizzo IP dell'endpoint di origine di accedere al mio server interno. Innanzitutto, ho creato un port forwarding sul router perimetrale (173.180.222.170) per inviare il traffico sulla porta 30485 al mio gateway interno (10.11.11.241) sulla porta 5432 dove posso ottimizzare l'accesso in base all'indirizzo IP di origine tramite le regole di iptables. Da lì, il traffico di rete scorre attraverso un tunnel SSH al server Web che esegue il database PostgreSQL. Con la configurazione descritta il client_addr nell'output di pg_stat_activity apparirà come 127.0.0.1.

Prima di consentire il traffico in entrata, i log di iptables mostrano 12 tentativi dall'istanza di replica a ip=3.227.167.58):

Jan 19 17:35:28 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=23973 DF PROTO=TCP SPT=54662 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:35:29 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=23974 DF PROTO=TCP SPT=54662 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:35:31 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=23975 DF PROTO=TCP SPT=54662 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:35:35 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=23976 DF PROTO=TCP SPT=54662 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:35:48 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=4328 DF PROTO=TCP SPT=54667 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:35:49 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=4329 DF PROTO=TCP SPT=54667 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:35:51 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=4330 DF PROTO=TCP SPT=54667 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:35:55 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=4331 DF PROTO=TCP SPT=54667 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:36:08 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=8298 DF PROTO=TCP SPT=54670 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:36:09 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=8299 DF PROTO=TCP SPT=54670 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:36:11 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=8300 DF PROTO=TCP SPT=54670 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Jan 19 17:36:16 mha.can.local kernel: filter/INPUT: IN=enp0s29f7u2 OUT= MAC=00:24:9b:17:3a:fa:9c:1e:95:e5:ad:b0:08:00 SRC=3.227.167.58 DST=10.11.11.241 LEN=60 TOS=0x00 PREC=0x00 TTL=39 ID=8301 DF PROTO=TCP SPT=54670 DPT=5432 WINDOW=26880 RES=0x00 SYN URGP=0

Dopo aver consentito l'indirizzo IP dell'endpoint di origine (3.227.167.58), il test di connessione ha esito positivo e la configurazione dell'endpoint di origine è completa. Abbiamo anche una connessione SSL per crittografare il traffico attraverso le reti pubbliche. Questo può essere confermato sul server PostgreSQL utilizzando la query seguente e nella console AWS:

postgres=# SELECT datname, usename, client_addr, ssl, cipher, query, query_start FROM pg_stat_activity a, pg_stat_ssl s where a.pid=s.pid and usename = 's9sdemo';

datname | usename | client_addr | ssl | cipher | query | query_start

---------+---------+-------------+-----+--------+-------+-------------

(0 rows)

...e poi guarda mentre esegui la connessione dalla console AWS. I risultati dovrebbero essere simili ai seguenti:

postgres=# \watch



                                                                           Sun 19 Jan 2020 06:50:51 PM PST (every 2s)



    datname     | usename | client_addr | ssl |           cipher |                 query | query_start

----------------+---------+-------------+-----+-----------------------------+------------------------------------------------------------------------------------+-------------------------------

 nextcloud_prod | s9sdemo | 127.0.0.1   | t | ECDHE-RSA-AES256-GCM-SHA384 | select cast(setting as integer) from pg_settings where name = 'server_version_num' | 2020-01-19 18:50:51.463496-08

(1 row)

...mentre la console AWS dovrebbe segnalare un successo:

Come indicato nella sezione dei prerequisiti, se scegliamo l'opzione di migrazione Pieno carico , replica in corso, dovremo modificare i permessi per l'utente PostgreSQL. Questa opzione di migrazione richiede privilegi di superutente, quindi ho modificato le impostazioni per l'utente PostgreSQL creato in precedenza:

nextcloud_prod=# \du s9sdemo

         List of roles

Role name | Attributes | Member of

-----------+------------+-----------

s9sdemo   | Superuser  | {}

Lo stesso documento contiene le istruzioni per modificare postgresql.conf. Ecco una differenza rispetto all'originale:

--- a/var/lib/pgsql/data/postgresql.conf

+++ b/var/lib/pgsql/data/postgresql.conf

@@ -95,7 +95,7 @@ max_connections = 100                 # (change requires restart)



# - SSL -



-#ssl = off

+ssl = on

#ssl_ca_file = ''

#ssl_cert_file = 'server.crt'

#ssl_crl_file = ''

@@ -181,6 +181,7 @@ dynamic_shared_memory_type = posix  # the default is the first option



# - Settings -



+wal_level = logical

#wal_level = replica                   # minimal, replica, or logical

                                       # (change requires restart)

#fsync = on                            # flush data to disk for crash safety

@@ -239,6 +240,7 @@ min_wal_size = 80MB

#max_wal_senders = 10          # max number of walsender processes

                              # (change requires restart)

#wal_keep_segments = 0         # in logfile segments; 0 disables

+wal_sender_timeout = 0

#wal_sender_timeout = 60s      # in milliseconds; 0 disables



#max_replication_slots = 10    # max number of replication slots

@@ -451,6 +453,7 @@ log_rotation_size = 0                       # Automatic rotation of logfiles will

#log_duration = off

#log_error_verbosity = default         # terse, default, or verbose messages

Infine, non dimenticare di regolare le impostazioni di pg_hba.conf per consentire la connessione SSL dall'indirizzo IP dell'istanza di replica.

Ora siamo pronti per il passaggio successivo.

Punto finale di destinazione

Segui la procedura guidata per creare l'endpoint di destinazione:

Questo passaggio presuppone che l'istanza RDS con l'endpoint specificato esista già insieme a il database vuoto nextcloud_awsdms. Il database può essere creato durante la configurazione dell'istanza RDS.

A questo punto, se la rete AWS è configurata correttamente, dovremmo essere pronti per eseguire il test di connessione:

Con l'ambiente in atto, ora è il momento di creare l'attività di migrazione :

Attività di migrazione

Una volta completata la procedura guidata, la configurazione si presenta così:

...e la seconda parte della stessa vista:

Una volta avviata l'attività, possiamo monitorare l'avanzamento:apri l'attività dettagli e scorri verso il basso fino a Statistiche tabella:

 AWS DMS utilizza lo schema memorizzato nella cache per migrare le tabelle del database. Durante la migrazione, possiamo continuare a "osservare" le query sul database di origine e il log degli errori di PostgreSQL, oltre alla console AWS:

In caso di errori, nella console viene visualizzato lo stato di errore:

Un posto dove cercare indizi è CloudWatch, anche se durante i miei test i log alla fine non è stato pubblicato, il che potrebbe essere solo un altro problema tecnico nella versione beta di AWS DMS 3.3.0 come si è rivelato essere verso la fine di questo esercizio:

L'avanzamento della migrazione è ben visualizzato nella console AWS DMS:

Una volta completata la migrazione, rivedendo ancora una volta, il log degli errori di PostgreSQL , rivela un messaggio sorprendente:

Quello che sembra accadere è che in PostgreSQL 9.6, 10 la tabella pg_class contiene la colonna denominata relhaspkey, ma non è il caso in 11. E questo è il problema tecnico nella versione beta di AWS DMS 3.3.0 a cui mi riferivo in precedenza.

GCP

L'approccio di Google si basa sullo strumento open source PgBouncer. L'entusiasmo è stato di breve durata, poiché la documentazione ufficiale parla della migrazione di PostgreSQL in un ambiente con motore di calcolo.

Ulteriori tentativi di trovare una soluzione di migrazione a Cloud SQL che assomigli ad AWS DMS non sono riusciti. Le strategie di migrazione del database non contengono alcun riferimento a PostgreSQL:

Le installazioni PostgreSQL in loco possono essere migrate a Cloud SQL utilizzando i servizi di uno dei partner di Google Cloud.

Una potenziale soluzione potrebbe essere PgBouncer su Cloud SQL, ma non rientra nell'ambito di questo blog.

Servizi cloud Microsoft (Azure)

Al fine di facilitare la migrazione dei carichi di lavoro PostgreSQL da locale al database di Azure gestito per PostgreSQL, Microsoft fornisce Azure DMS che, secondo la documentazione, può essere utilizzato per migrare con tempi di inattività minimi. L'esercitazione Migrazione di PostgreSQL al database di Azure per PostgreSQL online tramite DMS descrive questi passaggi in dettaglio.

La documentazione di Azure DMS discute in dettaglio i problemi e le limitazioni associati alla migrazione dei carichi di lavoro PostgreSQL in Azure.

Una notevole differenza rispetto a AWS DMS è il requisito di creare manualmente lo schema:

Una demo di questo sarà l'argomento di un futuro blog. Resta sintonizzato.