Eksport til objektlager
Ét JSON-objekt pr. opfyldt mål i en bucket, du ejer. Dette er vejen til alle data warehouses, der ikke er BigQuery.
1. Hullet, der lukkes
Indtil nu var der præcis én vej fra MousePlayer til et data warehouse, og den førte til Google. Brugte du Snowflake, Redshift eller ClickHouse, var der ingen - selvom alle tre uden problemer læser fra objektlager.
Derfor skriver broen til objektlager i stedet for til hvert data warehouse for sig. Snowflake, Redshift og ClickHouse indlæser fra S3, og BigQuery indlæser fra Google Cloud Storage. Én eksport når dem alle.
| Hvor | Sådan adresseres det |
|---|---|
| Amazon S3 | Signature Version 4, bucket i værtsnavnet |
| Cloudflare R2 | Signature Version 4 mod dit kontoendepunkt |
| Google Cloud Storage | via det S3-kompatible API med en HMAC-nøgle |
| MinIO, Wasabi, Backblaze B2 og andre | Signature Version 4 mod dit endepunkt |
| Azure Blob Storage | et container-SAS-link - helt uden signering hos os |
2. Hvorfor Azure skiller sig ud, og hvorfor det er bedre
Azure Blob bruger ikke Signature Version 4; det signerer med SharedKey. Vi kunne have bygget endnu en signeringsmetode. I stedet bruger broen et container-SAS-link - en URL, du genererer i din egen lagerkonto med signaturen allerede inkluderet.
Det betyder mindre kode hos os og mindre tillid krævet af dig. Vi ser slet ingen kontonøgle: du giver en tilladelse, du selv har afgrænset til én container, med en selvvalgt udløbsdato, og som altid kan tilbagekaldes uden at berøre andet.
Brug samme begrænsning på S3-siden: giv adgangsnøglen tilladelse til at skrive under dette ene præfiks og intet andet. En nøgle, der kun kan tilføje til mouseplayer/goals/ kan ikke læse dine andre buckets, selv hvis den lækkes.
3. Ét objekt pr. mål, og nøglen er en dato
Objektlager kan ikke tilføje til eksisterende objekter. En daglig fil skulle skrives helt om hver gang, og to mål, der ankom samtidig, ville overskrive hinanden. Derfor bliver hvert opfyldt mål et selvstændigt objekt.
Prisen er mange små objekter; nøglestrukturen gør det håndterbart:
prefix/YYYY/MM/DD/channel/session-goal.json
Et data warehouse læser én dag som én partition, og efterindlæsning er en præfiksscanning frem for en forespørgsel. Vil du partitionere efter projekt i stedet for dato, skal du placere kanal-ID'et i præfikset.
Hvert objekt er én JSON-linje
Bevidst uden indrykning, så et helt præfiks læses som NDJSON uden at åbne objekterne enkeltvis. Tidsstempel, projekt, session, kunde-ID, mål, værdi, valuta og linket til afspilning af optagelsen.
En tom værdi er null, ikke nul
Et mål uden pengeværdi skriver null. I et data warehouse ville nul blive lagt til en total, der aldrig fandtes - forskellen mellem »intet beløb aftalt« og »et beløb på nul« bevares i eksporten.
4. Læs dette først, hvis svaret er 403
En afvist S3-forespørgsel siger næsten intet, og der er en grund til, at fejlen i vores log siger mere end S3: regionen indgår i signaturen. En forkert region og en forkert nøgle giver samme 403, så den oplagte mistanke - nøglen - er kun rigtig halvdelen af gangene.
Tre ting at kontrollere i denne rækkefølge:
- Regionen, præcis som bucketen angiver den. R2 og Google Cloud Storage bruger
autoog kontrollerer den ikke; det gør alle andre. - Præfikstilladelsen. En nøgle afgrænset til
mouseplayer/kan ikke skrive tilmouseplayer-goals/- den afsluttende skråstreg er vigtig i en ressource-ARN. - Endepunktet, for R2 og S3-kompatible lagre. Indsæt værtsnavnet uden
https://; vi fjerner det uanset hvad, men en tilføjet sti betyder en anden bucket.
Adgangsnøglens ID gemmes bevidst i klartekst. Det sendes med hver signeret forespørgsel som en del af designet, så kryptering ville være arbejde uden beskyttelse. Hemmeligheden krypteres, vises aldrig igen og kommer aldrig i den interne opgavekø.
Alle nævnte varemærker tilhører deres respektive ejere. MousePlayer har ingen forretningsforbindelse med disse udbydere.