עודכן לפני חודש
TCP לא סומך על הרשת. הוא פשוט לא יכול להרשות לעצמו.
כל מנה נושאת שאלה סמויה: קיבלת את זה? הנמען עונה עם אישורים. כשהתשובות מפסיקות — או חוזרות שגויות — TCP מניח את הגרוע מכל ושולח את הנתונים שנית. הפרנויה הזו היא המחיר של אמינות.
איך TCP יודע שמשהו השתבש
TCP משתמש במספרי רצף ואישורים כדי לעקוב אחרי כל בייט בדרכו. השולח ממספר כל קטע. הנמען מגיב עם ACK המציין את הבייט הבא שהוא מצפה לו. זה יוצר לולאת משוב: שלח, אשר, שלח עוד.
כשלולאת המשוב מתפרקת, TCP שם לב. יש שני אותות:
פסק זמן. השולח ממתין ל-ACK. אם לא מגיע דבר בתוך חלון מחושב, TCP מניח שהקטע אבד ומשדר מחדש.
ACKים כפולים. הנמען מקבל קטעים שלא לפי הסדר — נניח, קטעים 1, 2, 3, ואז 5. קטע 4 חסר. הנמען לא יכול לאשר את קטע 5 כיוון ש-ACKים הם מצטברים (מאשרים עד מספר רצף מסוים). אז הוא שולח ACK נוסף לקטע 3. ועוד אחד כשמגיע קטע 6. כל קטע שמגיע שלא לפי הסדר מפעיל ACK כפול.
TCP לא מחכה שהרשת תגיד לו שמשהו השתבש. הוא מסיק אובדן מתבניות — שקט שבמקומו צריכה להיות הכרה, חזרה שבמקומה אמור להיות התקדמות.
פסק הזמן לשידור חוזר
פסק הזמן לשידור חוזר (RTO) קובע כמה זמן TCP ממתין לפני שמחליט שקטע אבד.
קצר מדי: TCP משדר מחדש ללא צורך, מבזבז רוחב פס ומחמיר עומס.
ארוך מדי: אפליקציות קופאות כשמנות אכן אובדות.
TCP מחשב RTO באופן דינמי מזמן הסבב המדוד (RTT) — הזמן שלוקח לקטע להגיע ליעד ול-ACK לחזור. אך RTT משתנה ללא הרף. עומס, שינויי ניתוב, עיכובי עיבוד — כולם משפיעים עליו.
כדי להתמודד עם השונות הזו, TCP שומר RTT מוחלק (SRTT) שממצע מדידות אחרונות, וכן שונות RTT (RTTVAR) שעוקבת אחרי התנודות. נוסחת ה-RTO מ-RFC 62981:
זה שמרני בכוונה — בדרך כלל פי כמה מה-RTT הממוצע, כדי להימנע מטעות בין שונות עיכוב רגילה לאובדן.
כשפסק הזמן יורה, TCP לא רק משדר מחדש — הוא מכפיל את ה-RTO לניסיונות עוקבים. נסיגה אקספוננציאלית זו מפחיתה את העומס על רשת שעלולה להיות עמוסה. אם כמה שידורים חוזרים נכשלים ברציפות, TCP בסופו של דבר מוותר ומדווח על שגיאה לאפליקציה.
שידור חוזר מהיר: קריאת החדר
המתנה לפסקי זמן היא איטית. בחיבור עם RTT של 50ms אך RTO של 200ms, התאוששות מבוססת פסק זמן לוקחת פי ארבעה מהדרוש.
כשהשולח מקבל שלושה ACKים כפולים לאותו מספר רצף — ארבעה ACKים זהים סה"כ — הוא לא מחכה לפסק הזמן. הוא משדר מחדש מיד.
למה שלושה? ACK כפול בודד עשוי פשוט לאמר שמנות הגיעו שלא לפי הסדר. שניים עדיין יכולים להצביע על סדרה מחדש. אבל שלושה ACKים כפולים — הנמען שואל על אותו דבר שוב ושוב — זה האות של TCP שמשהו באמת חסר.
כלל ה"ACK כפול משולש" הזה מתאושש מאובדן בסביבות RTT אחד, במקום לחכות לכל תקופת פסק הזמן.
אישור סלקטיבי
אישורי TCP סטנדרטיים הם מצטברים: "קיבלתי הכל עד בייט 1000." זה עובד כשקטע אחד אבד. אבל כשמספר קטעים אובדים מאותה חלונית, השולח יודע שמשהו חסר — אך לא מה בדיוק.
אישור סלקטיבי (SACK), המוגדר ב-RFC 20182, מתקן זאת. כש-SACK מופעל, הנמען מדווח: "קיבלתי בייטים 1-1000, וגם בייטים 2001-3000, אבל חסרים לי 1001-2000."
עכשיו השולח יודע בדיוק אילו קטעים לשדר מחדש. ללא SACK, הוא עשוי לשדר מחדש הכל מהאובדן הראשון ואילך. עם SACK, הוא משדר מחדש רק מה שבאמת חסר.
SACK נמצא במשא ומתן במהלך הגדרת החיבור — שני הצדדים חייבים לתמוך בו. מערכות הפעלה מודרניות מפעילות אותו כברירת מחדל. הוא בעל ערך במיוחד בחיבורים עם רוחב פס גבוה ועיכוב גבוה, שבהם קטעים רבים יכולים לצוף ברשת בו-זמנית.
עלות השידור החוזר
כל שידור חוזר הוא בזבוז — הרשת נשאה את הנתונים האלה פעמיים, האפליקציה הזדקקה להם פעם אחת.
במקרה הטוב: שידור חוזר מהיר עובד, עולה RTT אחד נוסף של עיכוב.
במקרה הגרוע: שידור חוזר מבוסס פסק זמן עם נסיגה אקספוננציאלית הופך מנה אחת אבודה לשניות של עיכוב.
שידורים חוזרים גם מפעילים בקרת עומס. פסק זמן אומר ל-TCP שהרשת מוצפת, אז TCP מקצץ את קצב השידור שלו — לפעמים ב-90% או יותר. לוקח זמן להתאושש. שידור חוזר מהיר עדין יותר (מחצית הקצב במקום איפוס מלא), אך עדיין משפיע על תפוקה.
רשת בריאה מציגה שיעורי שידור חוזר מתחת ל-1%. שיעורים מעל 3-5% מצביעים על בעיות: עומס, חומרה פגומה, הפרעות אלחוטיות, בעיות ניתוב. תעבורה אינטראקטיבית (SSH, משחקים) סובלת מעיכוב מוגבר. העברות נתחות סובלות מתפוקה מופחתת.
אבחון בעיות שידור חוזר
כשקצב השידורים החוזרים עולה, בדקו את התבנית.
שידורים חוזרים קבועים בקצב נמוך מרמזים על בעיות חומרה מתמשכות: אי-התאמת דופלקס, כבל פגום, אות אלחוטי שולי.
שידורים חוזרים פרציים מצביעים על עומס או הפרעה שמופיעים ונעלמים בהתאם לעומס התעבורה.
לכידת מנות (tcpdump, Wireshark) חושפת פרטים. האם אותם קטעים משודרים מחדש מספר פעמים? זה אובדן חמור. האם השידורים החוזרים פזורים על מספרי רצף שונים? זה אובדן אקראי. האם הם קשורים לנקודות שיא בתעבורה? זה עומס.
סטטיסטיקות מערכת גם עוזרות. בלינוקס, netstat -s מציג מונים מצטברים של שידורים חוזרים. מעקב אחריהם לאורך זמן חושף מתי התחילו הבעיות ואם הן קשורות לשינויים — הגדרות חדשות, שינויים בתבניות תעבורה, החלפות חומרה.
גורמים נפוצים: buffer bloat (חציצה מופרזת שגורמת לפסקי זמן), עומס ללא ניהול תורים מתאים, הפרעות אלחוטיות, כרטיסי רשת פגומים, התקני ביניים שמורידים מנות בצורה בלתי צפויה. במרכזי נתונים, שימו לב לניתוב אסימטרי שבו ACKים עוברים בנתיבים שונים מהנתונים, מה שעלול להפעיל שידורים חוזרים כוזבים.
שאלות נפוצות על שידורים חוזרים ב-TCP
למה TCP ממתין לשלושה ACKים כפולים ולא לאחד בלבד?
מנות לפעמים מגיעות שלא לפי הסדר מבלי לאבד — נתבים יכולים לשלוח אותן בנתיבים שונים. ACK כפול בודד עשוי פשוט לאמר שיש סדרה מחדש. שלושה ACKים כפולים פירושם שהנמען קיבל מספר קטעים עוקבים בעוד אותו קטע עדיין חסר. בנקודה כזו, סדרה מחדש אינה סבירה ואובדן כמעט ודאי.
מה ההבדל בין שידור חוזר לשידור חוזר כוזב?
שידור חוזר שולח מחדש נתונים שאכן אבדו. שידור חוזר כוזב שולח מחדש נתונים שלא אבדו — ה-ACK פשוט התעכב. שידורים חוזרים כוזבים מבזבזים רוחב פס ועלולים להפעיל בקרת עומס מיותרת. שונות RTT גבוהה מגבירה שידורים חוזרים כוזבים, כיוון שפסק הזמן יורה לפני ש-ACKים מעוכבים מגיעים.
האם אפשר לכוונן את התנהגות השידור החוזר של TCP?
כן, אבל בזהירות. לינוקס חושפת פרמטרים כגון tcp_retries1 ו-tcp_retries2 השולטים בכמה פעמים TCP משדר מחדש לפני ויתור. הורדתם גורמת לחיבורים להיכשל מהר יותר כשהרשת שבורה. העלתם שומרת על חיבורים חיים יותר זמן אך מעכבת את זיהוי השגיאות. ברירות המחדל עובדות טוב לרוב התרחישים.
איך אובדן מנות משפיע על שידור וידאו?
זה תלוי בפרוטוקול. שידור מבוסס TCP (כגון וידאו HTTPS מסוים) מושהה בזמן שהשידורים החוזרים מסתיימים. שידור מבוסס UDP (כגון WebRTC) מדלג על נתונים אבודים, גורם לפגמים ויזואליים אך שומר על השמעה בזמן אמת. זו הסיבה שוידאו חי משתמש לעתים קרובות ב-UDP — רגע של תקלה עדיף על פיגור.
מקורות
האם דף זה היה מועיל?