فصل دوم از کتاب I ♥ Logs
از بین کاربردهای لاگ، اولین کاربردی که میخواهیم دربارهی آن صحبت کنیم، Data Integration یا یکپارچگی داده است. ابتدا آن را تعریف کنیم:
یکپارچگی داده یعنی در دسترس قرار دادن کلیه داده های یک سازمان در اختیار کلیه سرویس ها و سیستم هایی که به آن داده احتیاج دارند
اصطلاح Data Integration آنچنان رایج نیست اما معادل بهتری هم وجود ندارد. اصطلاح ETL یعنی Extract, Transform, Load معمولا یک قسمت محدود از Data Integration را شامل میشود. اما خب بیشتر چیزهایی که اینجا میگوییم میتواند به عنوان ETLای در نظر گرفته شود که همچنین شامل سیستمهای بلا درنگ و جریان پردازش میشود.
استفادهی بهینه از دادهها، احتیاج به چیزی مانند هرم سلسلهمراتب نیازهای مزلو دارد. پایهی هرم شامل ضبط تمام دادههای مربوطه و قرار دادن آنها در یک محیط پردازش مناسب است (مثلا یک سیستم پردازش کوئری یا اسکریپت پایتون) این دادهها باید به روشی یکسان مدل سازی شوند تا خواندن و پردازش آن آسان شود. وقتی این نیاز برطرف شد، منطقی است که به دنبال زیرساختی باشیم تا این داده را به روشهای مختلف پردازش کنیم: MapReduce، سیستمهای کوئری بلا درنگ و ...
دو مورد باعث میشوند یکپارچگی داده تبدیل به یک مسئلهی دشوار شود.
اگر ۱۵ سال پیش از یک شرکت میپرسیدید که چه دادهای دارند، شروع به توصیف دادههای معاملاتی خود شامل کاربران، محصولات و سفارشها میکردند که در یک Relational Database نگهداری میشد.
اما تعریفها گسترش پیدا کردهاند. امروزه شرکتها شامل Event Data نیز هستند. دادههای رویدادی، چیزهایی را که اتفاق میافتند ضبط میکنند.مثلا در سیستمهای مبتنی بر وب، این یعنی فعالیتهای کاربر.
این نوع دادهها باعث میشوند روشهای سنتی یکپارچگی داده، تکانی به خود بدهند چون دادههای رویدادی بسیار بسیار بزرگتر از دادههای معاملاتی قدیمی میشوند.
دومین مورد، هیاهوی سیستمهای دادهای تخصصی است که طرفدارهای زیادی پیدا کردهاند و معمولا هم به صورت رایگان در اختیار هستند. این سیستمهای تخصصی برای OLAP، جستجو، ذخیرهسازی آنلاین، پردازش دستهای، تحلیل گراف و ... وجود دارند.
ترکیب دادههای زیاد در انواع مختلف و میل به وارد کردن این دادهها در سیستمهای متنوع، باعث میشود یکپارچگی داده تبدیل به یک مسئلهی پیچیده شود.
چطور میتوانیم این مشکل را حل کنیم؟ اینطور که پیداست ساختمان دادهی طبیعی برای مدیریت جریان داده بین سیستمها، لاگ است. دستورالعمل آن ساده است:
تمام دادههای یک سازمان را بگیر و برای اشتراکگذاری بلا درنگ، آن را در یک لاگ مرکزی قرار بده
هر منبع داده را میتوان با لاگ خود مدل کرد. منبع داده میتواند یک برنامه باشد که ایونتها را لاگ میکند (مثلا کلیکها یا بازدیدهای صفحهها) یا یک تیبل دیتابیس باشد که تغییرات را لاگ میکند. هر سیستمی که در لاگ مشترک میشود (Subscribe)، با حداکثر سرعت لاگ را میخواند، هر رکورد تازه را به استور خود اعمال میکند و مکان خود را در فایل لاگ به جلو میبرد. هر نوع سیستم دادهای میتواند در این لاگها مشترک شود: کش، هدوپ، یک دیتابیس سایت، سیستم جستجو و ...
مفهوم لاگ به هر کدام از تغییرها یک ساعت منطقی میدهد تا همهی مشترکین را بتوان با آن اندازه گیری کرد. این امر استدلال دربارهی وضعیت سیستمهایی که در لاگ مشترک هستند، راحتتر میکند چون هر کدام زمانی را که یک چیزی را خواندهاند، دارند.
برای اینکه این مورد بیشتر ملموس شود، یک حالت ساده را در نظر بگیرید که یک دیتابیس و چند سرور کش وجود دارد. لاگ یک راه برای همگامسازی تمام آپدیتها در تمام این سیستمها ارائه میدهد و بر اساس زمانی که در لاگ قرار دارند، میتوان دربارهی وضعیت آنها استدلال کرد. فرض کنید یک رکورد با ورودی X در لاگ مینویسیم و بعد میخواهیم آن را از کش بخوانیم. اگر میخواهیم تضمین کنیم که دادههای قدیمی را نمیبینیم، باید مطمئن باشیم از کشی که تا ورودی X نخوانده است، نمیخوانیم.
انبار داده، پایگاه دادهی تحلیلی یا Data Warehouse یک مخزن(Repository) برای دادهی تمیز، یکپارچه و ساختار یافته است تا بتوان بر روی آن تحلیل انجام داد. تعریفی که از Data Warehouse ارائه شد، شامل چند بخش است. داده از منابع دادهی مختلف استخراج میشود، تبدیل به یک فرم قابل فهم میشود(ساختار پیدا میکند) و در یک انبار دادهی مرکزی ذخیره میشود. داشتن یک همچین مرکزی که یک کپی تمیز از تمام دادههای ما دارد، یک دارایی بسیار ارزشمند برای تحلیل و پردازشهای مبتنی بر داده است. اما روشهای رسیدن به آن کمی تاریخ گذشته هستند.
مشکل اصلی یک سازمان دادهمحور، اتصال دادهی تمیز و یکپارچه به انبار داده است. انبار داده یک زیرساخت کوئری دستهای است که مناسب گزارش و تحلیل است؛ مخصوصا زمانی که کوئریها شامل Count، Aggregation و Filtering است. اما داشتن یک سیستم کوئری دستهای که تنها مخزن دادهی تمیز و کامل است، یعنی برای سیستمهایی که به وارد شدن لحظهای داده احتیاج دارند، داده غیر قابل دسترس است. مثل سیستمهای پردازش بلا درنگ، سیستمهای جستجو و سیستمهای مانیتورینگ.
در واقع ETL شامل دو چیز است. اول یک فرآیند استخراج و پاکسازی داده انجام میشود. در اینجا دادههایی که در سیستمهای مختلف وجود دارند، جمعآوری میشوند و عملا محدودیتهایی که هر سیستم خاص ایجاد میکند، از بین میرود. دوم، داده برای کوئریهای مناسب انبار داده دوباره ساختار بندی میشود (مثلا تبدیل به Star Schema یا Snowflake Schema میشود، یا به فرمت ستونی تبدیل میشود و ...) ترکیب این دو مورد یک مشکل است. مخزنی که شامل دادهی تمیز و یکپارچه است، باید به صورت بلا درنگ برای پردازش با تاخیر کم در دسترس باشد.
مشکل قدیمی تیم انبار داده این است که آنها مسئول جمعآوری و پاکسازی تمام دادهای هستند که توسط بقیهی تیمهای سازمان تولید میشود. تولید کنندههای داده معمولا اطلاعی از استفادهی داده در انبار داده ندارند و در نهایت دادهای تولید میکنند که استخراج آن سخت است و احتیاج به تبدیلهای پیچیده دارد تا به شکل قابل استفاده در بیاید.
یک روش بهتر این است که یک پایپلاین مرکزی داشته باشیم، یعن لاگ، که یک API کاملا مشخص شده برای اضافه کردن داده دارد. وظیفهی ایجاد یکپارچگی با این پایپلاین و ارائهی دادهی تمیز با ساختار مناسب، برعهدهی سازندهی داده است. این یعنی به عنوان قسمتی از طراحی و پیادهسازی سیستمشان، آنها باید مسئلهی خارج کردن داده با ساختار مناسب برای تحویل به پایپلاین را در نظر بگیرند.
اضافه شدن سیستمهای ذخیرهسازی جدید هیچ عواقبی برای تیم انبار داده ندارد، چون آنها یک نقطهی مرکزی برای ادغام دارند. تیم انبار داده تنها مسئلهی بارگزاری دادهی ساختار یافته از لاگ مرکزی و انجام تغییرات مناسب با سیستمشان را انجام میدهند.
این نکتهی مقیاسپذیری سازمانی موقعی اهمیت پیدا میکند که یک سازمان میخواهد یک سری سیستمهای دادهای به انبار دادههای قدیمی خود اضافه کند. برای مثال، میخواهد قابلیت جستجو را به تمام دیتاستهای سازمان اضافه کند. یا میخواهد سیستم مانیتورینگ دادهی جریانی به همراه نمودار و سیستم اطلاعرسانی اضافه کند. در هر صورت، زیرساخت انبار دادهی قدیمی یا کلاستر هدوپ، نامناسب خواهد بود. این توجیه می کند که چرا بعضی از سازمانها این قابلیتها را برای تمام دادههای خود ندارند. در مقابل، اگر سازمان دادههای خود را با ساختار و یک شکل ساخته بود، اضافه کردن یک سیستم که به تمام دادهها دسترسی دارد تنها به چند تغییر کوچک در پایپلاین احتیاج داشت.
این معماری اختیارهای مختلفی در اختیار ما میگذارد که داده را کجا تمیز یا تبدیل کنیم:
بهترین مدل این است که تولید کنندهی داده، قبل از وارد شدن داده به لاگ، پاکسازی را انجام دهد. این یعنی دادهها به شکل متعارف هستند و تحت تاثیر و در اختیار یک کد که آنها را تولید کرده یا سیستمی که در آن قرار گرفته بودند، نیستند. این جزئیات بهتر است توسط تیمی که داده را تولید میکند، مدیریت شود چون این تیم بیشترین اطلاعات را دربارهی دادهی خود دارد. هر منطقی که در این مرحله اعمال میشود، باید برگشتپذیر (Reversible) و بدون از دست دادن (Loseless) باشد.
هر نوع تبدیلی که یک مقداری به داده اضافه میکند و میتواند بلا درنگ انجام شود، باید به صورت پسپردازش روی لاگ خام که تولید شده است، انجام شود. با این کار، لاگ اصلی همچنان در دسترس است، و همچنین عملیات پسپردازش ما باعث تولید یک لاگ فایل اضافی شده است.[منظور این است که اطلاعات درون لاگ اصلی قرار میگیرند. با انجام عملیات پسپردازش، یک لاگ جدید تولید میشود که مستقل از لاگ اصلی است]
در نهایت، فقط Aggregationای که مختص سیستم مقصد است باید به عنوان بخشی از فرآیند بارگیری در سیستم مقصد تعریف شود. این ممکن است شامل تبدیل داده به یک Star Schema یا Snowflake Schema برای تحلیل و گزارش در انبار داده باشد.
بیایید دربارهی مزایای جانبی این معماری صحبت کنیم: سیستمهای جداشده و ایونت محور را در اختیار ما میگذارد.
روش معمول برای دادههای کاربران در صنعت وب، این است که دادهها در یک فایل تکست لاگ شوند تا بتوانند در یک انبار داده یا Hadoop برای Aggregation و Query قرار بگیرند. مشکل این روش همان مشکل روش "تمام ETL" است که قبلا گفتیم: جریان داده را به قابلیتها و برنامهی پردازش انبار داده مبتنی میکند.
لینکدین از روش Log-Centric برای دادههای ایونت استفاده میکند. از Kafka به عنوان لاگ مرکزی که چند سیستم در آن مشترک میشوند، استفاده میکند. صد ها نوع ایونت تعریف شده است که هر کدام یک Attribiute خاص دربارهی یک عمل را ضبط میکنند.
برای فهمیدن خوبی این روش، یک عملیات سادهی نمایش آگهی شغلی را در نظر بگیرید. صفحهی آگهی شغلی باید فقط شامل منطق نمایش شغل باشد. اما در یک سایت داینامیک، این میتواند همراه با یک سری عملیات دیگر که نامربوط به نمایش شغل هستند، همراه شوند. برای مثال فرض کنید میان این سیستمها باید یکپارچگی ایجاد کنیم:
خیلی زود، عمل سادهی نمایش آگهی شغلی تبدیل به یک عمل پیچیده شد. با اضافه کردن دیگر جاها برای نمایش، مانند اپلیکیشن موبایل، این پیچیدگی مدام در حال افزایش است. بدتر، سیستمها در هم تنیده میشوند؛ شخصی که روی نمایش شغل کار میکرد، حالا باید دربارهی بقیهی سیستمها و نحوهی کارکرد آنها آشنا باشد تا مطمئن باشد یکپارچگی حفظ شده است. این فقط یک مثال بود، در عمل سختتر از این هم میشود.
روش ایونتمحور یک روش برای سادهسازی این عملیات ارائه میدهد. صفحهی نمایش آگهی شغلی حالا فقط یک شغل نمایش میدهد و این مورد را که یک شغل به همراه یک سری ویژگیها نمایش داده شده است، ضبط میکند. حال هر کدام از بقیهی سیستمها که به این ویژگیها احتیاج دارند، مثلا سیستم پیشنهادگر یا سیستم امنیتی، در لاگ مشترک میشوند و پردازش خود را انجام میدهند. کد مختص نمایش لازم نیست از کاری که بقیهی سیستمها انجام میدهند، مطلع باشد یا اگر یک مصرف کنندهی دادهی جدید اضافه شد، تغیری بکند.