Експортиране в обектно хранилище

По един JSON обект за всяка изпълнена цел, във ваш собствен bucket. Това е пътят към всяко хранилище за данни, което не е BigQuery.

1. Празнината, която запълва

Досега имаше точно един път от MousePlayer към хранилище за данни и той водеше към Google. Ако използвате Snowflake, Redshift или ClickHouse, нямаше такъв — въпреки че и трите четат безпроблемно от обектно хранилище.

Затова мостът записва в обектно хранилище, вместо поотделно във всяко хранилище за данни. Snowflake приема от S3, Redshift приема от S3, ClickHouse приема от S3, а BigQuery приема от Google Cloud Storage. Едно експортиране достига до всички.

КъдеКак се адресира
Amazon S3Signature Version 4, bucket в хоста
Cloudflare R2Signature Version 4 към крайната точка на акаунта ви
Google Cloud Storageчрез неговия S3-съвместим API с HMAC ключ
MinIO, Wasabi, Backblaze B2 и другиSignature Version 4 към вашата крайна точка
Azure Blob StorageSAS връзка към контейнер — без подписване от наша страна

2. Защо Azure е различен и защо това е по-добре

Azure Blob не използва Signature Version 4; подписва с SharedKey. Можехме да изградим втора схема за подписване. Вместо това мостът приема SAS връзка към контейнер — URL адрес, който генерирате в собствения си акаунт за съхранение и който вече съдържа подписа.

Това означава по-малко код от наша страна и по-малко необходимо доверие от ваша. Никога не виждаме ключ на акаунта: предоставяте разрешение с обхват, който сами сте определили, за един контейнер, с избрана от вас дата на изтичане и възможност за отмяна по всяко време, без да засягате нищо друго.

Същата сдържаност е полезна и за S3: дайте на ключа за достъп разрешение за запис само в този един префикс и нищо друго. Ключ, който може само да добавя в mouseplayer/goals/, не може да чете другите ви bucket-и, дори да изтече.

3. Един обект за всяка цел, а ключът е дата

Обектното хранилище няма добавяне към съществуващ файл. Дневен файл би трябвало да се пренаписва изцяло всеки път и две едновременно пристигнали цели биха се презаписали взаимно. Затова всяка изпълнена цел става отделен обект.

Цената са много малки обекти; структурата на ключовете прави това практично:

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

Хранилището за данни чете един ден като един дял, а попълването назад е сканиране на префикс, не заявка. Ако искате разделяне по проект вместо по дата, включете идентификатора на канала в префикса.

Всеки обект е един ред JSON

Умишлено без отстъпи, за да може целият префикс да се чете като NDJSON, без обектите да се отварят един по един. Времеви печат, проект, сесия, клиентски идентификатор, цел, стойност, валута и връзката за възпроизвеждане на записа.

Празната стойност е null, а не нула

Цел без парична стойност записва null. В хранилище за данни нулата би се сумирала в обща стойност, която никога не е съществувала — разликата между „няма договорена сума“ и „сума нула“ се запазва при експортирането.

4. Ако отговори с 403, първо прочетете това

Отхвърлена S3 заявка казва почти нищо и има причина съобщението за грешка в дневника ни да казва повече от S3: регионът участва в подписа. Грешният регион и грешният ключ дават еднакво 403, затова очевидното подозрение — ключът — е правилно само в половината случаи.

Три неща за проверка, в този ред:

  • Регионът, точно както го съобщава bucket-ът. R2 и Google Cloud Storage приемат auto и не го проверяват; всички останали го правят.
  • Разрешението за префикса. Ключ с обхват mouseplayer/ не може да записва в mouseplayer-goals/ — крайната наклонена черта има значение в ARN на ресурс.
  • Крайната точка, за R2 и S3-съвместими хранилища. Поставете хоста без https://; премахваме го и в двата случая, но добавен път означава друг bucket.

Идентификаторът на ключа за достъп умишлено се съхранява като открит текст. По замисъл той се предава с всяка подписана заявка, затова шифроването му би било усилие без защита. Тайната е шифрована, никога не се показва отново и никога не влиза във вътрешната опашка със задачата.

Всички споменати тук търговски марки принадлежат на съответните им собственици. MousePlayer няма търговски отношения с тези доставчици.