توضیحات · دو
دانلودی که بینقص پیش میرود حالت آسان است، و هر برنامهای آن را با کفایت از پس برمیآید. تفاوتهای جالب وقتی پیدا میشوند که بخشی از پست کم باشد، و این خیلی بیشتر از آنچه حالت تمیز نشان میدهد رخ میدهد. این چیزی است که واقعاً میگذرد، و اینکه چرا اینقدر وقت میبرد.
شکل مسئله
یک پست Usenet یک فایل نیست. هزاران مقالهٔ کوچک است، هرکدام مستقل روی کارسازهای هر ارائهدهنده ذخیره شده، و NZBای که دانلود میکنی فهرست نامهای آنهاست. یک انتشار 6.5 GB تقریباً 9,000 تای آنهاست.
مقالهها به دلایل معمولی گم میشوند. ارائهدهندهها آنها را برای دورهٔ نگهداری ثابتی نگه میدارند و بعد پاک میکنند. برخی ارائهدهندهها مقالهٔ خاصی را از همان اول هرگز دریافت نکردهاند، چون انتشار میان کارسازها ناقص است. گاهی بارگذاری هنگام انتشار ناتمام بوده، و بخشی از آن هیچجا هرگز وجود نداشته. علت هرچه باشد، اثر یکی است: برنامهٔ تو مقالهای میخواهد، و پاسخ بهجای داده یک رد است.
این آنقدر عادی است که کسانی که در Usenet پست میگذارند حسابش را میکنند. تقریباً هر انتشاری همراه با دادهٔ توازن میآید، معمولاً فایلهای PAR2، یعنی اطلاعات افزونهٔ اضافی که از روی اصل محاسبه شده. اگر بخشی از محتوا کم باشد، توازن میتواند بازسازیاش کند، به شرط آنکه به قدر کافی داشته باشی. یک پست معمولی حدود 10% توازن به همراه دارد، پس پست میتواند سهم قابل توجهی از خودش را از دست بدهد و همچنان کاملاً بازیافتنی بماند.
پس پست آسیبدیده معمولاً دانلودی خراب نیست. دانلودی است که پیش از کامل شدن اندکی حساب لازم دارد. تنها پرسش این است که یک برنامه چقدر طول میکشد تا این را دریابد، و درست همانجاست که به اندازهٔ دو برابر یا بیشتر فرق میکنند.
بخش گران
وقتی کارسازی مقالهای را ندارد، یک رد برمیگرداند، و برنامه آنگاه کارساز بعدی فهرست تو را میآزماید. این کار درستی است، چون ارائهدهندهٔ دوم خیلی وقتها آن را دارد. هزینه وقتی پیدا میشود که هیچکس آن را نداشته باشد.
در آن صورت برنامه تمام فهرست ارائهدهندههای تو را میپیماید، هر بار یک کارساز، و پیش از آنکه بتواند نتیجه بگیرد مقاله واقعاً رفته است، از تکتکشان رد میگیرد. این پیمایش پیاپی است، و ردها کندتر از آناند که مردم گمان میکنند. آنها را مستقیم اندازه گرفتیم، روی خطی بیکار، بیآنکه هیچ محتوایی جابهجا شود:
| ارائهدهنده | زمان پاسخ به یک درخواست عادی | زمان رد کردن یک مقالهٔ گمشده |
|---|---|---|
| ارائهدهندهٔ A | 77.5 ms | 78.8 ms |
| ارائهدهندهٔ B | 10.5 ms | 454 ms |
| ارائهدهندهٔ C | 10.8 ms | 871 ms |
| ارائهدهندهٔ D | 9.9 ms | 1,227 ms |
| ارائهدهندهٔ E | 10.6 ms | 2,239 ms |
دو چیز به چشم میآید. نخست اینکه پراکندگی عظیم است: یک رد بسته به اینکه کدام ارائهدهنده پاسخ میدهد جایی بین 79 ms و 2.2 ثانیه هزینه دارد، تفاوتی نزدیک به سی برابر. دوم اینکه یک ارائهدهنده اساساً در همان زمانی که پرسیدن میبرد رد میکند، حال آنکه دیگری بیش از دویست برابر زمان پاسخ عادی خودش طول میدهد تا نه بگوید. این تأخیر شبکه نیست، کاری است که در سمت آنها میگذرد، و پرسیدن با رفتوبرگشت کمتر بهسختی کمکی میکند.
جمع بزن: یک پیمایش کامل روی پنج ارائهدهنده، برای یک مقالهٔ واحد که دیگر وجود ندارد، حدود 5 ثانیه هزینه دارد. حالا در نظر بگیر که پست آسیبدیده مقالههای بسیاری از این دست دارد، و برنامهای که آنها را پیاپی پردازش میکند این هزینه را بارها میپردازد در حالی که اتصال تو بیکار نشسته است. دانلود کند نیست چون داده کند میرسد. داده اصلاً رسیدن را متوقف کرده، و برنامه منتظر است چیزی به او گفته شود که خودش به قدر کافی اطلاعات دارد تا استنتاجش کند.
راهحل
بصیرت این نیست که ردها را تندتر کنیم، چون ارائهدهندهها در اختیار ما نیستند. این است که لحظهای را دریابیم که پاسخ دیگر اهمیتی ندارد.
در هر لحظه از دانلود، برنامه دو چیز میداند: چند تکه هنوز به حساب نیامده، و چقدر دادهٔ توازن از پیش در دست دارد. اگر توازنِ در دست برای بازسازی همهٔ آنچه مانده کافی باشد، آنگاه پاسخ به «آیا کسی این مقاله را دارد؟» دیگر نمیتواند نتیجه را عوض کند. چه بلهٔ کند باشد چه نهِ کند، فایل به هر حال بازسازی میشود. ادامهٔ پیمایش چیزی جز تأخیر نمیخرد.
پس نسخهٔ کنونی در آن نقطه پرسیدن را بس میکند و یکراست به ترمیم میرود. خودِ بازسازی سریع است و همیشه بوده: حدود 2.3 ثانیه روی پستی 6.5 GB، و آن عدد در هر نسخهای که سنجیدهایم یکی است. زمان صرفهجوییشده تماماً انتظاری است که دیگر رخ نمیدهد.
| پست 6.5 GB، 60 مقالهٔ گمشده | زمان تا فایل وارسیشده |
|---|---|
| انتظار برای رد هر ارائهدهنده | 23 s |
| ایستادن بهمحض آنکه توازن شکاف را بپوشاند | 13 s |
| که از آن، خودِ حساب ترمیم | 2.3 s |
همین تغییر روی پست آسیبندیده هیچ کاری نمیکند، و این روشنترین شاهد است که کار مورد نظر ما را میکند: بی مقالهٔ گمشده پیمایشی نیست که کوتاه شود، و هر دو نسخه کاری تمیز 6.5 GB را در 7 ثانیهٔ یکسان تمام میکنند.
این یک معامله است، نه بردی مجانی. ترمیم زودهنگام یعنی نگه داشتن دادهٔ توازن در حافظه بهجای دور انداختن و آوردن بیشتر در آینده، پس اوج حافظه (RSS) روی پستی بهشدت آسیبدیده از حدود 0.8 GB به حدود 1.3 GB میرسد، و تقریباً 400 MB بیشتر از ارائهدهندهها میکشیم. روی پست آسیبندیده حافظه بیتغییر در 0.24 GB میماند. فکر میکنیم برای بیشتر مردم این معاملهٔ درستی است، چون حافظه تنها در حالتی خرج میشود که ده ثانیه برایت میخرد، اما هزینهای واقعی است و برایش تنظیمی هست.
نام ارائهدهندهها در جدول رد عمداً پوشیده مانده است. این اعداد ویژگی یک اندازهگیری در یک شب از یک مکاناند، و ارائهدهندهای که بهگونهٔ دیگری نمایه میکند، یا که اتفاقاً در شبی بد به آن رسیدیم، نباید بر پایهٔ یک دور به کندی متهم شود. آنچه برای استدلال اهمیت دارد شکل ماجراست: ردها بهشدت متغیرند، و مجموع آنقدر بزرگ هست که بر دانلودی آسیبدیده چیره شود. اعداد به تفکیک ارائهدهنده و خروجی خام کاوش در سوابق داخلی ماست، و اعداد سرتاسریای که آنها را توضیح میدهند در صفحهٔ محکها است.