.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man v6.0.2 (Pod::Simple 3.45) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Required to disable full justification in groff 1.23.0. .if n .ds AD l .\" ======================================================================== .\" .IX Title "RRD_PDPCALC 1" .TH RRD_PDPCALC 1 2026-08-08 1.11.0 rrdtool .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "نام (NAME)" rrd_pdpcalc \- منطق محاسبات درونی PDP همراه با یک مثال از Tianpeng Xia .SH "توضیحات (DESCRIPTION)" .IX Header "DESCRIPTION" این مقاله نحوه محاسبه PDP را به روشی مفصل و در عین حال قابل فهم، همراه با یک مثال توضیح می‌دهد. .SH "مروری بر مبانی PDP (Refreshing some basics about PDP)" .IX Header "Refreshing some basics about PDP" .SS "دانش پایه (Fundamental knowledge)" .IX Subsection "Fundamental knowledge" اگر آموزش‌ها یا صفحات راهنما (man pages) را در وبگاه رسمی یا نوشته‌های دیگران مطالعه نکرده‌اید، اکیداً پیشنهاد می‌کنم این کار را انجام دهید. همان‌طور که در توضیحات گفته شد، این مقاله صرفاً نحوه محاسبه یک PDP را توضیح می‌دهد و نه تعریف آن را. بنابراین لطفاً مطالب زیر را بخوانید تا درک اولیه‌ای از PDP به دست آورید: .PP \- نوشته Alex van den Bogaerdt. این مقاله PDP را به شکلی بسیار مفصل و شفاف توضیح داده است، با این حال، «فرایند نرمال‌سازی» را در بخش «Normalize interval» به روش درستی توضیح نمی‌دهد (بر خلاف نسخه رسمی که من شخصاً با خود \f(CW@oetiker\fR تأیید کردم). این نقص را می‌توان به راحتی در نمودارهای میله‌ای که در بخش «منطق‌های محاسباتی» مورد بحث قرار گرفته است مشاهده کرد. .PP \- این مورد در وبگاه رسمی قرار دارد. در واقع این صفحه راهنما برای «rrdcreate» است و آنچه در پشت صحنه در ارتباط با محاسبه PDP رخ می‌دهد را در بخش «The HEARTBEAT and the STEP» آشکار می‌سازد. .PP نمودار متنی Don Baarda توضیح روشنی در مورد نحوه تولید داده‌های \fBUNKNOWN\fR و نحوه تأثیر مقدار heartbeat بر نمونه‌برداری ارائه می‌دهد. متأسفانه این نمودار روش شفافی برای نحوه محاسبه PDPها ارائه نمی‌کند. .PP \- یک آموزش رسمی و مفصل دیگر توسط Alex van den Bogaerdt. به طور مشابه، این آموزش فقط مثال‌هایی با داده‌های توزیع‌شده به صورت یکنواخت و دقیق طبق step تعیین‌شده ارائه می‌دهد. .PP اگر تمایلی به انجام آزمایش ندارید یا چندان به سازوکار درونی آن اهمیت نمی‌دهید، می‌توانید همین‌جا متوقف شوید و به موضوعات کاربردی‌تر مانند صدور نمودارها یا راهنمای دستورها توجه کنید. اما اگر از آن دسته افرادی مانند من هستید که به همان اندازه به منطق‌های محاسباتی اهمیت می‌دهید، لطفاً به خواندن ادامه دهید. .SH "منطق‌های محاسباتی (Calculation logics)" .IX Header "Calculation logics" اینجا بخش اصلی این مقاله آغاز می‌شود. در ادامه این بخش، مایلم دو نسخه از روش‌های محاسبه را ارائه دهم، یکی توسط Alex van den Bogaerdt و دیگری توسط \f(CW@eotiker\fR. .PP برای ارائه توضیحی مناسب با نویسه‌های اسکی (ASCII)، هر دو نسخه را با نمودار زیر به جای یک تصویر واقعی توضیح خواهم داد. .PP .Vb 11 \& | \& | (v1) \& | _\|_\|_\|_\|_\|_\|_ (v4) (v5) \& | | | (v3) _\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_ \& | | | _\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_\|_| || | \& | | | | || || | \& | | | | || || | \& | | | (v2) | || || | \& | | |_\|_\|_\|_\|_\|_\|_\|_| || || | \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-> \& 0 1 3 7 17 20 21 .Ve .PP محور X نشان‌دهنده بازه‌های زمانی (هر ثانیه نشان‌دهنده یک بازه است) و محور Y نشان‌دهنده مقدار است. .PP بیایید همه‌چیز را کمی واضح‌تر کنیم: .PP \&\- مقدار step برابر با ۵ است .PP \&\- هر PDP تنها در صورتی به‌روزرسانی می‌شود که مقداری در آخرین بازهٔ PDP یا پس از آن دریافت شود؛ برای نمونه، آخرین بازهٔ PDP از ۱۶ تا ۲۰، عدد ۲۰ است .PP \&\- مقدار heartbeat برابر با ۲۰ است، بنابراین نمونه‌های کل دوره ۷\-۱۷ نادیده گرفته نمی‌شوند .PP \&\- در ثانیه ۳، اولین مقدار با عنوان v1 وارد می‌شود و به همین ترتیب .PP \&\- ثانیه ۰ مبدأ است و به عنوان یک نمونه به شمار نمی‌آید .SS "نسخه Bogaerdt (Bogaerdt version)" .IX Subsection "Bogaerdt version" همان‌طور که در این صفحه دیده می‌شود: ، پس از این‌که تمام داده‌های اولیه به نرخ تبدیل شدند (البته به جز GAUGE)، به گفته نویسنده در صورتی که دقیقاً بر اساس step یا در مرزهای زمانیِ به خوبی تعریف‌شده توزیع نشده باشند، باید از یک \fBفرایند نرمال‌سازی (normalization process)\fR عبور کنند. .PP این به چه معناست؟ اساساً اگر تمام داده‌های \fBشناخته‌شده (known)\fR (در مقابل یک مقدار \fBناشناخته (unknown)\fR) حداقل ۵۰٪ از تمام بازه‌ها را در طول یک دوره تشکیل دهند، یک PDP بر اساس آن‌ها محاسبه می‌شود. .PP به نظر می‌رسد این نسخه تا رسیدن به بخش نمودار میله‌ای به خوبی پیش می‌رود. .PP طبق نمودار میله‌ای اسکی، نتایج زیر حاصل می‌شود: .PP از ثانیه ۱ به بعد، مقدار PDP هر دوره (۱\-۵، ۶\-۱۰، ...) با میانگین‌گیری از تمام مقادیر موجود در آن محاسبه می‌شود. .PP بنابراین: \&\- مقدار PDP از ۱ تا ۵ برابر است با (v1*3+v2*2)/5 .PP \&\- مقدار PDP از ۶ تا ۱۰ برابر است با (v2*2+v3*3)/5 .PP \&\- مقدار PDP از ۱۱ تا ۱۵ برابر است با (v3*5)/5، زیرا تمام مقادیر در بازه‌های ۱۱، ۱۲، ۱۳، ۱۴ و ۱۵ یکسان بوده و برابر با v3 هستند .PP \&\- ... .ie n .SS "نسخه رسمی (همچنین نسخه @oetiker):" .el .SS "نسخه رسمی (همچنین نسخه \f(CW@oetiker\fP):" .IX Subsection "The official version( also @oetiker version):" با استفاده از همان نمودار، این نسخه موارد زیر را پیشنهاد می‌کند: .PP \&\- مقدار PDP از ۱ تا ۵ برابر است با (v1*3+v2*2)/5 .PP \&\- مقادیر PDP از ۶ تا ۱۰ و ۱۱ تا ۱۵ \fBیکسان (SAME)\fR هستند که برابر است با (v2*2+v3*8) .PP \&\- ... .SS "یک مقایسه و توضیحات بیشتر (A Comparison and some explanation)" .IX Subsection "A Comparison and some explanation" بنابراین ما این دو نسخه را دیدیم که مقادیر PDP آن‌ها از ۶ تا ۱۰ و ۱۱ تا ۱۵ با یکدیگر همخوانی ندارند. .PP چرا چنین است؟ .PP زیرا تفاوت بین نسخه رسمی و نسخه Bogaerdt از شیوه محاسبه آن‌ها برای PDP(6\-10) و PDP(11\-15) ناشی می‌شود. .PP بیایید با استفاده از نمودار میله‌ای بالا با جزئیات بیشتری درباره این موضوع بحث کنیم. .PP \fIنسخه Bogaerdt،\fR .IX Subsection "Bogaerdt's version," .PP مقادیر PDP \fBهمیشه به صورت مجزا محاسبه می‌شوند\fR، فارغ از اینکه مقادیر چگونه دریافت شوند. .PP برای مثال، مقدار موجود در بازه ۱۷ پس از آخرین بازهٔ PDP(11\-15) می‌آید. همچنین، مقدار بلافاصله قبلی پیش از بازه ۱۷ در ۷ قرار دارد. به تمام بازه‌های ۷ تا ۱۷ مقدار v3 اختصاص داده شده است. از آنجا که هر PDP به صورت مجزا محاسبه می‌شود، مقدار PDP(6\-10) برابر با (v2*2+v3*3)/5 است در حالی که PDP(11\-15) برابر با (v3*5)/5 خواهد بود. .PP \fIنسخه رسمی\fR .IX Subsection "The official version" .PP مقادیر PDP \fBهمیشه بر اساس گام‌هایی (steps) محاسبه می‌شوند که به‌روزرسانی بعدی در بر می‌گیرد\fR، چه ۱ گام باشد، چه ۲ گام یا n گام؛ به عبارت دیگر، ممکن است PDPها \fBبا هم\fR محاسبه شوند. .PP برای نمونه، به‌روزرسانی در بازه ۱۷ هر دو دوره PDP(6\-10) و PDP(11\-15) را در بر می‌گیرد، زیرا مقدار \fBبلافاصله\fR قبلی در ۷ قرار دارد و ۷ بین ۶ و ۱۰ است، و ۱۷ پس از ۱۵ قرار دارد. دوره‌های PDP(1\-5) و PDP(16\-20) در آن گنجانده نمی‌شوند زیرا به‌روزرسانی در بازه ۷ پیش‌تر محاسبه برای PDP(1\-5) را فعال کرده است و به‌روزرسانی در بازه ۱۷ پیش از آخرین بازهٔ PDP(16\-20) یعنی ۲۰ می‌آید. .PP به همین دلیل است که PDP(6\-10) و PDP(11\-15) دارای مقداری یکسان یعنی (v2*2+v3*8) هستند. .SH "یک مثال (An example)" .IX Header "An example" اگر هنوز سردرگم هستید، نگران نباشید؛ یک مثال برای کمک به شما در اینجا آورده شده است. .PP بیایید با چند دستور دست‌به‌کار شویم: .PP .Vb 6 \& rrdtool create target.rrd \-\-start 1000000000 \-\-step 5 DS:mem:GAUGE:20:0:100 RRA:AVERAGE:0.5:1:10 \& rrdtool update target.rrd 1000000003:8 1000000006:1 1000000017:6 \e \& 1000000020:7 1000000021:7 1000000022:4 \e \& 1000000023:3 1000000036:1 1000000037:2 \e \& 1000000038:3 1000000039:3 1000000042:5 \& rrdtool fetch target.rrd AVERAGE \-\-start 1000000000 \-\-end 1000000045 .Ve .PP اساساً کدهای بالا شامل ۳ دستور است: create، update و fetch. ابتدا یک فایل rrd جدید ایجاد می‌کنیم، سپس مقداری داده به آن تزریق کرده و در نهایت تمام PDPها را از rrd واکشی می‌کنیم. .SS "تمرکز بر گام‌های منفرد (Focus on single steps)" .IX Subsection "Focus on single steps" برای ارائه توضیحی دقیق، فرایند محاسبه هر یک از PDPها ارائه شده است. .PP در زیر خروجی دستورهای بالا آمده است: .PP .Vb 10 \& 1000000005: 5.2000000000e+00 \& 1000000010: 5.5000000000e+00 \& 1000000015: 5.5000000000e+00 \& 1000000020: 6.6000000000e+00 \& 1000000025: 1.7333333333e+00 \& 1000000030: 1.7333333333e+00 \& 1000000035: 1.7333333333e+00 \& 1000000040: 2.8000000000e+00 \& 1000000045: nan \& 1000000050: nan .Ve .PP نکته: عدد 1000000005 به معنای PDP از 1000000001 تا 1000000005 است و به همین ترتیب. برای اختصار و خوانایی بهتر، فقط از دو رقم آخر استفاده می‌کنیم، بنابراین 05 نشان‌دهنده 1000000005 است. ما نوع منبع داده (data source) را gauge انتخاب می‌کنیم زیرا مقادیر اولیه به عنوان نرخ در نظر گرفته می‌شوند و به تبدیل اضافی نیازی نیست؛ برای جزئیات بیشتر به این مقاله مراجعه کنید. .PP 05: 5.2 = (8*3+1*2)/5 .PP 10: 5.5 = (1*1+6*9)/10 .PP 15: مشابه مورد قبلی .PP 20: 6.6 = (6*2+7*3)/5 .PP 25: 1.73333 = (7+4+3+1*12)/15 .PP \&... .PP 45: nan، چرا که آخرین مقدار در ۴۲ قرار دارد که باعث فعال شدن محاسبه برای PDP(41\-45) نمی‌شود .PP 50: nan، دلیل اینکه چرا این PDP ناشناخته نمایش داده می‌شود در این مقاله توضیح داده شده است: .SH "خلاصه (SUMMARY)" .IX Header "SUMMARY" با همه این گفته‌ها، امیدوارم درک روشنی از «جادوی» محاسبات درونی PDPها به دست آورده باشید. .SS "سایر منابع (Other References)" .IX Subsection "Other References" .IP \(bu 4 یک اسکریپت پوستهٔ بسیار خوب PowerShell برای تولید نمودارهای میله‌ای اسکی: .IP \(bu 4