- เหมือนที่ NetworkManager อาจตัดสินว่าความไม่เสถียรของการเชื่อมต่อช่วงสั้น ๆ คือ “ไม่มีเครือข่าย” ซอฟต์แวร์บางตัวก็เชื่อการตัดสินสถานะของตัวเองมากกว่า การกู้คืนของ TCP แต่ในเครือข่ายจริงสิ่งนี้อาจเสี่ยงได้
- ความเชื่ออย่าง “ข้อมูลที่ส่งไปจะต้องไปถึง”, “สุดท้ายทั้งสองฝั่งจะตกลงกันได้ว่าไบต์ใดถูกส่งถึงแล้ว”, และ “สามารถรับประกันได้ด้วย application protocol อย่าง HTTP หรือ SMTP” ล้วนพังทลายได้ในบางสถานการณ์
- ถ้าการเชื่อมต่อขาดระหว่างจัดการ ACK ฝั่งส่งจะไม่มีทางรู้ว่าอีกฝั่งได้รับเซกเมนต์นั้นแล้วหรือไม่ และข้อจำกัดนี้ก็แก้ไม่ได้ด้วยสตรีม TCP แบบสองฝ่ายเพียงเส้นเดียว เช่นเดียวกับ Two Generals’ Problem
- แม้แต่ SMTP ก็กล่าวถึงปัญหานี้ใน RFC 1047 และ RFC 2821 โดยในจุดที่ความรับผิดชอบในการส่งต่อถูกส่งมอบ หากการเชื่อมต่อล้มเหลวก็จะมีช่วงคลุมเครือที่อาจเกิด การส่งซ้ำ หรือการตกหล่นได้
- หากมองข้ามเครือข่ายแปลก ๆ ว่าเป็นข้อยกเว้น หรือไม่สนใจรายละเอียดอย่างอัลกอริทึม Nagle, การควบคุมความคับคั่ง, หรือการบล็อก ICMP ก็จะตีความความขัดข้องจริงผิดได้ง่าย
ปัญหาของการสรุปสถานะเครือข่ายก่อน TCP
- ผู้ใช้ที่ใช้ NetworkManager เคยพบ การเชื่อมต่อไร้สายไม่เสถียร ในสภาพแวดล้อมการโรมมิงระหว่างหอพักกับแคมปัสในอดีต และเจอสถานการณ์ที่เมื่อมี packet loss เพียงเล็กน้อย ระบบทั้งระบบก็ถูกแจ้งว่า “ไม่มีเครือข่าย”
- ตอนนั้นเครือข่ายอาจกลับมาได้ในไม่ช้า และ การกู้คืนของ TCP ตามปกติ แม้จะทำให้ latency พุ่งสูงขึ้น ก็อาจยังโปร่งใสสำหรับแอปพลิเคชัน
- กรณีนี้เชื่อมโยงไปสู่ปัญหาที่แอปพลิเคชันหรือคอมโพเนนต์ของระบบตีความความขัดข้องชั่วคราวที่ TCP จัดการได้ว่าเป็นความล้มเหลวเร็วเกินไป
ความเชื่อที่มักผิดเกี่ยวกับ TCP
- ข้อความต่อไปนี้เป็นความเชื่อที่พบบ่อยเมื่อพูดถึง TCP แต่แต่ละข้ออย่างน้อยก็ ไม่จริง ในบางกรณี
- TCP เชื่อถือได้ ดังนั้นข้อมูลทุกอย่างที่ส่งจะไปถึงอีกฝั่ง
- TCP โดยรวมแล้วเชื่อถือได้
- ต่อให้ TCP ไม่ได้ให้ความเชื่อถือได้แบบสมบูรณ์ ฝั่งส่งและฝั่งรับก็จะตกลงกันได้อย่างถูกต้องในที่สุดว่าไบต์ใดถูกส่งไปแล้ว
- หากสร้าง application protocol แบบเน้นข้อความอย่าง HTTP หรือ SMTP บน TCP ก็สามารถสร้างการรับประกันแบบนั้นได้
- มีสิ่งที่เรียกว่าแพ็กเก็ต TCP
- ไม่มีสิ่งที่เรียกว่าแพ็กเก็ต TCP
- ถ้าเชื่อมต่อไปยัง remote host ที่รู้จักกันดีไม่ได้ แปลว่าออฟไลน์อยู่
- อัลกอริทึม Nagle นั้นดี
- อัลกอริทึม Nagle นั้นแย่
- ไม่จำเป็นต้องสนใจอัลกอริทึม Nagle
- คิดว่า TCP เป็นเหมือน Unix pipe แบบสองทิศทางที่วิ่งผ่านเครือข่ายก็เพียงพอแล้ว
- ถ้าเครือข่ายโปร่งใสต่อ TCP ก็ย่อมโปร่งใสต่อ IP ด้วย
- ถ้าเครือข่ายโปร่งใสต่อ HTTP/1.1 ก็ย่อมโปร่งใสต่อ TCP ด้วย
- เครือข่ายแปลก ๆ ที่ไม่โปร่งใสต่อโปรโตคอลมาตรฐานเป็นเรื่องยกเว้น จึงมองข้ามได้
- TCP ถูกอิมพลีเมนต์อยู่บน IP
เหตุใดจึงยากที่จะตกลงกันได้อย่างแม่นยำว่าไบต์ใดถูกส่งถึงแล้ว
- ประเด็นข้อ 1~4 ก่อนหน้านี้ที่เกี่ยวกับความเชื่อถือได้ของ TCP เชื่อมโยงกับ Two Generals’ Problem
- หากการเชื่อมต่อขาดไปตอนที่ ACK ยังประมวลผลไม่เสร็จ ฝั่งส่งจะไม่มีวิธียืนยันได้ว่าเซกเมนต์นั้นถูกรับแล้วหรือไม่
- ข้อจำกัดนี้ไม่หายไป แม้จะซ้อนเลเยอร์ที่ซับซ้อนกว่าลงบน TCP เพิ่มอีกก็ตาม
- บนสตรีม TCP แบบสองฝ่ายเพียงเส้นเดียว ไม่สามารถสร้างการรับประกันแบบนั้นได้ และการรับประกันลักษณะดังกล่าวต้องใช้แนวทางคล้าย Paxos หรือ Raft พร้อมอย่างน้อย 3 โหนด
- ปัญหาประเภทเดียวกันนี้ใช้ได้ไม่เฉพาะกับ TCP แต่รวมถึงบริการแบบสองฝ่ายบน UDP หรือ IP ด้วย
พื้นที่สีเทาของความรับผิดชอบในการส่งต่อที่ SMTP เผยให้เห็น
- SMTP เป็นบริการที่ทั้งสองฝั่งต้องใส่ใจอย่างชัดเจนว่าข้อความถูกรับแล้วหรือไม่ จึงทำให้ปัญหานี้เห็นได้ชัด
- RFC 1047 กล่าวถึงปัญหานี้ในมุมของ SMTP และ RFC 2821 ก็กำหนดว่าอิมพลีเมนเทชันควรปฏิบัติตามคำแนะนำสำคัญของ RFC 1047
- ในตัวอย่างของ SMTP มีการแยกสถานะต่อไปนี้
- สามารถไปถึงจุดที่ทั้งสองฝั่งตกลงกันได้ว่าอีเมลถูกส่งจากไคลเอนต์ไปยังเซิร์ฟเวอร์แล้ว
- สามารถไปถึงจุดที่ทั้งสองฝั่งตกลงกันได้ว่าเซิร์ฟเวอร์รับผิดชอบการส่งต่ออีเมลแล้ว
- แต่ก่อนหน้านั้นจำเป็นต้องผ่านสถานะที่ยังคลุมเครือว่าใครเป็นผู้รับผิดชอบการส่งต่ออีเมลอยู่ในขณะนั้น
- หากการเชื่อมต่อขาดในสถานะคลุมเครือนี้ ก็จะทำให้อีเมล ซ้ำ หรือ ตกหล่น
- สเปกของ SMTP ระบุว่าควรเลือกฝั่งที่ทำให้อีเมลซ้ำ แต่ในทางปฏิบัติไม่อาจรู้ได้ว่าการอิมพลีเมนต์ถูกทดสอบมาแค่ไหน
- จุดมุ่งหมายของ Paxos และ Raft ไม่ได้อยู่ที่การทำให้ถึงสถานะสุดท้ายเท่านั้น แต่เพื่อหลีกเลี่ยงสถานะคลุมเครือแบบนี้ด้วย
ข้อจำกัดของความรู้ที่ยังเหลืออยู่ในการตกลงกันระหว่างสองฝ่าย
- มีความเห็นหนึ่งมองว่า แม้บนลิงก์ที่ไม่น่าเชื่อถือแต่ไม่ได้มีเจตนาร้าย ทั้งสองฝ่ายก็ยังอาจตกลงกันได้เกี่ยวกับชุดไบต์บางส่วนว่า “ถูกส่งถึงแล้วและทั้งคู่รู้ข้อเท็จจริงนี้”
- การอภิปรายเพิ่มเติมสรุปว่า ฝ่ายหนึ่งอาจรู้ได้ว่าชุดที่ตกลงกันนั้นมีอย่างน้อย N ไบต์แรกอยู่แน่นอน แต่ไม่อาจรู้ได้ว่าชุดที่ตกลงกันนั้นคือ N ไบต์แรกอย่างพอดี
- ดังนั้น แม้อาจมีชุดไบต์ที่ “ส่งถึงแน่นอนและทั้งสองฝ่ายรู้” อยู่จริง แต่หลังจากนั้นก็ยังคงมี พื้นที่สีเทา ที่ฝั่งส่งและฝั่งรับไม่สามารถยืนยันสถานะความรู้ของกันและกันได้
- หากมองข้ามความต่างนี้ ก็จะทำให้ระบบกระจายเกิดความล้มเหลวแปลก ๆ ได้ง่าย
กับดักของเครือข่ายจริงและเลเยอร์ล่าง
- ความเชื่อที่ว่า “เครือข่ายแปลก ๆ ที่ไม่โปร่งใสต่อโปรโตคอลมาตรฐานมองข้ามได้” ได้ก่อปัญหามาแล้วหลายครั้ง
- buffer bloat ถูกยกเป็นตัวอย่างกรณีที่เราเตอร์ทำลายกลไกควบคุมความคับคั่ง
- เครือข่ายที่บล็อก ICMP หรือทิ้งทราฟฟิกที่ตัวเองไม่เข้าใจก็อาจเป็นปัญหาได้เช่นกัน
- ความเชื่อที่ว่า “ไม่จำเป็นต้องรู้เรื่องการควบคุมความคับคั่ง” ก็ใกล้เคียงกับการเข้าใจ TCP ผิดเช่นกัน
- ตัวอย่างย่อยคือแนวคิดว่า “ถ้าไม่ได้ความเร็วตามต้องการ ก็แค่เปิดการเชื่อมต่อ TCP หลายเส้น”
ยังไม่มีความคิดเห็น