کتابهای کلیدواژه: مقیاسپذیری · همهٔ کتابها
کتابخانهٔ شنیدنی شبگفتار
کتابهای مقیاسپذیری
خلاصههای صوتی فارسی کتابهای مرتبط با مقیاسپذیری؛ کتاب و فصل دلخواهتان را برای شنیدن انتخاب کنید.
این مجموعه خلاصهٔ کتابهاست؛ نسخهٔ کامل کتاب اصلی نیست.
3 عنوان · 24 قسمت منتشرشده
راه را پیدا کنید
مسیرهای مطالعاتی
قفسهٔ کتابها
از این کتابها شروع کنید
فصل سوم: ذخیرهسازی و بازیابی اطلاعات
رایگانتوضیح و منابع این قسمت
تا حالا به این فکر کردهاید که وقتی دادهای را به پایگاه داده میدهید، دقیقاً چه اتفاقی در لایههای زیرین ذخیرهسازی میافتد و چطور این دادهها دوباره با سرعت بالا پیدا میشوند؟ خیلی وقتها برنامهنویسان موتورهای ذخیرهسازی را از صفر نمینویسند، اما انتخاب درست میان گزینهها و تنظیم دقیق آنها برای رسیدن به کارایی مطلوب نیازمند درک آنچه در پشت صحنه میگذرد است. در کتاب «طراحی برنامههای دادهگرا» نوشتهٔ «مارتین کلپمن» در فصل سوم این موضوع بررسی میشود که پایگاههای داده چگونه دادهها را ذخیره و بازیابی میکنند. در ادامه، چند ایدهٔ کلیدی این بخش را با هم مرور میکنیم.
سادهترین شکل پایگاه داده میتواند تنها یک فایل متنی باشد که در آن هر دستور نوشتن، اطلاعات را به انتهای فایل الحاق میکند. مشکل اینجاست که برای خواندن یا پیدا کردن یک مقدار، باید کل فایل از ابتدا تا انتها اسکن شود که با افزایش حجم دادهها، زمان پاسخدهی بهشدت بالا میرود. برای حل این مشکل، پایگاه داده از index (ایندکس) استفاده میکند؛ یک ساختار کمکی برای پیدا کردن سریع داده که از دادههای اصلی مشتق میشود. ایندکسها سرعت خواندن را بالا میبرند اما هر ایندکس جدیدی نوشتن را کند میکند، زیرا با هر تغییر داده، خود ایندکس هم باید بهروزرسانی شود و این یک دادوستد مهم در سیستمهای ذخیرهسازی است.
یکی از شیوههای ایندکسگذاری برای دادههای کلید-مقدار، نگهداری یک ساختار هش (hash) در حافظه رم است که هر کلید را به آدرس بایت آن در فایل روی دیسک وصل میکند. موتوری مثل Bitcask از همین روش استفاده میکند که برای خواندن و نوشتنهای سریع بسیار عالی است، به شرطی که تمام کلیدها در حافظه جا شوند. برای اینکه فایلهای لاگ تا ابد بزرگ نشوند، پایگاه داده آنها را به قطعات مشخصی تقسیم کرده و عملیات فشردهسازی و تجمیع را روی آنها انجام میدهد تا کلیدهای تکراری حذف شوند و فقط آخرین مقدار باقی بماند.
روش پیشرفتهتر دیگر، استفاده از Sorted String Table SSTable است که در آن جفتهای کلید-مقدار بر اساس کلید مرتب شدهاند. وقتی دادهها مرتب باشند، ادغام فایلها بسیار کارآمد میشود و دیگر نیازی نیست ایندکس تمام کلیدها کامل در حافظه بماند زیرا ایندکسهای پراکنده هم میتوانند مسیر را نشان دهند. برای پیادهسازی این رویکرد روی دیسک، نوشتنها ابتدا وارد یک ساختار متوازن در حافظه رم به نام memtable میشوند و وقتی حجم آنها زیاد شد، به شکل یک فایل مرتب روی دیسک ریخته میشوند. کتابخانههایی مثل LevelDB و RocksDB از ساختاری به نام LSM-tree (درخت LSM) استفاده میکنند که ترکیبی از این جدولهای مرتب و لاگهای حافظهای است تا توان عملیاتی نوشتن را به شکل چشمگیری افزایش دهند.
در سوی مقابل، ساختار پرکاربرد دیگر B-tree (درخت B) است که پایگاه داده را به بلوکها یا صفحات با اندازهٔ ثابت تقسیم میکند و آنها را در جا بازنویسی میکند. در این ساختار، هر صفحه شامل تعدادی کلید و ارجاع به صفحات فرزند است که درخت را متوازن نگه میدارد و جستجوی کلیدها را با تعداد کمتری از پرشها ممکن میسازد. البته برای جلوگیری از خرابی دادهها هنگام قطع برق، تغییرات ابتدا در یک write-ahead log (لاگ نوشتن پیشرو) ثبت میشود که یعنی لاگ تغییرات پیش از اعمال آنها نوشته میشود تا در صورت بروز مشکل، وضعیت سیستم بازیابی شود.
در نهایت، تفاوت اساسی میان سامانههای پردازش تراکنش و سامانههای تحلیلی وجود دارد که اولی برای خواندن و نوشتنهای تعاملی سریع با تعداد رکورد کم طراحی شدهاند و دومی برای اسکن میلیونها رکورد و محاسبهٔ آماری استفاده میشوند. در انبارهای داده data warehouse، رویکرد ذخیرهسازی ستونی به جای سطری به کار میرود تا پرسوجوهای تحلیلی فقط ستونهای مورد نیاز را بخوانند و با فشردهسازی پیشرفته، کارایی پردازش دادهها به حداکثر برسد.
پیشنهاد من این است که پیش از انتخاب نهایی موتور ذخیرهسازی برای پروژهٔ خود، الگوهای خواندن و نوشتن برنامهتان را بهدقت بررسی کنید؛ اگر سیستم شما با حجم عظیمی از نوشتنهای سریع روبهرو است، ساختارهای مبتنی بر لاگ و پیادهسازیهای مرتبشده میتوانند انتخاب بهتری باشند، در حالی که برای بارهای کاری سنتیتر، ساختارهای مبتنی بر درخت همچنان گزینهای قابل اتکا هستند.
شناخت این لایههای زیرین به شما کمک میکند تا به جای حدس و گمان، با آگاهی کامل از ساختارهای دادهای پشت صحنه، معماری نرمافزار خود را بهینه کنید.
فصل دوم: مدلهای داده و زبانهای پرسوجو
رایگانتوضیح و منابع این قسمت
تا حالا به این فکر کردهاید که چرا وقتی میخواهید ساختار پیچیدهای مثل مشخصات یک کاربر را در پایگاه داده ذخیره کنید، گاهی کدهای برنامهنویسی شما پر از ترجمههای دستوپاگیر میشود؟ چطور انتخاب یک مدل داده میتواند تعیین کند که نوشتن کدام ویژگی نرمافزار آسان یا عذابآور باشد؟ چه فرقی بین روشهای مختلف سازماندهی اطلاعات در زیر پوست برنامهها وجود دارد؟
در کتاب «طراحی برنامههای دادهگرا» نوشتهٔ «مارتین کلپمن»، فصل دوم به بررسی مدلهای داده و زبانهای پرسوجو میپردازد تا ببینیم زیربنای انتخابهای ما در ذخیرهسازی اطلاعات چیست.
اولین ایدهٔ کلیدی، مدل رابطهای (Relational Model) در برابر مدل سندی (Document Model) است. مشکل اینجاست که برنامههای امروزی با شیءها کار میکنند، در حالی که پایگاههای دادهٔ سنتی اطلاعات را در جدولها نگه میدارند و این فاصله به ناهمگونی شیء-رابطهای (Impedance Mismatch) منجر میشود. گزینههای مختلفی مانند جدولهای نرمالشده، دادههای ساختیافته درون ستونها یا ذخیرهٔ جیسان وجود دارد که هرکدام تعادلی بین پیچیدگی کد و انعطاف ایجاد میکنند؛ مثلاً ذخیرهٔ مشخصات یک رزومه به شکل یک سند واحد جیسان، دسترسی به تمام اطلاعات را با یک پرسوجو ممکن میکند.
ایدهٔ دوم، روابط چند به چند و محدودیت مدلهای سندی است. مشکل اینجاست که وقتی دادهها بهشدت به هم مرتبط میشوند، مدلهایی که پشتیبانی مناسبی از اتصالها ندارند کار را سخت میکنند. نویسنده توضیح میدهد که مدلهای سندپایه برای ساختارهای درختی یک به چند عالی هستند، اما اگر روابط پیچیده شوند، ممکن است به تکرار دادهها یا پیادهسازی دستی ارتباطها در کد برنامهنویسی نیاز پیدا کنید. برای نمونه، اضافه کردن امکان ارجاع به شرکتها یا توصیههای کاربران دیگر در یک شبکهٔ اجتماعی، مدلهای سندی را دچار چالش میکند.
ایدهٔ سوم، مسئلهٔ طرحواره اسکیما (Schema) و انعطاف آن است. مشکل اینجاست که تغییر ساختار دادهها در پایگاههای داده میتواند وقتگیر باشد و به بازنویسی اطلاعات نیاز پیدا کند. گزینههای پیش رو بین مدل اسکیما-روی-نوشتن (Schema-on-Write) که ساختار را در زمان درج داده کنترل میکند و اسکیما-روی-خواند (Schema-on-read) که ساختار را در زمان خواندن تفسیر میکند متغیر است. برای مثال، پایگاههای دادهٔ سندی به شما اجازه میدهند بدون تغییر قبلی ساختار جدول، فیلد جدیدی را به برخی اسناد اضافه کنید و ناسازگاریها را هنگام خواندن مدیریت کنید.
ایدهٔ چهارم، تفاوت زبانهای پرسوجو است. مشکل اینجاست که دستورات دستوری به کامپیوتر میگویند چه عملیاتی را به چه ترتیبی انجام دهد، که نوشتن برنامههای موازی را دشوار میکند. گزینههای بهتری مثل زبانهای پرسوجوی اعلامی (Declarative) وجود دارند که در آنها فقط الگوی دادهٔ مورد نظر را توصیف میکنید. مثلاً در زبان اسکیوال (SQL) شما مشخص میکنید چه اطلاعاتی میخواهید و موتور پایگاه داده خودش تصمیم میگیرد از چه روشی برای سریعتر شدن کار استفاده کند.
ایدهٔ پنجم، مدلهای مبتنی بر گراف برای دادههای بهشدت مرتبط است. مشکل اینجاست که وقتی همهچیز میتواند به همهچیز وصل باشد، مدلهای جدولمحور یا درختی ناکارآمد میشوند. گزینههایی مانند گرافهای ویژگی (Property Graphs) از رأسها (Vertices) و یالها (Edges) تشکیل شدهاند تا ارتباطهای پیچیده را به شکلی طبیعی ذخیره و پرسوجو کنند. برای مثال، پیدا کردن مسیر مهاجرت افراد از یک کشور به قارهای دیگر در پایگاههای دادهٔ گرافی با زبانهایی مثل سایفر (Cypher) بسیار کوتاهتر و خواناتر از اسکیوال پیادهسازی میشود.
پیشنهاد من این است که هنگام طراحی سیستم جدید، به جای پیروی کورکورانه از ترندهای روز، به نوع روابط واقعی بین دادههایتان نگاه کنید؛ اگر دادههایتان درختهای مستقل هستند مدل سندپایه را انتخاب کنید و اگر با شبکهای پیچیده از ارتباطات روبرو هستید، پایگاه دادههای گرافی را به کار بگیرید.
انتخاب درست مدل داده، مرز میان یک معماری نرمافزار تمیز و توسعهپذیر با کدهایی پر از وصله و پینه است که در نهایت سرنوشت محصول شما را رقم میزند.
فصل اول: برنامههای قابلاعتماد، مقیاسپذیر و قابلنگهداری
رایگانتوضیح و منابع این قسمت
وقتی به اینترنت و سرویسهای بزرگ نگاه میکنیم، به نظر میرسد این فناوریها همیشه بینقص کار کردهاند. اما پشت این سادگی ظاهری، چالشهای بسیار پیچیدهای در مدیریت حجم انبوه دادهها وجود دارد که مهندسان نرمافزار هر روز با آنها دستوپنجه نرم میکنند.
این مباحث برگرفته از کتاب «طراحی برنامههای دادهگرا» نوشتهٔ «مارتین کلپمن» است و به ما نشان میدهد چگونه باید سیستمهایی بسازیم که در برابر مشکلات مقاوم باشند و با رشد حجم اطلاعات، عملکرد خود را حفظ کنند.
اولین اصل بنیادین در طراحی چنین سیستمهایی، قابلیت اعتماد (Reliability) است؛ یعنی توانایی سیستم در ادامهٔ کار درست حتی وقتی خطا رخ میدهد. در دنیای واقعی، سختافزارها خراب میشوند، نرمافزارها باگ دارند و انسانها اشتباه میکنند. برای نمونه، در یک کلاستر بزرگ با هزاران هارد دیسک، خرابی روزانهٔ چند قطعه کاملاً عادی است. نویسنده توضیح میدهد که به جای تلاش برای حذف کامل خطاها، باید با افزودن قابلیت تحمل خطا و استفاده از تکنیکهایی مانند تستهای مخرب خودکار، مطمئن شویم سیستم با خرابیها از پا نمیافتد.
دومین چالش مهم، مقیاسپذیری (Scalability) است که توانایی سیستم در مدیریت رشد بار و حجم داده را توصیف میکند. وقتی تعداد کاربران یا حجم درخواستها دهها برابر میشود، نمیتوان انتظار داشت همان معماری قبلی پاسخگو باشد. برای مثال، در طراحی شبکهای مانند توییتر، چالش اصلی تعداد توییتها نیست، بلکه توزیع نامتوازن دنبالکنندگان است که باعث میشود ارسال یک توییت ساده به میلیونها عملیات نوشتن منجر شود و مهندسان ناچار شوند بین انجام کار هنگام نوشتن یا هنگام خواندن دادهها تعادل برقرار کنند.
برای سنجش این مقیاسپذیری، ما به معیارهای دقیق عملکرد نیاز داریم. میانگین زمان پاسخگویی معمولاً شاخص مناسبی نیست چون اثر کاربران کند را پنهان میکند. به همین دلیل استفاده از صدکها percentiles اهمیت پیدا میکند؛ یعنی بررسی تاخیر در صدکهای نود و پنجم یا نود و نهم تا مطمئن شویم حتی کاربرانی که دادههای بیشتر یا درخواستهای سنگینتری دارند، تجربهٔ کندی نداشتهاند و صفهای انتظار سرور باعث تاخیر آبشاری نمیشود.
سومین ستون اصلی، قابلیت نگهداری (Maintainability) است که تلاش میکند سهولت تغییر، تعمیر و ادارهٔ سیستم در طول زمان را فراهم کند. بخش بزرگی از هزینهٔ نرمافزار مربوط به روزهای پس از توسعه است و پیچیدگیهای تصادفی که در کد یا معماری انباشته میشوند، کار تیمهای مهندسی و عملیات را دشوار میکنند. استفاده از انتزاعهای مناسب، مانند زبانهای سطح بالا یا پایگاههای دادهای که جزئیات پیچیدهٔ ذخیرهسازی روی دیسک را پنهان میکنند، ابزارهایی هستند که به ما کمک میکنند پیچیدگیها را مهار کنیم.
پیشنهاد عملی من به شما این است که وقتی سیستم جدیدی را طراحی میکنید، از همین امروز مانیتورing و سنجش صدکهای واقعی تاخیر را در سمت کلاینت جدی بگیرید و پیش از اینکه مقیاس سیستم شما را غافلگیر کند، فرضهای خود دربارهٔ بار کاری را مستند کنید.
امیدوارم این مرور کوتاه به شما کمک کرده باشد نگاه عمیقتری به زیرساخت برنامههای دادهگرا داشته باشید. تا اپیزود بعدی، پیروز و پایدار باشید.
پیشگفتار
رایگانتوضیح و منابع این قسمت
وقتی درگیر ساخت برنامههای سمت سرور هستید، مدام با کلمات دهانپُرکنی مثل پایگاههای دادهٔ غیررابطهای، مقیاسپذیری وب و معماری ابری بمباران میشوید. اما واقعاً پشت این همه اصطلاح رنگارنگ چه اصول پایداری نهفته است که با تغییر کردن ابزارها همچنان سر جای خودشان باقی میمانند؟
این پرسش محوری کتاب «طراحی برنامههای دادهگرا» نوشتهٔ «مارتین کلپمن» است؛ راهنمایی عمیق که کمک میکند از سطح این اصطلاحات عبور کنیم و به درک درستی از مهندسی داده برسیم.
نخستین چالش در این مسیر، ساختن سیستمی است که در برابر خطاهای مختلف مقاومت کند. در مهندسی نرمافزار، قابلیت اعتماد (Reliability) یعنی توانایی سیستم در ادامهٔ کار درست حتی وقتی خطا رخ میدهد. فرض کنید در یک سامانهٔ بانکی، بروز یک نقص سختافزاری یا خطای انسانی نباید کل داراییها را به خطر بیندازد. انتخابهای معماری ما باید طوری باشد که سیستم در مواجهه با این مشکلات پیشبینینشده، پابرجا بماند.
چالش دوم به رشد مداوم حجم اطلاعات مربوط میشود. وقتی یک اپلیکیشن با میلیونها کاربر روبهرو میشود، مقیاسپذیری (Scalability) یعنی توانایی سیستم در مدیریت رشد بار و حجم داده اهمیت حیاتی پیدا میکند. اگر بدون نیاز واقعی سراغ معماریهای پیچیده و توزیعشده برویم، دچار بهینهسازی زودهنگام میشویم و هزینههای گزافی میپردازیم؛ اما اگر سیستم را درست طراحی نکنیم، در روزهای اوج ترافیک زمین گیر خواهیم شد.
مسئلهٔ سوم به طول عمر کدها و زیرساختها برمیگردد. قابلیت نگهداری (Maintainability) یعنی سهولت تغییر، تعمیر و ادارهٔ سیستم در طول زمان که کمک میکند تیمهای نرمافزاری بدون هدر دادن انرژی، ویژگیهای جدید را به محصول اضافه کنند. کتاب توضیح میدهد که چطور میتوان ساختارها را طوری چید که تغییر نیازمندیهای کسبوکار، کل پروژه را از بین نبرد و توسعهدهندگان در سالهای آینده هم از کار کردن روی کدها لذت ببرند.
در نهایت، وقتی از یک ماشین فراتر میرویم و به سراغ سامانههای توزیعشده میرویم، هماهنگی بین بخشهای مختلف سخت میشود. سازگاری نهایی (Eventual Consistency) یعنی نسخهها در نهایت همخوان میشوند، نه لزوماً در همان لحظه؛ روشی که در بسیاری از پایگاههای دادهٔ مقیاسپذیر برای سرعت بخشیدن به پاسخدهی به کار میرود و البته پیچیدگیهای منطقی خاص خودش را دارد.
پیشنهاد من این است که وقتی ابزار جدیدی وارد بازار میشود، بهجای هجوم آوردن برای یادگیری تمام جزئیات سطحی آن، ابتدا اصول پایهای ذخیرهسازی، پردازش و توزیع داده را مرور کنید تا ببینید آیا واقعاً حلکنندهٔ مسئلهٔ واقعی شما هستید یا خیر.
شناخت این اصول زیربنای ساخت هر نرمافزار مقاومتپذیری است که باید هر روز در دنیای واقعی دوئت کند. امیدوارم این مرور کوتاه نگاه تازهای به معماری دادهها به شما داده باشد.