> سلام :) این ترجمه فارسی از یک منبع انگلیسی زبان هست. هدف از این ترجمه کمک به کسانی است که تا حدودی با زبان انگلیسی مشکل دارند( تا بتونن از محتویات آموزشی اون استفاده کنند). با این حال، اگر در زمینه برنامه نویسی و حوزه کامپیوتر فعالیت میکنید حتما به دنبال اون باشید که توانایی خودتون رو در مطالعه متنهای انگلیسی تقویت کنید. آخر هر بخش سعی کردم ترجمه اصطلاحات لازم رو بیارم که کمکی کرده باشم در یادگیری شما.
> در ترجمه این متن، سعی کردم که مفهوم رو منتقل کنم و از ترجمه کلمه به کلمه، که ممکنه باعث پیچیدگی بشه، خودداری کردم. با این حال در ادامه نحوه همکاری مشخص شده. خوشحال میشم کمک کنید تا این منبع رو به خوبی برای هم زبونای خودمون آماده کنیم. ممنون :)
<palign="center">
<imgsrc="http://i.imgur.com/jj3A5N8.png">
<br/>
</p>
## هدف
> یادبگیریم که چه طوری سیستم های مقیاس-بزرگ طراحی کنیم
> برای مصاحبه طراحی سیستم آماده بشیم
### یادبگیریم که چه طوری سیستم های مقیاس-بزرگ طراحی کنیم
اینکه چه طوری یک سیستم مقایس-بزرگ را طراحی کنیم کمک میکنه که یه مهندس بهتری بشیم. مبحث طراحی سیستم، یک بحث گستردهای هست و برای این موضوع **منابع زیادی داخل وب پراکنده وجود داره** . این مخزن یک مجموعهی منظم و ساختاریافته از منابعی هست که به شما کمک میکنه، یاد بگیرید چهطوری سیستمهای بسازید که بتونه در مقایس بزرگ کار کنه.
> System Design: طراحی سیستم, Large-Scale: مقیاس-بزرگ, Repository | Repo. : مخزن
### از جامعه متنباز یادبگیریم
این پروژه متن باز در حال کامل شدن هست و در حقیقت یک پیشنویسه.
از [کمک](#همکاری) به این پروژه استقبال میشه
> Open-Source: متن باز, Contributing : کمک کردن
### برای مصاحبه طراحی سیستم آماده شویم
علاوهبر آزمون کدنویسی در مصاحبه، در بسیاری از شرکتهای تکنولوژی طراحی سیستم یکی از **قسمتهای لازم** در فرآیند **مصاحبه فنی** است.
**سوالهای مصاحبه طراحی سیستم را تمرین کنید** و جوابهاتون رو با **راهکارهای نمونه** داده شده **مقایسه** کنید: توضیحات،کد و دیاگرامها
موضوعات بیشتر برای آمادگی در مصاحبه:
* [راهنمای مطالعه](#راهنمای-مطالعه)
* [چگونه به سوالات طراحی سیستم در مصاحبه پاسخ بدیم؟](#نحوه-برخورد-با-سوالات-مصاحبه-طراحی-سیستم)
محتویاتی که نیاز به پرداختن بیشتر و اضافه کردن مطلب دارند در بخش [تحت توسعه](#تحت-توسعه) هستند. قسمت قوانین همکاری رو ببینید
> [قوانین همکاری](CONTRIBUTING.md).
## فهرست موضوعات طراحی سیستم
> خلاصهای از مباحث متنوع طراحی سیستم به همراه مزیتها و معایت آنها. در حقیقت هرچیز یک تریدآف یا به عبارتی تعادلی بین مزایا و معایب هست. هر بخش شامل لینکهایی به منابعی هستند که به طور مفصلتر به موضوع مربوطه پرداختن.
بیشتر کاندیداهای باتجربه ازشون انتظار میره که بیشتر در مورد طراحی سیستم بدونن. معمارها یا تیم لیدرها ممکنه ازشون انتظار بره که از آدمهای معمولی بیشتر بدونن. توی کمپانیهای شاخ ممکنه که چند دور مصاحبه برای طراحی داشته باشند
خیلی کلی شروع کنید و بعد توی یه زمینهای برید و عمیق بشید. این آموزش باعث میشه که شما در مورد مباحث مختلف طراحی سیستم یکم دانش کسب کنید. آموزشهایی که در ادامه میاد رو بر اساس موارد مختلفی مثل زمانی که دارید، تجربهای که دارید، سمتی که دارید براش مصاحبه میرید و اینکه چه کمپانی دارید میرید تنظیم کنید.
* **اگر زمان مصاحبه کوتاهی دارید** - هدفتون باشه رو این که به صورت **موضوعی** مباحث طراحی سیستم رو بخونید از اینجا. برید سراغ حل **بعضی** از سوالات مصاحبه.
* **اگر زمان مصاحبتون متوسطه** - هدفتون باشه که هم به صورت **موضوعی** و هم **یکم عمقی** مباحث رو پیگیری کنید.توی این مرحله **تعداد زیادی** مساله حل کنید..
* **اگرزمان مصاحبتون زیاده** - هدفتون باشه که به صورت **موضوعی** و با **عمق زیاد** به مباحث طراحی سیستم بپردازید. سعی کنید تا میتویند سوالات بیشتری حل کنید.
| برای درک کلی از این که سیستمها به چه صورتی کار میکنن به قسمت [فهرست موضوعات طراحی سیستم](#فهرست-موضوعات-طراحی-سیستم) مراجعه کنید | :+1: | :+1: | :+1: |
| براساس کمپانی که قصد دارید برید مصاحبه، پستهای [وبلاگ مهندسی](#وبلاگهای-مهندسی-کمپانیها) اون رو مطالعه کنید | :+1: | :+1: | :+1: |
| قسمت [معماری دنیای واقعی](#معماری-های-دنیای-واقعی) را به خوبی مطالعه کنید | :+1: | :+1: | :+1: |
| به طور کامل روی قسمت [سوالات مصاحبه طراحی سیستم با پاسخ](#سوالات-مصاحبه-طراحی-سیستم-همراه-با-پاسخ) کارکنید | بعضی قسمتاش | قسمت زیادش | تا اونجایی که میشه |
| به طور کامل روی قسمت [سوالات مصاحبه طراحی شئ گرا با پاسخ](#سوالات-مصاحبه-طراحی-شئ-گرا-به-همراه-پاسخ) کار کنید | بعضی قسمتاش | قسمت زیادش | تا اونجایی که میشه |
مصاحبه طراحی سیستم شبیه یه مکالمهای هست که جواب قطعی و مشخصی نداره. انتظار میره با جوابهایی که میدید روندش رو مشخص کنید. یعنی این که با جوابش صرفا یک بله یا خیر نیست و با جواب شما روند مصاحبه تغییر میکنه
شما میتونید از روشی که در ادامه میاد برای پیشبرد روند مصاحبه استفاده کنید. برای این کار به طور کامل روی قسمت [سوالات مصاحبه طراحی سیستم با پاسخ](#سوالات-مصاحبه-طراحی-سیستم-همراه-با-پاسخ) کار کنید البته به صورت قدمهایی که در ادامه آورده شدن
نیازمندیها و اسکوپ مسالهای که قراره حل کنید رو دربیارید. یه سری سوال بپرسید تا بیاد دستتون که محدودیتها و کاربردهای این سیستم چیه و بعد روی فرضیات بحث کنید.
- چه کسی قراره از این سیستم استفاده کنه؟
- اون کسایی که استفاده میکنن، چطوری قرار استفاده کنند؟
- چقدر کاربر توی این سیستم هست؟
- سیستم چی کار میکنه؟
- ورودی و خروجی سیستم چیا هستن؟
- چقدر داده قراره که سیستم هندل کند؟
- چه تعداد درخواست در ثانیه انتظار داریم؟
- چه نسبتی از خوندن به نوشتن مورد انتظارمونه؟
### قدم ۲: یک طراحی سطح بالا درست کنید
یه طراحی سطح بالا و کلی از اجزای مهم بکشید
- اجزای اصلی و ارتباطشون رو بکشید
- ایده هاتون رو باهاش تایید کنید و بررسی کنید ببینید درسته یا نه
سراغ جزئیات بیشتر، برای هر المان اصلیتر و مهم، برید. به عنوان مثال اگر ازتون خواستن که [یک سرویس برای کوتاه کردن لینک](#طراحی-سرویس-کوتاه-کردن-لینک) طراحی کنید، موارد زیر رو بررسی کنید:
روشها و ترید-آف های محتمل رو مورد بحث و بررسی قرار بدید. هر چیزی یک ترید-آف هست. مشکلات و باتلنک ها رو با استفاده از [اصول طراحی سیستم های مقایس پذیر](#فهرست-موضوعات-طراحی-سیستم) مورد بررسی و چالش قرار بدید و بیان کنید.
در قدم بعدی، ما به ترید-آف های سطح بالاتری میپردازیم مانند:
* **کارایی** دربرابر **مقایس پذیری**
* **تاخیر** دربرابر **بازدهی**
* **دسترسی پذیری** دربرابر **یکپارچگی**
یادتون باشه که **همه چیز یک ترید-آف هست**
در ادامه ما به مباحث زیر میپردازیم:
DNS, CDNs, load balancers.
## کارایی در برابر مقایس پذیری
یک سرویس رو **مقایس پذیر** میگیم وقتی که متناسب با منابعی که به سیستم اضافه میکنیم **کارایی** اون هم افزایش پیدا بکنه. به طورکلی منظور از افزایش کارایی اینه که تعداد کاربیشتری رو انجام بدیم اما ممکنه که بتونه کارهای باحجم بزرگتر هم بتونه هندل کنه مثل زمانی که مجموعه داده هامون زیاد میشه و رشد میکنه<sup><ahref=http://www.allthingsdistributed.com/2006/03/a_word_on_scalability.html>1</a></sup>
یه روش دیگه برای نگاه به قضیه کارایی و مقایس پذیری به صورت زیر هست:
* اگر شما مشکل کارایی دارید، سیستم شما برای یک کاربر کند کار میکنه
* اگر شما مشکل مقیاس پذیری دارید، سیستم شما برای یک کاربر سریعه ولی برای بار زیاد کند عمل میکنه
### منابع برای مطالعه بیشتر
* [A word on scalability](http://www.allthingsdistributed.com/2006/03/a_word_on_scalability.html)
**تاخیر** زمانی هست که باید *کاری* انجام بشه یا نتیجهای ایجاد بشه. **بازدهی** میزان تعداد همین کارها هست که باید توی یک واحد زمانی انجام بشه.
به طور کلی شما باید برای **بیشترین بازدهی** به همراه **تاخیر قابل قبول** برنامه ریزی کنید.
### منابع برای مطالعه بیشتر
* [Understanding latency vs throughput](https://community.cadence.com/cadence_blogs_8/b/sd/archive/2010/09/13/understanding-latency-vs-throughput)
## دسترس پذیری دربرابر یکپارچگی
### CAP تئوری
<palign="center">
<imgsrc="http://i.imgur.com/bgLMI2u.png">
<br/>
<i><ahref=http://robertgreiner.com/2014/08/cap-theorem-revisited>Source: CAP theorem revisited</a></i>
</p>
در سیستمهای توزیع شده کامپیوتری شما تنها میتونید که ۲ تا از گارانتیهای زیر رو تضمین کنید:
* **یکپارچگی** - هر عملیات خواندن نزدیکترین دادهای که تازه نوشته شده رو میگیره یا با خطا مواجه میشه
* **دسترس پذیری** - هر درخواست یک پاسخ میگیره، بدون هیچ تضمینی که جدیدترین نسخه از اطلاعات رو بگیره.
* **تحمل پارتیشن** - سیستم میتونه به عملیات خودش ادامه علی رغم اینکه به خاطر خطاهای شبکه مجبور به پارتیشن بنده شده باشه
*شبکه ها قابل اتکا نیستن، بنابریان لازمه که شما تحمل پارتیشن رو پشتیبانی کنید. بنابراین باید بین یکپارچگی و دسترس پذیری یک ترید-آف انجام بدیدی و یکی رو انتخاب کنید*
انتظار برای گرفتن جواب از یک نود پارتیشن شده ممکنه باعث بشه تا تایم-اوت بگیریم. این مدل یک انتخاب مناسبه اگر سیستم شما نیاز داره که به صورت اتمیک بخونه و بنویسیه.
پاسخهایی که دریافت میشه جدیدترین نسخه از داده روی اون نود رو برمیگردونه. نوشتن ممکنه نیاز به زمان داشته باشه تا در کل سیستم اعمال بشه
این مدل انتخاب خوبیه اگر شما نیاز به [یکپارچگی موکول](#یکپارچگی-موکول) نیاز دارید یا زمانی که سیستم نیاز داره که مستقل از خطاهای خارج از خودش به علمکردش ادامه بده
* [A plain english introduction to CAP theorem](http://ksat.me/a-plain-english-introduction-to-cap-theorem/)
* [CAP FAQ](https://github.com/henryr/cap-faq)
## الگوهای یکپارچگی
زمانی که تعدادی کپی از دادههای یکسان داریم، یک سری انتخاب داریم که چطوری کلاینتها رو سینکرون نگه داریم تا همه یک نمای یکسان از داده داشته باشند. با توجه به تعریف یکپارچگی از [تئوری کپ](#CAP-تئوری) - هر عملیات خوندن داده نزدیک ترین نسخه از داده نوشته شده رو میگیره یا خطا میگیره.
### یکپارچگی ضعیف
بعد از این که یک عملیات نوشتن انجام شد، عملیات خوندن ممکنه دیده بشه یا نشه. بهترین روش برای خوندن انتخاب میشه.
این روش در سیستمهای نظیر مِم-کش دیده میشه. یکپارچگی ضعیف در سیستمهای با نیاز بلادرنگ نظیر وویپ، ویدیو چت و بازیهای بلادرنگ چندنفره کاربرد داره. برای مثال، اگر شما پشت تلفن باشید و چند ثانیه ارتباط قطع بشه و بعد دوباره وصل بشید، اون چیزی که گفته شده رو دیگه از دست دادید.
### یکپارچگی موکول
بعد از یک عملیات نوشتن، عملیاتهای خوندن معمولا در میزان چند میلی ثانیه میتونن اونو ببینن. داده به صورت ناهمگام در جاهای دیگه کپی میشه
این روش در سیستمهایی نظیر دی-اِن-اِس و ایمیل دیده میشه. این مدل در سیستمهای با دسترس پذیری بالا به خوبی کار میکنه.
### یکپارچگی قوی
بعد از عملیات نوشتن، عملیاتهای خوندن اونو میبینن. داده به صورت همگام کپی میشود.
این روش معمولا در فایل سیستمها و مدیریت پایگاه دادهرابطهای دیده میشه. در سیستمهایی که نیاز به تراکنش دارند این مدل به خوبی عمل میکنه.
### منابع برای مطالعه بیشتر
* [Transactions across data centers](http://snarfed.org/transactions_across_datacenters_io.html)
## الگوهای دسترس پذیری
دو مدل برای پشتیبانی از دسترس پذیری بالا وجود داره:
در این مدل، هارت-بیت بین سرور فعال و غیر فعال که درحالت آماده باشه رد و بدل میشه. اگر هارت-بیت قطع بشه سرور غیرفعال آی-پی سرور فعال رو دراختیار میگیره و درخواستها رو هندل میکنه.
طول زمان پایین بودن به ۲ صورت مشخص میشه. سرور غیر فعال از به صورت هات لود میشه یا زا شرایط لود سرد اصطلاحا فعال میشه. فقط سرور فعال ترافیک رو هندل میکنه.
این مدل رو مستر-اِسلِیو هم میگن
#### Active-active
در این حالت هر دو سرور ترافیک رو هندل میکنه و بار بین این دو تقسیم میشه.
اگر سرورها به صورت عمومی روی اینترنت باشن، دی-اِن-اِس باید آی-پی هر دو سرور رو بدونه. اگر سرورها در شبکه داخلی باشن، لایه برنامه باید از حضور این دو سرور آگاهی داشه باشه.
این مدل به عنوان مستر-مستر هم شناخته میشه.
### معایب این الگو
* این الگو نیاز به سخت افزار بیشتر هست و پیچیدگی رو هم افزایش میده
* اگر یک سیستم فعال فِیل بشه قبل از این که داده جدید نوشته بتونه کپی بشه توی سرور غیرفعال، امکان از دست رفتن داده هست.
### تکرارکردن
#### مستر-اسلیو و مستر-مستر
این موضوع در بخش [پایگاه داده](#پایگاهداده) بررسی شده
<i><ahref=http://www.slideshare.net/srikrupa5/dns-security-presentation-issa>Source: DNS security presentation</a></i>
</p>
سیستم نام دامنه یا همان دی-اِن-اِس نام یک یک دامنه را به آی-پی آن ترجمه میکند.
www.example.com -> IP address.
دی-اِن-اِس به صورت سلسله مراتبی هست و تعداد کمی سرور اصلی در لایههای بالا وجود داره. روتر یا آی-اِس-پی شما اطلاعات مربوط به دی-ان-اس هایی که برای جستجو استفاده میشن رو در اختیار شما میزارن. دی-ان-اس های لایه پایینتر معمولا این نگاشت بین نام دامنه و آی-پی رو کش میکنن که ممکنه بعد از مدتی اعتبار این نگاشتها از بین بره به خاطر این که انتشار تغییرات در دی-ان-اس کنده. نتایجی که از دی-ان-اس برای شما میاد ممکنه که در مرورگر یا سیستم عامل کش برای مدت مشخصی کش بشه، به این مدت مشخص تایم-تو-لیو گفته میشه
> [time to live (TTL)](https://en.wikipedia.org/wiki/Time_to_live) : تایم-تو-لیو
* **NS record (name server)** - این رکورد سرورهای دی-ان-اس مربوط به دامنه یا زیردامنه رو مشخص میکنه
* **MX record (mail exchange)** - مِیل-سرورهای شما برای دریافت پیامها رو مشخص میکنه
* **A record (address)** - یک نام رو به یک آی-پی نگاشت میکنه
* **CNAME (canonical)** - یک نام رو به نام دیگه یا سی-نیم یا اِی-رکورد دیگه نگاشت میکنه. به مثال زیر توجه کنید
* > example.com -> www.example.com
سرویسهای نظیر سرویس های زیر سرویسهای دی-ان-اس مدیریت شده رو ارائه میکنن
[CloudFlare](https://www.cloudflare.com/dns/) و [Route 53](https://aws.amazon.com/route53/)
بعضی از سرویسهای دی-ان-اس میتونن ترافیک رو از راههای مختلفی ارسال کنند:
* از ارسال ترافیک به سرورهایی که در حال نگهداری هستند خودداری میکنه
* براساس سایز کلاستری که هست میتونه بالانس ایجاد کنه
* برای آ-ب تستینگ
* Latency-based |براساس تاخیر
* Geolocation-based | براساس موقعیت جغرافیایی
### معایب دی-ان-اس
* دسترسی به سرور دی-ان-اس یک تاخیری رو موجب میشه که با استفاده از کشینگ گفته شده برطرف میشه.
* مدیریت سرورهای دی-ای-اس ممکنه پیچیده باشه بااین حال توسط دولت ها،آی-اس-پی ها و کمپانیهای بزرگ مدیریت میشه
* > [governments, ISPs, and large companies](http://superuser.com/questions/472695/who-controls-the-dns-servers/472729).
* سرویس دی-ان-اس اخیرا مورد حمله دی-داس قرارگرفته و باعث شده تا کاربران نتونن به وب سایتها دسترسی پیدا کنن، وب سایتهایی نظیر توییتر - از طریق اینکه آی-پی توییتر رو نمیتونستن پیدا کنن
<i><ahref=https://www.creative-artworks.eu/why-use-a-content-delivery-network-cdn/>Source: Why use a CDN</a></i>
</p>
یک شبکه توزیع محتوا یا سی-دی-ان یک شبکه توزیع شده از پروکسی سرورهاست که محتوا را از مکانهایی که به کاربر نزدیکتره به دستش میرسونه. به طور کلی فایلهای ایستا مثل اچ-تی-ام-ال، جاوااسکریپت و سی-اس-اس، عکس، ویدیو از طریق سی-دی-ان به کاربر داده میشه. با این حال سی-دی-ان هایی نظیر کلود-فرانت که برای شرکت آمازون است محتوای غیر ایستا یا داینامیک رو هم پشتیبانی میکنه. عملیات گرفتن دی-ای-اس سایت میگه به کاربر که باید به کدوم سرور متصل بشه.
انتشار محتوا از طریق سی-دی-ان ها میتونه باعث افزایش کارایی چشمگیری بشه. این افزایش به خاطر ۲ علت زیر هست:
* کاربران محتوا را از مرکزدادهای که بهشون نزدیکه میگیرن.
* سرورهای شما احتیاجی نیست که به درخواستی پاسخ بدن که سی-دی-ان میتونه پاسخ بده
### Push CDNs
پوش سی-دی-ان زمانی که سرورشما تغییر روی محتوا داشته باشه، تغییرات رو میگیره. در این حالت شما مسوول تهیه محتوا برای سی-دی-ان هستید، باید محتوا رو آپلود مستقیم اپلود کنید روی سی-دی-ان و یو-آر-ال ها رو دوباره نویسی کنید که به سی-دی-ان اشاره کنه. شما میتونید تظیم کنید که چه زمانی محتوایی که گذاشتید مدت استفادش از بین بره و چه زمانی آپدیت بشه. محتوا زمانی آپلود میشه که یا جدید باشه یا تغییر پیدا کرده باشه که باعث کاهش ترافیک میشه ولی افزایش میزان حافظه هم هست.
سایتهایی که ترافیک کمی دارند یا محتوایی دارند که آپدیت نمیشن اغلب اوقات با این مدل پوش سی-دی-ان به خوبی کار میکنن. محتواها یکبار در سی-دی-ان گذاشته میشن به جای اینکه طی یه بازهی مشخصی همینطوری از سرور آورده بشن توی سی-دی-ان
### Pull CDNs
پول سی-دی-ان محتوای جدید رو از سرور شما میگیره وقتیکه کاربر اول درخواست برای اون محتوا رو میده. شما محتوا رو میزارید روی سرورتون و یو-آر-ال ها روی سی-دی-ان میزارید. این کار باعث میشه که درخواستها کندتر بشن البته تا وقتی که محتوا روی سی-دی-ان کش بشه.
یک تایم-تو-لیو برای اینکه چه مدت زمانی محتوا باید کش بشه رو مشخص میکنه. پول سی-دی-ان میزان استورج رو کم میکنه روی سی-دی-ان اما میتونه ترافیک اضافی هم ایجاد کنه اگر فایلها قبل از این که به سی-دی-ان بیان کش اونها منتقضی بشه.
سایتهای با ترافیک سنگین خیلی خوب بای این مدل پول سی-دی-ان کار میکنن چون که با آخرین درخواست برای محتوای تازه خواسته شده روی سی-دی-ان مواجه میشه، ترافیک به صورت یکسان پخش میشه.
### معایب سی-دی-ان
* هزینه ها خیلی وابسته به ترافیکه که وجود داره با این حال این رو هم مد نظر بگیرید که این هزینه ها رو درکنار هزینههای استفاده نکردن از سی-دی-ان ببینید.
* محتوا ممکنه قبل از این که تایم-تو-لیو اون تموم بشه منقضی بشه
* سی-دی-ان ها باید برای اینکه محتوای ایستا به سی-دی-ان اشاره کنن یو-آر-ال هاش رو تغییر بده.
<i><ahref=http://horicky.blogspot.com/2010/10/scalable-system-design-patterns.html>Source: Scalable system design patterns</a></i>
</p>
لودبالانسرها درخواست هایی که از سمت کاربران میاد رو بین منابع محاسبانی که هست مثل اپلیکیشن سرورها یا پایکاه دهدهها توزیع میکنه. در هر کدوم از این حالات لودبالانسر پاسخ درخواست رو از اون منبع محاسباتی به کاربر برمیگردونه. لودبالانسر ها در مورد زیر موثر هستند:
* از رفتن درخواست ها به سرورهایی که سالم نیستن جلوگیری میکنه
* از زیربار رفتن بیش از اندازه منابع جلوگیری میکنه
* کمک میکنه که سیستم از شکست نقطهای رنجنبرهHelping eliminate single points of failure
* > Single Point of Failure: شکست نقطهای
لودبالانسرها میتونن به صورت سخت افزاری پیاده سازی بشن(که گرون میشه) یا به صورت نرم افزاری پیاده سازی بشن مثلا برنامه زیر
> HAProxy
مزایای دیگه هم داره به طور مثال:
* **SSL termination** - درخواست هایی که از سمت کاربر میاد را رمزگشایی میکنه و جوابهایی که باید سرور بده رو هم رمزنگاری میکنه بنابراین سرورهای لازم نیست تا این عملیاتهای سنگین محاسباتی رو انجام بدن
* از نصب گواهیهای ایکس.۵۰۶ روی هر سرور جلوگیری میکنه
لودبالانسرها میتونن ترافیک رو براساس معیارهای مختلفی پخش کنن:
* Random
* Least loaded
* Session/cookies
* [Round robin or weighted round robin](http://g33kinfo.com/info/archives/2657)
* [Layer 4](#layer-4-load-balancing)
* [Layer 7](#layer-7-load-balancing)
### توزیع بار لایه ۴
> Packet: پکت
لودبالانسرهای لایه ۴ به اطلاعاتی که در لایهی ترسنپورت است نگاه میکنند و تصمیم میگیردن که چهطوری درخواستها رو توزیع کنند. به طورکلی یعنی نگاه به اطلاعتی نظیر مبدا درخواست، آی-پی مقصد و پورت هایی که در هدر وجود دارد اما به محتوای پکتی که ارسال میشود نگاهی نمیشود این نوع لودبالانسرها پکتهای شبکه را به سرورهای بالادستی ارسال و یا از پکتهای شبکه را دریافت میکنن که به صورت عملیات ترجمه آدرس شبکه انجام میشه.
> [Network Address Translation (NAT)](https://www.nginx.com/resources/glossary/layer-4-load-balancing/): ترجمه آدرس شبکه
### توزیع بار لایه ۷
لودبالانسرهای لایه ۷ به لایهی برنامه نگاه میکنند و تصمیم میگیرند که چهطوری درخواست ها رو توزیع کنند. این کار میتونی با استفاده از داده هایی که در هدر، محتوای پیام و کوکیهاست صورت بپذیره. این لودبالانسرها ترافیک شبکه رو تموم میکنه، پیام رو میخونه و یک تصمیم برای توزیع بار میگیره و بعدش یک کانکشن به سروری که حاصل تصمیمش هست ایجاد میکنه. برای مثال، یه لود بالانسر لایه ۷ میتونه ترافیکهای مربوط به ویدیو رو به یک سرور بفرسته درحالیکه ترافیکهای مربوط به قبضهای پرداختی میشه رو به یک سرور دیگه ای که از نظر امنیتی قوی تر هست بفرسته.
با احتساب هزینهای که بابت انعطاف پذیری در نظر بگیریم، لودبالانسینگ لایه ۴ نیاز به منابع و زمان کمتری داره نسبت به لایه ۷ با این حال کاراییش روی سیستمهای مدرن معمولی میتونه کم اثر باشه.
### مقایس پذیری افقی
> Upstream: بالادستی, Downstream: رو به پایین. سروری که ازش دانلود میشه بیشتر, Horizontal Scaling: مقایس کردن افقی, Vertical Scaling: مقایس کردن عمودی
لودبالانسرها میتونن کمکی باشن برای اسکیل کردن افقی و باعث افزایش کارایی و دسترس پذیری بشن. اسکیل کردن با استفاده از سیستمهای عادی تر(تعداد ماشینها رو زیاد کنیم) خیلی از نظر هزینه به صرفه تره و باعث میشه تا دسترس پذیری بیشتری داشته باشیم تا این که بیایم یک سرور رو از نظر سخت افزاری ارتقا بدیم که معمولا گرون میشه، که بهش میگن **مقیاس کردن عمودی**. همینطور کار با یک سیستم عادی خیلی آسونتره واسه آدما تا اینکه بخوان با سیستمهای تخصصی شده برای کارای سطح کلان کار کنن.
#### معایب مقایس پذیری افقی
* مقیاس پذیری افقی باعث پیچیدگی میشه و باید سرورهای کلون شده ایجاد کنید.
* Servers should be stateless: این سرورها نباید حاوی دادههایی باشن که مخصوص کاربراس مثل سشنها یا عکس پروفایل کاربرا
* سشنها میتونن توی یک مرکز ذخیره سازی داده مرکزی ذخیره بشن مثلا پایگاه داده یا یک کش با قابلیت نگهدارندگی دائمی
* > [پایگاهداده](#پایگاهداده) (SQL, NoSQL)
> [کش](#کش) (Redis, Memcached)
* سرورهایی که معمولا ترافیک دانلودشوندگی دارند مثلا کشها یا پایگاهدادهها نیازدارند که تعداد کانکشنهای همزمان بیشتری رو نسب به سرورهای بالادستی هندل کنن
### معایب لود بالانسر
* لودبالانسر میتونه گلوگاه مشکل کارایی باشه اگر منابع لازم به اندازه کافی نداشته باشه یا اگر اینکه به درستی تنظیم نشده باشه
* با استفاده از لودبالانسر مشکل شکست نقطهای از بین میره ولی میزان پیچیدگی رو زیاد میکنه
* یک دونه لودبالانسر میتونه خودش یک شکست نقطهای باشه با این حال با تنظیم چندتا لودبالانسر پیچیدگی هم زیاد میشه.
یک پروکسی معکوس یک وب سروی هست که سرویسها داخلی رو تجمیع میکنه و باعث میشه که از بیرون به یک واسط یکارچه دسترسی داشته باشید. درخواستها از کلاینتها فوروارد میشن به سروری که میتونه درخواست رو جواب بده قبل از اینکه پروکسی معکوس جواب رو به کاربر برگردونه.
مزایای بیشترش شامل موارد زیر میشه:
* **Increased security** - اطلاعات مربوط به سرورهای بک-اند رو مخفی میکنه، میتونه آی-پی ها رو بلک-لیست کنه و تعداد کانکشنها برای هر کلاینت رو محدود کنه
* **Increased scalability and flexibility** - کلاینتها فقط آی-پی پروکسی معکوس رو میبینن و این اجازه میده که شما سرورها تون رو اسکیل کنید یا تنظیماتش رو تغییر بدید
* **SSL termination** - میتونه درخواستهای ورودی رو رمزگشایی کنه و جوابهایی که سرور میفرسته رو رمز گذاری کنه تا این عملیات محاسباتی سنگین از دوش سرور برداشته بشه.
* نیاز به نصب گواهیهای ایکس.۵۰۹ رو روی هر سرور نداره
* **Caching** - برای درخواستهایی که کش شدن میتونه جوابشون رو از روی کش بده
* **Static content** - میتونه محتوای ایستا رو به صورت مستقیم جواب بده
* HTML/CSS/JS
* عکسها
* فیلمها
* غیره
### لودبالانسر دربرابر پروکسی معکوس
* اگر تعداد سرور زیادی دارید استفاده از لودبالانسر بهتره. معمولا لودبالانسر ترافیک رو بین سرورهایی که یک کار مشابه انجام میدن توزیع میکنه.
* پروکسی معکوسها هم حتی زمانی که شما یه دونه وب سرور یا اپلیکیشن سرور دارید مفید باشن. مزایی که قبلا اشاره شد رو برای شما فراهم میکنن.
* برنامههای زیر هر دو میتونن که لودبالانسینگ انجام بدن و هم پروکسی معکوس لایه ۷
* > NGINX و HAProxy
### معایب پروکسی معکوس
* باعث افزایش پیچیدگی میشه
* یک دونه پروکسی معکوس میتونه یه شکست نقطهای باشه و با تنظیم کردن چندتا از این پروکسی سرورها(به عنوان مثال به صورت [فِیل-اُوِر](https://en.wikipedia.org/wiki/Failover)) باعث افزایش پیچیدگی میشه.
### منابع برای مطالعه بیشتر
* [Reverse proxy vs load balancer](https://www.nginx.com/resources/glossary/reverse-proxy-vs-load-balancer/)
<i><ahref=http://lethain.com/introduction-to-architecting-systems-for-scale/#platform_layer>Source: Intro to architecting systems for scale</a></i>
</p>
> Single Responsibility Principle(SRP): اصل تک مسولیتی, Asynchronism: ناهمگامی, Worker: وُرکر
جداسازی لایه وب از لایه برنامه(که بعضا به عنوان لایه پلتفرم هم شناخته میشه) به شما این امکان رو میده که هر دو لایه رو مستقل از هم دیگه اسکیل کنید. اضافه کردن یک اِی-پی-آی جدید به لایهی برنامه مستقل از اینکه به وب سرور بخواید چیزی اضافه کنید انجام میشه.
**اصل تک مسولیتی** به دنبال این هست که سرویسهای کوچک و خودمختاری رو داشته باشکه بتونن باهم کار کنن. تیمهای کوچیک با سرویسهای کوچیک میتونن خیلی سریعتر و قویتر برای رشد برنامه ریزی کنند.
وُرکرهایی که در لایه برنامه هستند باعث میشن تا قابلیت [ناهمگامی](#ناهمگامی) رو بتونیم داشته باشیم.
### میکروسرویس ها
> Well-defined: خوش تعریف
مرتبط با این بحث مبحث [میکروسرویسها](https://en.wikipedia.org/wiki/Microservices) است که میتونیم به عنوان مجموعهای از سرویسهای ماژولار، کوچک و قابل دیپلوی شدن مستقل تعریف کرد. هر سرویس یک پروسس یکتایی رو اجرا میکنه و از طریق یک پروتکل ارتباطی سبک و خوش تعریف با بقیه سرویسها در ارتباطه تا یک هدف تجاری رو به سرانجام برسونه <sup><ahref=https://smartbear.com/learn/api-design/what-are-microservices>1</a></sup>
پینترسنت به عنوان مثال میتونه سرویسهایی نظیر پروفایل کاربر، فید فالورها، فالورها، جستجو، اپلود عکس و ... رو داشته باشه.
### کشف سرویس
سیستم هایی نظیر کنسول، ای-تی-سی-دی و زووکیپر به وسیلهی نگهداشتن اطلاعات در مورد اسمها و آدرسها و پورتهای سرویسها کمک کنن تا سرویسها بتونن همدیگه رو پیدا کنند.
هر دو سرویس کنسول و ای-تی-سی-دی یک ذخیره کلید-مقدار در درون خودشون دارند که برای مواردی مثل ذخیره کردن کانفیگ ها و یا دادههایی که باید به اشتراک باشن میتونه مفید باشه.
* اضافه کردن لایه برنامه که به صورت کمترین وابستگی باشه نیاز داره که در سطح معماری، عملیات و فرآیند راهکار متفاوتی اتخاذ بشه(در برابر حالت سیستم یکدست(
* میکروسرویسها میتونن در دیپلوی کردن و عملیات مربوطه پیچیدگی اضافه کنن
### منابع برای مطالعه بیشتر
* [Intro to architecting systems for scale](http://lethain.com/introduction-to-architecting-systems-for-scale)
* [Crack the system design interview](http://www.puncsky.com/blog/2016/02/14/crack-the-system-design-interview/)
* **Atomicity** - هر تراکنشی یا کامل اتفاق میوفته یا اصلا نمیشه
* **Consistency** - هر تراکنش باعث میشه که پایگاه داده از یک حالت درست به حالت درست دیگه بره
* **Isolation** - اجرای تراکنشها به صورت همزمان همان خروجی رو خواهد داشت که اگر اونا رو پشت سرهم/سریالی اجرا میشدن
* **Durability** - زمانی که یک تراکنش انجام میش، باقی میمونه
روشهای مختلفی برای اسکیل کردن پایگاهدادههای رابطهای وجود داره:
**master-slave replication**, **master-master replication**, **federation**, **sharding**, **denormalization**, and **SQL tuning**.
#### Master-slave replication
مستر هم عملیات خواندن و هم نوشتن رو انجام میده، نوشتنها رو برای ۱ یا تعداد بیشتری از اسلیوها تکرار میکنه، اسلیوها فقط عملیات خواندن رو انجام میدن. اسلیوها هم میتونن خودشون به صورت درختی یک سری اسلیو دیگه رو مثل خودشون تکرار کنن. اگر نود مستر خاموش بشه یا کلا از دسترس خارج بشه، سیستم کار خودش رو ادامه به صورت حالت فقط-خواندنی ادامه تا زمانی که یکی از این نودهای اسلیو بشه مستر یا یه مستر دیگه آماده بشه.
* یه مکانیزم منطقی اضافی میخواد که بتونه نود اسلیو رو به نود مستر ارتقا بده
* به قسمت زیر برید چون نکاتش مشترک هست
* > [معایب: replication](#معایب-replication)
#### Master-master replication
هردوی مسترها عملیات خواندن و نوشتن را انجام میدن و زمانی که قصد انجام نوشتن دارند باهم هماهنگ میشن. اگر یکی از این مسترها پایین بیاد، سیستم میتونه با هر دو عملیات خواندن و نوشتن کارش رو ادامه بده.
* شما به یک لودبالانسر نیاز دارید یا اینکه باید در لایه برنامهتون تغییراتی ایجاد کنید که مشخص کنه که کجا بنویسه.
* بیشتر سیستمهای مستر-مستر به صورت ناهمگون-ضعیف هستند(که مخالف اصل اَسید هس) یا اینکه باعث میشه که تاخیر عملیات نوشتن به خاطر نیاز به همگامسازی افزایش پیدا کنه.
* رفع تداخل بیشتر اتفاق میوفته اگر تعداد نودهای نوشتن بیشتر بیشتر بشه و همینطور میزان تاخیرهم زیاد میشه.
* قسمت زیر رو ببنید چرا که نکات مشترک هستند برای مستر-مستر و مستر-اسلیو
* > [معایب: replication](#معایب-replication)
##### معایب replication
* اگر نود مستر قبل از اینکه عملیات نوشتنی که به تازگی اتفاق افتاده رو نتونه رو نودهای دیگه تکرارکنه و در این حین پایین بیاد یا فِیل بشه، امکان این هست که دادهها از بین برن.
* عملیات نوشتن روی نودهای خواندن دوباره اعمال میشه. اگر تعداد نوشتنها خیلی زیاد بشه نودهای خواندن به خاطر تکرار عملیات نوشتن هنگ میکنن و نمیتونن تعداد عملیاتهای خواندن زیادی انجام بدن
* هرچه تعداد نودهای اسلیو برای خواندن بیشتر باشه،باید تعداد بیشتری عملیات رو روی این نودها تکرار کنید که این خودش باعث میشه که شما یک لگ برای عملیات تکرار کردن داشته باشید
* روی بعضی سیستم ها نوشتن روی مستر میتونه به صورت ایجاد چند تِرِد برای نوشتن موازی انجام بگیره اما روی نودهای خواندنی فقط یک تِرِد میتونه عملیات نوشتن رو انجام بده که اونم به صورت پشت سرهم انجام میشه.
* ریپلیکیشن باعث میشه تا سخت افزار بیشتری اضافه بشه و پیچیدگی رو افزایش میده.
<i><ahref=https://www.youtube.com/watch?v=vg5onp8TU6Q>Source: Scaling up to your first 10 million users</a></i>
</p>
فِدِرِیشن ( یا تقسیم عملکردی) پایگاه دادهها رو براساس کاری که انجام میدن تکه تکه میکنه. برای مثال بهجای یک پایگاهداده یک-تکه، شما میتونید ۳ تا پایگاه داده داشته باشید. **انجمنها**،**کاربران** و **محصولات** که باعث میشه تا تعداد عملیاتهای خواندن و نوشتن کم بشه و در نتیجه لگی که به خاطر عملیات ریپلیکیشن هست کاهش پیدا کنه. پایگاهدادههای کوچکتر باعث میشن تا دادههای بیشتری بتونه توی رم قراربگیره و این باعث میشه تا نتایج بیشتری در کش پیدابشن به خاطر اصل محلی بودن. بدون داشتن یک نود مستر مرکزی برای انجام عملیات نوشتن ها میتونید که تعداد نوشتنها رو به صورت موازی انجام بدید که این باعث میشه تا بازدهی بیشتری داشته باشید.
##### معایب: federation
* اگر شِمای شما نیاز به توابع یا جداول بزرگ باشه موثر نیست
* شما باید لایه منطق برنامه تون رو به روز کنید تا برنامه بتونه بفهمه به کدوم پایگاهداده باید عملیات نوشتن یا خوندن رو بفرسته.
* انجام عملیات جوین از دوتا پایگاه داده میتونه خیلی پیچیده باشه. لینک زیر رو ببنید
* > [server link](http://stackoverflow.com/questions/5145637/querying-data-by-joining-two-tables-in-two-database-on-different-servers): جوین ۲ تا پایگاه داده
* باعث افزایش سخت افزار و افزودن پیچیدگی میشه
##### منابع بیشتربرای مطالعه
* [Scaling up to your first 10 million users](https://www.youtube.com/watch?v=vg5onp8TU6Q)
شاردینگ دادهها رو در پایگاه دادههای مختلفی توزیع میکنه این توزیع به این صورت هست که هر پایگاه داده فقط بخشی از داده اصلی رو در خودش داره. به عنوان مثال پایگاه داده مربوط به کاربران رو در نظر بگیرید، هرچه تعداد کاربران افزایش پیدا کنه تعداد شاردهایی که باید اضافه بشه به کلاستر هم افزایش پیدا میکنه.
مشابه مزیتهایی مربوط [فدریشن](#federation) ، شاردینگ باعث میشه تا تعداد ترافیک خواندن و نوشتن کم بشه و ریپلیکیشن رو هم کم کنه و وجود داده در کش رو هم افزایش میده. سایز ایندکسها هم کم میشه که بهطورکلی باعث میشه تا کارایی رو افزایش بده و سرعت کوئری ها رو زیاد کنه. اگر یک شاردی بیاد پایین، بقیهی شاردها هنوز کار میکنن با این حال شما باید یه فرآیند ریپلیکیشن اضافه کنید که داده از بین نره. شبیه فدریشن، هیچ نودمرکزی برای نوشتن به صورت پشت سرهم وجود نداره و باعث میشه تا نوشتن به صورت موازی صورت بگیره و بازدهی افزایش پیدا کنه.
راههای عمومی که برای شارد کردن جدول کاربران وجود داره هم براساس اسم فامیلی کاربر میشه هم براساس اسم کوچیکشون یا موقعیت جغرافیاییشون.
##### معایب: sharding
* باید منطق لایه برنامه رو تغییر بدید تا بتونه با شاردها کارکنه که این باعث میشه تا کوئری های اس-کیو-ال پیچیده بشن.
* توزیع داده ها میتونه نامتوازن باشن توی یه شارد. برای مثال یه مجموعه ای از کاربران روی یک شارد باعث بشن که لود روی اون بیشتر از بقیه بشه.
* دوباره بالانس کردن باعث میشه تا پیچیدگی رو افزایش بده. یک تابع شاردینگ که براساس یک تابع نگاشت استوار میتونه میزان انتقال دادهها رو کاهش بشده.
دی-نرمالایزکردن سعی میکنه که باعث افزایش کارایی خواندن بشه در ازای افزایش چند عملیات نوشتن. یه سری کپی از دادهها توی جدولهای مختلف نوشته میشه تا از سربار سنگین جوین جلوگیری کنه. بعضی از آر-دی-بی-اِم-اِس ها مثل [پوست-گِرِس](https://en.wikipedia.org/wiki/PostgreSQL) و اوراکل از [ویو-متریالایز](https://en.wikipedia.org/wiki/Materialized_view) پشتیبانی میکنن که کمک میکنه که اطلاعات اضافی رو ذخیره کنید و کپی دادهها رو با هم سازگار نگه دارید.
زمانی که دادهها به روش [فدریشن](#federation) و [شاردینگ](#sharding) توزیع میشن مدیریت جوینها بین دیتا سنترهای باعث میشه که پیچیدگی خیلی زیاد بشه. دی-نرمالایزیشن شاید باعث بشه که این نیاز به این نوع جوین ها رو از ببره.
دربیشتر سیستمها عملیات خوندن میتونه به نسبت ۱۰۰:۱ یا حتی ۱۰۰۰:۱ نسبت به عملیات خواندن باشه. عملیات خواندنی که باعث بشه تا جوین پیچیده پایگاهداده انجام بشه میتونه خیلی سنگین باشه و مدت زمان قابل توجی روی عملیات دیسک سپری بشه.
##### معایب: denormalization
* دادهها چندجا یکسان کپی میشن و تکراری داریم
* محدودیت ها میتونه کمک کنه که کپیهای داده ها با هم سینک بمونن که این کار باعث میشه تا طراحی پایگاه داده رو پیچیده کنی
* پایگاهداده دی-نرمالایز شده زیر عملیات سنگین نوشتن ممکنه کارایی خیلی بدی داشته باشه نسبت به مشابه نرمالایز شدش
تون-کردن اس-کیو-ال یک مبحث خیلی گستردهای است و تعداد [کتابهای](https://www.amazon.com/s/ref=nb_sb_noss_2?url=search-alias%3Daps&field-keywords=sql+tuning) زیادی در این زمینه به عنوان منبع نوشته شده است.
خیلی مهمه که شما **بنچمارک** و **پروفایل** کنید تا بتونید چالشهای دیده نشده رو شبیه سازی کنید و پیداشون کنید
* **Benchmark** - شبیهسازی شرایط لود زیاد با ابزارهایی مثل [اِی-بی](http://httpd.apache.org/docs/2.2/programs/ab.html)
* **Profile** - استفاده از ابزارهایی مثل [لاگ کوئریهای کند](http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html) برای ترک درن مشکلات کارایی
بنچمارک کردن و پروفایل کردن ممکنه که شما رو به سمت بهینه سازی های زیر برسونه
##### Tighten up the schema
* MySQL dumps to disk in contiguous blocks for fast access.
* Use `CHAR` instead of `VARCHAR` for fixed-length fields.
*`CHAR` effectively allows for fast, random access, whereas with `VARCHAR`, you must find the end of a string before moving onto the next one.
* Use `TEXT` for large blocks of text such as blog posts. `TEXT` also allows for boolean searches. Using a `TEXT` field results in storing a pointer on disk that is used to locate the text block.
* Use `INT` for larger numbers up to 2^32 or 4 billion.
* Use `DECIMAL` for currency to avoid floating point representation errors.
* Avoid storing large `BLOBS`, store the location of where to get the object instead.
*`VARCHAR(255)` is the largest number of characters that can be counted in an 8 bit number, often maximizing the use of a byte in some RDBMS.
* Set the `NOT NULL` constraint where applicable to [improve search performance](http://stackoverflow.com/questions/1017239/how-do-null-values-affect-performance-in-a-database-search).
##### Use good indices
* Columns that you are querying (`SELECT`, `GROUP BY`, `ORDER BY`, `JOIN`) could be faster with indices.
* Indices are usually represented as self-balancing [B-tree](https://en.wikipedia.org/wiki/B-tree) that keeps data sorted and allows searches, sequential access, insertions, and deletions in logarithmic time.
* Placing an index can keep the data in memory, requiring more space.
* Writes could also be slower since the index also needs to be updated.
* When loading large amounts of data, it might be faster to disable indices, load the data, then rebuild the indices.
##### Avoid expensive joins
* [Denormalize](#denormalization) where performance demands it.
##### Partition tables
* Break up a table by putting hot spots in a separate table to help keep it in memory.
##### Tune the query cache
* In some cases, the [query cache](http://dev.mysql.com/doc/refman/5.7/en/query-cache) could lead to [performance issues](https://www.percona.com/blog/2014/01/28/10-mysql-performance-tuning-settings-after-installation/).
##### منابع برای مطالعه بیشتر
* [Tips for optimizing MySQL queries](http://20bits.com/article/10-tips-for-optimizing-mysql-queries-that-dont-suck)
* [Is there a good reason i see VARCHAR(255) used so often?](http://stackoverflow.com/questions/1217466/is-there-a-good-reason-i-see-varchar255-used-so-often-as-opposed-to-another-l)
* [How do null values affect performance?](http://stackoverflow.com/questions/1017239/how-do-null-values-affect-performance-in-a-database-search)
داده ها دی-نرمالایز میشن و جوین های معمولا در لایه ی برنامه انجام میشن. بیشتر نو-اس-کیو-ال ها از اصل **اَسید** برای تراکنش های پشتیبانی نمیکنن و [یکپارچگی موکول](#eventual-consistency) رو به این اصل ترجیح میدن
**بِیس** معمولا برای توصیف ویژگیهای پایگاه داده های نو-اس-کیو-ال استفاده میشد. در مقایسه با تئوری کپ ، بِیس دسترس پذیری رو بر یکپارچگی ترجیح میده.
> [تئوری CAP](#CAP-تئوری)
> Consistent: استوار
* **Basically available** - سیستم دسترسپذیری رو تضمین
* **Soft state** - وضعیت سیستم ممکنه که بدون گرفتن ورودی در طول زمان دچار تغییر بشه.
* **Eventual consistency** - سیستم در طول یک مدت زمانی استوار میشه با این شرط که در طول این مدت ورودی نگیره
علاوه براین که باید انتخاب کنید که [اس-کیو-ال یا نو-اس-کیو-ال](sql-or-nosql#) بدنیست که پایگاه داده های نو-اس-کیو-ال رو انواعش رو بشناسید و اونی که بهترین فیت برای کاربردتون هست را انتخاب کنید. ما در ادامه موارد زیر روبررسی میکنیم.
یک ذخیره سازی کلید-مقدار به طور عمومی به شما این امکان رو میده که از عملیات خوندن و نوشتن رو با اُ(۱) انجام بدید و معمولا توسط حافظههای اس-اس-دی و رم پشتیبانی میشن. این ذخیره کنندههای داده میتونن کلیدها رو به [به ترتیب الفبایی](#https://en.wikipedia.org/wiki/Lexicographical_order) مرتب نگه دارن که باعث میشه تا بازیابی کلیدها به صورت بازهای بهینه تر و به صرفهتر بشه.
این ذخیرهکننده ها معمولا با کارایی بالاهستند و برای مدلهای دادهای ساده یا دادههایی که خیلی سریع تغییر میکنند مثل دادههایی که توی کش هستند مورد استفاده قرار میگیرند.
یک مخزن کلید-مقدار معمولا پایهای اصلی برای سیستمهای پیچیدهای مانند ذخیرهساز های اسنادی و در بعضی موردها پایگاهدادههای گرافی،مورد استفاده قرار میگیرد.
* [Disadvantages of key-value stores](http://stackoverflow.com/questions/4056093/what-are-the-disadvantages-of-using-a-key-value-table-over-nullable-columns-or)
> Abstraction: key-value store with documents stored as values
یک ذخیرهساز اسنادی حول اسناد شکل میگیره(مانند ایکس-ام-ال، جیسان، باینری و ...) که در اینجا یک سند تمام اطلاعات مربوط به یک شی رو در اون ذخیره میکنه. ذخیرهسازهای اسنادی ای-پی-آی ها یا زبانهای کوئری در اختیار قرار میدهند تا بتونیم براساس این روشها ساختار داخلی خود سند رو مورد جستجو قرار بدیم. به یاد داشته باشید که خیلی از ذخیرهسازهای کلید-مقدار شامل ویژگیهایی هستند که میتونه با متادیتاهای مربوط به مقدارهای یک کلید هم کارکنه که باعث میشه که مرز بین این ذخیرهسازها رو کمرنگتر میکنه از لحاظ نوع محل ذخیرهسازی.
براساس پیادهسازی های زیرساختی ، اسناد هم به صورت تگها، کالکشنها، متادیتاها یا پروندهها سازماندهی میشن. باوجوداینکه اسناد میتونن باهم دیگه گروه بشن یا توی یه دسته سازماندهی بشن،با اینحال میتونن هرکدوم فیلدهای مخصوص خودشون رو داشته باشند که در بقیه موجود نباشه.
بعضی از این ذخیرهسازها مثل [مونگو-دی-بی](https://www.mongodb.com/mongodb-architecture#) و [کوچ-دی-بی](https://blog.couchdb.org/2016/08/01/couchdb-2-0-architecture/#) زبانهایی شبیه اس-کیو-ال برای انجام کوئریهای پیچیده فراهم کردند. [داینامو-دی-بی](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/decandia07dynamo.pdf#) هر دو نوع کلید-مقدار و اسنادی رو پشتیبانی میکنه.
ذخیرهساز های اسنادی انعطاف زیادی رو میدن و معمولا جاهایی که تغییرات داد مکرر اتفاق میوفته استفاده میشه.
المان اصلی و پایهای برای ذخیرهساز واید-کالم یک ستون(یک جفت اسم/مقدار) است. یه ستون میتونه توی دسته بندی گروهی خاصی(مثل همون جدول توی اس-کیو-ال) دسته بندی بشه. ابر گروههای ستونی به صورت دسته بندی گروهی برخی از این گروهها استفاده میشن. شما میتونید به هر ستونی که میخواید با استفاده از کلید اون سطر به صورت مستقل دسترسی داشته باشید و ستونها با یک کلید سطر مشابه یه سطر رو تشکلی میدن. هر مقدار شامل یک استمپ-زمانی برای ورژنگذاری و رفع تداخل است.
> Super Column Family: ابرگروه ستونی, Column Family گروه ستونی: , Row Key: کلید سطر
گوگل [بیگ-تیبل](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf) رو به عنوان اولین ذخیرهساز ستونی معرفی کرد که روی [اچ-بیس](https://www.mapr.com/blog/in-depth-look-hbase-architecture) متن باز که در اکوسیستم هدوپ استفاده میشه و یا [کاساندرا](http://docs.datastax.com/en/archived/cassandra/2.0/cassandra/architecture/architectureIntro_c.html) که برای فیسبوک است، مورد استفاده قرار بگیره. ذخیرهسازهایی مثل بیگ-تیبل،اچ-بیس و کاساندرا کلیدها رو بهصورت مرتب الفبایی نگهداری میکنن که باعث میشه که بازیابی براساس یک رنج از کلیدها به صورت موثر تر و بهینه تر باشد.
ذخیرهسازهای ستونی دسترسپذیری بالا و قابلیت اسکیل شدن بالا رو دراختیار قرار میدن. معمولا برای مجموعه دادههای خیلی بزرگ مورد استفاده قرار میگیرند.
##### منابع برای مطالعه بیشتر
* [SQL & NoSQL, a brief history](http://blog.grio.com/2015/11/sql-nosql-a-brief-history.html)
در یک پایگاه داده گرافی هر نود یک رکورد است و هر یال یک رابطه بین دو نود. پایگاهدادههای گرافی برای نمایش رابطههای پیچیده مورد استفاده قرار میگیرند که معمولا تعداد کلید خارجی زیادی دارند یا رابطههای چند-به-چند زیادی دارند.
پایگاهداده های گرافی دارای کارایی بالا هستند و برای مدلهای دادهای که روابط پیچیده دارند مورد استفاده قرار میگیرند مانند شبکههای اجتماعی. این دسته از پایگاهدادهها تقریبا جدید هستند و خیلی مورد استفاده قرار نگرفته اند،معمولا پیدا کردن منابع و یا ابزار برای این دست از پایگاهداده ها دشواره. خیلی از پایگاه داده های گرافی معمولا از طریق [رِست ای-پی-آی](#representational-state-transfer-rest) قابل دسترسی هستند.
##### منابع برای مطالعه بیشتر در مورد پایگاهداده گرافی
* [Explanation of base terminology](http://stackoverflow.com/questions/3342497/explanation-of-base-terminology)
* [NoSQL databases a survey and decision guidance](https://medium.com/baqend-blog/nosql-databases-a-survey-and-decision-guidance-ea7823a822d#.wskogqenq)
<i><ahref=https://www.infoq.com/articles/Transition-RDBMS-NoSQL/>Source: Transitioning from RDBMS to NoSQL</a></i>
</p>
دلایلی که باید **ازاس-کیو-ال** باید استفاده کرد:
* دادهها دارای ساختار هستند
* شِمای مورد استفاده خیلی قطعی و مشخص
* دادههای رابطهای
* نیاز به جوین های پیچیده دارید
* نیاز به تراکنشها هست
* یک الگوی مشخص برای اسکیل کردن دارید
* از نظر تعداد توسعه دهنده، جامعه پشتبان، کد، ابزار و ... بیشتر موجوده
* جستوجو با استفاده از ایندکسها خیلی سریع تره
دلایل برای استفاده از نو-اس-کیو-ال:
* دادههای شبه-ساختار یافته
* شمای دادهها داینامیکه یا انعطافپذیره
* دادههای غیر رابطهای
* نیاز به جوین های پیچیده ندارید
* حجم دادهها در حد ترابایت یا پتا بایت هست
* حجمکاریتون خیلی داده محور هست
* میزان بازدهی بالا برای تعداد آی-اُ بر ثانیه
نمونههایی از مواردی که برای نو-اس-کیو-ال خیلی مناسبه:
* حجمزیاد دادههای مربوط به لاگ یا کلیک کردنها
* لیدربوردها در بازی ها مثلا یا دادههای مربوط به امتیاز
* دادههای موقت مثل اطلاعات کارتهای خرید
* جداولی که تعداد درخواست برای دادههای اون زیاده
* جداولی که برای متادیتا هست یا برای جستوجو استفاده میشن
##### منابع بیشتر برای مطالعه
* [Scaling up to your first 10 million users](https://www.youtube.com/watch?v=vg5onp8TU6Q)
* [SQL vs NoSQL differences](https://www.sitepoint.com/sql-vs-nosql-differences/)
## Cache
<palign="center">
<imgsrc="http://i.imgur.com/Q6z24La.png">
<br/>
<i><ahref=http://horicky.blogspot.com/2010/10/scalable-system-design-patterns.html>Source: Scalable system design patterns</a></i>
</p>
کش کردن باعث میشه تا زمان لود صفحه بهبود پیدا کنه و میتونه لود روی سرور شما و یا پایگاه داده رو کم کنه. در این مدل دیسپچر اول داخل کش رو نگاه میکنه اگر که درخواست قبلا داده شده بود و نتیجش بود اونجا، برمیگردونه که باعث میشه که زمان واقعی اجرا رو صرفه جونیی کنه.
پایگاه دادهها معمولا از یک توزیع یکنواختی از خواندن ها یا نوشتنها توی پارتیشن بهره میگرن. آیتمهایی که خیلی مورد استفاده هستند میتونن این توزیع رو دچار چلگی کنن که باعث میشه که ما باتلنک داشته باشیم. استفاده از کش در جلوی پایگاه داده میتونه کمک کنه که این توزیع غیر یکنواخت رو بعضا دارای پیک ترافیک رو جلوش رو بگیره.
### کش سمت کلاینت
کشها میتونن که در بخش کلاینت (مثل مرورگر یا سیستم عامل) قرار بگیرند یا در [سمت سرور](#پروکسی-معکوس) باشن یا کلا یک لایه کش جدا وجود دارشته باشه
### CDN کش در
[سی-دی-ان ها](#شبکه-توزیع-محتوا-CDN) به عنوان یک نوع از کش درنظر گرفته میشن
### Web server caching
[پروکسی ها معکوس](#وب-سرور-پروکسی-معکوس) و کشها مثل [وارنیش](https://www.varnish-cache.org/) میتونن محتوای ایستا و داینامیک رو به صورت مستقیم جوابگو باشن. وب سرورهای هم میتونن درخواستها رو کش کنن و جوابها رو بدون اینکه به لایه برنامه بدن برگردونن
### کش پایگاه داده
پایگاهداده شما معمولا شامل یک سری لایه کش به صورت پیشفرض در تنظیماتش هست که برای کاربرادهای عمومیتر مورد استفاده است. تغییر این تنظیمات برای یک کاربرد خاص میتونه این افزایش کارایی رو حتی بیشتر هم بکنه.
### کش در برنامه
کشها داخل حافظه مثل مِمکش و رِدیس ذخیرهسازهای کلید-مقدار هستند که بین برنامه شما و منبع نگه داری داده شما قرار میگیره. از اونجایی که داده ها داخل رم نگه داری میشه، سرعت بیشتری نسبت به پایگاه داده های معمولی داره چرا که توی اونا داده روی دیسک ذخیره میشه. رم نسبت دیسک محدودتره بنابراین الگوریتمهای [غیر معتبر کردن کش](https://en.wikipedia.org/wiki/Cache_algorithms) مثل [آخرین نزدیکترین استفاده - اِل-آر-یو](https://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used) میتونه کمک کنه که آیتمهای سرد رو غیر معتبر کنه و دادهها داغتر رو توی رم نگه داره.(منظور از داغ بیشتر مورد استفاده است و منظور از سر برعکس داغ)
رِدیس ویژگیها بیشتر زیر رو هم داره:
* امکان دائمی کردن داده
* دادهاسختارهای درونی مثل مجموعههای مرتب و لیستها
سطحهای مختلفی وجود دارند که میتونید کش کردن رو انجام بدید که به دو دسته کلی تقسیم میشن: **کوئریهای پایگاهداده** و **اشیا**
* در سطح سطری
* در سطح کوئری
* اشیای که سریالایز شدن به طور کامل
* صفحات اچ-تی-ام-ال که به صور کامل رندر شدن
به طورکلی، شما بهتره که از کش کردن به صورت فایلی دوری کنین چرا که اسکیل-کردن خودکار و کلون کردن رو خیلی سخت میکنه.
### کش در سطح کوئری پایگاه داده
هرزمانی که شما کوئری به پایگاه داده میزنید،کوئری رو به صورت هش شده به عنوان کلید درنظر بگیرید و جوابش رو به عنوان مقدار توی کش ذخیره کنید. این روش از مشکلاتی که مربوط به انقضا میشه رنج میبره:
* پاک کردن نتایجی که حاضل کوئری های پیچیدس سخت میشه
* اگر یک قسمت از داده مثل یک سلول از یک جدول تغییر کنه، شما باید هرچی که کش کردید که شامل اون سلول میشه رو پاک کنید
### کش در سطح آبجکت
داده تون رو به عنوان یک شی نگاه کنید، مثل همون کاری که توی برنام میکنید. مجموعه دادههاتون رو از توی پایگاهداده دربیارید و توی یک کلاس یا یه ساختمان داده ذخیره کنید
* اگر داده تغییر کرد، اون شی رو پاک کنید از کش
* امکان پردازش ناهمگام رو هم فراهم میکنه: وُرکرها آخرین اشیا کش شده رو جمع میکنن
پیشنهاداتی برای اینکه چیا رو کش کنید:
* سِشِن کاربر
* صفحات کاملا رندرشده
* Activity streams
* User graph data
### چه زمانی کش را آپدیت کنیم
از اونجایی که شما فقط میتونید یه بخش محدودی از دادهها رو بزارید توی کش، لازم دارید بدونید که چه استراتژی برای اپدیت کردن کشتون برای کاربرد شما بهتره
#### Cache-aside
<palign="center">
<imgsrc="http://i.imgur.com/ONjORqk.png">
<br/>
<i><ahref=http://www.slideshare.net/tmatyashovsky/from-cache-to-in-memory-data-grid-introduction-to-hazelcast>Source: From cache to in-memory data grid</a></i>
</p>
> Storage: اِستورج
برنامه مسول نوشتن و خواندن از کش اِستورج هست. کش با خود استورج به صورت مستقیم در ارتباط نیست. برنامه کارهای زیر رو انجام میده:
* دنبال یک آیتم خاص توی کش میگرده، که نتیجش این میشه که آیتم داخل کش نیست
* اون آیتم رو از پایگاه داده لود میکنه
* اون آیتم رو توی کش اضافه میکنه
* آیتم رو بر میگردونه
```
def get_user(self, user_id):
user = cache.get("user.{0}", user_id)
if user is None:
user = db.query("SELECT * FROM users WHERE user_id = {0}", user_id)
if user is not None:
key = "user.{0}".format(user_id)
cache.set(key, json.dumps(user))
return user
```
[مِم-کش-دی](https://memcached.org/) معمولا به این حالت ازش استفاده میشه
عملیاتهای خواندنی که در ادامه میاد که مربوط به همون داده ای هست که توی کش نوشته شده سریعتر انجام میشه. کش-اِساید به تحت عنوان بارگذاری تنبل هم گفته میشه. تنها دادهای که درخواست داده میشه کش میشه که این باعث میشه تا کش با دادههایی که درخواست داده نشدن پر نشه.
##### معایب
* هر نبودن در کش باعث میشه تا ۳ مسیر طی بشه که این خودش باعث میشه که تاخیر قابل توجهی ایجاد بشه.
* داده میتونه غیرمعتبر بشه اگر که داخل پایگاه داده تغییر کرده باشه. این مشکل با ست کردن یک تام-تو-لیو برطرف میشه به اینصورت که کش مجبوره بعد این مدت اپدیت بشه. یا با استفاده از روش رایت-ثُرو میشه این مشکل رو برطرف کرد.
* اگر نودی فِیل بشه، اون با یک نود جدید جایگزین میشه و نود خالی باعث میشه تا تاخیر افزایش پیدا کنه
برنامه کش رو به عنوان استور اصلی دادهها استفاده میکنه یعنی نوشتن و خوندن داده رو در اون انجام میده در حالی که کش مسول نوشتن و خوندن توی پایگاهداده هست:
* برنامه یک آیتم رو به کش اضافه میکنه یا آپدیتش میکنه
* کش به صورت همگام عملیاتهای نوشتن رو توی پایگاه داده انجام میشده
* بعد نتیجه برمیگرده
کد برنامه:
```
set_user(12345, {"foo":"bar"})
```
کد کش:
```
def set_user(user_id, values):
user = db.query("UPDATE Users WHERE id = {0}", user_id, values)
cache.set(user_id, user)
```
این روش با توجه به عملیات نوشتنی که داره به طور کلی کند هست اما عملیاتهای خوندنی که در ادامه اتفاق میوفته خیلی سریع هستند. کاربران معمولا زمانی که میخوان به روز رسانی دادههاشون رو انجام بدن خیلی نسبت تاخیر واکنش نشون نمیدن نسبت به زمانی که قصد دارن دادهها رو بخونن. دادهها داخل کش غیرمعتبر نمیشن
##### معایب
* وقتی نود جدید درست میشه به خاطر اسکیل کردن یا فِیل شدن، نود جدید آیتمها رو کش نمیکنه تا زمانیکه در پایگاه داده به روز رسانی بشن. استفاده از روش کش-اِساید با این روش میتونه این مشکل رو برطرف کنه.
* بیشتر دادههایی که نوشته میشن تو کش ممکنه خونده نشن که البته میتونه با استفاده از تای-تو-لیو این تاثیر رو کم کرد..
* به صورت ناهمگام آیتم رو توی اون منبع ذخیره مینویسه که باعث میشه تا کارایی سیستم بهبود پیدا کنه
##### معایب
* اگر قبل از اینکه محتوای داخل کش مورد استفاده قرار بگیره، کش پایین بیاد ممکنه که دادهها رو از دست بدیم.
* پیاده سازی این روش نسبت به روش های کش-اساید و یا رایت-ثُرو پیچیدهتر هست.
#### Refresh-ahead
<palign="center">
<imgsrc="http://i.imgur.com/kxtjqgE.png">
<br/>
<i><ahref=http://www.slideshare.net/tmatyashovsky/from-cache-to-in-memory-data-grid-introduction-to-hazelcast>Source: From cache to in-memory data grid</a></i>
</p>
شما میتونید کش رو طوری تنظیم کنید که به صورت خودکار هر آیتم داخل کش که اخیر مورد استفاده قرار گرفته رو قبل از زمان انقضاش رِفرِش کنید
این روش میتونه باعث بشه که تاخیر کاهش پیداکند نسبت حال رید-ثُرو اگر کش بتونه به دقت تشخیص بده که کدوم آیتم احتمالا در آینده مورد نیاز خواهد بود.
##### معایب
* اگر پیشبینی اینکه کدوم آیتم در آینده مورد نیاز خواهد بود به خوبی انجام نشه باعث میشه تا کارایی کاهش پیدا کنه نسبت به حالتی که از این مود استفاده نشه.
### معایب کش
* نیاز داره سازگاری بین کشها و منابع درستیشون مثل پایگاه دادهها به وسیلهی [غیرمعتبرسازی کش](https://en.wikipedia.org/wiki/Cache_algorithms) تامین بشه.
* نیاز داره که تغییراتی در برنامه ایجاد بشه مثل اضافه کردن رِدیس یا مِم-کش-دی
* غیرمعتبرسازی کش مشکل دشواری هست و یه پیچیدگی در مورد زمان آپدیت کش به وجود میاره.
### منابع برای مطالعه بیشتر
* [From cache to in-memory data grid](http://www.slideshare.net/tmatyashovsky/from-cache-to-in-memory-data-grid-introduction-to-hazelcast)
* [Scalable system design patterns](http://horicky.blogspot.com/2010/10/scalable-system-design-patterns.html)
* [Introduction to architecting systems for scale](http://lethain.com/introduction-to-architecting-systems-for-scale/)
<i><ahref=http://lethain.com/introduction-to-architecting-systems-for-scale/#platform_layer>Source: Intro to architecting systems for scale</a></i>
</p>
جریان کاری ناهمگام باعث میشه تا زمان درخواست برای عملیاتهای سنگین کاهش پیدا کنه که اگر معمولی به صورت همگام بود زمان بیشتری میگرفت. همینطور باعث میشه تا کارهای زمانبر مثل اگریگیت کردن دادهها از قبل انجام بشن.
### Message queues
صفهای پیام، پیامها را میگرند،نگه میدارن و بعد میرسونن. اگر یه عملیاتی برای اجرای همگام خیلی کند باشه میتونید از یه صف با جریان کاری زیر استفاده کنید:
* یک برنامه یک کار رو به صف اضافه میکنه، بعد به کاربر از وضعیت کاری که فرستاده اطلاع میده.
* یک وُرکر کار رو از صف بر میداره پردازش میکنه و بعد سیگنالی مبنی بر این که کار تموم شده ارسال میکنه.
روند اجرایی کاربر بلاک نمیشه و کار در پسزمینه در حال انجامه. در این مدت کلاینت میتونه یه پردازش خیلی کمی انجام بده که نشون بده که اون کار تموم شده(به کاربر). برای مثال، اگر پستی رو توییت میشه، پست میتونه همون لحظه به تامیلاینتون اضافه بشه اما ممکنه یکم زمان ببره تا قبل از اینکه به تمام فالورهای شما برسه.
**ردیس** یک بروکر پیام ساده و کاربردی است اما پیامها میتونن گم بشن داخلش.
**ربیت-اِم-کیو** معروفه اما باید از پروتکل اِی-اِم-کیو-پی استفاده کنید و نودهای خودتون رو مدیریت کنید.
**آمازون اِس-کیو-اِس** به صورت هاست شده هست اما ممکنه که تاخیر زیادی داشته باشه و امکان داره که پیام ۲ بار دریافت بشه.
### Task queues
صفهای تسکها تسکهای و دادههای مربوط به اون رو میگیره، اجراشون میکنه بعد نتایجش رو برمیگردونه. تسکها میتونن زمانبندی رو پشتیبانی کنن و میتونه به برای کارهایی که از نظر محاسباتی خیلی سنگینه استفاده بشه که در پسزمینه اجرا بشن.
**سِلِری** پشتیبانی برای زمانبندی داره و به صورت رسمی از پایتون پشتیبانی میکنه.
### Back pressure
اگر صفها شروع به رشد زیادی بکنه، سایز صف میتونه از میزان حافظه بیشتر بشه، باعث بشه که دادهها توی کش پیدا نشن، باعث بشه خواندن از دیسک زیاد بشه و حتی کارایی رو کمتر میکنه. [بک-پِرِشِر](http://mechanical-sympathy.blogspot.com/2012/05/apply-back-pressure-when-overloaded.html) میتونه با محدودیت گذاشتن روی سایز صف، نرخ بازدهی بالا و زمان پاسخگویی مناسبی برای کارهایی که در داخل صف هستند رو باعث میشه. زمانی که صف پر میشه، کلاینت های جوابی مبنی بر این که سرور مشغوله یا کد اچ-تی-تی-پی ۵۰۳ میگیرن تا بعدا دوباره درخواست رو بفرستن و امتحان کنن. کلاینت ها میتونن درخواست رو بعدا تکرار کنه شاید با [بک-آف نمایی](https://en.wikipedia.org/wiki/Exponential_backoff) .
### معایب ناهمگام
* کاربردهایی که نیاز به محاسبات سنگین و جریان کاری بلادرنگ نداره بهتره تا از مدلهای اجرایی همگام استفاده کنه چون که استفاده از صف باعث میشه که پیچیدگی و تاخیر زیاد بشه.
### منابع برای مطالعه بیشتر
* [It's all a numbers game](https://www.youtube.com/watch?v=1KRYH75wgy4)
* [Applying back pressure when overloaded](http://mechanical-sympathy.blogspot.com/2012/05/apply-back-pressure-when-overloaded.html)
* [What is the difference between a message queue and a task queue?](https://www.quora.com/What-is-the-difference-between-a-message-queue-and-a-task-queue-Why-would-a-task-queue-require-a-message-broker-like-RabbitMQ-Redis-Celery-or-IronMQ-to-function)
## ارتباط
<palign="center">
<imgsrc="http://i.imgur.com/5KeocQs.jpg">
<br/>
<i><ahref=http://www.escotal.com/osilayer.html>Source: OSI 7 layer model</a></i>
</p>
### Hypertext transfer protocol (HTTP)
اچ-تی-تی-پی یک روش برای کدگذاری داده برای انتقال داده بین کلاینت و سرور است. این متد یک پروتکل درخواست/پاسخ هست، یعنی: کلاینت ها درخواستشون رو میفرستند و سرورها جوابهاشونو با محتوا و استاتوس، که وضعیت کامل شدن درخواست هست، رو به اونها میدن. اچ-تی-تی-پی خود-شامل هست یعنی اینکه اجازه میده که درخواستها و پاسخها از روترهای میانی مسیر و سروهای سرراه بگذره درحالی که این لایههای میانی باعث میشن که لودبالانسینگ، کش کردن، رمزنگاری، و فشرده سازی اتفاق بیوفته.
یک درخواست ساده اچ-تی-تی-پی شامل یک فعل(متد) و یک ریسورس یا منبع(اِند-پوینت) هست. در ادامه افعال رایج در اچ-تی-تی-پی آورده شده:
| فعل | توضیحات | Idempotent* | امن | قابل کش شدن |
| POST | یک ریسورس میسازه یا یک فرآیند رو آغاز میکنه که داده رو هندل کنه | نه | نه | اگر پاسخ دارای اطلاعاتی باشه که تازه باشه |
| PUT | یک ریسورس میسازه یا جایگزین میکنه | بله | نه | نه |
| PATCH | یک ریسورس رو یه بخشیش رو به روز میکنه | نه | نه | اگر پاسخ دارای اطلاعاتی باشه که تازه باشه |
| DELETE | یک ریسورس رو پاک میکنهDeletes a resource | بله | نه | نه |
*میتونه به تعداد دفعات زیادی فراخوانی بشه بدون اینکه نتیجش تغییری کنه
اچ-تی-تی-پی یک پروتکل لایه برنامه است که به پروتکلهای سطح پایین تری مثل **تی-سی-پی** و **یو-دی-پی** وابسته هست.
> TCP: تی-سی-پی, UDP: یو-دی-پی
#### منابع برای مطالعه بیشتر
* [What is HTTP?](https://www.nginx.com/resources/glossary/http/)
* [Difference between HTTP and TCP](https://www.quora.com/What-is-the-difference-between-HTTP-protocol-and-TCP-protocol)
* [Difference between PUT and PATCH](https://laracasts.com/discuss/channels/general-discussion/whats-the-differences-between-put-and-patch?page=1)
### Transmission control protocol (TCP)
<palign="center">
<imgsrc="http://i.imgur.com/JdAsdvG.jpg">
<br/>
<i><ahref=http://www.wildbunny.co.uk/blog/2012/10/09/how-to-make-a-multi-player-game-part-1/>Source: How to make a multiplayer game</a></i>
</p>
تی-سی-پی یک پروتکل ارتباط-محور روی یک [شبکه آی-پی](https://en.wikipedia.org/wiki/Internet_Protocol) هست. ایجاد و خاتمه یک کانکشن با استفاده از یک [هندشِیک](https://en.wikipedia.org/wiki/Handshaking) انجام میشه. تمام پکتهایی که ارسال میشن تضمین میشن که به ترتیب به مقصد برسه و بدون اختلال از طریق موارد زیر:
* شماره سیکوئنس و [فیلدهای چِک-سام](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Checksum_computation) برای هر پکِت
* پکِتهای [تایید](https://en.wikipedia.org/wiki/Acknowledgement_(data_networks)) و دوباره ارسالهایی که به صورت خودکار انجام میشن.
اگر ارسال کننده یک پاسخ درست دریافت نکند، دوباره پکِتها را میفرستد. اگر تعداد متعددی تایم-اُوت اتفاق بویفتد، کانکشن قطع میشه. تی-سی-پی [کنترل جریان](https://en.wikipedia.org/wiki/Flow_control_(data)) و [کنترل ازدحام](https://en.wikipedia.org/wiki/Network_congestion#Congestion_control) اجرا میکنه. این تضمینها باعث میشه تا تاخیر به وجود بیاد و به طور کلی باعث بشه تا نسبت به انتقال به روش یو-دی-پی کمتر بهینه باشه.
برای اطمینان از نرخ بازدهی بالا، وب سرورها تعداد زیادی کانکشن تی-سی-پی رو باز نگه میدارن، که این باعث میشه تا میزان مصرف حافظه زیاد بشه. تعداد کانکشن باز زیاد بین تِرِدهای یک وب سرور و به عنوان مثال یک سرور [مِم-کش-دی](#memcached) میتونه پرهزینه باشه. [کانکشن پولینگ](https://en.wikipedia.org/wiki/Connection_pool) میتونه زمانیکه امکانش هست به یو-دی-پی سويیچ انجام بشه.
تی-سی-پی برای کارهایی که نیاز به اطمینان بالایی هست و از نظر زمانی حساس نیست مناسبه. بعضی مثالهاش شمال وب سرورها، اطلاعات پایگاه داده، اِس-اِم-تی-پی، اِف-تی-پی، و اِس-اِس-اِچ هست.
زمانهایی تی-سی-پی باید به جای یو-دی-پی استفاده بشه:
* قصد دارید که دادهها دست نخورده برسن
* قصد بهترین تخمین از بازدهی شبکه را داشته باشید
> Intact: دست نخورده, High Available: اطمینان بالا
### User datagram protocol (UDP)
<palign="center">
<imgsrc="http://i.imgur.com/yzDrJtA.jpg">
<br/>
<i><ahref=http://www.wildbunny.co.uk/blog/2012/10/09/how-to-make-a-multi-player-game-part-1/>Source: How to make a multiplayer game</a></i>
</p>
یو-دی-پی کانکشن-لِس هست. دیتاگرامها(مشابه پکِتها) فقط در سطح دیتاگرام تضمین میشن. دیتا گرامها ممکنه که خارج از ترتیبشون به مقصد برسن یا کلا نرسن. یو-دی-پی از کنترل ازدحام پشتیبانی نمیکنه. مستقل از تضمینهایی که تی-سی-پی پشتیبانی میکنه، یو-دی-پی به طور کلی بهینهتر هست.
یو-دی-پی میتونه برادکست کنه، دیتا گرامها رو به تمام دیوایسها روی سابنت بفرسته. این امکان برای [دی-اِچ-سی-پی]() خوبه چرا که کلاینت هنوز آدرس آی-پی نگرفتن، بنابراین یک راه برای جلوگیری از این که تی-سی-پی بدون آدرس آی-پی شروع به ارسال کنه هست.
یو-دی-پی کمتر قابل اطمینان هست ما برای مواردی که نیاز بلادرنگ دارند مثل وُیپ، چت تصویری، استریم کردن، و بازیهای بلادرنگ چند نفره به خوبی عمل میکنه.
> VoIP: وُیپ, Streaming: استریم کردن , Realtime: بلادرنگ
زمانی از یو-دی-پی به جای تی-سی-پی استفاده کنید که:
* نیاز به کمترین تاخیر دارید.
* دیر رسیدن دیتا از گم شدنش خیلی بدتره
* میخواید اصلاح خطای خودتون رو پیاده سازی کنید
#### منابع بیشتر برای مطالعه تی-سی-پی و یو-دی-پی
* [Networking for game programming](http://gafferongames.com/networking-for-game-programmers/udp-vs-tcp/)
* [Key differences between TCP and UDP protocols](http://www.cyberciti.biz/faq/key-differences-between-tcp-and-udp-protocols/)
* [Difference between TCP and UDP](http://stackoverflow.com/questions/5970383/difference-between-tcp-and-udp)
* [Transmission control protocol](https://en.wikipedia.org/wiki/Transmission_Control_Protocol)
* [Scaling memcache at Facebook](http://www.cs.bu.edu/~jappavoo/jappavoo.github.com/451/papers/memcache-fb.pdf)
### Remote procedure call (RPC)
<palign="center">
<imgsrc="http://i.imgur.com/iF4Mkb5.png">
<br/>
<i><ahref=http://www.puncsky.com/blog/2016/02/14/crack-the-system-design-interview/>Source: Crack the system design interview</a></i>
</p>
در یک آر-پی-سی کلاینت باعث اجرای یک رویه در فضای آدرس متفاوت،که معمولا یک سرور ریموت هست، میشه. این رویه طوری کد شده که انگار به صورت محلی فراخوانیش انجام میشه، جزییات اینکه چهطور ارتباط با سرور صورت میگیره رو از برنامه کلاینت پنهان میکنه. فراخوانیهای راهدور معمولا کندتر هستند و کمتر قابل اطمینانن نسبت به فراخوانیهای محلی بنابراین بهتره که فراخوانیهای راهدور رو از فراخوانیهای محلی متمایز کنیم. چارچوبهای شناخته شده آر-پی -سی شامل [پروتو-باف](https://developers.google.com/protocol-buffers/)، [ثریفت](https://thrift.apache.org/) , [آو-رو](https://avro.apache.org/docs/current/) هستند.
> Protobuf: پروتو-باف, Thrift: ثریفت, Avro: آو-رو
آر-پی-سی یک پروتکل درخواست-جواب هست:
* **Client program** - رویهی کلاینت-اِستاب رو فراخوانی میکنه. پارامترها شبیه به فراخوانی محلی داخل یک پشته نوشته میشن.
* **Client stub procedure** - آی-دی رویه و آرگومانهای اون رو مارشال میکنه(جمع میکنه) داخل درخواست.
* **Client communication module** - سیستم عامل پیام رو از کلاینت به سرور میفرسته.
* **Server communication module** - سیستم عامل پکتهای ورودی رو به رویه استاب سرور میده
* **Server stub procedure** - نتایج بازمیشن(آن-مارشال)، رویهای از سرور که با آی-دی رویه مطابقت داشته باشه با آرگومانهای دادهشده اجرا میشه.
* سرور در پاسخ مراحل بالا رو به صورت معکوس انجام میده
نمونه فراخوانی آر-پی-سی:
```
GET /someoperation?data=anId
POST /anotheroperation
{
"data":"anId";
"anotherdata": "another value"
}
```
تمرکز آر-پی-سی روی بیان رفتارهاست. آر-پی-سیها معمولا برای دلایلی مثل کارایی برای ارتباطات داخلی استفاده میشند، همینطور که شما میتونید از فراخوانیهای نِیتیو که انجام میدید و مناسب کاربردتون هست استفاده کنید.
زمانی از یک کتابخونه نِیتو(که تحت عنوان اِس-دی-کِی هم شناخته میشن) استفاده کنید که:
* پلتفرم مقصدتون رو میشناسید
* میخواید که نحوه دسترسی به "منطق" تون رو کنترل کنید
* میخواید نحوه کنترل خطاهایی که توی کتابخونتون اتفاق میوفتن رو مدیریت کنید
* کارایی و تجربهکاربری یکی از دغدغههای اصلی شماست
اِی-پی-آیهای اچ-تی-تی-پی که از **رِست** پیروی میکنن بیشتر برای اِی-پی-آیهای عمومی مورد استفاده قرار میگیرن.
#### معایب RPC
* کلاینتهای آر-پی-سی خیلی وابسته میشن به پیاده سازی سرویسها
* اِی-پی-آیهای جدید باید برای هر عمل جدید یا کاربرد جدید تعریف بشن
* دیباگ کردن آر-پی-سی میتونه دشوار باشه
* ممکنه شما نتونید از تکنولوژیهایی که درحال حاضر هستند استفاده کنید. برای مثال، ممکنه نیاز باشه تا تلاش بیشتری بکنید تا مطمئن بشد که [فراخوانیهای آر-پی-سی به درستی کش شدن](http://etherealbits.com/2012/12/debunking-the-myths-of-rpc-rest/) روی سرورهای کش مثل [اِس-کویید](http://www.squid-cache.org/)
### Representational state transfer (REST)
رِست یک نوع استایل معماری هست که مدل کلاینت/سرور رو ایجاب میکنه جایی که کلاینتها روی یک سری ریسورس که سرور مدیرتش میکنه قراره کاری انجام بدن. سرور یک نمایشی از ریسورسها رو ارائه میکنه و همچنین عملکردهایی که میتونه هم تغییر ایجاد کنه یا یک نمایش جدیدی از ریسورس رو بده. تمام ارتباطات باید بدون حالت و قابل کش کردن باشه.
چهار کیفیت از یک واسط رِست-فول وجود داره:
* **Identify resources (URI in HTTP)** - از یک یو-آر-آی مشابه برای هر عملیاتی استفاده میکنه
* **Change with representations (Verbs in HTTP)** - از افعال، هدرها و بادی استفاده میکنه.
* **Self-descriptive error message (status response in HTTP)** - از کدهای وضعیت استفاده میکنه و دوباره چرخ رو اختراع نمیکنه.
* **[HATEOAS](http://restcookbook.com/Basics/hateoas/) (HTML interface for HTTP)** - وب سرویس شما بهتره که به طور کامل در مرورگر قابل دسترسی باشه
رِست تمرکزش روی نمایش داده است. این معماری وابستگی بین کلاینت/سرور رو کم میکنه و معمولا برای اِی-پی-آیهای اچ-تی-تی-پی عمومی مورد استفاده قرار میگیره. رِست یه روش کلیتری و یکدستتری برای به نمایش گذاشتن ریسورسها استفاده میکنه که از طریق یو-آر-آی، [نمایش از طریق هِدِرها](https://github.com/for-GET/know-your-http-well/blob/master/headers.md) ، و اکشنها که به واسطه فعلهایی مثل گِت، پُست، پوت، دیلیت و پَچ است. با توجه به این که فاقد حالت هست، رِست برای اسکیل کردن افقی و پاتیشنبندی خیلی مناسبه.
* باتوحه به این که تمرکز رِست روی به نمایش گذاشتن دادههاس، برای ریسورسهایی که به صورت معمولی و سلسله مراتبی مدیرت میشن مناسب نیست. برای مثال، برگردوندن لیست آپدیتهای رکوردها توی رنج ۱ ساعت پیش که با یک سری رخدادهای خاص مِچ شده باشه چیزی نیست که بشه به صورت مسیر اونو به راحتی نشون داد. در صورت استفاده از رِست،باید این کار به وسیله ترکیبی از یو-آر-آیها، کوئری پارامترها و احتمالا با یک ریکوست بادی پیاده سازی بشه.
* رِست معمولا روی چندتا فعل محدود(گِت، پُست، پوت، دیلیت و پَچ) تمرکز داره که بعضی وقتا برای کاربرد شما مناسب نیست. برای مثال، انتقال مستنداتی که دیگه منتقضی شدن به فولدری آرشیو ممکنه که خیلی تر و تمیز با این فعلها نشه بیانش کرد.
* گرفتن ریسورس های پیچیده با ساختار سلسله مراتبی تودرتو احتیاج داره که تعداد رفت و برگشت زیاده رو بین کلاینت و سرور شاهد باشیم تا سرور یک صفحه تنها رو نمایش بده به عنوان مثال، گرفتن محتوای یک پست از بلاگ و کامنت هایی که روی اونه. برای برنامه های موبایل در شرایطی که باید بین شبکههای مختلفی کار کنند این رفت و برگشت ها خیلی مورد علاقه نیست.
* به مرورزمان، تعداد فیلدهای بیشتری ممکنه که به پاسخ اِی-پی-آی اضافه بشه و کلاینتهای قدیمی فیلدهای جدید رو هم میگیرن حتی اون دسته از فیلدهایی که بدردشون نمیخوره که این باعث میشه سایز پی-لود زیاد بشه و این خودش یعنی افزایش تاخیر.
* [Why REST for internal use and not RPC](http://arstechnica.com/civis/viewtopic.php?t=1190508)
## امنیت
این قسمت ممکنه شامل یه سری به روز رسانی ها بشه. قسمت [همکاری](#contributing) بررسی کنید.
امنیت یک مبحث گستردهای هست. احتمالا نیازی ندارید که بیشتر از مسايل پایهای رو در مورد امنیت بدونید مگر اینکه تجربهی خوبی در این زمینه یا پیشزمینه امنیت داشته باشید و یا قصد دارید که برای پوزیشنی که نیاز به دانش امینت داره برید:
* Encrypt in transit and at rest.
* Sanitize all user inputs or any input parameters exposed to user to prevent [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) and [SQL injection](https://en.wikipedia.org/wiki/SQL_injection).
* Use parameterized queries to prevent SQL injection.
* Use the principle of [least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege).
### منابع برای مطالعه بیشتر
* [Security guide for developers](https://github.com/FallibleInc/security-guide-for-developers)
* [OWASP top ten](https://www.owasp.org/index.php/OWASP_Top_Ten_Cheat_Sheet)
## پیوست
بعضا از شما میخوان که یه سری محاسبات سریعی رو انجام بدید. برای مثال ممکنه نیاز داشته داشته بدونید که چقدر زمان نیازه تا ۱۰۰ تصویر ثامب-نِیل از روی دیسک تولید بشه یا اینکه چقدر حافظه یک ساختمان داده خاص نیاز داره. **جدول اعداد توان ۲** و **اعداد تاخیری که هر برنامه نویسی باید بدونه** یه منبع مناسب هست برای این کار.
* [Latency numbers every programmer should know - 1](https://gist.github.com/jboner/2841832)
* [Latency numbers every programmer should know - 2](https://gist.github.com/hellerbarde/2843375)
* [Designs, lessons, and advice from building large distributed systems](http://www.cs.cornell.edu/projects/ladis2009/talks/dean-keynote-ladis2009.pdf)
* [Software Engineering Advice from Building Large-Scale Distributed Systems](https://static.googleusercontent.com/media/research.google.com/en//people/jeff/stanford-295-talk.pdf)
### سوالات بیشتر مصاحبه طراحی سیستم
> سوالات رایج مصاحبه طراحی سیستم به همراه لینک به منابعی که روش حلش رو ارائه کرده
| Design a file sync service like Dropbox | [youtube.com](https://www.youtube.com/watch?v=PE4gwstWhmc) |
| Design a search engine like Google | [queue.acm.org](http://queue.acm.org/detail.cfm?id=988407)<br/>[stackexchange.com](http://programmers.stackexchange.com/questions/38324/interview-question-how-would-you-implement-google-search)<br/>[ardendertat.com](http://www.ardendertat.com/2012/01/11/implementing-search-engines/)<br>[stanford.edu](http://infolab.stanford.edu/~backrub/google.html) |
| Design a scalable web crawler like Google | [quora.com](https://www.quora.com/How-can-I-build-a-web-crawler-from-scratch) |
| Design Google docs | [code.google.com](https://code.google.com/p/google-mobwrite/)<br/>[neil.fraser.name](https://neil.fraser.name/writing/sync/) |
| Design a key-value store like Redis | [slideshare.net](http://www.slideshare.net/dvirsky/introduction-to-redis) |
| Design a cache system like Memcached | [slideshare.net](http://www.slideshare.net/oemebamo/introduction-to-memcached) |
| Design a recommendation system like Amazon's | [hulu.com](http://tech.hulu.com/blog/2011/09/19/recommendation-system.html)<br/>[ijcai13.org](http://ijcai13.org/files/tutorial_slides/td3.pdf) |
| Design a tinyurl system like Bitly | [n00tc0d3r.blogspot.com](http://n00tc0d3r.blogspot.com/) |
| Design a chat app like WhatsApp | [highscalability.com](http://highscalability.com/blog/2014/2/26/the-whatsapp-architecture-facebook-bought-for-19-billion.html)
| Design a picture sharing system like Instagram | [highscalability.com](http://highscalability.com/flickr-architecture)<br/>[highscalability.com](http://highscalability.com/blog/2011/12/6/instagram-architecture-14-million-users-terabytes-of-photos.html) |
| Design the Facebook news feed function | [quora.com](http://www.quora.com/What-are-best-practices-for-building-something-like-a-News-Feed)<br/>[quora.com](http://www.quora.com/Activity-Streams/What-are-the-scaling-issues-to-keep-in-mind-while-developing-a-social-network-feed)<br/>[slideshare.net](http://www.slideshare.net/danmckinley/etsy-activity-feeds-architecture) |
| Design the Facebook timeline function | [facebook.com](https://www.facebook.com/note.php?note_id=10150468255628920)<br/>[highscalability.com](http://highscalability.com/blog/2012/1/23/facebook-timeline-brought-to-you-by-the-power-of-denormaliza.html) |
| Design the Facebook chat function | [erlang-factory.com](http://www.erlang-factory.com/upload/presentations/31/EugeneLetuchy-ErlangatFacebook.pdf)<br/>[facebook.com](https://www.facebook.com/note.php?note_id=14218138919&id=9445547199&index=0) |
| Design a graph search function like Facebook's | [facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-building-out-the-infrastructure-for-graph-search/10151347573598920)<br/>[facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-indexing-and-ranking-in-graph-search/10151361720763920)<br/>[facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-the-natural-language-interface-of-graph-search/10151432733048920) |
| Design a content delivery network like CloudFlare | [cmu.edu](http://repository.cmu.edu/cgi/viewcontent.cgi?article=2112&context=compsci) |
| Design a trending topic system like Twitter's | [michael-noll.com](http://www.michael-noll.com/blog/2013/01/18/implementing-real-time-trending-topics-in-storm/)<br/>[snikolov .wordpress.com](http://snikolov.wordpress.com/2012/11/14/early-detection-of-twitter-trends/) |
| Design a random ID generation system | [blog.twitter.com](https://blog.twitter.com/2010/announcing-snowflake)<br/>[github.com](https://github.com/twitter/snowflake/) |
| Return the top k requests during a time interval | [ucsb.edu](https://icmi.cs.ucsb.edu/research/tech_reports/reports/2005-23.pdf)<br/>[wpi.edu](http://davis.wpi.edu/xmdv/docs/EDBT11-diyang.pdf) |
| Design a system that serves data from multiple data centers | [highscalability.com](http://highscalability.com/blog/2009/8/24/how-google-serves-data-from-multiple-datacenters.html) |
| Design an online multiplayer card game | [indieflashblog.com](http://www.indieflashblog.com/how-to-create-an-asynchronous-multiplayer-game.html)<br/>[buildnewgames.com](http://buildnewgames.com/real-time-multiplayer/) |
| Design a garbage collection system | [stuffwithstuff.com](http://journal.stuffwithstuff.com/2013/12/08/babys-first-garbage-collector/)<br/>[washington.edu](http://courses.cs.washington.edu/courses/csep521/07wi/prj/rick.pdf) |
| Design an API rate limiter | [https://stripe.com/blog/](https://stripe.com/blog/rate-limiters) |
| Add a system design question | [Contribute](#contributing) |
### معماری های دنیای واقعی
> مقالههایی در مورد اینکه سیستمهای دنیای واقعی به صورتی طراحی شدهاند
<palign="center">
<imgsrc="http://i.imgur.com/TcUo2fw.png">
<br/>
<i><ahref=https://www.infoq.com/presentations/Twitter-Timeline-Scalability>Source: Twitter timelines at scale</a></i>
</p>
**روی جزيات مقالههای زیر تمرکز نکنید،در عوض:**
* اصول مشترک، تکنولوژیهای مرسوم، و الگوهایی که در این مقالات استفاده شده رو پیدا کنید.
* اینکه چه کامپوننتی چه مسالهای رو حل میکنه، کجا کار میکنه، و کجا کار نمیکنه رو بررسی کنید
| Data processing | **MapReduce** - Distributed data processing from Google | [research.google.com](http://static.googleusercontent.com/media/research.google.com/zh-CN/us/archive/mapreduce-osdi04.pdf) |
| Data processing | **Spark** - Distributed data processing from Databricks | [slideshare.net](http://www.slideshare.net/AGrishchenko/apache-spark-architecture) |
| Data processing | **Storm** - Distributed data processing from Twitter | [slideshare.net](http://www.slideshare.net/previa/storm-16094009) |
| | | |
| Data store | **Bigtable** - Distributed column-oriented database from Google | [harvard.edu](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf) |
| Data store | **HBase** - Open source implementation of Bigtable | [slideshare.net](http://www.slideshare.net/alexbaranau/intro-to-hbase) |
| Data store | **Cassandra** - Distributed column-oriented database from Facebook | [slideshare.net](http://www.slideshare.net/planetcassandra/cassandra-introduction-features-30103666)
| Data store | **DynamoDB** - Document-oriented database from Amazon | [harvard.edu](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/decandia07dynamo.pdf) |
| Data store | **MongoDB** - Document-oriented database | [slideshare.net](http://www.slideshare.net/mdirolf/introduction-to-mongodb) |
| Data store | **Spanner** - Globally-distributed database from Google | [research.google.com](http://research.google.com/archive/spanner-osdi2012.pdf) |
| Data store | **Memcached** - Distributed memory caching system | [slideshare.net](http://www.slideshare.net/oemebamo/introduction-to-memcached) |
| Data store | **Redis** - Distributed memory caching system with persistence and value types | [slideshare.net](http://www.slideshare.net/dvirsky/introduction-to-redis) |
| | | |
| File system | **Google File System (GFS)** - Distributed file system | [research.google.com](http://static.googleusercontent.com/media/research.google.com/zh-CN/us/archive/gfs-sosp2003.pdf) |
| File system | **Hadoop File System (HDFS)** - Open source implementation of GFS | [apache.org](https://hadoop.apache.org/docs/r1.2.1/hdfs_design.html) |
| | | |
| Misc | **Chubby** - Lock service for loosely-coupled distributed systems from Google | [research.google.com](http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/archive/chubby-osdi06.pdf) |
| ESPN | [Operating At 100,000 duh nuh nuhs per second](http://highscalability.com/blog/2013/11/4/espns-architecture-at-scale-operating-at-100000-duh-nuh-nuhs.html) |
| Google | [Google architecture](http://highscalability.com/google-architecture) |
| Instagram | [14 million users, terabytes of photos](http://highscalability.com/blog/2011/12/6/instagram-architecture-14-million-users-terabytes-of-photos.html)<br/>[What powers Instagram](http://instagram-engineering.tumblr.com/post/13649370142/what-powers-instagram-hundreds-of-instances) |
| Justin.tv | [Justin.Tv's live video broadcasting architecture](http://highscalability.com/blog/2010/3/16/justintvs-live-video-broadcasting-architecture.html) |
| Facebook | [Scaling memcached at Facebook](https://cs.uwaterloo.ca/~brecht/courses/854-Emerging-2014/readings/key-value/fb-memcached-nsdi-2013.pdf)<br/>[TAO: Facebook’s distributed data store for the social graph](https://cs.uwaterloo.ca/~brecht/courses/854-Emerging-2014/readings/data-store/tao-facebook-distributed-datastore-atc-2013.pdf)<br/>[Facebook’s photo storage](https://www.usenix.org/legacy/event/osdi10/tech/full_papers/Beaver.pdf) |
| Mailbox | [From 0 to one million users in 6 weeks](http://highscalability.com/blog/2013/6/18/scaling-mailbox-from-0-to-one-million-users-in-6-weeks-and-1.html) |
| Pinterest | [From 0 To 10s of billions of page views a month](http://highscalability.com/blog/2013/4/15/scaling-pinterest-from-0-to-10s-of-billions-of-page-views-a.html)<br/>[18 million visitors, 10x growth, 12 employees](http://highscalability.com/blog/2012/5/21/pinterest-architecture-update-18-million-visitors-10x-growth.html) |
| Playfish | [50 million monthly users and growing](http://highscalability.com/blog/2010/9/21/playfishs-social-gaming-architecture-50-million-monthly-user.html) |
| Tumblr | [15 billion page views a month](http://highscalability.com/blog/2012/2/13/tumblr-architecture-15-billion-page-views-a-month-and-harder.html) |
| Twitter | [Making Twitter 10000 percent faster](http://highscalability.com/scaling-twitter-making-twitter-10000-percent-faster)<br/>[Storing 250 million tweets a day using MySQL](http://highscalability.com/blog/2011/12/19/how-twitter-stores-250-million-tweets-a-day-using-mysql.html)<br/>[150M active users, 300K QPS, a 22 MB/S firehose](http://highscalability.com/blog/2013/7/8/the-architecture-twitter-uses-to-deal-with-150m-active-users.html)<br/>[Timelines at scale](https://www.infoq.com/presentations/Twitter-Timeline-Scalability)<br/>[Big and small data at Twitter](https://www.youtube.com/watch?v=5cKTP36HVgI)<br/>[Operations at Twitter: scaling beyond 100 million users](https://www.youtube.com/watch?v=z8LU0Cj6BOU) |
لیست وبلاگها در اینجا نسبتا کوتاهتر نگه داشته میشه و ریپازیتوری زیر شامل لیست بلندی از این وبلاگهاست که برای جلوگیری از دوباره نویسی در اینجا، فقط همین بخش کم آورده شده. وبلاگ مهندسی کمپانیتون روبه ریپازیتوری زیر اضافه کنید
* [A distributed systems reading list](http://dancres.github.io/Pages/)
* [Cracking the system design interview](http://www.puncsky.com/blog/2016/02/14/crack-the-system-design-interview/)
## اطلاعات تماس
در صورتی که نیازه تا با من در مورد ایشوها، سوالها یا کامنتها صحبت کنید، راحت باشید و ارتباط بگیرید.
اطلاعات تماس من روی [صفحه گیت-هاب](https://github.com/donnemartin) من قابل دسترسی هست.
## License
*I am providing code and resources in this repository to you under an open source license. Because this is my personal repository, the license you receive to my code and resources is from me and not my employer (Facebook).*
Copyright 2017 Donne Martin
Creative Commons Attribution 4.0 International License (CC BY 4.0)