Esportazione su storage a oggetti

Un oggetto JSON per ogni obiettivo raggiunto, in un bucket di sua proprietà. È il percorso verso qualsiasi data warehouse diverso da BigQuery.

1. La lacuna che colma

Finora esisteva un solo percorso da MousePlayer a un data warehouse e portava a Google. Per Snowflake, Redshift o ClickHouse non c’era, sebbene tutti e tre leggano senza problemi dallo storage a oggetti.

Il connettore scrive quindi sullo storage a oggetti anziché su ogni warehouse separatamente. Snowflake, Redshift e ClickHouse acquisiscono da S3; BigQuery da Google Cloud Storage. Una sola esportazione li raggiunge tutti.

DestinazioneModalità di accesso
Amazon S3Signature Version 4, bucket nell’host
Cloudflare R2Signature Version 4 verso l’endpoint dell’account
Google Cloud Storagetramite l’API compatibile S3, con chiave HMAC
MinIO, Wasabi, Backblaze B2 e altriSignature Version 4 verso il suo endpoint
Azure Blob Storageun link SAS del contenitore, senza alcuna firma da parte nostra

2. Perché Azure è diverso e perché è meglio

Azure Blob non usa Signature Version 4, ma SharedKey. Avremmo potuto costruire un secondo sistema di firma. Il connettore accetta invece un link SAS del contenitore - un URL generato nel suo account di archiviazione con la firma già inclusa.

Meno codice da parte nostra e meno fiducia da parte sua. Non vediamo mai una chiave account: ci consegna un permesso limitato da lei a un contenitore, con la scadenza scelta e revocabile in ogni momento senza toccare altro.

Conviene applicare la stessa cautela a S3: autorizzi la chiave a scrivere solo in questo singolo prefisso e nient’altro. Una chiave che può solo aggiungere a mouseplayer/goals/ non può leggere gli altri bucket neppure in caso di fuga.

3. Un oggetto per obiettivo e una chiave basata sulla data

Lo storage a oggetti non consente aggiunte in coda. Un file giornaliero andrebbe riscritto per intero ogni volta e due obiettivi simultanei si sovrascriverebbero. Ogni obiettivo raggiunto diventa quindi un oggetto distinto.

Il prezzo è avere molti piccoli oggetti; l’organizzazione delle chiavi rende il tutto gestibile:

prefix/YYYY/MM/DD/channel/session-goal.json

Un warehouse legge un giorno come una partizione e il recupero storico è una scansione del prefisso anziché una query. Per partizionare per progetto invece che per data, inserisca l’ID canale nel prefisso.

Ogni oggetto è una riga JSON

Volutamente senza rientri, per leggere un intero prefisso come NDJSON senza aprire gli oggetti uno a uno. Timestamp, progetto, sessione, ID cliente, obiettivo, valore, valuta e link di riproduzione.

Un valore vuoto è null, non zero

Un obiettivo senza valore monetario scrive null. In un warehouse uno zero entrerebbe in una somma producendo un totale mai esistito: la distinzione fra «nessun importo concordato» e «un importo pari a zero» sopravvive all’esportazione.

4. Se risponde 403, legga prima qui

Una richiesta S3 rifiutata dice pochissimo e c’è un motivo per cui il nostro registro spiega più di S3: la regione entra nella firma. Regione sbagliata e chiave sbagliata producono lo stesso 403, quindi il sospetto più ovvio, la chiave, è corretto solo metà delle volte.

Tre cose da controllare, nell’ordine:

  • La regione, esattamente come la indica il bucket. R2 e Google Cloud Storage accettano auto senza verificarla; gli altri la verificano.
  • Il permesso sul prefisso. Una chiave limitata a mouseplayer/ non può scrivere in mouseplayer-goals/ - la barra finale conta nell’ARN della risorsa.
  • L’endpoint, per R2 e storage compatibili S3. Incolli l’host senza https://; lo rimuoviamo comunque, ma un percorso aggiunto indica un bucket diverso.

L’ID della chiave di accesso è volutamente conservato in chiaro. Viaggia in ogni richiesta firmata per progettazione, quindi cifrarlo aggiungerebbe lavoro senza protezione. Il secret è cifrato, mai più mostrato e mai inserito nella coda interna.

Tutti i marchi citati appartengono ai rispettivi titolari. MousePlayer non ha rapporti commerciali con questi fornitori.