CodeCrafters
یو یو, ipfs چیست؟(InterPlanetary File System) یک پروتکل غیرمتمرکز برای ذخیرهسازی و شتراکگذاری دادههاست که با استفاده از آدرسدهی مبتنی بر محتوا (Content Addressing) و به روش p2p ، اطالاعت رو بین نودهای مختلف توزیع میکنه. برخلاف سیستمهای متمرکز که به سرورهای…
قسمت دوم: نودها سودشون چیه و پروژههای کریپتو چرا عاشقش شدن؟
خب، تا اینجا فهمیدیم IPFS چطوری دادهها رو بین نودهای شبکه پخش میکنه و چطور آدرسدهیش مبتنی بر محتوا (Content Addressing) هست، اما سوال اصلی اینه:
نودها چجوری سود میکنن؟
نودها (همون کامپیوترهایی که دادهها رو نگه میدارن و بین همدیگه رد و بدل میکنن) تو IPFS یه چیزی بیشتر از یک نقش ساده دارن:
ذخیرهسازی و اشتراکگذاری دادهها: نودها فایلها رو نگه میدارن و وقتی کسی درخواست داد، سریع اون فایل رو ارسال میکنن.
پاداش برای سرویسدهی: پروژههای مبتنی بر IPFS، مخصوصاً تو دنیای کریپتو و Web3، معمولاً برای نودهایی که بیشتر و بهتر خدمات میدن پاداش میدن. یعنی هر چقدر یک نود دادهها رو سریعتر و مطمئنتر تحویل بده، سود بیشتری میبره.
استفاده از توکنها: شبکههای ذخیرهسازی غیرمتمرکز مثل Filecoin که بر پایه IPFS ساخته شده، به نودها توکن Filecoin میدن به عنوان پاداش. این توکنها میشه در بازارهای کریپتو معامله کرد و سود واقعی ازشون گرفت.
چرا پروژههای بزرگ کریپتو مثل Chainlink و غیره IPFS رو انتخاب کردن؟
Chainlink و ذخیرهسازی دادههای اوراکل: Chainlink که نقش اوراکلهای امن رو بازی میکنه، نیاز داره دادهها رو جایی امن، سریع و غیرمتمرکز ذخیره کنه. IPFS این امکان رو بهش میده تا دادهها رو بدون وابستگی به یک سرور خاص، بین هزاران نود توزیع کنه و تضمین کنه که دادهها دستکاری نشدن.
غیرمتمرکز بودن و امنیت: پروژههایی که امنیت و اعتماد بالا براشون مهمه، به IPFS تکیه میکنن چون امکان سانسور و از بین رفتن داده تقریبا صفر میشه.
مقیاسپذیری: IPFS به دلیل ساختار توزیعشده، مقیاسپذیری خیلی بهتری نسبت به سیستمهای سنتی ذخیرهسازی داره. برای پروژههای کریپتو که روز به روز بزرگتر میشن، این موضوع حیاتی محسوب میشه.
پروژههای معروف دیگه که IPFS دارن استفاده میکنن:
ایک-Filecoin: شبکه ذخیرهسازی غیرمتمرکز که با IPFS کاملا یکپارچه شده و توکن مخصوص به خودش رو داره.
دو-اArweave: پروتکلی برای ذخیره دائمی دادهها، که IPFS هم بهش کمک میکنه.
سه=Unstoppable Domains: استفاده از IPFS برای ساخت دامنههای وب غیرقابل سانسور.
چهار-Audius: پلتفرم موزیک غیرمتمرکز که IPFS رو برای نگهداری موزیکها و دادهها استفاده میکنه.
#ipfs
#web3
@code_crafters
خب، تا اینجا فهمیدیم IPFS چطوری دادهها رو بین نودهای شبکه پخش میکنه و چطور آدرسدهیش مبتنی بر محتوا (Content Addressing) هست، اما سوال اصلی اینه:
نودها چجوری سود میکنن؟
نودها (همون کامپیوترهایی که دادهها رو نگه میدارن و بین همدیگه رد و بدل میکنن) تو IPFS یه چیزی بیشتر از یک نقش ساده دارن:
ذخیرهسازی و اشتراکگذاری دادهها: نودها فایلها رو نگه میدارن و وقتی کسی درخواست داد، سریع اون فایل رو ارسال میکنن.
پاداش برای سرویسدهی: پروژههای مبتنی بر IPFS، مخصوصاً تو دنیای کریپتو و Web3، معمولاً برای نودهایی که بیشتر و بهتر خدمات میدن پاداش میدن. یعنی هر چقدر یک نود دادهها رو سریعتر و مطمئنتر تحویل بده، سود بیشتری میبره.
استفاده از توکنها: شبکههای ذخیرهسازی غیرمتمرکز مثل Filecoin که بر پایه IPFS ساخته شده، به نودها توکن Filecoin میدن به عنوان پاداش. این توکنها میشه در بازارهای کریپتو معامله کرد و سود واقعی ازشون گرفت.
چرا پروژههای بزرگ کریپتو مثل Chainlink و غیره IPFS رو انتخاب کردن؟
Chainlink و ذخیرهسازی دادههای اوراکل: Chainlink که نقش اوراکلهای امن رو بازی میکنه، نیاز داره دادهها رو جایی امن، سریع و غیرمتمرکز ذخیره کنه. IPFS این امکان رو بهش میده تا دادهها رو بدون وابستگی به یک سرور خاص، بین هزاران نود توزیع کنه و تضمین کنه که دادهها دستکاری نشدن.
غیرمتمرکز بودن و امنیت: پروژههایی که امنیت و اعتماد بالا براشون مهمه، به IPFS تکیه میکنن چون امکان سانسور و از بین رفتن داده تقریبا صفر میشه.
مقیاسپذیری: IPFS به دلیل ساختار توزیعشده، مقیاسپذیری خیلی بهتری نسبت به سیستمهای سنتی ذخیرهسازی داره. برای پروژههای کریپتو که روز به روز بزرگتر میشن، این موضوع حیاتی محسوب میشه.
پروژههای معروف دیگه که IPFS دارن استفاده میکنن:
ایک-Filecoin: شبکه ذخیرهسازی غیرمتمرکز که با IPFS کاملا یکپارچه شده و توکن مخصوص به خودش رو داره.
دو-اArweave: پروتکلی برای ذخیره دائمی دادهها، که IPFS هم بهش کمک میکنه.
سه=Unstoppable Domains: استفاده از IPFS برای ساخت دامنههای وب غیرقابل سانسور.
چهار-Audius: پلتفرم موزیک غیرمتمرکز که IPFS رو برای نگهداری موزیکها و دادهها استفاده میکنه.
#ipfs
#web3
@code_crafters
🔥7
Redirection - بخش اول
پروتکل HTTP به تنهایی برای تمام نیازهای ارتباطی وب کافی نیست. گاهی اوقات پیامهای کاربر تا رسیدن به سرور اصلی از مسیرهای مختلفی عبور میکنند و بین چندین سرور جابهجا میشوند. این مسیرهای پیچیده میتوانند باعث تاخیر یا حتی نرسیدن پیام به مقصد شوند. Redirection یکی از راهکارهاییست که برای بهینهسازی این فرایند استفاده میشود.
چرا از Redirection استفاده میکنیم؟
هدف اصلی Redirection سریعتر شدن ترنزکشنها و کاهش زمان انتظار کاربر است. مثلا ممکن است درخواست کاربر به سروری نزدیکتر فرستاده شود تا با سرعت بیشتری پاسخ دریافت شود.
ریدایرکشن چگونه انجام میشود؟
ریدایرکشن میتواند در لایههای مختلفی انجام شود.
گاهی مرورگر طوری تنظیم میشود که درخواست را به یک پروکسی سرور بفرستد. گاهی هم DNS resolver آدرس یک سرور دیگر را ارائه میدهد. حتی در برخی موارد این روترها یا سوییچها هستند که مسیر پیام را مشخص میکنند. گاهی هم خود وبسرور تصمیم میگیرد پیام را به سرور مناسبتری منتقل کند.
HTTP Redirection
یکی از روشهای رایج برای این موضوع، ارسال HTTP Redirection با کد ۳۰۲ است.
فرض کنید یک Load Balancer دارید که وظیفهاش تقسیم درخواستها بین چند سرور است. کاربر A درخواست خود را به لود بالانسر میفرستد و پاسخ ۳۰۲ دریافت میکند که در آن آدرس سرور مناسب قرار دارد. حالا مرورگر باید درخواست را به این آدرس جدید ارسال کند.
اینکه لود بالانسر بر چه اساسی تصمیمگیری میکند، موضوعیست که در آینده به آن خواهیم پرداخت.
البته یکی از مشکلات این روش، نیاز به ارسال چند درخواست برای رسیدن به سرور نهایی است که باعث افزایش تاخیر میشود.
DNS Redirection
زمانی که کاربر میخواهد به سایت codecrafters.ir دسترسی پیدا کند، DNS resolver باید این نام دامنه را به یک IP تبدیل کند. این IP میتواند از منابع مختلفی مثل مرورگر، DNS سرور شبکه یا منابع دیگر بیاید.
ما میتوانیم DNS سرور را طوری تنظیم کنیم که هر بار IP متفاوتی ارائه دهد. این کار میتواند به روش سادهای مثل round robin انجام شود یا با تحلیل متریکهای پیچیدهتر، تصمیم بهتری بگیرد.
در بخش بعدی به روشهایی مثل Anycast Addressing و IP-MAC Forwarding میپردازیم.
#http_guideline
@code_crafters
پروتکل HTTP به تنهایی برای تمام نیازهای ارتباطی وب کافی نیست. گاهی اوقات پیامهای کاربر تا رسیدن به سرور اصلی از مسیرهای مختلفی عبور میکنند و بین چندین سرور جابهجا میشوند. این مسیرهای پیچیده میتوانند باعث تاخیر یا حتی نرسیدن پیام به مقصد شوند. Redirection یکی از راهکارهاییست که برای بهینهسازی این فرایند استفاده میشود.
چرا از Redirection استفاده میکنیم؟
هدف اصلی Redirection سریعتر شدن ترنزکشنها و کاهش زمان انتظار کاربر است. مثلا ممکن است درخواست کاربر به سروری نزدیکتر فرستاده شود تا با سرعت بیشتری پاسخ دریافت شود.
ریدایرکشن چگونه انجام میشود؟
ریدایرکشن میتواند در لایههای مختلفی انجام شود.
گاهی مرورگر طوری تنظیم میشود که درخواست را به یک پروکسی سرور بفرستد. گاهی هم DNS resolver آدرس یک سرور دیگر را ارائه میدهد. حتی در برخی موارد این روترها یا سوییچها هستند که مسیر پیام را مشخص میکنند. گاهی هم خود وبسرور تصمیم میگیرد پیام را به سرور مناسبتری منتقل کند.
HTTP Redirection
یکی از روشهای رایج برای این موضوع، ارسال HTTP Redirection با کد ۳۰۲ است.
فرض کنید یک Load Balancer دارید که وظیفهاش تقسیم درخواستها بین چند سرور است. کاربر A درخواست خود را به لود بالانسر میفرستد و پاسخ ۳۰۲ دریافت میکند که در آن آدرس سرور مناسب قرار دارد. حالا مرورگر باید درخواست را به این آدرس جدید ارسال کند.
اینکه لود بالانسر بر چه اساسی تصمیمگیری میکند، موضوعیست که در آینده به آن خواهیم پرداخت.
البته یکی از مشکلات این روش، نیاز به ارسال چند درخواست برای رسیدن به سرور نهایی است که باعث افزایش تاخیر میشود.
DNS Redirection
زمانی که کاربر میخواهد به سایت codecrafters.ir دسترسی پیدا کند، DNS resolver باید این نام دامنه را به یک IP تبدیل کند. این IP میتواند از منابع مختلفی مثل مرورگر، DNS سرور شبکه یا منابع دیگر بیاید.
ما میتوانیم DNS سرور را طوری تنظیم کنیم که هر بار IP متفاوتی ارائه دهد. این کار میتواند به روش سادهای مثل round robin انجام شود یا با تحلیل متریکهای پیچیدهتر، تصمیم بهتری بگیرد.
در بخش بعدی به روشهایی مثل Anycast Addressing و IP-MAC Forwarding میپردازیم.
#http_guideline
@code_crafters
👍8
The_repository_pattern_via_CQRS_with_Python_Django_Elasticsearch.pdf
1.1 MB
پیادهسازی الگوی مخزن (Repository) از طریق CQRS با استفاده از Python-Django-ElasticSearch
#Django
#CQRS
#ElasticSearch
@code_crafters
#Django
#CQRS
#ElasticSearch
@code_crafters
❤11👎9
داشتم کتاب «طراحی برنامههای داده محور» رو میخوندم
کتابش بشدت سنگین و پر از مفاهیم و مسائل سنگین و پیچیده هستش ولی ایدهها و موضوعات جالبی داخلش مطرح هستش
یجای کتاب بحث راجب دادههای کلید/مقدار هستش و یک موضوع جالبی مطرح کرد با این عنوان که شما اگه در کلیدی که درست میکنید (مثلا ۳۲ کاراکتر) اگه یکمقدار یکتا داشته باشید براتون کافیه تا بعدا هرجا خواستید با اون کلید کار کنید فقط مقدار یکتای اون رو صدا بزنید و داشته باشید
وقتی بهش فکر کردم دیدم همین رو تو پلتفرمهای روزمرگی مورد استفاده خودمون هم دیدم (لاگ مربوط به گیت که فقط کافیه چند کاراکتر اولش رو بدونی، id مربوط به موجودیتهای داخل داکر که بازم کافیه چند مقدار اولش رو بدونی، هم لاگ گیت و هم id موجودیتهای داکر یک رشته حداقل ۶۴ کاراکتری هستند) این مقدار یکتا منجر میشه که هم سرعت کارمون بیشتر بشه هم کار کردن باهاش راحتتر باشه (واسه خودمون و سیستم)
یادمه یبار یکی از بچهها یکی از مشکلاتی که داشتند تو سیستمشون و راجبش باهم صحبت کردیم این بود که کلید ۶۴ کاراکتری رو داخل ردیس ذخیره کرده بودن که از طریق اون به یکسری اطلاعات برسند که مورد استفاده در کل سیستم بود، و خب جستجوی یک مقدار ۶۴ کاراکتری در بین هزارتا کلید با یک مقدار یکتای ۷ کاراکتری خیلی متفاوت هستش
حتی همین ایده کثیف هم برای توکنهای بزرگ احراز هویت بشدت کاربردی هستش و کار رو برامون راحت تر میکنه، انگار که یک پوینتر مستقیم به اون توکن داریم همیشه و فرقی نمیکنه این توکن در ردیس باشه یا در دیتابیس یا هرجایی دیگه، پوینتر ما همیشه برامون مستقیم به اون توکن اشاره میکنه
بحث جایی جذاب میشه که شما با این پوینتر حتی میتونید کارهای خلاقانه و کثیفی انجام بدید مثه چی؟؟؟ تصور کنید که برنامه شما از لحاظ امنیتی حساس هستش و میخواید فقط در یک لحظه یک حساب کاربری در یک دستگاه هویتش مشخص باشه و ورود کرده باشه، شما دیگه لازم نیست بیاید یک جدول بسازید و کلی منطق بنویسید که این رو مدیریت کرده باشید، کافیه که یک الگوی یکسان برای تولید پوینتر داشته باشید که به راحتی از طریق اون بتونید این موضوع رو مدیریت کنید و تمام
@code_crafters
کتابش بشدت سنگین و پر از مفاهیم و مسائل سنگین و پیچیده هستش ولی ایدهها و موضوعات جالبی داخلش مطرح هستش
یجای کتاب بحث راجب دادههای کلید/مقدار هستش و یک موضوع جالبی مطرح کرد با این عنوان که شما اگه در کلیدی که درست میکنید (مثلا ۳۲ کاراکتر) اگه یکمقدار یکتا داشته باشید براتون کافیه تا بعدا هرجا خواستید با اون کلید کار کنید فقط مقدار یکتای اون رو صدا بزنید و داشته باشید
وقتی بهش فکر کردم دیدم همین رو تو پلتفرمهای روزمرگی مورد استفاده خودمون هم دیدم (لاگ مربوط به گیت که فقط کافیه چند کاراکتر اولش رو بدونی، id مربوط به موجودیتهای داخل داکر که بازم کافیه چند مقدار اولش رو بدونی، هم لاگ گیت و هم id موجودیتهای داکر یک رشته حداقل ۶۴ کاراکتری هستند) این مقدار یکتا منجر میشه که هم سرعت کارمون بیشتر بشه هم کار کردن باهاش راحتتر باشه (واسه خودمون و سیستم)
یادمه یبار یکی از بچهها یکی از مشکلاتی که داشتند تو سیستمشون و راجبش باهم صحبت کردیم این بود که کلید ۶۴ کاراکتری رو داخل ردیس ذخیره کرده بودن که از طریق اون به یکسری اطلاعات برسند که مورد استفاده در کل سیستم بود، و خب جستجوی یک مقدار ۶۴ کاراکتری در بین هزارتا کلید با یک مقدار یکتای ۷ کاراکتری خیلی متفاوت هستش
حتی همین ایده کثیف هم برای توکنهای بزرگ احراز هویت بشدت کاربردی هستش و کار رو برامون راحت تر میکنه، انگار که یک پوینتر مستقیم به اون توکن داریم همیشه و فرقی نمیکنه این توکن در ردیس باشه یا در دیتابیس یا هرجایی دیگه، پوینتر ما همیشه برامون مستقیم به اون توکن اشاره میکنه
بحث جایی جذاب میشه که شما با این پوینتر حتی میتونید کارهای خلاقانه و کثیفی انجام بدید مثه چی؟؟؟ تصور کنید که برنامه شما از لحاظ امنیتی حساس هستش و میخواید فقط در یک لحظه یک حساب کاربری در یک دستگاه هویتش مشخص باشه و ورود کرده باشه، شما دیگه لازم نیست بیاید یک جدول بسازید و کلی منطق بنویسید که این رو مدیریت کرده باشید، کافیه که یک الگوی یکسان برای تولید پوینتر داشته باشید که به راحتی از طریق اون بتونید این موضوع رو مدیریت کنید و تمام
@code_crafters
❤3
فردوی خفتهای بودم
در شبی تاریک و جنگ زده
و تو به تحریک خصمانه بدخواهانمان
عمیقترین نگاههای سنگرشکنت را
مخفیانه با شبح چشمهایت
سوی قلب من انداختی
عمق من را شکافتی
و من چه بیصدا
در لحظهای غفلت انگیز
و بی دفاع در مقابل تو
از درون فرو ریختم
بگذار روشنایی بیاید
آنگاه که
از این شب تاریک گذر کنیم
و این جنگ میان من و تو به پایان برسد
با دیده خدایان از آسمان
نظاره کن و بنگر
چگونه رنگ باختم
سیما به دگرگونی گرفتم
حفرههای روی تن من را
که یادگار از تو بجا مانده
و خوشنودی بیگانگان از این تنش را
چه ساده بودم من
که از تووه ستیزه جو
صلح میخواستم
تو بگو
بعد من و شکستن احساس من
با نگاههای سنگین مردمان این شهر چه میکنی؟؟؟
در شبی تاریک و جنگ زده
و تو به تحریک خصمانه بدخواهانمان
عمیقترین نگاههای سنگرشکنت را
مخفیانه با شبح چشمهایت
سوی قلب من انداختی
عمق من را شکافتی
و من چه بیصدا
در لحظهای غفلت انگیز
و بی دفاع در مقابل تو
از درون فرو ریختم
بگذار روشنایی بیاید
آنگاه که
از این شب تاریک گذر کنیم
و این جنگ میان من و تو به پایان برسد
با دیده خدایان از آسمان
نظاره کن و بنگر
چگونه رنگ باختم
سیما به دگرگونی گرفتم
حفرههای روی تن من را
که یادگار از تو بجا مانده
و خوشنودی بیگانگان از این تنش را
چه ساده بودم من
که از تووه ستیزه جو
صلح میخواستم
تو بگو
بعد من و شکستن احساس من
با نگاههای سنگین مردمان این شهر چه میکنی؟؟؟
🤡10💔5🔥1
بچهها دستم خورد با اکانت ادمین گروه رو پاک کردم
راهی واسه برگردوندنش هست؟؟؟
راهی واسه برگردوندنش هست؟؟؟
🤣19🔥1💔1
خب میتونید برگردید
ولی منتها شماره کسی رو نتونم ببینم ریموش میکنم
ولی منتها شماره کسی رو نتونم ببینم ریموش میکنم
🍌13🙏2😁1
تو ادامه خوندن کتاب «طراحی برنامههای داده محور» به بحث race conditions رسیدم و دو نوع اون رو مطرح کرد (skew, phantom) بحث جایی شدت میگیره که بخوایم از طراحی سیستمهای توزیع شده استفاده کنیم (بصورت partitioningو node شده)
در بحث skew دو نوع متفاوت داریم
clock skew:
بطور صریح اون رو مشکلات همزمانی صدا میزنیم، تصور کنید که چند نود دیتابیس ما در چند منطقه زمانی مختلف قرار دارن (یا به هر دلیل دیگه زمان بندیشون یکسان و هماهنگ نیست بین nodeها)
تصور کنید تایم پزشک برای ساعت ۱۰:۳۰ رو میخوایم رزرو کنیم
نود اول ساعت ده میخواد رزرو کنه (تایم داخلی سیستمش ساعت ۱۰ هستس)
نود دوم در همون موقع میخواد رزو کنه (تایم داخلی سیستمش ساعت ۱۰ و یک ثانیه هستش)
هردو تراکنش انجام میشه بابت ناهماهنگی زمانی و رزرو ساعت ۱۰:۳۰ دقیقه دوتا مشتری داره
data skew:
بطور صریح نابرابری توزیع بهش میگیم، جایی رخ میده که ما دو شیفت برای رزرو داریم و هر شیفت روی پارتیشن جداگانه (یک و دو) ذخیره میشه شیفت اول مشتری بیشتری داره نسبت به شیفت دوم بابت همین تراکنشهای شیفت اول با کندی بیشتر و سنگینی روبرو میشه
در بحث phantoms هم زمان روی داد
phantom read ، write skew
رخ میده
نود اول دفعه اول چک میکنه و موقع چک دوم میبینه یکسری دیتا دیگه اضافه یا حذف شدن در این بازه و محاسبات (مقادیر موجودیتها تغییر کرده در این بازه)
نود اول چک میکنه میبینه رزرو خالیه و موجود، جواب رو برمیگردونه و تو این بازه تصمیم گیری نود دوم میاد میبینه رزرو خالی هستش و رزرو رو ثبت میکنه، نود اول برمیگرده و میبینه تو همین بازه کم رزرو خالی نیست (این رو تو سایتهای پرداخت سهمیهها بشدت میبینیم که معمولا با برگشت پول و تراکنش به مبدا صورت میگیره و هندلش میکنن)
نحوه مقابله و هندل کردنشون چجوریه بیایم از select for update یا redis تو پروژه ازش استفاده کنیم
@code_crafters
در بحث skew دو نوع متفاوت داریم
clock skew:
بطور صریح اون رو مشکلات همزمانی صدا میزنیم، تصور کنید که چند نود دیتابیس ما در چند منطقه زمانی مختلف قرار دارن (یا به هر دلیل دیگه زمان بندیشون یکسان و هماهنگ نیست بین nodeها)
تصور کنید تایم پزشک برای ساعت ۱۰:۳۰ رو میخوایم رزرو کنیم
نود اول ساعت ده میخواد رزرو کنه (تایم داخلی سیستمش ساعت ۱۰ هستس)
نود دوم در همون موقع میخواد رزو کنه (تایم داخلی سیستمش ساعت ۱۰ و یک ثانیه هستش)
هردو تراکنش انجام میشه بابت ناهماهنگی زمانی و رزرو ساعت ۱۰:۳۰ دقیقه دوتا مشتری داره
data skew:
بطور صریح نابرابری توزیع بهش میگیم، جایی رخ میده که ما دو شیفت برای رزرو داریم و هر شیفت روی پارتیشن جداگانه (یک و دو) ذخیره میشه شیفت اول مشتری بیشتری داره نسبت به شیفت دوم بابت همین تراکنشهای شیفت اول با کندی بیشتر و سنگینی روبرو میشه
در بحث phantoms هم زمان روی داد
phantom read ، write skew
رخ میده
نود اول دفعه اول چک میکنه و موقع چک دوم میبینه یکسری دیتا دیگه اضافه یا حذف شدن در این بازه و محاسبات (مقادیر موجودیتها تغییر کرده در این بازه)
نود اول چک میکنه میبینه رزرو خالیه و موجود، جواب رو برمیگردونه و تو این بازه تصمیم گیری نود دوم میاد میبینه رزرو خالی هستش و رزرو رو ثبت میکنه، نود اول برمیگرده و میبینه تو همین بازه کم رزرو خالی نیست (این رو تو سایتهای پرداخت سهمیهها بشدت میبینیم که معمولا با برگشت پول و تراکنش به مبدا صورت میگیره و هندلش میکنن)
نحوه مقابله و هندل کردنشون چجوریه بیایم از select for update یا redis تو پروژه ازش استفاده کنیم
@code_crafters
❤4🔥1
در ادامه کتاب «طراحی برنامههای داده محور» و موضوع race conditions ها که بالاتر گفتیم دو رویکرد عمده دیگه در داخل دیتابیسها هستش که داخل کتاب مطرح شده
read commit
این رویکرد به ما میگه که باید آخرین تغییرات ثبت شده رو بخونیم و اطمینان از این بابت انجام بدیم که dirty read ها خونده نمیشن در پاسخ به کوئری ها، در پستگرس این رویکرد بصورت پیش فرض فعال هستش و کار میکنه یعنی خود پستگرس این اطمینان رو بهمون میده تغییرات ثبت شده نهایی رو بهمون برمیگردونه (داخل جنگو وقتی commit=False میزنی در واقع dirty read تولید کردی و اگه خوندنی از دیتابیس در اون لحظه صورت بگیره پستگرس خروجی رو شامل این نمیکنه)
اما تو این سطح از کار (read commit اطمینان میده بهمون که dirty read نداشته باشیم) ما یه مشکل داریم اونم (phantom read) non repeatable read ها هستش، یعنی اگه در لحظه خوندن کامیت ثبت شده یک کوئری هم ثبت بشه متاسفانه خروجی شما شامل این تغییرات این کوئری نمیشه اصلا
snapshot isolation
در این سطح در هر کوئری در لحظه اجرا یک تصویر ثابت از دیتابیس بهش میدیم
بابت جلوگیری از مسئله بالا (phantom read) ما سراغ snapshot و ارتقا سطح serializable level در دیتابیس میریم و با فعال کردن repeatable read میایم و مانع این موضوع phantom read میشیم، تو حالت snapshot ما تضمین میکنیم در طول انجام عملیاتهای زمانبر مانند olap کوئریها از یک تصویر از یک سطح دیتابیس بخونن و تا زمان اتمام این حالت باقی بمونه برامون و اگه ناهماهنگی در سطح رکورد ببینه با استفاده از مکانیسم rollback مانع خطا در خروجی میشه، اما این سطح از ایزوله سازی نمیتونه مانع write skew (تو آپدیت های بعدی در کوئریهای بعدی ممکنه تصویر ما حاوی تغییراتی شده باشه) بشه بابت همین باید سطح ایزوله کردن رو بالا ببریم
serializable isolation
در این سطح از دیتابیس یک تصویر ثابت از دیتابیس به همه کوئریها میدیم
در مشکل بالاتر که گفتیم write skew ما سطح serializable level رو میزاریم روی serializable و این بالاترین سطح ایزوله کردن در دیتابیس هستش و مانع این نوع race condition و مابقی خطاهای دیگه در طول این پست میشه (همه رو برامون هندل میکنه-phantom,write,commit,lost update-) تضمین میکنه در یک olap طولانی یک تصویر کامل از دیتابیس داشته باشیم حتی اگر هر چقدر هم زمان کوئریها طول بکشه، تصور کنید دوتا کوئری سنگین زمانبر داریم و ممکنه در مابین این دو کوئری یک write بخواد صورت بگیره اینجا پستگرس با استفاده از مکانیسم conflict detection تشخیص میده تعارض در دادههای ما بین دو کوئری هستش و rollback میزنه و اطمینان میده که تصاویر یکسانی برای هردو کوئری هست تا خروجی یکسان باشه و بصورت سریالی پشت سرهم (هیچ کویری دیگری بین این دوتا) صورت نگرفته
@code_crafters
read commit
این رویکرد به ما میگه که باید آخرین تغییرات ثبت شده رو بخونیم و اطمینان از این بابت انجام بدیم که dirty read ها خونده نمیشن در پاسخ به کوئری ها، در پستگرس این رویکرد بصورت پیش فرض فعال هستش و کار میکنه یعنی خود پستگرس این اطمینان رو بهمون میده تغییرات ثبت شده نهایی رو بهمون برمیگردونه (داخل جنگو وقتی commit=False میزنی در واقع dirty read تولید کردی و اگه خوندنی از دیتابیس در اون لحظه صورت بگیره پستگرس خروجی رو شامل این نمیکنه)
اما تو این سطح از کار (read commit اطمینان میده بهمون که dirty read نداشته باشیم) ما یه مشکل داریم اونم (phantom read) non repeatable read ها هستش، یعنی اگه در لحظه خوندن کامیت ثبت شده یک کوئری هم ثبت بشه متاسفانه خروجی شما شامل این تغییرات این کوئری نمیشه اصلا
snapshot isolation
بابت جلوگیری از مسئله بالا (phantom read) ما سراغ snapshot و ارتقا سطح serializable level در دیتابیس میریم و با فعال کردن repeatable read میایم و مانع این موضوع phantom read میشیم، تو حالت snapshot ما تضمین میکنیم در طول انجام عملیاتهای زمانبر مانند olap کوئریها از یک تصویر از یک سطح دیتابیس بخونن و تا زمان اتمام این حالت باقی بمونه برامون و اگه ناهماهنگی در سطح رکورد ببینه با استفاده از مکانیسم rollback مانع خطا در خروجی میشه، اما این سطح از ایزوله سازی نمیتونه مانع write skew (تو آپدیت های بعدی در کوئریهای بعدی ممکنه تصویر ما حاوی تغییراتی شده باشه) بشه بابت همین باید سطح ایزوله کردن رو بالا ببریم
serializable isolation
در مشکل بالاتر که گفتیم write skew ما سطح serializable level رو میزاریم روی serializable و این بالاترین سطح ایزوله کردن در دیتابیس هستش و مانع این نوع race condition و مابقی خطاهای دیگه در طول این پست میشه (همه رو برامون هندل میکنه-phantom,write,commit,lost update-) تضمین میکنه در یک olap طولانی یک تصویر کامل از دیتابیس داشته باشیم حتی اگر هر چقدر هم زمان کوئریها طول بکشه، تصور کنید دوتا کوئری سنگین زمانبر داریم و ممکنه در مابین این دو کوئری یک write بخواد صورت بگیره اینجا پستگرس با استفاده از مکانیسم conflict detection تشخیص میده تعارض در دادههای ما بین دو کوئری هستش و rollback میزنه و اطمینان میده که تصاویر یکسانی برای هردو کوئری هست تا خروجی یکسان باشه و بصورت سریالی پشت سرهم (هیچ کویری دیگری بین این دوتا) صورت نگرفته
@code_crafters
❤3
در ادامه کتاب «طراحی برنامههای داده محور» در بخش race conditions کتاب یک الگوی دیگری برای رفع شرایط مسابقه رو هم بررسی میکنه (two-phace locking) یا به اختصار 2PL که البته این رویکرد منسوخ شده اما منتها جهت درک بهتره دو سطح serializable در snapshot کمک کننده هستش
2PL
رویکرد با قفل کردن در دیتابیس عمل میکنه، این الگو بشدت بدبین هستش و هر وقت صورت بگیره دوتا قفل انجام میده بک قفل اشتراکی برای خوندن و بک قفل انحصاری برای نوشتن و تراکنشها رو در صف انتظار قرار میده تا زمانیکه قفل باز بشه (در صورت نیاز کل دیتابیس رو یکجا و به یک صورت قفل میکنه)، موجب کندی و تاخیر شدید در پاسخ به کوئریها میشه و دیتابیس رو از هرگونه عملی محروم میکنه تا کوئری فعال کننده قفل تموم بشه و دیتابیس رو آزاد کنه، تصور کنید که select for update رو روی کل موجودیت دیتابیس اجرا کردید، اما تمام شرایط مسابقه رو هندل میکنه کامل (phamtom read, lost update, write skew, dirty data)، این رویکرد هم کوئریها رو بصورت سریالی انجام میده (انگار که چند کوئری بزرگ و طولانی پشت سرهم اجرا شدن)
snapshot isolation
در رویکرد سطح ایزوله با repeatable read و فعال کردن اون (در اجرای هر کوئری یه تصویر ثابت در ابتدا به کوئری میدیم) ما مشکل phamtom read رو بر طرف میکنیم منتها با مشکل write skew روبرو بودیم، اگه در بدنه atomic بیایم از select for update استفاده کنیم مشکل write skew برطرف میشه منتها مشکل اساسی تر این هستش که تعارض رو فقط برای ردیف اعلام شده بر روی اون انجام میده نه کل دیتابیس و تداخل داده در ردیفهایی که قفل روی اونها صورت نگرفته شکل میگیره و write skew همچنان پابرجا هستش
serializable snapshot isolation
یا به اختصار SSI بهش میگیم، رویکرد خوشبینانه در برخورد با اتفاقات داره، دیتابیس رو قفل نمیکنه بلکه یک تصویر ثابت به کوئری میده و مابقی کوئریهای دیگه اگه خوندن باشن رو باز میزاره جهت اجرا و کوئریهای نوشتن رو چک میکنه با روش (conflict detection) اگه تداخل باشه لغو و roll back میزنه و در غیر این صورت اجرا میشه، کوئریها رو به شکل سریالی اجرا میکنه و هیچ قفلی روی دیتابیس نمیزاره تو حالت partitioning به خوبی کار میکنه و مناسب کوئریهای سبک و پرفورمنس عالی برای اونها داره (پرفورمنس بشدت وابسته به رفتار مهندسی نرم افزار در پروژه می باشد) جالبه که در برخورد با conflict detection سخت برخورد نمیکنه (با استفاده از MVCC در پستگرس) تراکنشهارو در حد نیاز و کم بررسی میکنه و این عامل پرفورمنس داخلش هستش
یه نکته جالب هم بگم سریالی برخورد کردن با داده خودش یه مفهوم بزرگی هستش که کمک میکنه تا داده رو در یک ترد و یک پردازنده عملیات روش انجا بدیم ایده اصلی redis از این مفهوم و برپایه اون استوار هستش
@code_crafters
2PL
رویکرد با قفل کردن در دیتابیس عمل میکنه، این الگو بشدت بدبین هستش و هر وقت صورت بگیره دوتا قفل انجام میده بک قفل اشتراکی برای خوندن و بک قفل انحصاری برای نوشتن و تراکنشها رو در صف انتظار قرار میده تا زمانیکه قفل باز بشه (در صورت نیاز کل دیتابیس رو یکجا و به یک صورت قفل میکنه)، موجب کندی و تاخیر شدید در پاسخ به کوئریها میشه و دیتابیس رو از هرگونه عملی محروم میکنه تا کوئری فعال کننده قفل تموم بشه و دیتابیس رو آزاد کنه، تصور کنید که select for update رو روی کل موجودیت دیتابیس اجرا کردید، اما تمام شرایط مسابقه رو هندل میکنه کامل (phamtom read, lost update, write skew, dirty data)، این رویکرد هم کوئریها رو بصورت سریالی انجام میده (انگار که چند کوئری بزرگ و طولانی پشت سرهم اجرا شدن)
snapshot isolation
در رویکرد سطح ایزوله با repeatable read و فعال کردن اون (در اجرای هر کوئری یه تصویر ثابت در ابتدا به کوئری میدیم) ما مشکل phamtom read رو بر طرف میکنیم منتها با مشکل write skew روبرو بودیم، اگه در بدنه atomic بیایم از select for update استفاده کنیم مشکل write skew برطرف میشه منتها مشکل اساسی تر این هستش که تعارض رو فقط برای ردیف اعلام شده بر روی اون انجام میده نه کل دیتابیس و تداخل داده در ردیفهایی که قفل روی اونها صورت نگرفته شکل میگیره و write skew همچنان پابرجا هستش
serializable snapshot isolation
یا به اختصار SSI بهش میگیم، رویکرد خوشبینانه در برخورد با اتفاقات داره، دیتابیس رو قفل نمیکنه بلکه یک تصویر ثابت به کوئری میده و مابقی کوئریهای دیگه اگه خوندن باشن رو باز میزاره جهت اجرا و کوئریهای نوشتن رو چک میکنه با روش (conflict detection) اگه تداخل باشه لغو و roll back میزنه و در غیر این صورت اجرا میشه، کوئریها رو به شکل سریالی اجرا میکنه و هیچ قفلی روی دیتابیس نمیزاره تو حالت partitioning به خوبی کار میکنه و مناسب کوئریهای سبک و پرفورمنس عالی برای اونها داره (پرفورمنس بشدت وابسته به رفتار مهندسی نرم افزار در پروژه می باشد) جالبه که در برخورد با conflict detection سخت برخورد نمیکنه (با استفاده از MVCC در پستگرس) تراکنشهارو در حد نیاز و کم بررسی میکنه و این عامل پرفورمنس داخلش هستش
@code_crafters
❤7
فیلم نهنگ آرنوفسکی
آرنوفسکی یکی از کارگردانهای متفکر هستش و بشدت ذهن پویا و فعالی داره
داخل فیلم مدام و مدام آرنوفسکی یه داستانی رو بازگو میکنه که خیلی عمیق هستش
راجب ناخدایی که اتفاقی با یکنفر آشنا میشه و متوجه حضور یک نهنگ در دریا میشه و ناخدا با تصور اینکه با کشتن نهنگ زندگیش بهتر میشه اما غافل از اینکه کشتن نهنگ یعنی پایان زندگی خودش
چه چیزی تو ته این داستان نهفته که آرنوفسکی مدام و مدام تاییدش میکنه، وقتی زندگیت رو صرف چیزی میکنی (هر چیزی) در واقع داری زندگیت رو نابود میکنی، نمیسازیش
ته ماجرا میبینی به چیزی که میخواستی ممکنه رسیده باشی اما زندگیت رفته واقعا و برنمیگرده
این نهنگ رو میتونی به هر چیزی تشبیه کرد، پول، لذت، شادی، خونواده، عشق، انسانیت، تخصص، تحصیل، سفر و ...
واقعیت زندگی دردناکتر ازون چیزی هست که بخوای بابتش (یا حتی بابت همه چیزش از بین بره یا فدا کنی) عمر میگذره و در دوران پیری خسته میشی، از خود زندگی که نتونستی بهش برسی و پی ببری بهش
تمام زندگی ما در یک توهم بزرگ و عمیق فرو رفته و در غفلتی بزرگتر پیچیده شده
به نهنگ زندگیتون فکر کنید
آرنوفسکی یکی از کارگردانهای متفکر هستش و بشدت ذهن پویا و فعالی داره
داخل فیلم مدام و مدام آرنوفسکی یه داستانی رو بازگو میکنه که خیلی عمیق هستش
راجب ناخدایی که اتفاقی با یکنفر آشنا میشه و متوجه حضور یک نهنگ در دریا میشه و ناخدا با تصور اینکه با کشتن نهنگ زندگیش بهتر میشه اما غافل از اینکه کشتن نهنگ یعنی پایان زندگی خودش
چه چیزی تو ته این داستان نهفته که آرنوفسکی مدام و مدام تاییدش میکنه، وقتی زندگیت رو صرف چیزی میکنی (هر چیزی) در واقع داری زندگیت رو نابود میکنی، نمیسازیش
ته ماجرا میبینی به چیزی که میخواستی ممکنه رسیده باشی اما زندگیت رفته واقعا و برنمیگرده
این نهنگ رو میتونی به هر چیزی تشبیه کرد، پول، لذت، شادی، خونواده، عشق، انسانیت، تخصص، تحصیل، سفر و ...
واقعیت زندگی دردناکتر ازون چیزی هست که بخوای بابتش (یا حتی بابت همه چیزش از بین بره یا فدا کنی) عمر میگذره و در دوران پیری خسته میشی، از خود زندگی که نتونستی بهش برسی و پی ببری بهش
تمام زندگی ما در یک توهم بزرگ و عمیق فرو رفته و در غفلتی بزرگتر پیچیده شده
به نهنگ زندگیتون فکر کنید
👍6
Kubernetes up and running
کوبرنتیز یک orchestrator اوپن سورس است که ابتدا توسط گوگل توسعه یافت و معرفی شد. تا سال ۲۰۱۴ یکی از معروفترین ابزارهای open source در مارکت شده بود.
کوبرنتیز ثابت کرد که میتواند سیستمهای توزیع شده را در تمام مقیاسها مدیریت کند. از یک کلاستر رزبریپای تا یک دیتاسنتر مجهز و حرفهای.
در دنیای distributed systems تمامی سرویسهای ما باید reliable و scaleable باشند. اما این به چه معنی است؟
یک برنامه میکروسرویس را درنظر بگیریم که دارای سرویسهای مختلفی است. کوبرنتیز وظیفه orchestrate کردن این پروژه را بر عهده گرفته است.
ما باید مطمئن باشیم که تمامی درخواستهای ما در این شبکه بین سرویسها جابجا میشود. پس در این بخش نیاز داریم که این شبکه قابل اعتماد(reliable) باشد.
اما این به تنهایی کافی نیست, ممکن است بخواهیم این سیستم را گسترس دهیم و به اصطلاح scale کنیم. کوبرنتیز این امکان را نیز برای ما مهیا کرده است.
مردم دلایل مختلفی برای استفاده از کوبرنتیز دارند, برای مثال:
• Development Velocity
• Abstracting your infrastructure
• Efficiency
• Cloud native ecosystem
در این پست میخواهیم اهمیت توسعه سریع با کوبرنتیز را مرور کنیم.
سالها پیش که نرمافزارها روی CD ها ذخیره و به فروش میرسیدند, چندان مهم نبود که اپدیتها در چه زمانی ریلیز میشوند, اما اکنون که برخی محصولات, به صورت روزانه اپدیت میدهند, بسیار مهم است که با کمترین downtime نسخه جدید را برای کاربران عرضه کنیم.
کوبرنتیز باعث میشود دیپلوی کردن اسانتر شود.
تصور کنید برای یک دیپلوی ساده, باید یکی از راه های زیر را دنبال کنید:
⁃ وارد کانتینر شوید و کد جدید را pull کنید
⁃ ایمیج را build کنید و کانترنر قدیمی را stop و با ایمیج جدید یک کانتینر بسازید
هردوی این کارها باعث میشود که ما downtime زیادی داشته باشیم. حال سناریو زیر را تصور کنید:
کوبرنتیز یک instance جدید با کد جدید بسازد و وقتی که مطمئن شدیم که کد درست بالا امده, با اینستنس قبلی جابجا کنیم.
جالب نیست؟ بنظر من که خیلی جالبه!
یکی دیگر از قابلیتهای جذاب کوبرنتیز self healing بودن آن است.
کوبرنتیز مدام تلاش میکند که درصورت بروز هرگونه مشکل, سرویس شما down نشود.
برای مثال در گذشته باید افرادی استخدام میشدند که هرگاه یک alert دریافت میکردند, باید سریعا سرویس را repair میکردند, اما الان کوبرنتیز باعث شده که دیگر نیازی به این افراد نداشته باشیم.
در این درس ۲ مورد از قابلیتهای کوبرنتیز را خواندیم. در درس های بعد کم کم به شناخت کوبرنتیز و کامپوننتهای داخلی آن میپردازیم.
#kubernetes_up_and_running
@Code_Crafters
کوبرنتیز یک orchestrator اوپن سورس است که ابتدا توسط گوگل توسعه یافت و معرفی شد. تا سال ۲۰۱۴ یکی از معروفترین ابزارهای open source در مارکت شده بود.
کوبرنتیز ثابت کرد که میتواند سیستمهای توزیع شده را در تمام مقیاسها مدیریت کند. از یک کلاستر رزبریپای تا یک دیتاسنتر مجهز و حرفهای.
در دنیای distributed systems تمامی سرویسهای ما باید reliable و scaleable باشند. اما این به چه معنی است؟
یک برنامه میکروسرویس را درنظر بگیریم که دارای سرویسهای مختلفی است. کوبرنتیز وظیفه orchestrate کردن این پروژه را بر عهده گرفته است.
ما باید مطمئن باشیم که تمامی درخواستهای ما در این شبکه بین سرویسها جابجا میشود. پس در این بخش نیاز داریم که این شبکه قابل اعتماد(reliable) باشد.
اما این به تنهایی کافی نیست, ممکن است بخواهیم این سیستم را گسترس دهیم و به اصطلاح scale کنیم. کوبرنتیز این امکان را نیز برای ما مهیا کرده است.
مردم دلایل مختلفی برای استفاده از کوبرنتیز دارند, برای مثال:
• Development Velocity
• Abstracting your infrastructure
• Efficiency
• Cloud native ecosystem
در این پست میخواهیم اهمیت توسعه سریع با کوبرنتیز را مرور کنیم.
سالها پیش که نرمافزارها روی CD ها ذخیره و به فروش میرسیدند, چندان مهم نبود که اپدیتها در چه زمانی ریلیز میشوند, اما اکنون که برخی محصولات, به صورت روزانه اپدیت میدهند, بسیار مهم است که با کمترین downtime نسخه جدید را برای کاربران عرضه کنیم.
کوبرنتیز باعث میشود دیپلوی کردن اسانتر شود.
تصور کنید برای یک دیپلوی ساده, باید یکی از راه های زیر را دنبال کنید:
⁃ وارد کانتینر شوید و کد جدید را pull کنید
⁃ ایمیج را build کنید و کانترنر قدیمی را stop و با ایمیج جدید یک کانتینر بسازید
هردوی این کارها باعث میشود که ما downtime زیادی داشته باشیم. حال سناریو زیر را تصور کنید:
کوبرنتیز یک instance جدید با کد جدید بسازد و وقتی که مطمئن شدیم که کد درست بالا امده, با اینستنس قبلی جابجا کنیم.
جالب نیست؟ بنظر من که خیلی جالبه!
یکی دیگر از قابلیتهای جذاب کوبرنتیز self healing بودن آن است.
کوبرنتیز مدام تلاش میکند که درصورت بروز هرگونه مشکل, سرویس شما down نشود.
برای مثال در گذشته باید افرادی استخدام میشدند که هرگاه یک alert دریافت میکردند, باید سریعا سرویس را repair میکردند, اما الان کوبرنتیز باعث شده که دیگر نیازی به این افراد نداشته باشیم.
در این درس ۲ مورد از قابلیتهای کوبرنتیز را خواندیم. در درس های بعد کم کم به شناخت کوبرنتیز و کامپوننتهای داخلی آن میپردازیم.
#kubernetes_up_and_running
@Code_Crafters
❤8
خب برید راجب socketify بخونید و بعدا هرکسی گفت پایتون واسه وب ضعیف و کند هستش، جواب دندان شکن بهش بدید
در کنارش هم تاسف برای دوستانی که با حرف بقیه در خصوص کند بودن فریمورکهای پایتون، رفتن سمت گو
#موقت
در کنارش هم تاسف برای دوستانی که با حرف بقیه در خصوص کند بودن فریمورکهای پایتون، رفتن سمت گو
#موقت
🔥13👎6❤1👍1
Kubernetes up and running - Lesson 2
هنگامی که محصول شما رشد میکند, شما باید هم محصول و هم تیم توسعه خود را scale کنید. خوشبختانه کوبرنتیز این قابلیت را به ما میدهد که به راحتی بتوانیم محصول خود را scale کنیم. اما چه چیزی باعث میشود که scale کردن در کوبرنتیز اینقدر ساده باشد؟
به سبب وجود داشتن معماری decoupled, کامپوننتها مستقل هستند و به کمک api و service load balancer ها با هم ارتباط ایجاد میکنند.
کوبرنتیز به شما این اجازه را میدهد که از یک کانتینر چندین replica داشته باشید که برای اضافه یا کم کردن آن نیاز دارید فقط یک عدد را در فایل کانفیگ تغییر دهید. حتی میتوانید این تصمیم گیری را بر عهده کوبرنتیز بگذارید که چند رپلیکا از اپلیکیشن داشته باشیم.
کوبرنتیز نه تنها محصول شما را scale میکند, بلکه میتواند تیم شما را نیز scale کند!
تحقیقات نشان داده است که یک تیم ایدهال باید ۶ الی ۸ عضو داشته باشد. به این تیمها “two pizza team” نیز میگویند.
این تیمها تصمیمات راحتتری میگیرند و عموما تسکها سریعتر deliver میشوند چرا که کانفلیکتهای کمتری در کد ایجاد میشود.
اگر یک کدبیس بزرگ داشته باشیم, قطعا هنگامی که کد را توسعه میدهیم به کانفلیکتهای زیادی برمیخوریم. اما کوبرنتیز به کمک تیمها امده و آنها را به توسعه با معماری میکروسرویس تشویق کرده.
کوبرنتیز برای توسعه میکروسرویس ابسترکشن و api های زیر را ارائه میدهد:
⁃ پاد (Pod): یک واحد توسعه که در خود یک یا چند کانتینر را جای میدهد
⁃ سرویسها: سرویسها به اما اجازه load balancing و ایزولیشن بین سرویسها را ارائه میدهد
⁃ نیماسپیسها: نیماسپیسها سطح دسترسی یک سرویس را تعیین میکند. برای مثال میتوانیم تعیین کنیم کدام سرویسها میتوانند به یک سرویس خاص دسترسی داشته باشند.
⁃ اینگرس (Ingress): این آبجکتها میتوانند چندین سرویس را به صورت یک Api ارائه دهند.
این دو درس تنها مقدمهای بر دنیای کوبرنتیز بوده است. در درسهای بعدی ما به مسائل پایهای و سپس عمیقتر کوبرنتیز میپردازیم.
#kubernetes_up_and_running
@Code_Crafters
هنگامی که محصول شما رشد میکند, شما باید هم محصول و هم تیم توسعه خود را scale کنید. خوشبختانه کوبرنتیز این قابلیت را به ما میدهد که به راحتی بتوانیم محصول خود را scale کنیم. اما چه چیزی باعث میشود که scale کردن در کوبرنتیز اینقدر ساده باشد؟
به سبب وجود داشتن معماری decoupled, کامپوننتها مستقل هستند و به کمک api و service load balancer ها با هم ارتباط ایجاد میکنند.
کوبرنتیز به شما این اجازه را میدهد که از یک کانتینر چندین replica داشته باشید که برای اضافه یا کم کردن آن نیاز دارید فقط یک عدد را در فایل کانفیگ تغییر دهید. حتی میتوانید این تصمیم گیری را بر عهده کوبرنتیز بگذارید که چند رپلیکا از اپلیکیشن داشته باشیم.
کوبرنتیز نه تنها محصول شما را scale میکند, بلکه میتواند تیم شما را نیز scale کند!
تحقیقات نشان داده است که یک تیم ایدهال باید ۶ الی ۸ عضو داشته باشد. به این تیمها “two pizza team” نیز میگویند.
این تیمها تصمیمات راحتتری میگیرند و عموما تسکها سریعتر deliver میشوند چرا که کانفلیکتهای کمتری در کد ایجاد میشود.
اگر یک کدبیس بزرگ داشته باشیم, قطعا هنگامی که کد را توسعه میدهیم به کانفلیکتهای زیادی برمیخوریم. اما کوبرنتیز به کمک تیمها امده و آنها را به توسعه با معماری میکروسرویس تشویق کرده.
کوبرنتیز برای توسعه میکروسرویس ابسترکشن و api های زیر را ارائه میدهد:
⁃ پاد (Pod): یک واحد توسعه که در خود یک یا چند کانتینر را جای میدهد
⁃ سرویسها: سرویسها به اما اجازه load balancing و ایزولیشن بین سرویسها را ارائه میدهد
⁃ نیماسپیسها: نیماسپیسها سطح دسترسی یک سرویس را تعیین میکند. برای مثال میتوانیم تعیین کنیم کدام سرویسها میتوانند به یک سرویس خاص دسترسی داشته باشند.
⁃ اینگرس (Ingress): این آبجکتها میتوانند چندین سرویس را به صورت یک Api ارائه دهند.
این دو درس تنها مقدمهای بر دنیای کوبرنتیز بوده است. در درسهای بعدی ما به مسائل پایهای و سپس عمیقتر کوبرنتیز میپردازیم.
#kubernetes_up_and_running
@Code_Crafters
❤7
درک یک پایان
رمانی به ظاهر ساده و کوتاه اما بشدت پیچیده و سنگین که محتوی فلسفه و روانشناختی و تحلیلی دارد
اخیرا به این فکر و باور بودم که 99 درصد زندگی یک انسان رو توهم تشکیل میدهد نه بیشتر، سعی داشتم با این دیدگاهم مقابله کنم
بطور اتفاقی با این کتاب آشنا شدم که صحه بر باورم گذاشت، ما در تعریف آگاهی به چند مورد اشاره میکنیم: گذشته فرد، سلامت فکری و روانی، درک او از محیط اطرافش و آنچه رخ میده
این کتاب با یک داستان ساده هر سه مورد ذکر شده راجب آگاهی رو نقض میکنه برای یک انسان و با این شرایط انسان رو وادار میکنه که نسبت به آنچه در زندگیش هست بازنگری کنه و اینکه با این اوصاف آیا انسان میتونه به پذیرش نسبت به مسائل برسه یا نه
آیا ما واقعا مسئولیم؟؟؟
@code_crafters
رمانی به ظاهر ساده و کوتاه اما بشدت پیچیده و سنگین که محتوی فلسفه و روانشناختی و تحلیلی دارد
اخیرا به این فکر و باور بودم که 99 درصد زندگی یک انسان رو توهم تشکیل میدهد نه بیشتر، سعی داشتم با این دیدگاهم مقابله کنم
بطور اتفاقی با این کتاب آشنا شدم که صحه بر باورم گذاشت، ما در تعریف آگاهی به چند مورد اشاره میکنیم: گذشته فرد، سلامت فکری و روانی، درک او از محیط اطرافش و آنچه رخ میده
این کتاب با یک داستان ساده هر سه مورد ذکر شده راجب آگاهی رو نقض میکنه برای یک انسان و با این شرایط انسان رو وادار میکنه که نسبت به آنچه در زندگیش هست بازنگری کنه و اینکه با این اوصاف آیا انسان میتونه به پذیرش نسبت به مسائل برسه یا نه
آیا ما واقعا مسئولیم؟؟؟
@code_crafters
❤4
Kubernetes in action - lesson 3
کوبرنتیز یک پلتفرم برای ساخت, دیپلوی و منیج کردن یک برنامه توزیع شده است. این برنامهها در سایز و اشکال مختلفی میتوانند باشند که روی یک یا چند سیستم به صورتهای متفاوت به اجرا درامدند. تمامی این برنامهها ورودیهایی را دریافت میکنند و میتوانند خروجیهایی را ارسال کنند. قبل از اینکه وارد این موضوع شویم, ابتدا باید بدانیم که چطور میتوانیم یک کانتینر اپلیکیشن بسازیم تا بتوانیم آن را در بستر این محیط به اجرا دربیاوریم.
برنامهها عموما ترکیبی از کتابخانهها و سورس کدها هستند که در مواقع مختلف روی کتابخانههای سیستمعاملی مانند libc و libssl نیز تکیه میکنند. این دیپندنسیها میتوانند گاهی مشکلاتی را بوجود بیاورند. برای مثال ممکن است یک کتابخانه روی لپتاپ برنامهنویس نصب باشد اما روی سرور پروداکشن این کتابخانه نصب نباشد. آنگاه به مشکلات مختلفی بر میخوریم.
این راه قدیمی که باید کل کد بیس روی یک ماشین با یک سیستمعامل مشخص و کتابخانههایی با ورژنهای مشخص اجرا شود, اکنون دیگر منقضی شده است. چرا که در تیمهای بزرگ این رویکرد تنها پیچیدگی را زیاد کرده بود.
یکی از راههایی که میتوانیم در مقابل این مشکل بایستیم این است که کل برنامه را تبدیل به یک package کنیم و آن را یکجایی push کنیم تا دیگران آن را pull کنند و از آن استفاده کنند. Docker یکی از محبوبترین ابزارها برای این کار است. با داکر میتوانیم یک ایمیج executable بسازیم و سپس آن را روی یک رجیستری push کنیم تا دیگران بتوانند از آن استفاده کنند.
پس درواقع container image ها یک مجموعهای از سورس کد و دیپندنسیهای آن هستند که در لایههای مختلفی از یک ایمیج ذخیره شدهاند. معروفترین فرمت این ایمیجها, فرمت ایمیجهای داکر است که توسط OCI, استداندارد سازی شده است.
خوشبختانه کوبرنتیز از فرمتهای docker image format و OCI ساپورت میکند.
ایمیج کانتینرها تنها یک فایل نیستند, بلکه آنها پوینتری به فایلهای دیگه هستند. ایمیجها از لایههایی تشکیل شدهاند که این لایهها ممکن است گاهی مدتها پیش توسعه یافته باشد.
ایمیجها معمولا با یک configuration file اجرا میشوند که در آن تنظیمات مربوط به نتورک, entrypoint command و syscall restriction کانفیگ میشوند.
کانتینرها به دو دسته تقسیم میشوند.
1- system containers
2- application containers
دسته اول به کانتینرهایی میگوییم که یک سیستمعامل کامل را نصب دارد که میتوانیم در آن اقدامات زیادی انجام دهیم. اما این کانتینرها منابع بیشتری مصرف میکنند, پس برنامهنویسها به دنبال یک راه بهتر و سبک تر رفتند و application containerها را پیدا کردند. این کانتینرها معمولا ایمیجهای سبکتری دارند. چرا که این کانتینرها با یک سیستمعامل پایهای و سبک بوت میشوند و تمرکز آنها بیشتر روی ابزاری است که توسعه میدهند.
اما یک ایمیج را چگونه میتوانیم بهینه کنیم؟
۱- فایلهای اضافی را در .dockerignore قرار دهیم.
سناریو زیر را درنظر بگیرید:
Layer 1: Contain a big file
Layer 2: Removes the big file
در سناریو بالا, خیلی بهتر میشد اگر از همان اول Big file را داخل .dockerignore قرار دهیم.
۲- به ترتیب اجرای دستورات دقت کنید.
به سناریوی زیر دقت کنید:
Dockerfile A:
Install big linux dependencies
Copy requirements.txt
Install reuirements
Dockerfile B:
Copy requirements.txt
Install reuirements
Install big linux dependencies
دو ایمیج بالا دقیقا یک کار را انجام میدهند, اما در ایمیج دومی هرگاه requirements.txt تغییر میکند, ما دیپندنسیهای سنگین را از نو نصب میکنیم! پس بهتر است این لایههای سنگین را در ابتدای فایل ایجاد کنیم.
در درسهای بعد به مسائلی همچون multistage image build میپردازیم.
#kubernetes_up_and_running
@Code_Crafters
کوبرنتیز یک پلتفرم برای ساخت, دیپلوی و منیج کردن یک برنامه توزیع شده است. این برنامهها در سایز و اشکال مختلفی میتوانند باشند که روی یک یا چند سیستم به صورتهای متفاوت به اجرا درامدند. تمامی این برنامهها ورودیهایی را دریافت میکنند و میتوانند خروجیهایی را ارسال کنند. قبل از اینکه وارد این موضوع شویم, ابتدا باید بدانیم که چطور میتوانیم یک کانتینر اپلیکیشن بسازیم تا بتوانیم آن را در بستر این محیط به اجرا دربیاوریم.
برنامهها عموما ترکیبی از کتابخانهها و سورس کدها هستند که در مواقع مختلف روی کتابخانههای سیستمعاملی مانند libc و libssl نیز تکیه میکنند. این دیپندنسیها میتوانند گاهی مشکلاتی را بوجود بیاورند. برای مثال ممکن است یک کتابخانه روی لپتاپ برنامهنویس نصب باشد اما روی سرور پروداکشن این کتابخانه نصب نباشد. آنگاه به مشکلات مختلفی بر میخوریم.
این راه قدیمی که باید کل کد بیس روی یک ماشین با یک سیستمعامل مشخص و کتابخانههایی با ورژنهای مشخص اجرا شود, اکنون دیگر منقضی شده است. چرا که در تیمهای بزرگ این رویکرد تنها پیچیدگی را زیاد کرده بود.
یکی از راههایی که میتوانیم در مقابل این مشکل بایستیم این است که کل برنامه را تبدیل به یک package کنیم و آن را یکجایی push کنیم تا دیگران آن را pull کنند و از آن استفاده کنند. Docker یکی از محبوبترین ابزارها برای این کار است. با داکر میتوانیم یک ایمیج executable بسازیم و سپس آن را روی یک رجیستری push کنیم تا دیگران بتوانند از آن استفاده کنند.
پس درواقع container image ها یک مجموعهای از سورس کد و دیپندنسیهای آن هستند که در لایههای مختلفی از یک ایمیج ذخیره شدهاند. معروفترین فرمت این ایمیجها, فرمت ایمیجهای داکر است که توسط OCI, استداندارد سازی شده است.
خوشبختانه کوبرنتیز از فرمتهای docker image format و OCI ساپورت میکند.
ایمیج کانتینرها تنها یک فایل نیستند, بلکه آنها پوینتری به فایلهای دیگه هستند. ایمیجها از لایههایی تشکیل شدهاند که این لایهها ممکن است گاهی مدتها پیش توسعه یافته باشد.
ایمیجها معمولا با یک configuration file اجرا میشوند که در آن تنظیمات مربوط به نتورک, entrypoint command و syscall restriction کانفیگ میشوند.
کانتینرها به دو دسته تقسیم میشوند.
1- system containers
2- application containers
دسته اول به کانتینرهایی میگوییم که یک سیستمعامل کامل را نصب دارد که میتوانیم در آن اقدامات زیادی انجام دهیم. اما این کانتینرها منابع بیشتری مصرف میکنند, پس برنامهنویسها به دنبال یک راه بهتر و سبک تر رفتند و application containerها را پیدا کردند. این کانتینرها معمولا ایمیجهای سبکتری دارند. چرا که این کانتینرها با یک سیستمعامل پایهای و سبک بوت میشوند و تمرکز آنها بیشتر روی ابزاری است که توسعه میدهند.
اما یک ایمیج را چگونه میتوانیم بهینه کنیم؟
۱- فایلهای اضافی را در .dockerignore قرار دهیم.
سناریو زیر را درنظر بگیرید:
Layer 1: Contain a big file
Layer 2: Removes the big file
در سناریو بالا, خیلی بهتر میشد اگر از همان اول Big file را داخل .dockerignore قرار دهیم.
۲- به ترتیب اجرای دستورات دقت کنید.
به سناریوی زیر دقت کنید:
Dockerfile A:
Install big linux dependencies
Copy requirements.txt
Install reuirements
Dockerfile B:
Copy requirements.txt
Install reuirements
Install big linux dependencies
دو ایمیج بالا دقیقا یک کار را انجام میدهند, اما در ایمیج دومی هرگاه requirements.txt تغییر میکند, ما دیپندنسیهای سنگین را از نو نصب میکنیم! پس بهتر است این لایههای سنگین را در ابتدای فایل ایجاد کنیم.
در درسهای بعد به مسائلی همچون multistage image build میپردازیم.
#kubernetes_up_and_running
@Code_Crafters
❤6