অবজেক্ট স্টোরেজে এক্সপোর্ট
প্রতি পূরণ করা লক্ষ্যে একটি JSON অবজেক্ট, আপনার নিজের বাকেটে। BigQuery ছাড়া অন্য সব ডেটা ওয়্যারহাউসে যাওয়ার পথ এটি।
1. যে ঘাটতি পূরণ করে
এতদিন MousePlayer থেকে ডেটা ওয়্যারহাউসে ঠিক একটি পথ ছিল, Google-এর দিকে। Snowflake, Redshift বা ClickHouse চালালে পথ ছিল না — যদিও তিনটিই সহজে অবজেক্ট স্টোরেজ থেকে পড়ে।
তাই ব্রিজ একে একে প্রতিটি ওয়্যারহাউসের বদলে অবজেক্ট স্টোরেজে লেখে। Snowflake S3 থেকে নেয়, Redshift S3 থেকে নেয়, ClickHouse S3 থেকে নেয় এবং BigQuery Google Cloud Storage থেকে নেয়। একটি এক্সপোর্ট সবার কাছে পৌঁছায়।
| কোথায় | যে পদ্ধতিতে পাঠানো হয় |
|---|---|
| Amazon S3 | Signature Version 4, হোস্টে বাকেট |
| Cloudflare R2 | আপনার অ্যাকাউন্ট এন্ডপয়েন্টে Signature Version 4 |
| Google Cloud Storage | HMAC কী দিয়ে তার S3-সামঞ্জস্যপূর্ণ API ব্যবহার করে |
| MinIO, Wasabi, Backblaze B2 ও অন্যান্য | আপনার এন্ডপয়েন্টে Signature Version 4 |
| Azure Blob Storage | কনটেইনার SAS লিংক — আমাদের দিকে কোনো স্বাক্ষর করাই নেই |
2. Azure আলাদা কেন, এবং তা ভালো কেন
Azure Blob Signature Version 4 ব্যবহার করে না; SharedKey দিয়ে স্বাক্ষর করে। দ্বিতীয় স্বাক্ষর পদ্ধতি তৈরি করতে পারতাম। তার বদলে ব্রিজ নেয় একটি কনটেইনার SAS লিংক — আপনার নিজের স্টোরেজ অ্যাকাউন্টে তৈরি URL, যার ভেতরেই স্বাক্ষর থাকে।
এতে আমাদের দিকে কোড কম, আপনার দিকে বিশ্বাসের প্রয়োজন কম। অ্যাকাউন্ট কী কখনো দেখি না: আপনি দেন নিজের নির্ধারিত পরিসরের অনুমতি, একটি কনটেইনারে, নিজের বেছে নেওয়া মেয়াদসহ; অন্য কিছু না ছুঁয়েই যেকোনো সময় প্রত্যাহারযোগ্য।
S3-এর দিকেও একই সীমা দেওয়া ভালো: অ্যাক্সেস কী-কে লেখার অনুমতি দিন শুধু এই একটি প্রিফিক্সে , আর কোথাও নয়। যে কী শুধু এই জায়গায় যোগ করতে পারে: mouseplayer/goals/ তা ফাঁস হলেও আপনার অন্য বাকেট পড়তে পারবে না।
3. প্রতি লক্ষ্যে একটি অবজেক্ট, কী হলো তারিখ
অবজেক্ট স্টোরেজে শেষে যোগ করার সুবিধা নেই। প্রতিবার দৈনিক ফাইল পুরো লিখতে হতো, আর একসঙ্গে দুটি লক্ষ্য এলে একে অন্যকে মুছে দিত। তাই প্রতিটি পূরণ করা লক্ষ্য আলাদা অবজেক্ট হয়।
বিনিময়ে অনেক ছোট অবজেক্ট হয়; কী-এর বিন্যাস সেটি ব্যবহারযোগ্য করে:
prefix/YYYY/MM/DD/channel/session-goal.json
ওয়্যারহাউস এক দিনকে এক পার্টিশন হিসেবে পড়ে, আর আগের ডেটা ভরা হয় কোয়েরির বদলে প্রিফিক্স স্ক্যান করে। তারিখের বদলে প্রকল্প অনুযায়ী পার্টিশন চাইলে প্রিফিক্সে চ্যানেল ID দিন।
প্রতিটি অবজেক্ট এক লাইন JSON
ইচ্ছাকৃতভাবে ইন্ডেন্ট ছাড়া, যাতে অবজেক্ট একে একে না খুলেই পুরো প্রিফিক্স NDJSON হিসেবে পড়া যায়। টাইমস্ট্যাম্প, প্রকল্প, সেশন, গ্রাহক ID, লক্ষ্য, মূল্য, মুদ্রা ও রেকর্ডিং চালানোর লিংক থাকে।
খালি মান null, শূন্য নয়
আর্থিক মূল্য না থাকা লক্ষ্য লেখে null। ওয়্যারহাউসে শূন্য যোগ হয়ে এমন মোট তৈরি করত যা ছিলই না — “পরিমাণ নির্ধারিত নয়” ও “শূন্য পরিমাণ”-এর পার্থক্য এক্সপোর্টেও থাকে।
4. 403 দিলে আগে এটি পড়ুন
প্রত্যাখ্যাত S3 রিকোয়েস্ট প্রায় কিছুই বলে না; আমাদের লগে S3-এর চেয়ে বেশি তথ্য থাকার কারণ: স্বাক্ষরে অঞ্চল থাকে। ভুল অঞ্চল ও ভুল কী একই 403 দেয়, তাই স্বাভাবিক সন্দেহ — কী — মাত্র অর্ধেক ক্ষেত্রে ঠিক।
এই ক্রমে তিনটি জিনিস দেখুন:
- অঞ্চল, বাকেট যেমন জানায় ঠিক তেমন। R2 ও Google Cloud Storage নেয়
autoএবং যাচাই করে না; অন্য সবাই করে। - প্রিফিক্সের অনুমতি। এই পরিসরে সীমিত কী:
mouseplayer/লিখতে পারে না এই জায়গায়:mouseplayer-goals/— resource ARN-এ শেষের স্ল্যাশ গুরুত্বপূর্ণ। - এন্ডপয়েন্ট, R2 ও S3-সামঞ্জস্যপূর্ণ স্টোরেজের জন্য। হোস্ট পেস্ট করুন, বাদ দিয়ে
https://; আমরা এমনিতেও সরাই, কিন্তু তার শেষে পথ যোগ করা থাকলে সেটি অন্য বাকেট।
অ্যাক্সেস কী ID ইচ্ছাকৃতভাবে খোলা রূপে রাখা হয়। নকশা অনুযায়ী প্রতিটি স্বাক্ষর করা রিকোয়েস্টে এটি যায়, তাই এনক্রিপ্ট করলে পরিশ্রম হতো, সুরক্ষা নয়। সিক্রেট এনক্রিপ্ট করা থাকে, আর দেখানো হয় না, এবং কাজ বহনকারী অভ্যন্তরীণ সারিতে কখনো যায় না।
এখানে উল্লিখিত সব ট্রেডমার্ক নিজ নিজ মালিকের। এই সেবাদাতাদের সঙ্গে MousePlayer-এর ব্যবসায়িক সম্পর্ক নেই।