RRDTUTORIAL(1) rrdtool RRDTUTORIAL(1)

rrdtutorial - راهنمای آموزشی RRDtool نوشته الکس ون دن بوگارت

ابزار RRDtool توسط توبیاس اوتیکر <tobi@oetiker.ch> با مشارکت افراد بسیاری از سراسر جهان نوشته شده است. این سند توسط الکس ون دن بوگارت <alex@vandenbogaerdt.nl> نوشته شده تا به شما در درک چیستی RRDtool و قابلیت‌های آن برای رفع نیازهایتان کمک کند.

مستندات ارائه‌شده همراه با RRDtool ممکن است برای برخی افراد بیش از حد فنی باشد. این راهنمای آموزشی اینجاست تا به شما در یادگیری مفاهیم پایه‌ای RRDtool کمک کند و شما را برای خواندن مستقل مستندات رسمی آماده سازد. همچنین مفاهیم کلی درباره آمار با تمرکز بر مدیریت شبکه را توضیح می‌دهد.

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

گاهی اوقات چیزها تغییر می‌کنند. این مثال در گذشته اعدادی مانند "0.04" را به جای "4.00000e-02" نمایش می‌داد. این‌ها در واقع یک عدد یکسان هستند که به اشکال متفاوتی نوشته شده‌اند. اگر نسخه‌های بعدی rrdtool خروجی را با کمی تفاوت در قالب نمایش دادند، نگران نشوید. مثال‌های موجود در این سند بر اساس نسخه 1.2.0 نرم‌افزار RRDtool معتبر و صحیح هستند.

همچنین، گاهی اشکالات نرم‌افزاری (باگ‌ها) رخ می‌دهند که می‌توانند بر نتایج مثال‌ها تأثیر بگذارند. مثال speed4.png در گذشته دچار چنین مشکلی بود (مدیریت داده‌های نامشخص در یک دستور if اشتباه بود). داده‌های معمولی به خوبی کار خواهند کرد (یک باگ در rrdtool معمولاً دوام زیادی ندارد)، اما موارد خاص مانند NaN و INF و امثال آن ممکن است کمی بیشتر زمان ببرند. در صورت امکان نسخه دیگری را امتحان کنید یا فعلاً با آن کنار بیایید.

من مثال speed4.png را اصلاح کردم (و یادداشتی به آن افزودم). ممکن است مثال‌های دیگری نیز وجود داشته باشند که دچار همان باگ یا اشکالات مشابه باشند. تلاش کنید خودتان آن را برطرف کنید؛ این یک تمرین عالی است. اما لطفاً نتیجه خود را به عنوان وصله برای سورس این سند ارسال نکنید؛ آن را در فهرست پستی کاربران مطرح کنید یا برای من ایمیل بفرستید.

نام RRDtool مخفف ابزار پایگاه‌داده راند روبین (Round Robin Database tool) است. راند روبین (دَوَرانی) روشی است که با مقدار ثابتی از داده‌ها و یک اشاره‌گر به عنصر فعلی کار می‌کند. دایره‌ای را تصور کنید که تعدادی نقطه بر روی محیط آن رسم شده است؛ این نقطه‌ها مکان‌هایی هستند که داده‌ها می‌توانند در آن‌ها ذخیره شوند. فلشی را از مرکز دایره به سمت یکی از نقطه‌ها رسم کنید؛ این همان اشاره‌گر است. هنگامی که داده جاری خوانده یا نوشته می‌شود، اشاره‌گر به سمت نقطه بعدی حرکت می‌کند. از آنجا که روی یک دایره قرار داریم، هیچ آغاز یا پایانی وجود ندارد و می‌توانید به صورت پیوسته و بی‌پایان به کار ادامه دهید. پس از مدتی، تمام مکان‌های موجود پر خواهند شد و این فرآیند به صورت خودکار مکان‌های قدیمی را مجدداً استفاده و بازنویسی می‌کند. به این ترتیب، حجم مجموعه داده رشد نخواهد کرد و در نتیجه به هیچ‌گونه نگهداری و مدیریت فضای دیسک نیاز ندارد. ابزار RRDtool با پایگاه‌های داده راند روبین (RRDها) کار می‌کند؛ داده‌ها را در آن‌ها ذخیره کرده و از آن‌ها بازیابی می‌نماید.

تقریباً هر چیزی را می‌توانید در آن قرار دهید، به شرط آنکه نوعی داده سری زمانی (time-series) باشد. این بدان معناست که شما باید بتوانید مقداری را در چندین نقطه زمانی اندازه‌گیری کرده و این اطلاعات را به RRDtool تحویل دهید. اگر قادر به انجام این کار باشید، RRDtool می‌تواند آن را ذخیره کند. مقادیر باید عددی باشند اما بر خلاف MRTG نیازی نیست که حتماً عدد صحیح باشند (بخش بعدی جزئیات بیشتری درباره این برنامه تخصصی‌تر ارائه خواهد داد).

بسیاری از مثال‌های زیر درباره SNMP صحبت می‌کنند که سرنام پروتکل مدیریت آسان شبکه (Simple Network Management Protocol) است. کلمه «آسان» به ساختار پروتکل اشاره دارد و به این معنی نیست که مدیریت یا مانیتورینگ یک شبکه کار ساده‌ای است. پس از مطالعه دقیق این سند، به اندازه کافی دانش خواهید داشت تا متوجه شوید دیگران درباره چه چیزی صحبت می‌کنند. در حال حاضر، فقط بدانید که از SNMP می‌توان برای پرس‌وجو از دستگاه‌ها جهت دریافت مقادیر شمارنده‌های نگهداری‌شده در آن‌ها استفاده کرد؛ و این همان مقادیر شمارنده‌ها است که می‌خواهیم در RRD ذخیره کنیم.

ابزار RRDtool از پروژه MRTG (Multi Router Traffic Grapher) منشعب شده است. پروژه MRTG در ابتدا به عنوان یک اسکریپت کوچک برای رسم نمودار استفاده از اینترنت در یک دانشگاه آغاز شد. بعدها از MRTG برای رسم نمودار سایر منابع داده از جمله دما، سرعت، ولتاژ، تعداد پرینت‌ها و موارد مشابه استفاده (و شاید سوءاستفاده!) شد.

به احتمال زیاد شما استفاده از RRDtool را برای ذخیره و پردازش داده‌های جمع‌آوری‌شده از طریق SNMP آغاز خواهید کرد. این داده‌ها معمولاً بایت‌ها (یا بیت‌ها) منتقل‌شده به و از یک شبکه یا رایانه خواهند بود. اما می‌توان از آن برای نمایش جزر و مد دریا، تابش خورشید، مصرف برق، تعداد بازدیدکنندگان یک نمایشگاه، سطح آلودگی صوتی در نزدیکی فرودگاه، دمای مکان تفریحی مورد علاقه شما، دمای داخل یخچال و هر آنچه تخیل شما بتواند تصورش را بکند نیز استفاده کرد.

شما فقط به یک حسگر (سنسور) برای اندازه‌گیری داده‌ها و توانایی تزریق این اعداد به RRDtool نیاز دارید. سپس RRDtool به شما امکان می‌دهد یک پایگاه‌داده ایجاد کنید، داده‌ها را در آن ذخیره نمایید، آن داده‌ها را بازیابی کنید و نمودارهایی با فرمت PNG برای نمایش در مرورگر وب بسازید. این تصاویر PNG وابسته به داده‌هایی هستند که جمع‌آوری کرده‌اید و می‌توانند برای مثال نمای کلی از میانگین مصرف شبکه یا پیک‌ها و اوج‌های رخ‌داده را نمایش دهند.

پیش از هر چیز: آن را دوباره بخوانید! ممکن است نکته‌ای را جا انداخته باشید. اگر قادر به کامپایل سورس‌کد نیستید و از یک سیستم‌عامل رایج استفاده می‌کنید، احتمالاً ایراد از RRDtool نیست. ممکن است نسخه‌های از پیش کامپایل‌شده‌ای در اینترنت موجود باشد؛ اگر از منابع معتبر هستند، یکی از آن‌ها را تهیه کنید.

از سوی دیگر، اگر برنامه اجرا می‌شود اما نتایج مورد انتظار را به شما نمی‌دهد، مشکل از نحوه پیکربندی آن خواهد بود. پیکربندی خود را مجدداً بررسی کرده و آن را با مثال‌های پیش رو مقایسه کنید.

یک فهرست پستی (میلینگ‌لیست) و آرشیوی از پیام‌های گذشته آن وجود دارد. برای چند هفته ایمیل‌های لیست را بخوانید و در آرشیو آن جستجو کنید. پرسیدن یک سوال بدون جستجو در آرشیو، رفتار نامناسبی تلقی می‌شود؛ زیرا ممکن است مشکل شما پیش‌تر برای فرد دیگری حل شده باشد! این اصل برای اکثر فهرست‌های پستی و نه فقط این مورد خاص صدق می‌کند. برای اطلاع از نشانی و نحوه استفاده از فهرست پستی، مستندات همراه RRDtool را بررسی کنید.

پیشنهاد می‌کنم همین حالا لحظه‌ای وقت بگذارید و با ارسال یک ایمیل به <rrd-users-request@lists.oetiker.ch> با موضوع "subscribe" در فهرست پستی مشترک شوید. اگر زمانی خواستید از این لیست خارج شوید، کافی است ایمیلی به همان نشانی اما با موضوع "unsubscribe" ارسال کنید.

با ارائه توضیحات مفصل همراه با مثال‌های دقیق. فرض من بر این است که دنبال کردن دستورالعمل‌ها به ترتیبی که ارائه شده‌اند، دانش کافی درباره RRDtool را به شما می‌دهد تا بتوانید خودتان دست به آزمایش بزنید. اگر در نخستین تلاش نتیجه نگرفتید، تسلیم نشوید؛ مطالبی را که فهمیده‌اید دوباره بخوانید، شاید نکته‌ای را از قلم انداخته باشید.

با دنبال کردن مثال‌ها، تجربه عملی کسب می‌کنید و از آن مهم‌تر، اطلاعات اولیه‌ای درباره نحوه کارکرد سیستم به دست می‌آورید.

شما باید اطلاعاتی درباره اعداد در مبنای شانزده (هگزادسیمال) داشته باشید. اگر با آن‌ها آشنایی ندارید، پیش از ادامه کار در اینجا، با مطالعه bin_dec_hex شروع کنید.

به نظر من بهترین روش برای یادگیری هر چیزی، انجام عملی آن است. چرا همین حالا شروع نکنیم؟ ما یک پایگاه‌داده ایجاد می‌کنیم، مقادیری را در آن قرار می‌دهیم و سپس این داده‌ها را مجدداً استخراج می‌کنیم. خروجی شما باید دقیقاً مشابه خروجی درج‌شده در این سند باشد.

ما کار را با چند مفهوم ساده آغاز می‌کنیم و یک خودرو را با یک مسیریاب (روتر) مقایسه می‌نماییم، یا کیلومتر (یا در صورت تمایل مایل) را با بیت‌ها و بایت‌ها می‌سنجیم. همه این‌ها در اصل یک مفهوم هستند: مقداری مشخص در طول یک زمان معین.

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

بیشتر مباحث مربوط به شبکه درباره بیت بر ثانیه (bits per second) صحبت می‌کنند، بنابراین بیایید از همین ابتدا به آن عادت کنیم. فرض کنید هر بایت هشت بیت است و شروع کنید به بیت فکر کنید نه به بایت. با این حال، شمارنده همچنان بایت‌ها را می‌شمارد! در دنیای SNMP بیشتر شمارنده‌ها ۳۲ بیتی هستند. این بدان معناست که آن‌ها از 0 تا 4294967295 را می‌شمارند. ما از این مقادیر در مثال‌ها استفاده خواهیم کرد. هنگامی که از دستگاه سوال می‌شود، مقدار فعلی شمارنده را برمی‌گرداند. از آنجا که زمان سپری‌شده از آخرین پرسش را می‌دانیم، اکنون می‌دانیم که چند بایت ***به طور میانگین*** در هر ثانیه منتقل شده است. محاسبه این موضوع چندان دشوار نیست؛ ابتدا در قالب کلمات، سپس به صورت محاسبات ریاضی:

1.
مقدار شمارنده فعلی را بگیرید و مقدار قبلی را از آن کم کنید.
2.
همین کار را با زمان فعلی و زمان قبلی (بر حسب ثانیه) انجام دهید.
3.
حاصل مرحله (۱) را بر حاصل مرحله (۲) تقسیم کنید؛ نتیجه، مقدار بایت در هر ثانیه است. آن را در هشت ضرب کنید تا تعداد بیت بر ثانیه (bps) به دست آید.
bps = (counter_now - counter_before) / (time_now - time_before) * 8

برای برخی افراد، ترجمه این مفهوم به مثال خودرو ممکن است به درک بهتر کمک کند. این مثال را در رانندگی واقعی امتحان نکنید و اگر چنین کردید، مسئولیت عواقب آن با من نیست!

افرادی که عادت به فکر کردن بر حسب کیلومتر بر ساعت ندارند، می‌توانند با تقسیم کیلومتر بر 1.6 (تقریب مناسب)، آن را به مایل بر ساعت تبدیل کنند. من از اختصارات زیر استفاده خواهم کرد:

m:    meter
km:   kilometer (= 1000 meters).
h:    hour
s:    second
km/h: kilometers per hour
m/s:  meters per second

شما در حال رانندگی با خودرو هستید. در ساعت 12:05 شمارنده روی داشبورد را می‌خوانید و به شما می‌گوید که خودرو تا آن لحظه 12345 کیلومتر حرکت کرده است. در ساعت 12:10 دوباره نگاه می‌کنید، عدد 12357 کیلومتر را نشان می‌دهد. این بدان معناست که شما در مدت پنج دقیقه 12 کیلومتر پیموده‌اید. یک دانشمند این مقدار را به متر بر ثانیه تبدیل می‌کند و این مقایسه بسیار خوبی برای درک مسئله (بایت در هر پنج دقیقه) در برابر (بیت بر ثانیه) است.

ما 12 کیلومتر معادل 12000 متر را طی کردیم. این کار را در پنج دقیقه معادل 300 ثانیه انجام دادیم. سرعت ما 12000 متر بر 300 ثانیه یا 40 متر بر ثانیه است.

همچنین می‌توانستیم سرعت را بر حسب کیلومتر بر ساعت محاسبه کنیم: 12 ضرب در 5 دقیقه برابر با یک ساعت است، بنابراین باید 12 کیلومتر را در 12 ضرب کنیم تا 144 کیلومتر بر ساعت به دست آید. برای دوستانی که با مایل کار می‌کنند: این معادل 90 مایل بر ساعت است، بنابراین این مثال را در خانه یا جایی که من زندگی می‌کنم امتحان نکنید :)

به خاطر داشته باشید: این اعداد صرفاً مقادیر میانگین هستند. به هیچ وجه نمی‌توان از روی این اعداد فهمید که آیا شما با سرعت ثابت رانندگی کرده‌اید یا خیر. مثالی در ادامه این راهنما وجود دارد که این موضوع را توضیح می‌دهد.

امیدوارم متوجه شده باشید که تفاوتی در محاسبه متر بر ثانیه یا بیت بر ثانیه وجود ندارد؛ تنها روش جمع‌آوری داده‌ها متفاوت است. حتی پیشوند k از کیلو نیز یکسان است، زیرا در اصطلاحات شبکه نیز k به معنای 1000 است.

اکنون پایگاه‌داده‌ای ایجاد می‌کنیم که بتوانیم تمام این اعداد جالب را در آن نگه داریم. روش اجرای برنامه ممکن است در سیستم‌عامل‌های مختلف کمی تفاوت داشته باشد، اما تصور می‌کنم در صورت تفاوت در سیستم خود بتوانید آن را حل کنید. اطمینان حاصل کنید که هنگام اجرای دستور زیر هیچ فایلی را روی سیستم خود بازنویسی نکنید و تمام خط را به عنوان یک خط طولانی و یکپارچه وارد کنید (من برای خوانایی بهتر آن را به چند خط شکستم) و تمام نویسه‌های '\' را نادیده بگیرید.

rrdtool create test.rrd             \
         --start 920804400          \
         DS:speed:COUNTER:600:U:U   \
         RRA:AVERAGE:0.5:1:24       \
         RRA:AVERAGE:0.5:6:10

(بنابراین دستور را این‌گونه وارد کنید: "rrdtool create test.rrd --start 920804400 DS ...")

ما یک پایگاه‌داده راند روبین به نام test (فایل test.rrd) ایجاد کردیم که از ظهر روزی که من شروع به نوشتن این سند کردم، یعنی ۷ مارس ۱۹۹۹ آغاز می‌شود (این تاریخ همان‌طور که در ادامه توضیح داده شده، به 920804400 ثانیه تبدیل می‌شود). پایگاه‌داده ما شامل یک منبع داده (DS) به نام "speed" است که یک شمارنده را نشان می‌دهد. این شمارنده هر پنج دقیقه یک‌بار خوانده می‌شود (این مقدار پیش‌فرض است، بنابراین نیازی به درج "--step=300" نیست). در همان پایگاه‌داده دو آرشیو راند روبین (RRA) نگهداری می‌شود؛ یکی داده‌ها را در هر بار خواندن میانگین می‌گیرد (یعنی چیزی برای میانگین‌گیری وجود ندارد، نمونه اولیه) و ۲۴ نمونه را نگهداری می‌کند (۲۴ ضرب در ۵ دقیقه برابر با ۲ ساعت است). دیگری ۶ مقدار را میانگین می‌گیرد (نیم ساعت) و شامل ۱۰ مورد از این میانگین‌ها است (مثلاً ۵ ساعت).

ابزار RRDtool با برچسب‌های زمانی خاصی کار می‌کند که از دنیای یونیکس آمده‌اند. این برچسب زمانی، تعداد ثانیه‌های سپری‌شده از ۱ ژانویه ۱۹۷۰ ساعت 00:00:00 هماهنگ جهانی (UTC) است. مقدار این برچسب زمانی به زمان محلی تبدیل می‌شود و بنابراین در مناطق زمانی مختلف، متفاوت به نظر خواهد رسید.

به احتمال زیاد شما در همان منطقه‌ای از جهان که من زندگی می‌کنم حضور ندارید. این بدان معناست که منطقه زمانی شما متفاوت است. در تمام مثال‌هایی که درباره زمان صحبت می‌کنم، ساعت‌ها ممکن است برای شما متفاوت باشند. این موضوع تأثیر چندانی بر نتایج مثال‌ها ندارد؛ فقط هنگام مطالعه، تفاوت ساعت‌ها را در نظر بگیرید. به عنوان مثال: در جایی که من "12:05" را می‌بینم، کاربران بریتانیا "11:05" را مشاهده خواهند کرد.

اکنون باید پایگاه‌داده خود را با چند عدد پر کنیم. فرض می‌کنیم اعداد زیر را خوانده‌ایم:

12:05  12345 km
12:10  12357 km
12:15  12363 km
12:20  12363 km
12:25  12363 km
12:30  12373 km
12:35  12383 km
12:40  12393 km
12:45  12399 km
12:50  12405 km
12:55  12411 km
13:00  12415 km
13:05  12420 km
13:10  12422 km
13:15  12423 km

پایگاه‌داده را به صورت زیر پر می‌کنیم:

rrdtool update test.rrd 920804700:12345 920805000:12357 920805300:12363
rrdtool update test.rrd 920805600:12363 920805900:12363 920806200:12373
rrdtool update test.rrd 920806500:12383 920806800:12393 920807100:12399
rrdtool update test.rrd 920807400:12405 920807700:12411 920808000:12415
rrdtool update test.rrd 920808300:12420 920808600:12422 920808900:12423

این دستورات بدین معنا هستند: پایگاه‌داده آزمایشی ما را با مقادیر زیر به‌روزرسانی کن

time 920804700, value 12345
time 920805000, value 12357

و غیره.

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

اکنون می‌توانیم داده‌ها را با استفاده از دستور "rrdtool fetch" از پایگاه‌داده خود بازیابی کنیم:

rrdtool fetch test.rrd AVERAGE --start 920804400 --end 920809200

این دستور باید خروجی زیر را بازگرداند:

                         speed
920804700: nan
920805000: 4.0000000000e-02
920805300: 2.0000000000e-02
920805600: 0.0000000000e+00
920805900: 0.0000000000e+00
920806200: 3.3333333333e-02
920806500: 3.3333333333e-02
920806800: 3.3333333333e-02
920807100: 2.0000000000e-02
920807400: 2.0000000000e-02
920807700: 2.0000000000e-02
920808000: 1.3333333333e-02
920808300: 1.6666666667e-02
920808600: 6.6666666667e-03
920808900: 3.3333333333e-03
920809200: nan
920809500: nan

توجه داشته باشید که ممکن است سطرهای بیشتری نسبت به آنچه انتظار دارید دریافت کنید. دلیل این امر آن است که شما بازه زمانی منتهی به 920809200 را درخواست کرده‌اید. عددی که در فهرست بالا جلوی :920809200 نوشته شده، بازه زمانی از 920808900 تا 920809200 را پوشش می‌دهد، بدون احتساب خود 920809200. بنابراین برای اطمینان، ورودی از 920809200 تا 920809500 را نیز دریافت می‌کنید زیرا شامل خود 920809200 است. همچنین ممکن است به جای "nan" عبارت "NaN" را ببینید که این موضوع به سیستم‌عامل بستگی دارد. "NaN" مخفف "Not A Number" (غیرعددی / نامشخص) است. اگر سیستم‌عامل شما "U" یا "UNKN" یا موارد مشابه را می‌نویسد، مشکلی نیست. اگر مورد دیگری اشتباه است، احتمالاً به دلیل خطایی است که مرتکب شده‌اید (البته با فرض اینکه راهنمای من درست باشد :-) ). در این صورت: پایگاه‌داده را حذف کرده و دوباره تلاش کنید.

مفهوم خروجی بالا در ادامه روشن خواهد شد.

دستور زیر را امتحان کنید:

rrdtool graph speed.png                                 \
        --start 920804400 --end 920808000               \
        DEF:myspeed=test.rrd:speed:AVERAGE              \
        LINE2:myspeed#FF0000

این دستور فایل speed.png را ایجاد می‌کند که از ساعت 12:00 آغاز شده و در ساعت 13:00 پایان می‌یابد. در این دستور متغیری به نام myspeed تعریف شده است که از داده‌های RRA با نام "speed" در پایگاه‌داده "test.rrd" استفاده می‌کند. خط رسم‌شده دارای ضخامت ۲ پیکسل است و متغیر myspeed را نمایش می‌دهد. رنگ آن نیز قرمز است (که با مقدار rgb مشخص شده است، در ادامه توضیح داده می‌شود).

متوجه خواهید شد که شروع نمودار از ساعت 12:00 نیست بلکه از ساعت 12:05 است. دلیل این امر آن است که پیش از آن زمان، داده کافی برای محاسبه میانگین در اختیار نداریم. این حالت تنها زمانی رخ می‌دهد که برخی نمونه‌ها وجود نداشته باشند که امیدواریم چندان اتفاق نیفتد.

اگر این مرحله با موفقیت کار کرد: تبریک می‌گویم! در غیر این صورت، بررسی کنید که کجای کار ایراد داشته است.

رنگ‌ها از ترکیب قرمز (red)، سبز (green) و آبی (blue) ساخته می‌شوند. برای هر یک از مؤلفه‌ها، مقدار استفاده را در مبنای شانزده (هگزادسیمال) مشخص می‌کنید که در آن 00 به معنای عدم استفاده و FF به معنای حداکثر استفاده است. «رنگ» سفید ترکیبی از تمام مؤلفه‌های قرمز، سبز و آبی است: FFFFFF «رنگ» سیاه به معنای خاموش بودن تمام رنگ‌هاست: 000000

red     #FF0000
green   #00FF00
blue    #0000FF
magenta #FF00FF     (mixed red with blue)
gray    #555555     (one third of all components)

علاوه بر این (در نسخه‌های اخیر RRDtool) می‌توانید یک کانال آلفا (شفافیت / transparency) نیز اضافه کنید. مقدار پیش‌فرض "FF" خواهد بود که به معنای کدر بودن (غیرشفاف) است.

تصویر PNG که به تازگی ایجاد کرده‌اید را می‌توانید با نمایشگر تصویر مورد علاقه خود مشاهده کنید. مرورگرهای وب نیز این PNG را از طریق آدرس "file:///the/path/to/speed.png" نمایش می‌دهند.

هنگام مشاهده تصویر، متوجه می‌شوید که محور افقی با برچسب‌های 12:10، 12:20، 12:30، 12:40 و 12:50 مشخص شده است. گاهی اوقات یک برچسب جا نمی‌شود (12:00 و 13:00 گزینه‌های احتمالی بودند)، بنابراین نادیده گرفته می‌شوند.

محور عمودی بازه‌ای را که وارد کرده‌ایم نمایش می‌دهد. ما کیلومتر را وارد کردیم و وقتی بر 300 ثانیه تقسیم می‌شود، به اعدادی بسیار کوچک می‌رسیم. دقیق‌تر بگوییم، مقدار اول 12 بود (12345 - 12357) و تقسیم آن بر 300 عدد 0.04 را به دست می‌دهد که RRDtool آن را به صورت "40 m" به معنای "40/1000" (میلی) نمایش می‌دهد. حرف "m" (میلی) هیچ ارتباطی با متر (که آن هم با m نشان داده می‌شود)، کیلومتر یا میلی‌متر ندارد! ابزار RRDtool از واحدهای فیزیکی داده‌های ما اطلاعی ندارد و صرفاً با اعداد بدون بعد کار می‌کند.

اگر مسافت‌ها را بر حسب متر اندازه‌گیری می‌کردیم، حاصل به صورت (12357000 - 12345000) تقسیم بر 300 معادل 12000 بر 300 برابر با 40 می‌شد.

از آنجا که اکثر افراد درک بهتری از اعداد در این محدوده دارند، این مورد را اصلاح می‌کنیم. می‌توانستیم پایگاه‌داده را دوباره بسازیم و داده‌های درست را ذخیره کنیم، اما راه بهتری وجود دارد: انجام برخی محاسبات ریاضی هنگام ایجاد فایل PNG!

rrdtool graph speed2.png                           \
   --start 920804400 --end 920808000               \
   --vertical-label m/s                            \
   DEF:myspeed=test.rrd:speed:AVERAGE              \
   CDEF:realspeed=myspeed,1000,\*                  \
   LINE2:realspeed#FF0000

توجه: من باید عملگر ضرب * را با یک بک‌اسلش اسکیپ می‌کردم. اگر این کار را انجام ندهم، ممکن است سیستم‌عامل آن را تفسیر کرده و برای بسط نام فایل‌ها به کار ببرد. همچنین می‌توانید کل خط را درون گیومه قرار دهید، مانند زیر:

"CDEF:realspeed=myspeed,1000,*"                  \

خلاصه مطلب این است: این RRDtool است که باید علامت * را ببیند، نه پوسته فرمان شما؛ و این پوسته فرمان است که \ را تفسیر می‌کند، نه RRDtool. اگر از سیستم‌عامل یا پوسته‌ای استفاده می‌کنید که رفتار متفاوتی دارد، ممکن است لازم باشد مثال‌ها را بر این اساس تنظیم نمایید.

پس از مشاهده این فایل PNG، متوجه می‌شوید که پسوند "m" (میلی) ناپدید شده است. این همان نتیجه درستی است که می‌خواستیم. همچنین یک برچسب متنی به تصویر اضافه شده است. به غیر از موارد ذکرشده، فایل PNG باید همانند قبل به نظر برسد.

محاسبات در بخش CDEF بالا مشخص شده‌اند و در نمادگذاری لهستانی معکوس ("RPN") نوشته شده‌اند. آنچه از RRDtool درخواست کردیم این بود: "منبع داده myspeed و عدد 1000 را بردار؛ و آن‌ها را در هم ضرب کن". فعلاً ذهن خود را درگیر RPN نکنید، در ادامه با جزئیات بیشتر توضیح داده خواهد شد. همچنین می‌توانید راهنمای آموزشی من درباره CDEFها و آموزش Steve Rader درباره RPN را مطالعه کنید؛ اما ابتدا این آموزش را به پایان برسانید.

صبر کنید! اگر می‌توانیم مقادیر را در 1000 ضرب کنیم، باید بتوان کیلومتر بر ساعت را نیز از همین داده‌ها استخراج و نمایش داد!

برای تبدیل مقداری که بر حسب متر بر ثانیه اندازه‌گیری شده است:

Calculate meters per hour:     value * 3600
Calculate kilometers per hour: value / 1000
Together this makes:           value * (3600/1000) or value * 3.6

در پایگاه‌داده نمونه خود اشتباهی مرتکب شده بودیم و باید با ضرب در 1000 آن را جبران کنیم. با اعمال این تصحیح:

value * 3.6  * 1000 == value * 3600

اکنون بیایید این PNG را بسازیم و جادوی بیشتری به آن اضافه کنیم...

rrdtool graph speed3.png                             \
     --start 920804400 --end 920808000               \
     --vertical-label km/h                           \
     DEF:myspeed=test.rrd:speed:AVERAGE              \
     "CDEF:kmh=myspeed,3600,*"                       \
     CDEF:fast=kmh,100,GT,kmh,0,IF                   \
     CDEF:good=kmh,100,GT,0,kmh,IF                   \
     HRULE:100#0000FF:"Maximum allowed"              \
     AREA:good#00FF00:"Good speed"                   \
     AREA:fast#FF0000:"Too fast"

توجه: در اینجا ما از روش دیگری برای اسکیپ کردن عملگر * استفاده کردیم و کل رشته را درون دابل کوتیشن قرار دادیم.

این نمودار بسیار بهتر به نظر می‌رسد. سرعت بر حسب کیلومتر بر ساعت نمایش داده می‌شود و حتی یک خط اضافی با حداکثر سرعت مجاز (در جاده‌ای که من در آن تردد می‌کنم) وجود دارد. من همچنین رنگ‌های استفاده‌شده برای نمایش سرعت را تغییر دادم و آن را از حالت خط به یک ناحیه توپر (area) تبدیل کردم.

محاسبات اکنون پیچیده‌تر شده‌اند. برای مقادیر سرعت درون محدوده مجاز، منطق به صورت زیر است:

Check if kmh is greater than 100    ( kmh,100 ) GT
If so, return 0, else kmh           ((( kmh,100 ) GT ), 0, kmh) IF

برای مقادیر بالاتر از سرعت مجاز:

Check if kmh is greater than 100    ( kmh,100 ) GT
If so, return kmh, else return 0    ((( kmh,100) GT ), kmh, 0) IF

دوست دارم باور داشته باشم که در زمینه نحوه دستکاری داده‌ها توسط دستور rrdtool graph تقریباً هیچ محدودیتی وجود ندارد. در اینجا چگونگی کارکرد آن را توضیح نمی‌دهم، اما به فایل PNG زیر نگاه کنید:

rrdtool graph speed4.png                           \
   --start 920804400 --end 920808000               \
   --vertical-label km/h                           \
   DEF:myspeed=test.rrd:speed:AVERAGE              \
   CDEF:nonans=myspeed,UN,0,myspeed,IF             \
   CDEF:kmh=nonans,3600,*                          \
   CDEF:fast=kmh,100,GT,100,0,IF                   \
   CDEF:over=kmh,100,GT,kmh,100,-,0,IF             \
   CDEF:good=kmh,100,GT,0,kmh,IF                   \
   HRULE:100#0000FF:"Maximum allowed"              \
   AREA:good#00FF00:"Good speed"                   \
   AREA:fast#550000:"Too fast"                     \
   STACK:over#FF0000:"Over speed"

یادداشت ابتدای سند را به خاطر دارید؟ من مجبور شدم داده‌های نامشخص را از این مثال حذف کنم. تعریف CDEF با نام 'nonans' جدید است و خط ششم (که قبلاً خط پنجم بود) قبلاً به صورت 'CDEF:kmh=myspeed,3600,*' نوشته شده بود.

بیایید یک صفحه HTML سریع و ساده بسازیم تا هر سه تصویر PNG را مشاهده کنیم:

<HTML><HEAD><TITLE>Speed</TITLE></HEAD><BODY>
<IMG src="speed2.png" alt="Speed in meters per second">
<BR>
<IMG src="speed3.png" alt="Speed in kilometers per hour">
<BR>
<IMG src="speed4.png" alt="Traveled too fast?">
</BODY></HTML>

این فایل را "speed.html" یا نامی مشابه بگذارید و آن را در مرورگر وب خود باز کنید.

اکنون تنها کاری که باید انجام دهید این است که مقادیر را به طور منظم اندازه‌گیری کرده و پایگاه‌داده را به‌روزرسانی کنید. هر زمان که می‌خواهید داده‌ها را مشاهده نمایید، فایل‌های PNG را مجدداً بسازید و مطمئن شوید که آن‌ها را در مرورگر خود نوسازی (refresh) می‌کنید. (توجه: فقط کلیک روی بازخوانی ممکن است کافی نباشد، به ویژه هنگامی که پروکسی‌ها درگیر هستند؛ کلیک با shift یا کلیدهای ترکیبی ctrl-F5 را امتحان کنید).

ما تاکنون از دستور "update" استفاده کرده‌ایم: این دستور یک یا چند پارامتر به شکل "<time>:<value>" دریافت می‌کند. خوشحال خواهید شد اگر بدانید که می‌توانید زمان جاری را با وارد کردن حرف "N" به جای برچسب زمانی مشخص کنید. یا اینکه می‌توانید از تابع "time" در پرل (کوتاه‌ترین مثال در این آموزش) استفاده نمایید:

perl -e 'print time, "\n" '

نحوه اجرای یک برنامه در فواصل زمانی منظم به سیستم‌عامل بستگی دارد. اما در اینجا یک مثال در قالب شبه‌کد آورده شده است:

- Get the value and put it in variable "$speed"
- rrdtool update speed.rrd N:$speed

(این کار را روی پایگاه‌داده آزمایشی ما امتحان نکنید، زیرا در مثال‌های بعدی به آن نیاز داریم).

همه چیز همین است. اسکریپت بالا را هر پنج دقیقه یک‌بار اجرا کنید. هر زمان که نیاز داشتید ظاهر نمودارها را ببینید، مثال‌های بالا را اجرا نمایید. حتی می‌توانید آن‌ها را نیز در قالب یک اسکریپت قرار دهید. پس از اجرای آن اسکریپت، صفحه speed.html را که قبلاً ساختیم مشاهده کنید.

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

بسیاری از افرادی که به RRDtool علاقه‌مند هستند، از شمارنده‌ای استفاده خواهند کرد که تعداد اکتت‌ها (بایت‌ها) منتقل‌شده توسط یک دستگاه شبکه را ثبت می‌کند. بنابراین بیایید در مرحله بعد دقیقاً همین کار را انجام دهیم. ما با شرح چگونگی جمع‌آوری داده‌ها شروع خواهیم کرد.

ممکن است برخی افراد یادآوری کنند که ابزارهایی وجود دارند که می‌توانند این جمع‌آوری داده‌ها را برای شما انجام دهند. حق با آن‌هاست! با این حال، معتقدم بسیار مهم است که بدانید این ابزارها الزامی و ضروری نیستند. زمانی که مجبورید علت بروز خطاها را ریشه‌یابی کنید، باید بدانید که سیستم چگونه در پشت صحنه کار می‌کند.

درباره یکی از ابزارهای مورد استفاده در مثال، در ابتدای این سند بسیار کوتاه صحبت شد که SNMP نام دارد. این روشی برای ارتباط با تجهیزات تحت شبکه است. ابزاری که من در ادامه استفاده می‌کنم "snmpget" نام دارد و نحوه کار آن بدین صورت است:

snmpget device password OID

یا

snmpget -v[version] -c[password] device OID

به جای device نام یا آدرس IP دستگاه خود را قرار می‌دهید. برای password از رشته خواندن کامیونیتی (community read string) استفاده می‌کنید که در دنیای SNMP این‌گونه نامیده می‌شود. برای برخی دستگاه‌ها ممکن است مقدار پیش‌فرض "public" کار کند، هرچند این مقدار می‌تواند به دلایل امنیتی و حریم خصوصی غیرفعال، تغییر یافته یا محافظت شده باشد. مستندات همراه دستگاه یا برنامه خود را مطالعه کنید.

سپس این پارامتر با نام OID وجود دارد که مخفف "شناسه شیء" (object identifier) است.

هنگامی که یادگیری SNMP را آغاز می‌کنید، بسیار گیج‌کننده به نظر می‌رسد. اما وقتی به پایگاه اطلاعات مدیریت ("MIB") نگاه می‌کنید، چندان دشوار نیست. این پایگاه مانند یک درخت وارونه است که داده‌ها را توصیف می‌کند؛ با یک گره به عنوان ریشه و از آنجا تعدادی شاخه. این شاخه‌ها به گره دیگری ختم می‌شوند، انشعاب می‌یابند و به همین ترتیب ادامه دارند. تمام شاخه‌ها دارای یک نام هستند و مسیری را تشکیل می‌دهند که ما تا پایین دنبال می‌کنیم. شاخه‌هایی که دنبال می‌کنیم عبارتند از: iso، org، dod، internet، mgmt و mib-2. این نام‌ها را می‌توان به صورت اعداد نیز نوشت که عبارتند از: 1 3 6 1 2 1.

iso.org.dod.internet.mgmt.mib-2 (1.3.6.1.2.1)

ابهامات زیادی در مورد نقطه ابتدایی (leading dot) که برخی برنامه‌ها استفاده می‌کنند وجود دارد. در یک OID هیچ نقطه ابتدایی وجود ندارد. با این حال، برخی برنامه‌ها می‌توانند بخش بالای OIDها را به عنوان پیش‌فرض در نظر بگیرند. برای نشان دادن تفاوت میان OIDهای خلاصه و OIDهای کامل، هنگام مشخص کردن OID کامل به یک نقطه در ابتدا نیاز دارند. اغلب این برنامه‌ها هنگام بازگرداندن داده‌ها به شما، بخش پیش‌فرض را حذف می‌کنند. برای پیچیده‌تر شدن اوضاع، آن‌ها چندین پیشوند پیش‌فرض متفاوت دارند...

بسیار خوب، بیایید به ابتدای OID خود بازگردیم: ما 1.3.6.1.2.1 را داشتیم. از آنجا، ما به ویژه به شاخه "interfaces" علاقه‌مندیم که دارای شماره ۲ است (یعنی 1.3.6.1.2.1.2 یا 1.3.6.1.2.1.interfaces).

ابتدا باید یک برنامه SNMP تهیه کنیم. ابتدا بررسی کنید که آیا بسته از پیش کامپایل‌شده‌ای برای سیستم‌عامل شما موجود است یا خیر. این روش ترجیحی است. در غیر این صورت، باید خودتان سورس‌کدها را دریافت کرده و کامپایل کنید. اینترنت پر از سورس‌ها، برنامه‌ها و غیره است. اطلاعات را با استفاده از موتور جستجو یا هر روشی که ترجیح می‌دهید بیابید.

فرض کنید برنامه را تهیه کرده‌اید. ابتدا سعی کنید داده‌هایی را جمع‌آوری نمایید که در اکثر سیستم‌ها در دسترس هستند. به یاد داشته باشید: برای بخشی از درختی که بیش از همه برای ما در این حوزه اهمیت دارد، نام کوتاهی وجود دارد!

من مثالی می‌زنم که می‌تواند در Fedora Core 3 استفاده شود. اگر برای شما کار نکرد، راهنمای snmp را مطالعه کرده و مثال را متناسب با سیستم خود تطبیق دهید.

snmpget -v2c -c public myrouter system.sysDescr.0

دستگاه باید با توصیفی از خود پاسخ دهد، که شاید این پاسخ خالی باشد. تا زمانی که پاسخ معتبری از دستگاه دریافت نکرده‌اید (شاید با استفاده از "گذرواژه" متفاوت یا دستگاهی دیگر)، ادامه کار فایده‌ای ندارد.

snmpget -v2c -c public myrouter interfaces.ifNumber.0

امیدواریم عددی به عنوان نتیجه دریافت کنید که تعداد رابط‌ها (اینترفیس‌ها) است. اگر چنین شد، می‌توانید ادامه دهید و برنامه دیگری به نام "snmpwalk" را امتحان کنید.

snmpwalk -v2c -c public myrouter interfaces.ifTable.ifEntry.ifDescr

اگر این دستور فهرستی از رابط‌ها را بازگرداند، تقریباً به مقصد رسیده‌اید. این یک مثال است:
[user@host /home/alex]$ snmpwalk -v2c -c public cisco 2.2.1.2

interfaces.ifTable.ifEntry.ifDescr.1 = "BRI0: B-Channel 1"
interfaces.ifTable.ifEntry.ifDescr.2 = "BRI0: B-Channel 2"
interfaces.ifTable.ifEntry.ifDescr.3 = "BRI0" Hex: 42 52 49 30
interfaces.ifTable.ifEntry.ifDescr.4 = "Ethernet0"
interfaces.ifTable.ifEntry.ifDescr.5 = "Loopback0"

روی این تجهیزات سیسکو (Cisco)، می‌خواهم رابط "Ethernet0" را مانیتور کنم و از خروجی بالا می‌بینم که این رابط شماره چهار است. دستور زیر را امتحان می‌کنم:

[user@host /home/alex]$ snmpget -v2c -c public cisco 2.2.1.10.4 2.2.1.16.4
interfaces.ifTable.ifEntry.ifInOctets.4 = 2290729126
interfaces.ifTable.ifEntry.ifOutOctets.4 = 1256486519

بنابراین اکنون من دو OID برای مانیتور کردن دارم که (این بار به صورت کامل) عبارتند از:

1.3.6.1.2.1.2.2.1.10

و

1.3.6.1.2.1.2.2.1.16

هر دو با شماره رابط ۴.

فریب نخورید، این نتیجه در نخستین تلاش من حاصل نشد. برای من هم مدتی طول کشید تا بفهمم همه این اعداد چه معنایی دارند. این امر بسیار کمک می‌کند وقتی که اعداد به متون توصیفی ترجمه می‌شوند... حداقل اکنون وقتی دیگران درباره MIBها و OIDها صحبت می‌کنند، می‌دانید موضوع از چه قرار است. شماره رابط را فراموش نکنید (اگر وابسته به رابط نیست، مقدار 0 بگذارید) و اگر پاسخی از snmpget دریافت نکردید، snmpwalk را امتحان کنید.

اگر بخش بالا را درک کردید و اعدادی از دستگاه خود دریافت نمودید، به مطالعه این آموزش ادامه دهید. در غیر این صورت، به عقب برگردید و این بخش را دوباره بخوانید.

بگذارید بخش هیجان‌انگیز کار آغاز شود. ابتدا یک پایگاه‌داده جدید ایجاد کنید. این پایگاه‌داده شامل داده‌هایی از دو شمارنده به نام‌های input و output است. داده‌ها در آرشیوهایی قرار می‌گیرند که میانگین آن‌ها را محاسبه می‌کنند. آن‌ها در هر نوبت ۱، ۶، ۲۴ یا ۲۸۸ نمونه را دریافت می‌کنند. همچنین داده‌ها در آرشیوهایی ذخیره می‌شوند که مقادیر بیشینه (حداکثر) را نگهداری می‌نمایند. این موضوع در ادامه توضیح داده خواهد شد. فاصله زمانی میان نمونه‌ها ۳۰۰ ثانیه است؛ یک نقطه شروع مناسب که معادل پنج دقیقه است.

1 sample "averaged" stays 1 period of 5 minutes
6 samples averaged become one average on 30 minutes
24 samples averaged become one average on 2 hours
288 samples averaged become one average on 1 day

بیایید سعی کنیم با MRTG سازگار باشیم که تقریباً مقدار داده زیر را ذخیره می‌کند:

600 5-minute samples:    2   days and 2 hours
600 30-minute samples:  12.5 days
600 2-hour samples:     50   days
732 1-day samples:     732   days

این بازه‌ها به دنبال یکدیگر اضافه می‌شوند، بنابراین کل داده‌های ذخیره‌شده در پایگاه‌داده تقریباً ۷۹۷ روز است. ابزار RRDtool داده‌ها را به شکل متفاوتی ذخیره می‌کند؛ آرشیو «هفتگی» را از جایی که آرشیو «روزانه» متوقف شده آغاز نمی‌کند. برای هر دو آرشیو، جدیدترین داده‌ها نزدیک به زمان «اکنون» (now) خواهند بود و بنابراین ما باید داده‌های بیشتری نسبت به MRTG نگهداری کنیم!

ما به موارد زیر نیاز خواهیم داشت:

600 samples of 5 minutes  (2 days and 2 hours)
700 samples of 30 minutes (2 days and 2 hours, plus 12.5 days)
775 samples of 2 hours    (above + 50 days)
797 samples of 1 day      (above + 732 days, rounded up to 797)
  rrdtool create myrouter.rrd         \
           DS:input:COUNTER:600:U:U   \
           DS:output:COUNTER:600:U:U  \
           RRA:AVERAGE:0.5:1:600      \
           RRA:AVERAGE:0.5:6:700      \
           RRA:AVERAGE:0.5:24:775     \
           RRA:AVERAGE:0.5:288:797    \
           RRA:MAX:0.5:1:600          \
           RRA:MAX:0.5:6:700          \
           RRA:MAX:0.5:24:775         \
           RRA:MAX:0.5:288:797

کار بعدی جمع‌آوری داده‌ها و ذخیره آن‌هاست. در اینجا یک مثال آورده شده است. این مثال تا حدی در قالب شبه‌کد نوشته شده و شما باید دریابید که دقیقاً در سیستم‌عامل خود چه کاری باید انجام دهید تا کار کند.

while not the end of the universe
do
   get result of
      snmpget router community 2.2.1.10.4
   into variable $in
   get result of
      snmpget router community 2.2.1.16.4
   into variable $out
   rrdtool update myrouter.rrd N:$in:$out
   wait for 5 minutes
done

سپس، پس از جمع‌آوری داده‌ها به مدت یک روز، سعی کنید با دستور زیر یک تصویر ایجاد نمایید:

rrdtool graph myrouter-day.png --start -86400 \
         DEF:inoctets=myrouter.rrd:input:AVERAGE \
         DEF:outoctets=myrouter.rrd:output:AVERAGE \
         AREA:inoctets#00FF00:"In traffic" \
         LINE1:outoctets#0000FF:"Out traffic"

این دستور باید تصویری شامل ترافیک به ارزش یک روز کامل تولید کند. یک روز معادل ۲۴ ساعت در ۶۰ دقیقه در ۶۰ ثانیه است: 24*60*60=86400؛ بنابراین ما از ۸۶۴۰۰ ثانیه قبل از زمان جاری شروع می‌کنیم. ما (با استفاده از تعاریف DEF) متغیرهای inoctets و outoctets را به عنوان مقادیر میانگین از پایگاه‌داده myrouter.rrd تعریف می‌کنیم و یک ناحیه توپر (area) برای ترافیک «ورودی» و یک خط برای ترافیک «خروجی» رسم می‌نماییم.

تصویر را مشاهده کنید و ثبت داده‌ها را برای چند روز دیگر ادامه دهید. در صورت تمایل می‌توانید مثال‌های مربوط به پایگاه‌داده آزمایشی را امتحان کنید و ببینید آیا می‌توانید گزینه‌ها و محاسبات گوناگون را به کار بگیرید یا خیر.

پیشنهاد: مقادیر را بر حسب بایت بر ثانیه و همچنین بیت بر ثانیه نمایش دهید. نمودار اترنت را طوری تنظیم کنید که در صورت فراتر رفتن از چهار مگابیت بر ثانیه، به رنگ قرمز درآید.

چند پاراگراف قبل به امکان نگهداری مقادیر بیشینه (حداکثر) به جای مقادیر میانگین اشاره کردم. بیایید کمی بیشتر به این موضوع بپردازیم.

تمام مطالب مربوط به سرعت خودرو را به یاد بیاورید. فرض کنید به مدت ۵ دقیقه با سرعت ۱۴۴ کیلومتر بر ساعت رانندگی کردیم و سپس توسط پلیس به مدت ۲۵ دقیقه متوقف شدیم. در پایان کلاس درس، لپ‌تاپ خود را برمی‌داریم و تصویری را که از پایگاه‌داده استخراج شده است ایجاد کرده و مشاهده می‌کنیم. اگر به دومین RRA که ساختیم نگاه کنیم، میانگین ۶ نمونه را خواهیم داشت. نمونه‌های اندازه‌گیری‌شده عبارت خواهند بود از: 144+0+0+0+0+0=144 که تقسیم بر ۳۰ دقیقه شده، برای جبران خطا در ۱۰۰۰ تصحیح شده، به کیلومتر بر ساعت تبدیل شده و نتیجه آن ۲۴ کیلومتر بر ساعت است. من همچنان جریمه می‌شوم، اما دیگر نه به خاطر سرعت غیرمجاز :)

مشخص است که در این حالت نباید به میانگین‌ها نگاه کنیم. در برخی موارد میانگین‌ها مفید هستند؛ اگر می‌خواهید بدانید چند کیلومتر پیموده‌اید، تصویر حاصل از میانگین گزینه درستی برای بررسی است. از سوی دیگر، برای سرعت حرکت ما، بالاترین اعداد ثبت‌شده بسیار جالب‌تر هستند. بعداً انواع بیشتری را خواهیم دید.

این موضوع در مورد داده‌های شبکه نیز صادق است. اگر می‌خواهید از حجم کل داده‌ها مطلع شوید، به میانگین‌ها نگاه کنید؛ اما اگر می‌خواهید نرخ و سرعت انتقال را بدانید، به مقادیر بیشینه بنگرید. با گذشت زمان، این دو مقدار بیشتر و بیشتر از یکدیگر فاصله می‌گیرند. در آخرین پایگاه‌داده‌ای که ساختیم، دو آرشیو وجود دارند که داده‌ها را به صورت روزانه نگهداری می‌کنند. آرشیوی که میانگین‌ها را نگه می‌دارد اعداد پایینی را نشان می‌دهد و آرشیوی که بیشینه‌ها را ثبت می‌کند اعداد بالاتری خواهد داشت.

برای خودروی من، این امر در روزهای کاری به میانگین‌های روزانه معادل 96/24=4 کیلومتر بر ساعت تبدیل می‌شود (زیرا من حدود ۹۴ کیلومتر در روز تردد می‌کنم)، در حالی که بیشینه سرعت من ۱۲۰ کیلومتر بر ساعت است (حداکثر سرعتی که هر روز به آن می‌رسم).

تفاوت بسیار بزرگی است. هرگز به نمودار دوم برای تخمین مسافت طی‌شده نگاه نکنید و به نمودار اول نیز برای تخمین سرعت من اتکا ننمایید. این روش زمانی کارایی دارد که نمونه‌ها مانند بازه‌های ۵ دقیقه‌ای به هم نزدیک باشند، اما در هنگام میانگین‌گیری در بازه‌های طولانی خیر.

در برخی روزها، من به سفرهای طولانی می‌روم. اگر به سفری در سرتاسر اروپا بروم و به مدت ۱۲ ساعت رانندگی کنم، نمودار اول به حدود ۶۰ کیلومتر بر ساعت افزایش می‌یابد. نمودار دوم ۱۸۰ کیلومتر بر ساعت را نشان خواهد داد. این بدان معناست که من مسافتی معادل ۶۰ کیلومتر بر ساعت ضرب در ۲۴ ساعت = ۱۴۴۰ کیلومتر را پیموده‌ام. من این کار را با سرعتی بالاتر و حداکثری حدود ۱۸۰ کیلومتر بر ساعت انجام دادم؛ با این حال، احتمالاً به این معنا نیست که ۸ ساعت با سرعت ثابت ۱۸۰ کیلومتر بر ساعت رانندگی کرده‌ام!

این یک مثال واقعی است: با جریان ترافیک در آلمان همراه شوید (بسیار سریع!) و چند بار برای بنزین و قهوه توقف کنید. در اتریش و هلند به آرامی برانید و در کوهستان‌ها و روستاها احتیاط کنید. اگر به نمودارهای حاصل از میانگین‌های ۵ دقیقه‌ای نگاه کنید، تصویر کاملاً متفاوتی به دست خواهید آورد. شما مقادیر یکسانی را در نمودارهای میانگین و بیشینه مشاهده خواهید کرد (به شرطی که من هر ۳۰۰ ثانیه اندازه‌گیری کرده باشم). قادر خواهید بود ببینید چه زمانی متوقف شدم، چه زمانی در بالاترین دنده بودم، چه زمانی در بزرگراه‌های سریع حرکت کردم و غیره. دانه‌بندی و دقت (granularity) داده‌ها بسیار بالاتر است، بنابراین می‌توانید جزئیات بیشتری را ببینید. با این حال، این کار نیازمند ۱۲ نمونه در هر ساعت یا ۲۸۸ مقدار در هر روز است که برای یک بازه زمانی طولانی‌تر، حجم عظیمی از داده خواهد شد. به همین دلیل ما داده‌ها را میانگین می‌گیریم و در نهایت به یک مقدار در هر روز می‌رسیم. البته از این یک مقدار نمی‌توان جزئیات زیادی را استخراج کرد.

مطمئن شوید که چند پاراگراف اخیر را به خوبی درک کرده‌اید. وجود یک خط و چند محور به خودی خود ارزشی ندارد؛ شما باید بدانید که آن‌ها چه مفهومی دارند و داده‌ها را به شیوه مناسب تفسیر کنید. این اصل برای تمام داده‌ها صادق است.

بزرگ‌ترین اشتباهی که می‌توانید مرتکب شوید، استفاده از داده‌های جمع‌آوری‌شده برای هدفی است که مناسب آن نیستند. در این صورت، نداشتن نمودار به مراتب بهتر از داشتن آن است.

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

ابزار RRDtool می‌تواند کارهای بیشتری نسبت به آنچه تاکنون آموخته‌ایم انجام دهد. پیش از ادامه با بخش‌های باقی‌مانده این سند، توصیه می‌کنم از ابتدا دوباره مرور کنید و تغییراتی را در مثال‌ها امتحان نمایید. اطمینان حاصل کنید که همه چیز را به طور کامل متوجه شده‌اید. این کار ارزش وقت گذاشتن را دارد و نه تنها در ادامه این آموزش، بلکه در مانیتورینگ روزمره شما سال‌ها پس از خواندن این مقدمه به کارتان خواهد آمد.

بسیار خوب، تمایل به ادامه دارید. خوش آمدید و برای سرعت بیشتر در مثال‌ها و توضیحات آماده شوید.

شما می‌دانید که برای مشاهده یک شمارنده در طول زمان، باید دو عدد را بردارید و اختلاف آن‌ها را بر زمان سپری‌شده تقسیم کنید. این روش برای مثال‌هایی که برایتان زدم منطقی است، اما احتمالات دیگری نیز وجود دارد. به عنوان مثال، من می‌توانم دمای روتر خود را در سه نقطه یعنی ورودی هوا (inlet)، نقطه داغ (hot-spot) و خروجی هوا (exhaust) بخوانم. این مقادیر شمارنده نیستند. اگر اختلاف دو نمونه را محاسبه کنم و آن را بر ۳۰۰ ثانیه تقسیم نمایم، در واقع نرخ تغییر دما در ثانیه را به دست آورده‌ام. امیدوارم این مقدار صفر باشد! در غیر این صورت، احتمالاً اتاق سرور آتش گرفته است :)

بنابراین چه کاری می‌توانیم انجام دهیم؟ ما می‌توانیم به RRDtool بگوییم مقادیری را که اندازه‌گیری می‌کنیم مستقیماً همان‌گونه که هستند ذخیره کند (این کاملاً دقیق نیست اما برای درک موضوع کافی است). نمودارهایی که می‌سازیم بسیار بهتر به نظر خواهند رسید و مقداری نسبتاً ثابت را نشان می‌دهند. من می‌دانم چه زمانی روتر مشغول است (روتر کار می‌کند -> برق بیشتری مصرف می‌کند -> گرمای بیشتری تولید می‌کند -> دما بالا می‌رود). من می‌دانم چه زمانی درها باز مانده‌اند (اتاق دارای تهویه مطبوع است -> هوای گرم از بقیه ساختمان وارد اتاق سرور می‌شود -> دمای ورودی هوا افزایش می‌یابد) و مواردی از این دست. نوع داده‌ای که قبلاً هنگام ایجاد پایگاه‌داده استفاده کردیم counter بود؛ اکنون نوع داده دیگری داریم و بنابراین نام متفاوتی برای آن وجود دارد که GAUGE نامیده می‌شود. انواع داده‌های دیگری نیز وجود دارند:

- COUNTER   we already know this one
- GAUGE     we just learned this one
- DERIVE
- ABSOLUTE

دو نوع دیگر DERIVE و ABSOLUTE هستند. نوع ABSOLUTE می‌تواند مانند شمارنده استفاده شود با یک تفاوت: RRDtool فرض می‌کند که شمارنده در هر بار خوانده شدن ریست (صفر) می‌شود؛ یعنی تفاضل (delta) آن بدون نیاز به محاسبه توسط RRDtool مشخص است، در حالی که برای نوع counter، ابزار RRDtool باید خودش این اختلاف را محاسبه کند. مثال: در اولین مثال ما (12345، 12357، 12363، 12363)، مقادیر تفاضل این‌گونه خوانده می‌شدند: نامشخص (unknown)، ۱۲، ۶، ۰. بقیه محاسبات یکسان باقی می‌ماند. نوع دیگر، یعنی DERIVE، مانند شمارنده است؛ اما بر خلاف شمارنده، می‌تواند کاهش نیز بیابد و در نتیجه ممکن است دارای تفاضل منفی باشد. باز هم بقیه محاسبات بدون تغییر باقی می‌مانند.

بیایید همه آن‌ها را امتحان کنیم:

rrdtool create all.rrd --start 978300900 \
         DS:a:COUNTER:600:U:U \
         DS:b:GAUGE:600:U:U \
         DS:c:DERIVE:600:U:U \
         DS:d:ABSOLUTE:600:U:U \
         RRA:AVERAGE:0.5:1:10
rrdtool update all.rrd \
         978301200:300:1:600:300    \
         978301500:600:3:1200:600   \
         978301800:900:5:1800:900   \
         978302100:1200:3:2400:1200 \
         978302400:1500:1:2400:1500 \
         978302700:1800:2:1800:1800 \
         978303000:2100:4:0:2100    \
         978303300:2400:6:600:2400  \
         978303600:2700:4:600:2700  \
         978303900:3000:2:1200:3000
rrdtool graph all1.png -s 978300600 -e 978304200 -h 400 \
         DEF:linea=all.rrd:a:AVERAGE LINE3:linea#FF0000:"Line A" \
         DEF:lineb=all.rrd:b:AVERAGE LINE3:lineb#00FF00:"Line B" \
         DEF:linec=all.rrd:c:AVERAGE LINE3:linec#0000FF:"Line C" \
         DEF:lined=all.rrd:d:AVERAGE LINE3:lined#000000:"Line D"

  • خط A از نوع COUNTER است، بنابراین باید پیوسته افزایش یابد و RRDtool باید اختلاف‌ها را محاسبه کند. همچنین RRDtool باید این اختلاف را بر میزان زمان سپری‌شده تقسیم نماید. نتیجه باید یک خط مستقیم روی عدد ۱ باشد (تفاضل‌ها ۳۰۰ و زمان نیز ۳۰۰ است).
  • خط B از نوع GAUGE است. این‌ها مقادیر «واقعی» هستند، بنابراین باید دقیقاً با آنچه وارد کرده‌ایم مطابقت داشته باشند: نوعی موج.
  • خط C از نوع DERIVE است. این باید شمارنده‌ای باشد که امکان کاهش دارد. در بازه بین ۲۴۰۰ و ۰ با مقدار ۱۸۰۰ در میان آن‌ها کاهش می‌یابد.
  • خط D از نوع ABSOLUTE است. این نوع شبیه به شمارنده است اما مستقیماً روی مقادیر بدون محاسبه اختلاف کار می‌کند. اعداد واردشده یکسان هستند اما همان‌طور که می‌بینید (امیدوارم)، نتیجه متفاوتی حاصل شده است.

این محاسبات به مقادیر زیر تبدیل می‌شوند که از ساعت 23:10 آغاز شده و در ساعت 00:10 روز بعد به پایان می‌رسند (که در آن "u" به معنای نامشخص یا رسم‌نشده است):

- Line A:  u  u  1  1  1  1  1  1  1  1  1  u
- Line B:  u  1  3  5  3  1  2  4  6  4  2  u
- Line C:  u  u  2  2  2  0 -2 -6  2  0  2  u
- Line D:  u  1  2  3  4  5  6  7  8  9 10  u

اگر فایل PNG شما تمام این موارد را نشان می‌دهد، می‌دانید که داده‌ها را درست وارد کرده‌اید، فایل اجرایی RRDtool به درستی کار می‌کند، نمایشگر تصویر شما را فریب نداده و با موفقیت وارد سال ۲۰۰۰ شده‌اید :)

می‌توانید همین مثال را چهار بار تکرار کنید، هر بار تنها با رسم یکی از خطوط.

بیایید داده‌ها را بار دیگر مرور کنیم:

  • خط A: مقادیر ۳۰۰، ۶۰۰، ۹۰۰ و غیره. اختلاف شمارنده همواره عدد ثابت ۳۰۰ است و اختلاف زمان نیز ۳۰۰ است. یک عدد تقسیم بر خودش همواره برابر با ۱ است (به جز تقسیم بر صفر که تعریف‌نشده/غیرمجاز است).

    چرا نقطه اول نامشخص است؟ ما می‌دانیم چه چیزی در پایگاه‌داده قرار داده‌ایم، درست است؟ بله، اما مقداری برای محاسبه تفاضل اولیه در دست نداشتیم، بنابراین نمی‌دانیم از کجا شروع کرده‌ایم. فرض اینکه از صفر شروع کرده‌ایم اشتباه خواهد بود، بنابراین چنین فرضی نمی‌کنیم!

  • خط B: چیزی برای محاسبه وجود ندارد. اعداد دقیقاً همان‌گونه که هستند نمایش داده می‌شوند.
  • خط C: باز هم مقدار شروع نامشخص است. داستان مشابه خط A است. در این حالت تفاضل‌ها ثابت نیستند و بنابراین خط نیز صاف نیست. اگر همان اعدادی را که برای خط A استفاده کردیم در پایگاه‌داده قرار می‌دادیم، خط مشابهی دریافت می‌کردیم. بر خلاف نوع counter، این نوع می‌تواند کاهش یابد و امیدوارم بعداً به شما نشان دهم چرا این موضوع تفاوت ایجاد می‌کند.
  • خط D: در اینجا خود دستگاه تفاضل‌ها را محاسبه می‌کند. بنابراین ما نخستین تفاضل را می‌دانیم و رسم می‌شود. ما همان ورودی خط A را داشتیم، اما مفهوم این ورودی متفاوت است و بنابراین خط متفاوتی رسم شده است. در این مورد، تفاضل‌ها هر بار ۳۰۰ واحد افزایش می‌یابند. تفاضل زمان در عدد ثابت ۳۰۰ باقی می‌ماند و بنابراین تقسیم این دو، مقادیر افزایشی را نشان می‌دهد.

چند مفهوم پایه‌ای دیگر برای نمایش باقی مانده است. هنوز برخی گزینه‌های مهم باید پوشش داده شوند و ما تا کنون به پدیده سرریز شمارنده‌ها (counter wraps) نگاهی نینداخته‌ایم. ابتدا سرریز شمارنده: در خودروی خود متوجه می‌شویم که کیلومترشمار عدد 999987 را نشان می‌دهد. ما ۲۰ کیلومتر حرکت می‌کنیم و شمارنده باید به 1000007 برسد. متأسفانه تنها ۶ رقم روی شمارنده ما وجود دارد، بنابراین عدد واقعی که نمایش داده می‌شود 000007 است. اگر بخواهیم این داده را روی نوع DERIVE رسم کنیم، بدین معنا خواهد بود که شمارنده ۹۹۹۹۸۰ کیلومتر به عقب بازگردانده شده است! در حالی که چنین نبوده و باید تدبیری برای محافظت در برابر این موضوع وجود داشته باشد. این سازوکار حفاظتی تنها برای نوع COUNTER در دسترس است که به هر حال برای این گونه شمارنده‌ها باید استفاده شود. نحوه کار آن چگونه است؟ نوع counter هرگز نباید کاهش یابد، بنابراین اگر کاهشی رخ دهد، RRDtool باید فرض کند که شمارنده سرریز کرده و دور زده است! اگر مقدار تفاضل منفی باشد، می‌توان این موضوع را با افزودن مقدار بیشینه شمارنده + ۱ جبران کرد. برای خودروی ما، محاسبات بدین صورت خواهد بود:

Delta = 7 - 999987 = -999980    (instead of 1000007-999987=20)
Real delta = -999980 + 999999 + 1 = 20

در زمان نگارش این سند، ابزار RRDtool شمارنده‌هایی را می‌شناسد که اندازه آن‌ها ۳۲ بیت یا ۶۴ بیت است. این شمارنده‌ها می‌توانند مقادیر مختلف زیر را مدیریت کنند:

- 32 bits: 0 ..           4294967295
- 64 bits: 0 .. 18446744073709551615

اگر این اعداد برای شما نامأنوس به نظر می‌رسند، می‌توانید آن‌ها را در قالب هگزادسیمال (مبنای شانزده) مشاهده کنید:

- 32 bits: 0 ..         FFFFFFFF
- 64 bits: 0 .. FFFFFFFFFFFFFFFF

ابزار RRDtool با هر دو نوع شمارنده به شکل یکسان رفتار می‌کند. در صورت وقوع سرریز (overflow) و منفی شدن تفاضل، RRDtool ابتدا مقدار بیشینه یک شمارنده کوچک + ۱ را به تفاضل اضافه می‌کند. اگر تفاضل همچنان منفی بماند، مشخص می‌شود که این شمارنده بزرگ بوده که سرریز کرده است. در این حالت بیشینه مقدار ممکن برای شمارنده بزرگ + ۱ اضافه شده و مقدار شمارنده کوچک که به اشتباه افزوده شده بود، کسر می‌گردد.

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

بخش بعدی چند مثال عددی برای سرریز شمارنده‌ها به شما ارائه می‌دهد. سعی کنید محاسبات را خودتان انجام دهید، یا اگر ماشین‌حساب شما قادر به پردازش این اعداد نجومی نیست، به درستی محاسبات من اعتماد کنید :)

اعداد تصحیح:

- 32 bits: (4294967295 + 1) =                                4294967296
- 64 bits: (18446744073709551615 + 1)
                                   - correction1 = 18446744069414584320
Before:        4294967200
Increase:                100
Should become: 4294967300
But really is:             4
Delta:        -4294967196
Correction1:  -4294967196 + 4294967296 = 100
Before:        18446744073709551000
Increase:                             800
Should become: 18446744073709551800
But really is:                        184
Delta:        -18446744073709550816
Correction1:  -18446744073709550816
                               + 4294967296 = -18446744069414583520
Correction2:  -18446744069414583520
                  + 18446744069414584320 = 800
Before:        18446744073709551615 ( maximum value )
Increase:      18446744069414584320 ( absurd increase, minimum for
Should become: 36893488143124135935             this example to work )
But really is: 18446744069414584319
Delta:                     -4294967296
Correction1:  -4294967296 + 4294967296 = 0
(not negative -> no correction2)
Before:        18446744073709551615 ( maximum value )
Increase:      18446744069414584319 ( one less increase )
Should become: 36893488143124135934
But really is: 18446744069414584318
Delta:                     -4294967297
Correction1:  -4294967297 + 4294967296 = -1
Correction2:  -1 + 18446744069414584320 = 18446744069414584319

همان‌طور که از دو مثال آخر مشاهده می‌کنید، برای اینکه RRDtool شکست بخورد به اعدادی بسیار عجیب و غیرعادی نیاز است (البته به شرطی که خودش بدون باگ باشد)، بنابراین چنین وضعیتی نباید رخ دهد. با این حال، SNMP یا هر روش دیگری که برای جمع‌آوری داده‌ها انتخاب می‌کنید، ممکن است گهگاه اعداد اشتباهی را گزارش کند. ما نمی‌توانیم از تمام خطاها جلوگیری کنیم، اما کارهایی وجود دارد که می‌توانیم انجام دهیم. دستور "create" در RRDtool دو پارامتر ویژه برای این منظور دریافت می‌کند. این پارامترها حداقل و حداکثر مقادیر مجاز را تعریف می‌کنند. تا کنون، ما از "U" به معنای "نامشخص" (unknown) استفاده می‌کردیم. اگر مقادیری را برای یک یا هر دوی آن‌ها تعیین کنید و RRDtool نقاط داده‌ای خارج از این محدوده‌ها دریافت کند، آن مقادیر را نادیده خواهد گرفت. برای دماسنجی بر حسب درجه سلسیوس، حداقل مطلق درست کمتر از 273- است. برای روتر من، می‌توانم فرض کنم این حداقل بسیار بالاتر است، بنابراین آن را روی 10 تنظیم می‌کنم، در حالی که حداکثر دما را روی 80 قرار می‌دهم. هر مقداری بالاتر از این نشان‌دهنده از کار افتادن دستگاه خواهد بود.

برای سرعت خودروی من، من هرگز انتظار اعداد منفی را ندارم و همچنین انتظار سرعتی بالاتر از ۲۳۰ را نیز ندارم. هر مقدار دیگری غیر از این باشد، حتماً خطایی رخ داده است. به یاد داشته باشید: عکس این قضیه صادق نیست؛ یعنی اگر اعداد از این فیلتر اعتبارسنجی عبور کنند، لزوماً به این معنا نیست که حتماً درست هستند. همیشه نمودار را با مقداری شک و تردید منطقی بررسی کنید اگر چیزی در آن به نظرتان عجیب می‌رسد.

یکی از ویژگی‌های مهم RRDtool هنوز توضیح داده نشده است: عملاً غیرممکن است که داده‌ها را جمع‌آوری کرده و دقیقاً در فواصل زمانی کاملاً یکسان به RRDtool تزریق کنید. بنابراین، RRDtool داده‌ها را درون‌یابی (interpolate) می‌کند تا در فواصل زمانی دقیق ذخیره شوند. اگر نمی‌دانید این به چه معناست یا چگونه کار می‌کند، این توضیحات برای شماست:

فرض کنید یک شمارنده دقیقاً در هر ثانیه یک واحد افزایش می‌یابد. شما می‌خواهید آن را در فواصل زمانی ۳۰۰ ثانیه‌ای اندازه‌گیری کنید. باید مقادیری را دریافت کنید که دقیقاً ۳۰۰ واحد با هم فاصله دارند. با این حال، به دلیل شرایط مختلف، شما چند ثانیه دیرتر اقدام می‌کنید و فاصله زمانی ۳۰۳ ثانیه می‌شود. در این حالت تفاضل نیز ۳۰۳ خواهد بود. مشخص است که RRDtool نباید عدد ۳۰۳ را در پایگاه‌داده ذخیره کند و باعث شود تصور کنید شمارنده در ۳۰۰ ثانیه ۳۰۳ واحد افزایش یافته است. اینجاست که RRDtool درون‌یابی می‌کند: مقدار ۳۰۳ را طوری تغییر می‌دهد که گویی زودتر ذخیره شده است و مقدار آن ۳۰۰ در ۳۰۰ ثانیه خواهد بود. دفعه بعد شما دقیقاً سر وقت اقدام می‌کنید. این بدان معناست که فاصله زمانی فعلی ۲۹۷ ثانیه است و شمارنده نیز ۲۹۷ واحد افزایش یافته است. باز هم RRDtool درون‌یابی می‌کند و عدد ۳۰۰ را همان‌طور که باید باشد ذخیره می‌نماید.

     in the RRD                 in reality
time+000:   0 delta="U"   time+000:    0 delta="U"
time+300: 300 delta=300   time+300:  300 delta=300
time+600: 600 delta=300   time+603:  603 delta=303
time+900: 900 delta=300   time+900:  900 delta=297

بیایید دو پایگاه‌داده یکسان ایجاد کنیم. من بازه زمانی 920805000 تا 920805900 را انتخاب کرده‌ام زیرا با اعداد مثال بسیار خوب هماهنگ است.

rrdtool create seconds1.rrd   \
   --start 920804700          \
   DS:seconds:COUNTER:600:U:U \
   RRA:AVERAGE:0.5:1:24

یک نسخه کپی بسازید

for Unix: cp seconds1.rrd seconds2.rrd
for Dos:  copy seconds1.rrd seconds2.rrd
for vms:  how would I know :)

تعدادی داده وارد کنید

rrdtool update seconds1.rrd \
   920805000:000 920805300:300 920805600:600 920805900:900
rrdtool update seconds2.rrd \
   920805000:000 920805300:300 920805603:603 920805900:900

خروجی گرافیکی ایجاد کنید

rrdtool graph seconds1.png                       \
   --start 920804700 --end 920806200             \
   --height 200                                  \
   --upper-limit 1.05 --lower-limit 0.95 --rigid \
   DEF:seconds=seconds1.rrd:seconds:AVERAGE      \
   CDEF:unknown=seconds,UN                       \
   LINE2:seconds#0000FF                          \
   AREA:unknown#FF0000
rrdtool graph seconds2.png                       \
   --start 920804700 --end 920806200             \
   --height 200                                  \
   --upper-limit 1.05 --lower-limit 0.95 --rigid \
   DEF:seconds=seconds2.rrd:seconds:AVERAGE      \
   CDEF:unknown=seconds,UN                       \
   LINE2:seconds#0000FF                          \
   AREA:unknown#FF0000

هر دو تصویر را با هم مشاهده کنید (آن‌ها را به فایل index.html خود اضافه کنید) و با هم مقایسه نمایید. با وجود اینکه ورودی‌ها متفاوت بودند، هر دو نمودار باید مقادیر یکسانی را نشان دهند.

اکنون زمان جمع‌بندی این راهنمای آموزشی فرارسیده است. ما تمام مبانی لازم را پوشش دادیم تا شما بتوانید با RRDtool کار کنید و مستندات تکمیلی موجود را بخوانید. نکات بسیار بیشتری برای کشف در RRDtool وجود دارد و شما کاربردهای بیشتر و بیشتری برای این بسته نرم‌افزار خواهید یافت. می‌توانید به سادگی و تنها با استفاده از مثال‌های ارائه‌شده و به تنهایی با RRDtool نمودارها را رسم کنید. همچنین می‌توانید از یکی از رابط‌های کاربری (front ends) موجود برای RRDtool استفاده نمایید.

به خاطر داشته باشید که در فهرست پستی RRDtool عضو شوید. حتی اگر به ایمیل‌های ارسالی پاسخ ندهید، این کار هم به شما و هم به سایر کاربران کمک می‌کند. بسیاری از چیزهایی که درباره MRTG (و بنابراین درباره RRDtool) می‌دانم را صرفاً با خواندن پیام‌های لیست بدون ارسال پستی به آن آموخته‌ام. نیازی به پرسیدن سوالات اولیه نداشتم زیرا در بخش پرسش‌های متداول (FAQ - آن را بخوانید!) و در ایمیل‌های مختلف کاربران پاسخ داده شده‌اند. با وجود هزاران کاربر در سراسر جهان، همیشه افرادی خواهند بود که سوالاتی بپرسند و شما بتوانید به آن‌ها پاسخ دهید زیرا شما این سند و سایر مستندات را خوانده‌اید در حالی که آن‌ها نخوانده‌اند.

صفحات راهنمای RRDtool

امیدوارم از مثال‌ها و توضیحات آن‌ها لذت برده باشید. اگر چنین است، با معرفی این سند به افرادی که سوالات اولیه دارند، به دیگران کمک کنید. آن‌ها نه تنها پاسخ‌های خود را دریافت خواهند کرد، بلکه هم‌زمان مطالب بسیار بیشتری را خواهند آموخت.

الکس ون دن بوگارت (Alex van den Bogaerdt) <alex@vandenbogaerdt.nl>

2026-08-08 1.11.0