Exportación a almacenamento de obxectos

Un obxecto JSON por obxectivo cumprido nun bucket seu. Esta é a vía para todos os almacéns de datos que non sexan BigQuery.

1. O oco que cobre

Ata agora só había unha vía de MousePlayer a un almacén de datos e levaba a Google. Se usa Snowflake, Redshift ou ClickHouse, non había ningunha, aínda que os tres len almacenamento de obxectos sen problemas.

Por iso a ponte escribe en almacenamento de obxectos e non en cada almacén de datos por separado. Snowflake, Redshift e ClickHouse reciben datos de S3 e BigQuery de Google Cloud Storage. Unha exportación chega a todos.

OndeComo se accede
Amazon S3Signature Version 4, co bucket no host
Cloudflare R2Signature Version 4 contra o endpoint da conta
Google Cloud Storagepola súa API compatible con S3 cunha clave HMAC
MinIO, Wasabi, Backblaze B2 e outrosSignature Version 4 contra o seu endpoint
Azure Blob Storageunha ligazón SAS do contedor, sen sinatura no noso lado

2. Por que Azure é distinto e por que é mellor

Azure Blob non usa Signature Version 4; asina con SharedKey. Poderiamos crear outro esquema de sinatura. No seu lugar a ponte acepta unha ligazón SAS do contedor — un URL que xera na súa conta de almacenamento coa sinatura xa dentro.

Isto significa menos código pola nosa parte e menos confianza necesaria pola súa. Nunca vemos unha clave de conta: entréganos un permiso que limitou vostede a un contedor, cunha caducidade escollida e revogable en calquera momento sen tocar nada máis.

Convén aplicar a mesma limitación en S3: dea á clave de acceso permiso para escribir só neste único prefixo e nada máis. Unha clave que só pode engadir a mouseplayer/goals/ non pode ler os outros buckets aínda que se filtre.

3. Un obxecto por obxectivo e a clave é unha data

O almacenamento de obxectos non permite engadir ao final. Un ficheiro diario tería que reescribirse enteiro cada vez e dous obxectivos simultáneos sobrescribiríanse. Por iso cada obxectivo cumprido convértese nun obxecto propio.

O custo son moitos obxectos pequenos; a estrutura da clave fai que funcione:

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

Un almacén de datos le un día como unha partición e unha carga histórica é unha exploración de prefixos, non unha consulta. Se quere particionar por proxecto e non por data, poña o ID da canle no prefixo.

Cada obxecto é unha liña JSON

Sen sangrado deliberadamente, para ler un prefixo completo como NDJSON sen abrir os obxectos un por un. Marca de tempo, proxecto, sesión, ID de cliente, obxectivo, valor, moeda e ligazón para reproducir a gravación.

Un valor baleiro é null, non cero

Un obxectivo sen valor monetario escribe null. Nun almacén de datos un cero sumaríase nun total que nunca existiu; a diferenza entre «sen importe acordado» e «importe cero» sobrevive á exportación.

4. Se responde 403, lea isto primeiro

Unha petición S3 rexeitada di moi pouco e hai un motivo polo que a nosa mensaxe de erro di máis que S3: a rexión entra na sinatura. Unha rexión incorrecta e unha clave incorrecta producen o mesmo 403, así que a sospeita evidente, a clave, só é correcta a metade das veces.

Tres cousas que comprobar, nesta orde:

  • A rexión, exactamente como a indica o bucket. R2 e Google Cloud Storage usan auto e non a comproban; os demais si.
  • O permiso do prefixo. Unha clave limitada a mouseplayer/ non pode escribir en mouseplayer-goals/ porque a barra final importa nun ARN de recurso.
  • O endpoint, para R2 e almacenamentos compatibles con S3. Pegue o host sen https://; retirámolo de todos os xeitos, pero unha ruta engadida é outro bucket.

O ID da clave de acceso gárdase sen cifrar deliberadamente. Viaxa en cada petición asinada por deseño, polo que cifralo sería esforzo sen protección. O segredo cífrase, non se mostra de novo e nunca entra na cola interna da tarefa.

Todas as marcas mencionadas aquí pertencen aos seus respectivos propietarios. MousePlayer non ten relación comercial con estes provedores.