# پایگاه‌های داده > NoSQL >  منظور از Eventual consistency و strong consistency در پایگاه داده های Nosql

## kiani2012

سلام
کسی میدونه منظور از Eventual consistency و strong consistency در پایگاه داده های Nosql چیه؟
و تفاوتشون چیه؟

----------


## -سیّد-

> سلام
> کسی میدونه منظور از Eventual consistency و strong consistency در پایگاه داده های Nosql چیه؟
> و تفاوتشون چیه؟


سلام

منظور از Strong consistency اینه که وقتی شما یه داده‌ای رو نوشتی، به محض این که OK رو از پایگاه داده گرفتی، از اون لحظه به بعد هر کسی اون داده رو بخونه آخرین نسخه رو ببینه.
مثال:
فرض کنید ۳ تا client دارید به نام‌های A و B و C.
در زمان ۱۰۰ (فرض کنید واحد زمان میلی ثانیه هست) آقای A داده‌ی x رو می‌نویسه و مقدارش رو می‌ذاره a. در زمان ۱۰۲، OK رو از پایگاه داده می‌گیره. حالا در زمان ۱۰۲ به بعد، هر کدوم از A یا B یا C اگه داده‌ی x رو بخونن، در صورت وجود Strong consistency باید مقدار a رو ببینن.
حالا فرض کنید در زمان ۱۲۰ آقای B همون داده‌ی x رو مقدارش رو می‌ذاره b و در زمان ۱۲۵، OK می‌گیره. تا قبل از ۱۲۵ هر کدوم از client ها که این داده رو بخونن، باید a بگیرن و بعد از اون باید b بگیرن. یعنی داده‌ی به‌روزرسانی شده رو ببینن.

اما Eventual consistency به این معنی هست که وقتی یه نفر یه مقداری رو نوشت، بقیه لزوماً همون موقع مقدار جدید رو نمی‌بینن و در اثر مرور زمان بالاخره یه وقتی می‌رسه که مقدار جدید رو ببینن. یعنی بسته به load سیستم و پارامترهای دیگه، ممکنه مثلاً ۱ دقیقه (یا یک ساعت، یا حتی یک روز) طول بکشه تا مقدار جدید رو ببینن.

یعنی توی همون مثال، در صورت وجود Eventual consistency وقتی که توی زمان ۱۲۵ OK رو به B دادیم، ممکنه توی زمان ۱۳۰ آقای C داده‌ی x رو که بخونه، مقدار قبلیش یعنی a رو ببینه. یا حتی توی حالت اول، ممکنه وقتی توی زمان ۱۰۲ OK رو به A دادیم، توی زمان ۱۱۰ یکی بیاد داده رو بخونه و پایگاه داده بهش بگه چنین داده‌ای وجود نداره. ولی بالاخره یه زمانی می‌رسه که مقدار رو ببینه. یعنی مثلاً همون client ممکنه توی زمان ۱۵۰ که بخونه، مقدارش رو ببینه.

به عنوان مثال، توی پایگاه‌های داده، HBase دارای Strong consistency هست. اما Cassandra دارای Eventual consistency هست که قابل تنظیم به Strong هست. ولی در صورتی که روی Strong تنظیمش کنید، performance اش پایین میاد (چون باید مطمئن بشه که تمام replica ها داده‌ی جدید رو گرفتن و بعد به شما OK بده برای write).

مثلاً facebook چون توی سیستم Messaging اش نیاز به Strong consistency داشت، این سیستم رو چند سال پیش از Cassandra به HBase منتقل کرد.

البته بحث زیاده، چون مثلاً HBase چیزی که نسبت به Cassandra کم داره، Availability هست.

----------


## kiani2012

سلام جناب سید خیلی ممنون از جواب خوبت
ی سوال اگر بقیه نتیجه تراکنشی را دیر ببینن که خیلی بده توی داده ها ناسازگاری پیش میاد؟
این نوع پایگاه داده ها کجا کاربرد دارن؟

----------


## -سیّد-

خوب این بستگی به کاربرد شما داره.
ببینین توی Big Data ممکنه برای شما  اهمیت نداشته باشه که مثلاً یه بخشی از داده دیرتر به‌روز بشه. مثلاً فرض  کنید ۱۰ میلیارد رکورد دارید، حالا ده هزار تاش دیرتر به‌روز بشن شاید  براتون مهم نباشه. عوضش سرعت write تون به شدت می‌تونه بالاتر بره.
مثال‌هاش  رو زیاد می‌تونید توی دنیای وب پیدا کنید. مثلاً معمولاً هر جایی که cache  وجود داره، یه مقداری inconsistency به وجود میاد، چون خیلی وقتها cache  نمی‌تونه خودش رو همیشه به‌روز نگه داره.

این صفحه توضیحات خوبی درباره‌ی این مدل داده:
http://www.allthingsdistributed.com/...onsistent.html
این مقاله هم خوبه:
https://queue.acm.org/detail.cfm?id=2462076

----------


## kiani2012

ok 
منظور از Sharding چیه؟

----------


## -سیّد-

وقتی شما با داده‌های زیاد سر و کار دارید، ۲ روش کلی برای handle کردن اونها وجود داره:
۱.  Vertical scaling: در این روش شما سرورتون رو قوی‌تر می‌کنید. یعنی فرض  کنید سیستمی دارید که توش برای سرویس دادن هر ۲۰۰ گیگابایت داده، یک core  از CPU به همراه ۱۶ گیگابایت RAM لازم داشته باشید، و خوب ۲۰۰ گیگابایت هم  هارد لازم دارید. حالا اگه داده‌ی شما به ۲ ترابایت برسه، اگه به صورت  vertical بخواین سیستم رو گسترش بدین، باید یه سیستم داشته باشید با ۱۰ تا  CPU core و ۱۶۰ گیگابایت RAM و ۲ ترابایت فضای ذخیره‌سازی. خوب این تا حدی  قابل تحمله. ولی اگه داده‌ی شما به ۲۰ ترابایت برسه، باید ۱۰۰ تا CPU core  داشته باشید و ۱.۶ ترابایت RAM و ۲۰ ترابایت هم فضای ذخیره‌سازی! خوب یه  همچین سیستمی به شدت گرون هست و اصلاً نمی‌صرفه آدم بهش فکر کنه. پس به  سراغ روش دوم می‌ریم.
۲. Horizontal scaling: در این روش شما داده رو  تکه تکه می‌کنید و هر تکه رو روی یه سرور نگهداری می‌کنید. به هر کدوم از  این تکه‌ها یک Shard می‌گن و به این روش Sharding هم می‌گن. حالا همون مثال  قبل رو در نظر بگیرید. برای ۲۰ ترابایت داده، می‌تونید مثلاً از ۲۰ تا  سرور که هر کدوم ۵ CPU core و ۸۰ گیگابایت RAM و ۱ ترابایت فضای ذخیره‌سازی  دارن استفاده کنید. تو این حالت هر shard شما ۱ ترابایت هست و روی یه سرور  ذخیره می‌شه.

البته مسائلی از قبیل replication رو هم باید در نظر  بگیرید که در نتیجه اگه مثلاً replication factor شما برابر ۲ باشه، توی  مثال قبل از هر shard باید ۲ تا ذخیره کنید و در نتیجه روی هر سرور ۲  ترابایت فضای هارد مصرف می‌شه.

این اسلایدهای گوگل هم خیلی خوب هستن و توش به مسئله‌ی sharding و replication هم اشاره شده:
http://research.google.com/people/je...L-Nov-2010.pdf


Sharding.png

----------


## kiani2012

آهان بسیار عالی جناب سید خیلی ممنون
یه مقاله س دارم میخونمش هر چقدر بیشتر میخونم بیشتر سوال برم پیش میاد 
شرمنده ، توی این مقاله نام از   Client sessions برده شده ، منظورش چیه؟ یکی از  جمله ها اینه 

at 32 client sessions, there is only a 10% reduction in throughput moving from eventual to strong consistency (As discussed above, test client configuration issues resulted in no data recorded for 500 and 1000 concurrent sessions.)


و سوال دیگه اینکه :
منظور از ایجاد کلاینت تست بار  ( Create Load Test Client ) چیه؟

----------


## kiani2012

کسی از Client Session اطلاعی نداره؟

----------


## -سیّد-

معنی دقیق اینایی که می‌گید توی اون مقاله مشخص می‌شه و من می‌تونم فقط مفاهیم کلی رو بگم (برای همین هم تا الان جواب ندادم که اگه کسی جواب دقیق‌تری داره بگه).
به طور کلی، session یا نشست، به معنای یه بازه‌ی زمانی حضور یه نفر توی سیستم هست. یعنی از لحظه‌ی اولی که شما وارد سیستم می‌شید، تا وقتی که باهاش خداحافظی می‌کنید، یه session هست. بعضی سیستم‌ها از وقتی که لاگین می‌کنید session رو براتون باز می‌کنن، بعضی دیگه از اولین باری که به سیستم سر می‌زنید (حتی اگه کلاً لاگین نکنید).
حالا این مفهوم تو جاهای مختلف هست. معروفترینش توی سایت‌ها هست، ولی توی سیستم‌های دیگه هم استفاده می‌شه. مثلاً شما وقتی می‌خواین با یه پایگاه داده ارتباط برقرار کنین، باید یه کانکشنی بهش بزنید. از لحظه‌ی اولی که کانکشن برقرار می‌شه تا وقتی که می‌بندیدش، یه session محسوب می‌شه.

حالا اینجا وقتی می‌گه ۳۲ تا client session داریم، یعنی ۳۲ نفر همزمان دارن با سیستم کار می‌کنن. البته ممکنه کل این ۳۲ تا روی یه سیستم باشن، یا حتی توی یه process باشن، یا حتی‌تر(!) توی یه thread باشن. مهم اینه که از دید سیستم، اینا ۳۲ تا کاربر هستن. ممکنه توی یه سیستمی به ازای هر process یک session بیشتر نتونید ایجاد کنید. یا مثلاً به ازای هر IP یه session داشته باشید (البته معمولاً هر thread یه session می‌تونه برای خودش ایجاد کنه).

بنابراین منظور اون جمله اینه که در حالتی که بار سیستم به اندازه‌ی ۳۲ تا کاربر همزمان هست، strong کردن consistency فقط ۱۰٪ کارآمدی سیستم رو کاهش داده.

در مورد سؤال دومتون: باز هم من می‌تونم مفهوم کلی رو بگم:
منظور از Load test اینه که شما یه باری روی سیستم بندازید تا بتونید سیستم رو توی شرایطی که تحت استفاده هست بررسی کنید (چیزایی مثل stability و availability و performance رو بررسی کنید که توی چه باری، چه تأثیری می‌پذیرن). در واقع این کار یه جواریی شبیه‌سازی شرایط واقعی هست که ۱۰۰ تا کاربر به صورت همزمان می‌خوان با سیستم شما کار کنن، برای همین شما یه Load test به اندازه‌ی ۱۰۰ نفر درست می‌کنید و شرایط سیستم رو بررسی می‌کنید. بعد مثلاً می‌بینید مشکلی برای سیستم به وجود نیومد، تعداد رو بالاتر می‌برید. بعد مثلاً می‌بینید که وقتی به ۵۰۰ نفر همزمان رسیدید، کم کم سیستم شروع می‌کنه به کند شدن. اینجا می‌تونید متوجه بشید که کشش سیستم شما چقدر هست.

روش سنتی (که  خیلی هم بین ما تنبلا طرفدار داره!) اینه که یه بسم‌الله می‌گین و سیستم رو می‌ذارین زیر بار! بعد از مدتی می‌بینید که ای داد بیداد! سر اعلام نتایج کنکور که شد، یهو در اثر مراجعه‌ی همزمان هزاران نفر به سایت، سایتتون اومد پایین! بعد سال بعد تلاشتون رو می‌کنید که پایین نیاد، و موفق می‌شید! ولی می‌بینید که هر query نزدیک به ۳۰ ثانیه طول می‌کشه تا جواب بگیره! اشاره هم به سایت خاصی نمی‌کنم!  :چشمک: 

(حالا یه کم هم از موتور خودمون تعریف کنم!) به عنوان مثال ما قبل از launch کردن موتور یوز، انواع تست‌ها رو انجام داده بودیم و به صورت تقریبی می‌دونستیم که توان موتور با توجه به سخت‌افزار فعلی در چه حد هست. برای همین وقتی که توی روزهای اول بالا اومدن موتور در اثر تبلیغ تلویزیونی چند بار peak شدید به سیستم خورد، مشکل خاصی پیش نیومد و سیستم تقریباً به صورت روان داشت جواب می‌داد. (پایان پیام تبلیغاتی!  :لبخند گشاده!: )

حالا که اینا رو گفتم، اجازه بدید این رو هم بگم که چرا روش سنتی بین ماها رواج داره. دلیلش اینه که کل روند تست (شامل طراحی تست، نوشتن کد تست، اجرای تست، و تحلیل خروجی تست) یه فرایند زمان‌بر هست، در حدی که بعضی وقتها انجام تست به اندازه‌ی نصف زمانی که برای نوشتن کد گذاشتید ازتون وقت می‌گیره (این تست که می‌گم شامل انواع تست می‌شه: هم تست صحت عملکرد سیستم، و هم تست performance). برای همین خوب خیلی ساده هست: مدیر می‌گه برای چی باید ۱.۵ برابر زمان بذارم و تست کنم سیستم رو؟ همون یک برابر زمان می‌ذارم و به سیستم اعتماد می‌کنم!
اشکال این کار اینه که هزینه‌ای که باید برای جبران خسارت‌های ناشی از تست نکردن سیستم بپردازید (هزینه فقط پول نیست، شامل چیزایی مثل زمان و اعتماد کاربرا و اعصاب نیروها هم می‌شه) به مراتب بیشتر از اون ۵۰٪ زمانیه که باید برای تست می‌ذاشتید.

یکی از ایرانی‌هایی که توی گوگل کار می‌کرد، می‌گفت گاهی برای ۱۰ خط کدی که می‌نویسیم، مجبور می‌شیم ۱۰۰ خط تست بنویسیم. (البته به *گاهی* توجه کنید! همیشه اینطوری نیست!)

----------


## kiani2012

آهان
ممنون :)

----------

