มีอะไรบางอย่างกำลังกวนใจคุณอยู่หรือเปล่า?
(antithesis.com)- Antithesis ต้องการนำ การทดสอบอัตโนมัติแบบกำหนดผลลัพธ์ได้ (deterministic autonomous testing) ที่ได้ผลใน FoundationDB มาประยุกต์ใช้กับซอฟต์แวร์ทั่วไป เพื่อเปลี่ยนบั๊กของระบบกระจายศูนย์ที่ทำซ้ำได้ยากให้กลายเป็นปัญหาที่ทำซ้ำได้
- FoundationDB สร้าง ซิมูเลชันแบบเธรดเดียว·โปรเซสเดียว ก่อนเริ่มพัฒนาฐานข้อมูลจริง และสามารถรันสถานการณ์ล้มเหลวที่พบได้น้อยซ้ำได้ด้วย random seed เดิม
- วิธีนี้ทำให้ ความล้มเหลวแบบไม่กำหนดผลลัพธ์ เช่น concurrency, ความหน่วงและการจัดลำดับแพ็กเก็ตใหม่ของเครือข่าย, ปัญหาดิสก์ และความขัดข้องของเครื่อง กลายเป็นสิ่งที่ทดสอบได้ และมีการประเมินว่า FoundationDB มีบั๊กที่ลูกค้ารายงานตลอดช่วงเวลาทั้งหมดเพียง 1–2 รายการ
- Antithesis สร้างไฮเปอร์ไวเซอร์ที่จำลอง คอมพิวเตอร์แบบกำหนดผลลัพธ์ได้ เพื่อไม่ให้ต้องเขียนซอฟต์แวร์เดิมใหม่ตั้งแต่ต้น และปัจจุบันมุ่งเน้นการทดสอบความน่าเชื่อถือและการทนทานต่อความขัดข้องของระบบกระจายศูนย์
- เคยร่วมงานกับ MongoDB, Ethereum Foundation และ Palantir และพัฒนาจากเครื่องมือค้นหาบั๊กหายากไปเป็น บริการทดสอบอย่างต่อเนื่อง ที่คอยตรวจสอบบิลด์ล่าสุดตลอดเวลา
Antithesis ที่เริ่มต้นจากประสบการณ์ของ FoundationDB
- Antithesis พัฒนาแบบ stealth มานานกว่า 5 ปี ก่อนเปิดตัวแพลตฟอร์มที่อิงจากประสบการณ์ด้าน การทดสอบแบบกำหนดผลลัพธ์ได้ ที่ได้จาก FoundationDB
- ก่อนเปิดตัว ได้ดำเนินงานด้านการจ้างงาน ลูกค้าช่วงแรก และนักลงทุน โดยแก่นสำคัญแรกที่เปิดเผยคือวิธีทดสอบระบบซับซ้อนให้ทำซ้ำได้
ปัญหาการตรวจสอบที่ยากที่สุดในฐานข้อมูลกระจายศูนย์
- FoundationDB เริ่มสร้างฐานข้อมูลกระจายศูนย์ที่ขยายได้ ทนทานต่อความขัดข้อง และรองรับ ACID transactions ในปี 2010
- ตอนนั้น Spanner ยังไม่ถูกเปิดเผย และมีหลายคนเข้าใจ CAP theorem ผิดว่า consistency ระดับสูงกับ availability ระดับสูงไม่สามารถมีร่วมกันได้
- ความยากที่สุดไม่ใช่ตัวฐานข้อมูลเอง แต่คือจะทดสอบระบบเช่นนั้นและมั่นใจในความถูกต้องได้อย่างไร
“unknown unknowns” ที่การทดสอบแบบเดิมมองข้าม
- ซอฟต์แวร์ต้องรับมือกับสถานการณ์ที่นักพัฒนาไม่ได้คิดไว้ล่วงหน้าด้วย แต่การทดสอบทั่วไปมักถนัดในการตรวจสอบเคสที่คาดการณ์ไว้แล้ว
- หากคาดการณ์สถานการณ์ใดได้มากพอที่จะเขียนเป็นเทสต์เคส โค้ดก็มีแนวโน้มสูงว่าจะถูกเขียนให้รับมือกับสถานการณ์นั้นแล้ว
- ดังนั้นการทดสอบแบบเดิมจึงมีประโยชน์ต่อ การป้องกัน regression แต่ไม่เก่งในการจับความล้มเหลวที่คาดไม่ถึงซึ่งเกิดจากผู้ใช้จริงและสภาพแวดล้อมการปฏิบัติงานจริง
- ในระบบ storage แบบกระจายศูนย์ ปัญหานี้ยิ่งใหญ่ขึ้น
- มี concurrency ทั้งภายในเครื่องและระหว่างเครื่องพร้อมกัน
- เครือข่ายอาจสร้างความหน่วงและการจัดลำดับแพ็กเก็ตใหม่ได้
- สาเหตุของความล้มเหลวกว้างมาก ตั้งแต่ดิสก์ เครื่องล่ม ไฟดับ ไฟไหม้ดาต้าเซ็นเตอร์ ไปจนถึงความผิดพลาดของมนุษย์
- หากบั๊กร้ายแรงไวต่อลำดับเหตุการณ์ที่เกี่ยวข้องกับหลายเครื่อง แม้พบแล้วครั้งหนึ่งก็ทำซ้ำอีกได้ยาก
ซิมูเลชันแบบกำหนดผลลัพธ์ได้ของ FoundationDB
- ทีม FoundationDB สร้าง network simulation แบบ event-driven ที่กำหนดผลลัพธ์ได้อย่างสมบูรณ์ก่อนเขียนฐานข้อมูล
- จำลองทั้งคลัสเตอร์ภายในแอปพลิเคชันแบบเธรดเดียว·โปรเซสเดียว และขับเคลื่อนการรันด้วยตัวสร้างเลขสุ่มเดียวกัน
- สามารถ inject ความขัดข้องของเครือข่าย ฆ่าเครื่อง และสร้างสถานการณ์ผิดปกติต่าง ๆ ซ้ำ ๆ ในคลัสเตอร์เสมือนได้
- หากการรันหนึ่งพบ bug ใน application logic ก็สามารถใช้ random seed เดิมเพื่อรันลำดับเหตุการณ์เดิมซ้ำได้
- ด้วยเหตุนี้ แม้แต่บั๊กที่พบได้น้อยมากก็สามารถติดตามได้โดยเพิ่ม log หรือทำขั้นตอน debug ซ้ำ
- มีการนำเสนอเรื่องนี้ที่ Strangeloop ในปี 2014 และดูวิดีโอได้ ที่นี่
วิธีที่การทดสอบเปลี่ยนความเร็วในการพัฒนา
- มีการประเมินว่าในประวัติทั้งหมดของบริษัท FoundationDB มีบั๊กที่ลูกค้ารายงานเพียง 1–2 รายการ
- Kyle Kingsbury หรือ “aphyr” ไม่ได้ทดสอบ FoundationDB ด้วย Jepsen เพราะเห็นว่าไม่น่าจะมีอะไรให้พบ
- เมื่อการทดสอบอยู่ในสภาพที่เปิดเผยบั๊กใหม่ได้ทันที วิธีเขียนโปรแกรมของทีมก็เปลี่ยนไปด้วย
- compiler และ strong type system ให้ความมั่นใจต่อบั๊กบางประเภทได้ แต่แตกต่างจากการรันซอฟต์แวร์จริงภายใต้สถานการณ์คาดไม่ถึงนับพันแบบ
- ด้วยความเชื่อนี้ ทีม FoundationDB จึงกล้าทำการเปลี่ยนแปลงครั้งใหญ่
- ลบ dependency ทั้งหมดรวมถึง Zookeeper และเขียน implementation ของ Paxos เองในเวลาอันสั้น โดย implementation ดังกล่าวรวมอยู่ใน งานวิจัย FoundationDB
- เขียนใหม่ ทั้ง subsystem สำหรับ transaction processing ให้เร็วขึ้นและขยายได้มากขึ้น
- ผลลัพธ์ที่ใหญ่ที่สุดไม่ใช่แค่การเพิ่มเสถียรภาพของฐานข้อมูล แต่คือการมอบ ผลิตภาพระดับทีมขนาดใหญ่กว่า 50 เท่า ให้กับทีมวิศวกรรมขนาดเล็ก
ช่องว่างที่ปรากฏหลัง Apple เข้าซื้อกิจการ
- Apple เข้าซื้อ FoundationDB ในปี 2015 และใช้เป็นฐานของ “cloud infrastructure” ของ Apple
- หลายปีต่อมา FoundationDB ถูกเปิดเป็น โอเพนซอร์ส
- แม้สมาชิกทีม FoundationDB จะกระจายไปยังบริษัทเทคโนโลยีขนาดใหญ่อื่น ๆ แต่องค์กรเหล่านั้นก็ไม่มีการทดสอบด้วย deterministic simulation แบบ FoundationDB
- การเปลี่ยนแปลงระบบ backend ดำเนินไปอย่างช้า ๆ เพราะคาดการณ์ผลกระทบที่ไม่ตั้งใจต่อระบบได้ยาก และการวินิจฉัยกับแก้ไขบั๊กใน production ต้องใช้เวลาของวิศวกรระดับสูงเป็นเดือน ๆ
- ในปี 2018 จึงเริ่ม Antithesis ร่วมกับ Dave Scherer โดยมีเป้าหมายเพื่อมอบ การทดสอบอัตโนมัติแบบกำหนดผลลัพธ์ได้ แบบ FoundationDB ให้ทีมอื่น ๆ ด้วย
วิธีทำให้ซอฟต์แวร์เดิมทำงานแบบกำหนดผลลัพธ์ได้
- FoundationDB เป็นโปรเจกต์ greenfield ที่ตั้งใจให้ทดสอบด้วยวิธีนี้ตั้งแต่ต้น และสามารถตัด dependency ออกได้
- ซอฟต์แวร์ทั่วไปสร้างเธรด ตรวจเวลา ขอค่าสุ่มจาก kernel และสื่อสารกับซอฟต์แวร์อื่นผ่านเครือข่าย
- เพราะ methodology การพัฒนาที่ต้องเขียนซอฟต์แวร์ทั้งหมดใหม่ตั้งแต่ต้นแพร่หลายได้ยาก Antithesis จึงเขียน ไฮเปอร์ไวเซอร์ ที่จำลองคอมพิวเตอร์แบบกำหนดผลลัพธ์ได้
- ผลคือซอฟต์แวร์ที่รันอยู่ภายในไฮเปอร์ไวเซอร์สามารถถูกวางไว้ใน สภาพแวดล้อมการรันแบบกำหนดผลลัพธ์ได้
- กระบวนการนี้รวมถึงงานที่จัดการพฤติกรรมระดับต่ำ เช่น extended page table ของ Intel CPU
- ปัญหาการหาการละเมิดคุณสมบัติใน state space ของโปรแกรมใด ๆ ยากกว่า halting problem และแม้จะมี halting oracle สำหรับทุกโปรแกรม ก็อาจมีคุณสมบัติการทดสอบที่คำนวณไม่ได้อยู่
แพลตฟอร์มปัจจุบันและกรณีลูกค้า
- แพลตฟอร์ม Antithesis มีเป้าหมายรับซอฟต์แวร์ของผู้ใช้มาเพื่อค้นหาบั๊ก และทำให้บั๊กที่พบสามารถทำซ้ำได้เสมอ
- แม้ในกรณีซับซ้อนที่หลายบริการสื่อสารกันผ่านเครือข่าย ก็พยายามรักษาความสามารถในการทำซ้ำ
- หลังพบบั๊กแล้ว สามารถใช้ความสามารถด้าน debugging ที่ทรงพลังได้
- ในระยะยาว แพลตฟอร์มถูกออกแบบให้ค้นหาบั๊กหลายประเภทในซอฟต์แวร์หลากหลายแบบ แต่ปัจจุบันมุ่งเน้น การทดสอบความน่าเชื่อถือและการทนทานต่อความขัดข้องของระบบกระจายศูนย์ ซึ่งมีประสบการณ์อยู่แล้ว
- ในช่วงไม่กี่ปีที่ผ่านมา ได้ร่วมงานกับทีมวิศวกรรมที่ดูแลระบบขนาดใหญ่และซับซ้อนซึ่งให้ความสำคัญกับความน่าเชื่อถือ
- ร่วมงานกับ MongoDB มาหลายปี เพื่อช่วยทดสอบ core server software และ WiredTiger storage engine
- ร่วมงานกับ Ethereum Foundation ตั้งแต่ราว 1 ปีก่อน Merge เพื่อช่วย ทดสอบ Merge และยังร่วมงานกันอยู่ในปัจจุบัน
- กำลังร่วมงานกับ Palantir ด้วย
จากเครื่องมือค้นหาบั๊กหายากสู่บริการทดสอบอย่างต่อเนื่อง
- ลูกค้าช่วงแรกใช้ Antithesis เหมือน เครื่องมือหน่วยรบพิเศษ สำหรับค้นหาและทำซ้ำบั๊กที่หาได้ยากและอันตรายที่สุด
- เมื่อแพลตฟอร์มเติบโตเต็มที่ขึ้นและโต้ตอบได้มากขึ้น จึงเปลี่ยนไปเป็น บริการต่อเนื่อง ที่ทดสอบบิลด์ล่าสุดอย่างสม่ำเสมอ
- เป้าหมายคือการลดเวลาตั้งแต่ตอนที่บั๊กถูกนำเข้ามา จนถึงตอนที่ถูกค้นพบ
- ในช่วงพัฒนา FoundationDB วิธีนี้ทำให้การวินิจฉัยและแก้ไขบั๊กง่ายขึ้นมาก และเพิ่มทั้งประสิทธิภาพกับคุณภาพซอฟต์แวร์
- Antithesis ต้องการ พูดคุย กับองค์กรที่ดำเนินระบบกระจายศูนย์และให้ความสำคัญกับความน่าเชื่อถือกับผลิตภาพทางวิศวกรรม
- สำหรับผู้ที่อยากทำงานกับปัญหายาก ๆ มี ประกาศรับสมัครงาน ให้ดู
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
รู้สึกว่าคำว่า นักพัฒนา 10x ระดับตำนาน ถูกบิดความหมายจนกลายเป็นคนที่ทำงานวันละ 15 ชั่วโมง สัปดาห์ละ 6.5 วัน แล้วหมดไฟ
แต่ 10x จริง ๆ หรือแม้แต่ประสิทธิภาพระดับ 50x นั้น มาจากคนที่ทำสิ่งที่แทบไม่มีใครคิดว่าทำได้หรือเข้าใจได้ ให้กลายเป็นซอฟต์แวร์ที่ใช้งานได้จริงในเวลาที่สั้นกว่ามาก
ผู้จัดการจำนวนมากมักสนใจคนที่ทำงานปริมาณ 8 ชั่วโมงให้กินเวลา 12 ชั่วโมง มากกว่าคนที่ทำงานแบบเดียวกันเสร็จใน 8 ชั่วโมง
อีกทั้งความพยายามที่ออกนอกกรอบ ‘ปกติ’ ก็มักไม่ถูกมองในแง่ดี และในตารางงานก็ไม่มีเวลาเผื่อไว้สำหรับการปรับปรุงกระบวนการ ดังนั้นในสถานการณ์ที่ทุกคนมองแค่ว่าต้องขนถังให้เร็วขึ้น การสร้างรถเข็นจึงถูกกดทับไว้
เพราะแบบนั้นนักพัฒนา 10x จึงมีอยู่จริง พออายุ 30 พวกเขาไม่ได้มีประสบการณ์เขียนโปรแกรม 10 ปี แต่ราว ๆ 20 ปี
ประสบการณ์ทำงานก็มีมากกว่ามากด้วย ตอนอายุ 15 อาจเริ่มจากงานจิปาถะประหลาด ๆ ที่ช่วยญาติเป็นครั้งคราว แต่พอราว 18 ก็เข้าไปทำงานในบริษัทจริงควบคู่กับเรียนวิทยาการคอมพิวเตอร์
อย่างน้อยเมื่อก่อนก็เป็นแบบนั้น ช่วงประมาณปี 2004 ถึงราว 2018 มันเป็นเรื่องจริง แต่ทุกวันนี้ในสภาพการจ้างงานปัจจุบันยังทำได้อยู่ไหมก็ไม่แน่ใจ
การที่นักพัฒนา 10x จะมีอยู่จริง แค่มีตัวอย่างไม่กี่คนก็พอแล้ว ดูเหมือนทุกคนจะเห็นตรงกันโดยทั่วไปว่าพวกเขาเป็นของหายาก และตัวอย่างของนักพัฒนา 10x ที่มองเห็นได้สาธารณะก็คือคนนี้ แม้เจ้าตัวคงไม่มีวันพูดแบบนั้น แต่จากที่ฉันเดา เขาน่าจะเป็น 10x engineer https://bellard.org/
ถ้าไม่เห็นด้วยก็อยากรู้ว่าต่างกันตรงไหน ฉันเองก็เป็นแค่คนที่คลำได้เพียงบางส่วนเหมือน คนตาบอดคลำช้าง และไม่ได้อ้างว่าเห็นภาพทั้งหมด
นักพัฒนาแบบกองทัพหนึ่งคน ที่ทำทุกอย่างได้เอง มักไม่ค่อยเข้ากับทีมที่งานถูกทำให้เป็นมาตรฐาน แตกย่อย และกระจายกันทำ
คนแบบนั้นเหมาะที่สุดเวลาทำโปรเจกต์ของตัวเองโดยไม่มีเพื่อนร่วมงานหรือผู้จัดการมารบกวน แต่ที่ทำงานส่วนใหญ่ไม่ได้เป็นแบบนั้น
พอเป็นส่วนหนึ่งของทีม ต่อให้เก่งแค่ไหนก็ไม่สามารถทำทุกอย่างคนเดียวได้มากนัก สุดท้ายก็ต้องเสียเวลาไปจัดการปัญหาที่เกิดจากเพื่อนร่วมทีมที่ช้ากว่าหรืออ่อนกว่ารวมถึงปัญหาด้านการจัดการ ทำให้ความเร็วตกลง ดังนั้นต่อให้มีร็อกสตาร์ ทีมก็จะเคลื่อนที่ด้วยความเร็วของตัวหารร่วมต่ำสุดอยู่ดี
การที่เราสร้างเครื่องมือภายใน และอยู่ใกล้กับกระบวนการรวมถึงผู้มีส่วนได้ส่วนเสียมาก ก็ช่วยด้วย
ประเด็นแบบ “อืม มีอีกวิธีที่จะบรรลุสิ่งนี้ได้” นี่แหละคือ 10x ไม่ใช่แค่การทำให้เร็วขึ้น
อาจเป็นบทเกริ่นที่ดีที่สุดเท่าที่เคยอ่านมาเลย
มันวางพื้นฐานได้ดีว่าคนเหล่านี้คือใครและเคยสร้างอะไรมา และอธิบายว่าสิ่งที่กำลังสร้างตอนนี้เป็นผลลัพธ์จากสิ่งที่เคยทำมาก่อน
ให้ความรู้สึกว่าพวกเขาอยากแก้ปัญหานี้ให้ทุกคน เพราะเคยสัมผัสมากับตัวแล้วว่าโซลูชันนี้ดีแค่ไหน
ต่อจากนั้นก็แสดงให้เห็นทีมที่ใช้อยู่แล้ว ซึ่งมีชื่อค่อนข้างใหญ่ที่ระบบซับซ้อนอยู่ด้วย
ทั้งหมดนี้ถูกห่อมาเป็นงานเขียนที่ดีซึ่งโดนใจทั้งนักพัฒนาและผู้ก่อตั้ง และ landing page ก็ยอดเยี่ยม
ฉันอยากเห็นกรณีใช้งานจริงและตัวอย่างมากกว่านี้
แต่สิ่งที่ได้กลับเป็นการไล่รายชื่อบริษัทใหญ่ไม่กี่แห่ง อ้างว่าเป็นผลิตภัณฑ์นวัตกรรมที่ทำงานได้ราวกับเวทมนตร์ แล้วก็ใส่คำฮิตตามสูตรอย่าง ‘โปรแกรมเมอร์ 10x’, ‘stealth mode’ ลงไป การเปิดเผยชื่อลูกค้าไปพร้อมกับพูดว่า stealth mode มันฟังไม่ค่อยสมเหตุสมผล
เพราะมันเสนอวิถีชีวิต วิธีคิด และวิธีลงมือทำแบบที่ฉันยังไม่เคยมีประสบการณ์มาก่อน จนทำให้ฉันอยากได้โซลูชันนั้น
บทความที่ลิงก์มานั้นกว่าจะบอกว่าจริง ๆ แล้วสร้างอะไร ก็ใช้ไป 3/4 ของเรื่องกับประวัติและการปูพื้น
เหมือนบล็อกสูตรอาหารชวนหงุดหงิดที่ฉันแค่อยากทำแพนเค้กวีแกน แต่ผู้เขียนกลับเล่าเรื่องวัยเด็กยืดยาวก่อน
เป็นมุมมองที่ดีมาก และไม่ได้อยากให้ดูเหมือนมองในแง่ลบ แต่รู้สึกว่าประโยคอย่าง “เจอบั๊กทั้งหมดแล้ว” จะเป็นจริงได้ก็ต่อเมื่อให้นิยามของ บั๊ก แคบมากเท่านั้น
บั๊กที่ร้ายและหาเจอยากที่สุดเท่าที่เคยเจอมา ไม่ใช่พวกที่ทำให้ระบบเข้าสู่สถานะผิดพลาด แต่เป็นปัญหาที่อยู่รอบ ๆ business logic ของแอปพลิเคชัน
ตัวอย่างเช่น ในฐานข้อมูลมีรายการธุรกรรมที่เสร็จสมบูรณ์ของลูกค้าอยู่ แต่ไม่มีรายการสินค้าที่ซื้อเสร็จสมบูรณ์เลย แล้วควรแสดงสิ่งนี้บนหน้าธุรกรรมล่าสุดของลูกค้าอย่างไร
ในกรณีแบบนั้น การทำให้ “มีอะไรบางอย่างแสดงขึ้นมาและไม่ crash” กับการรับประกันว่าสิ่งที่เลือกนั้นสมเหตุสมผลจริงในบริบทของตัวเลือกอื่น ๆ ทั้งระบบนั้นเป็นคนละเรื่องกันมาก
ถ้าเป็นฐานข้อมูลก็ยังมีปัญหาอย่าง “query planner สร้างแผนที่ไม่มีประสิทธิภาพมากใน edge case นี้” ได้อีก
ปัญหาประเภทนี้ตรวจจับแบบอัตโนมัติไม่ได้ เพราะมันไม่ใช่ปัญหาที่โปรแกรมไปถึงสถานะผิดพลาด แต่เป็นปัญหาว่าตั้งแต่แรกแล้ว ‘ความถูกต้อง’ ของแอปพลิเคชันคืออะไร
บางทีผมอาจตั้งเกณฑ์คำว่าบั๊กไว้สูงเกินไป แต่การจินตนาการถึงบั๊ก 0 ตัวกับการสร้างซอฟต์แวร์ในโลกจริงนั้นต่างกัน ถึงอย่างนั้นถ้าบอกว่า runtime error 0 ครั้ง แบบนี้ผมพอรับได้
แต่ก็เป็นความจริงที่ FoundationDB มีชื่อเสียงมากว่าเป็นตัวผลักดันแนวหน้าของแนวปฏิบัติด้านการทดสอบ: https://apple.github.io/foundationdb/testing.html
ปกติแล้วมันคงฟังดูเหมือนหยิ่งหรือมั่นใจเกินไป แต่กรณีนี้คือเข้าใกล้ zero bug ได้จริง ๆ
แน่นอนว่าคุณพิสูจน์ประพจน์เชิงปฏิเสธไม่ได้ แต่การไปถึงสถานะ “เขียวทั้งหมด” แบบนั้นก็ให้ความมั่นใจสูงมากว่ากำลังสร้างอยู่บนรากฐานที่แข็งแรง และเมื่อเวลาผ่านไปก็พิสูจน์ว่าเป็นแบบนั้นจริง
ปัญหารอบ ๆ business logic ไม่ใช่ความล้มเหลวของระบบ แต่เป็นกรณีที่ระบบทำงานตามสเปกแล้ว เพียงแต่สเปกยังครอบคลุมไม่พอ ดังนั้นก็แค่ต้องปรับปรุงซ้ำต่อไป
แน่นอนว่าซอฟต์แวร์จำนวนมากมีเอกสารไม่พอ และนั่นก็คือบั๊กของเอกสาร
ถึงอย่างนั้น เหตุผลที่นิยามนี้ดีคือ ต่อให้เอกสารยังไม่สมบูรณ์ มันก็ยังบังคับให้ถามว่า “เราจะบันทึกพฤติกรรมนี้ไว้จริง ๆ หรือจะเปลี่ยนพฤติกรรมแล้วค่อยบันทึกสิ่งนั้นแทน?”
อย่างน้อยสำหรับผม มันทำให้ปล่อยผ่านพฤติกรรมแปลก ๆ ไปแบบขอไปทีได้ยากขึ้นมาก
ตั้งแต่ได้รู้จักสายงานนี้ผ่านคู่มือ simulation ของ
sledhttps://sled.rs/simulation.html ก็สนใจมาก ๆ บทความนั้นแสดงภาพคร่าว ๆ ว่า FoundationDB ทำอย่างไรตอนนี้ผมกำลังพยายามนำรูปแบบการทดสอบคล้าย ๆ กันมาใช้ในที่ทำงาน โดยเขียนให้บริการสามารถรันอยู่บน
madsimhttps://github.com/madsim-rs/madsim?tab=readme-ov-file#madsim ได้แบบนี้เราจะยังเขียนบริการสไตล์ async/await บน tokio ต่อไปได้ แต่ในชุดทดสอบจะสลับไปใช้ deterministic executor ที่ patch แหล่งกำเนิดความไม่เป็นกำหนดทั้งหมด รวมถึง dependency ที่เรียกใช้ระบบปฏิบัติการด้วย ซึ่งทำงานได้ค่อนข้างลื่น
ที่ผู้เขียนบทความนี้บอกว่าต้นทุนเริ่มต้นมหาศาลนั้นไม่ได้พูดเกินจริงเลย การจัดการแหล่งความไม่เป็นกำหนดทุกจุดที่เป็นไปได้ และการเขียนบริการใหม่ให้ทดสอบได้และอยู่ในรูปแบบ sans-IO https://sans-io.readthedocs.io/ ต้องใช้แรงวิศวกรรมมาก
แต่พอวางระบบได้แล้ว ความมั่นใจที่คุณมีต่อโค้ดนั้นอธิบายเป็นคำพูดได้ยากมาก เมื่อรวมกับเครื่องมืออย่าง quickcheck https://github.com/BurntSushi/quickcheck?tab=readme-ov-file#quickcheck คุณจะทดสอบกรณีล้มเหลวละเอียดอ่อนนับแสนแบบได้ ทั้ง I/O, ลำดับเหตุการณ์, timeout, packet loss, ความขัดข้องของ filesystem และอื่น ๆ
ถ้าคุณมีความอดทนและความพยายามพอจะลงทุน การทดสอบแบบนี้เป็นเครื่องมือที่ทรงพลังมากที่ควรมีติดกล่องเครื่องมือไว้
ตัว Antithesis เองก็ดูน่าทึ่งมาก การกด deterministic testing ลงไปถึงชั้นใต้ระบบปฏิบัติการนั้นสุดยอดจริง ๆ และน่าจะทำให้ทดสอบทั้งระบบได้โดยไม่ต้องมาคอยเย็บ harness ด้วยมือทุกครั้ง อยากลองใช้เร็ว ๆ นี้เลย
ความซับซ้อนจำนวนมากที่ผมเห็นในระบบแบบนั้น มาจากการที่การเรียก “ฟังก์ชัน” เป็นแบบ asynchronous, พึ่งพาระบบปฏิบัติการ, อาจถูกรันในสักวันหรืออาจไม่ถูกรันเลย, คืนค่ากลับมาเป็นกองข้อความที่ต้อง parse เพื่อกลับเข้าสู่ static type system และยังมี failure mode ของตัวมันเองอีก
งานที่ดูเหมือนง่ายอย่างการ abstract logic ออกมาเป็นคอมโพเนนต์ที่มีชื่อ หรือก็คือฟังก์ชัน กลับกลายเป็นซับซ้อนมากอย่างสุดขั้ว
ถ้าเก็บ logic ไว้ใน process เดียวกันแล้วแค่เรียกฟังก์ชัน คุณก็ไม่จำเป็นต้องทดสอบความล้มเหลวแบบละเอียดอ่อนที่กล่าวมานั้นเลย
ไม่ใช่ว่า monolith จะเป็นตัวเลือกที่ดีเสมอหรือถูกเสมอไป แต่ผมสงสัยมากว่าสมัยนิยมของสถาปัตยกรรมซอฟต์แวร์แบบ service-based ทุกวันนี้นั้นสมเหตุสมผลและคุ้มกับสิ่งที่ได้กลับมาจริงหรือไม่
แล้วก็สงสัยด้วยว่ามีบริษัทที่ใช้ Rust และพัฒนาแบบนี้อยู่หรือเปล่า
เพิ่มเติมคือ TigerBeetle ก็เป็นผลิตภัณฑ์ที่เขียนด้วยแนวทางแบบนี้
madsimหรือ deterministic simulation testing แบบนี้ไหมบทความน่าสนใจมาก
การที่พูดประโยคอย่าง “การเขียนโปรแกรมในสภาพแบบนี้ก็เหมือนใช้ชีวิตอยู่ในสนามพลังที่ปกป้องคุณจากอันตรายทั้งปวง... เราลบ dependency ทั้งหมดรวมถึง Zookeeper เพราะมีบั๊ก แล้วก็เขียน Paxos implementation เองภายในเวลาอันสั้นมาก และมันไม่มีบั๊ก” พร้อมมีหลักฐานรองรับได้จริง คงเป็นอะไรที่สุดยอดมาก
หนังสือเล่มนั้นบอกว่า เวลาพยายามแก้ปัญหาของตัวเองแล้วต้องไป debug ซอฟต์แวร์ของคนอื่นเพราะบั๊กใน numerical software package มันน่าอึดอัดเกินไป เลยปกติจะเขียนเอง ยกเว้น linear algebra package
จุดที่ปวดหัวกว่านั้นคือ package อาจซ่อนข้อบกพร่องในการกำหนดรูปปัญหาไว้ได้ ถ้าเอาชุดสมการใส่ solver มันก็มักจะให้คำตอบออกมาเงียบ ๆ แม้เงื่อนไขจะไม่ดีหรือมี singularity ที่ไม่คาดคิดจนคำตอบไม่สอดคล้องกับความเป็นจริงทางกายภาพ และถ้ามันถูกฝังอยู่ในโปรแกรมใหญ่ ก็อาจทำให้เรามองข้ามความเป็นไปได้นั้นไป
ต่อให้พบพฤติกรรมที่น่าสงสัย การจะเข้าไปขุดปัญหาข้างใน package ก็ยาก สุดท้ายจึงต้องกลับมาเขียนใหม่เองอยู่ดี และถ้าทำแบบนั้นตั้งแต่แรก ก็มีโอกาสสูงว่าจะได้เจาะลึกความเป็นจริงของปัญหาและกำจัดความสับสนทางตรรกะไปล่วงหน้า
สุดท้ายแล้วจะเลือกทำแบบนี้หรือไม่ก็ขึ้นอยู่กับว่าเจ้าตัวเข้มงวดแค่ไหน dependency นั้นเข้มงวดแค่ไหน และมีเวลาอยู่เท่าไร ฉันคงไม่เขียนฐานข้อมูลเอง เพราะมันซับซ้อนเกินไปและมีตัวเลือกที่ผ่านการทดสอบมาอย่างดีมากมาย แต่ถ้าใช้แค่บางฟังก์ชันของ package เล็ก ๆ ที่ทดสอบมาไม่มาก การทำเองก็อาจสมเหตุสมผล
แต่ฉันไม่ได้อ้างว่าสเปกของฉันไม่มีบั๊ก
มีสามความคิด
อย่างแรก นี่เป็นไอเดียที่ยอดเยี่ยมและมาได้ถูกเวลา จากอารมณ์ของนักพัฒนาที่มีต่อ fuzzer, static type, memory safety, standardized protocol, container และอื่น ๆ รู้สึกได้ว่าผู้คนกำลังหมดความอดทนกับซอฟต์แวร์ที่ไม่เสถียรกันเสียที
อย่างที่สอง ดูเหมือนจะจับ ตลาดเฉพาะกลุ่ม ราคา 2 ดอลลาร์ต่อ CPU ต่อชั่วโมง, ถ้าจองล่วงหน้าคือ 7,000 ดอลลาร์ต่อ CPU ต่อปี, ไม่มี free tier สำหรับงานอดิเรกหรือซอฟต์แวร์เสรี·โอเพนซอร์ส และแม้แต่การทดลองใช้หรือซื้อก็ต้องติดต่อสอบถามก่อน เป็นโมเดลธุรกิจที่เจ็บปวดแต่ใช้ได้ เพียงแต่น่าเสียดายที่ไม่ได้มุ่งไปที่ผลกระทบเชิงบวกให้มากที่สุด
อย่างที่สาม คุณภาพของบทความและเอกสารสูงมาก และฉันชอบจริง ๆ ที่มีข้อความในเอกสารอย่าง “หากพบบั๊กในโปรดักชันหรือจากลูกค้า คุณควรเรียกร้องให้เราอธิบาย”
นี่แหละคือวิธีเอาใจนักพัฒนา ทำให้นึกถึง Mullvad ที่แม้เคยทำให้ฉันผิดหวัง แต่ฉันก็ยังแนะนำให้คนอื่นอยู่ดี
มีพูดถึงเรื่องนี้ไว้ที่ https://news.ycombinator.com/item?id=39358526 อนึ่ง ฉันเป็นผู้ร่วมก่อตั้ง Antithesis
ฮาร์ดแวร์เองก็อาจเริ่มเพิ่มฟีเจอร์เพื่อรองรับสิ่งนี้ และอีก 30 ปีข้างหน้า มันอาจกลายเป็นแค่วิธีปกติที่การคอมพิวติ้งทำงาน
แต่ก่อนที่ผู้บุกเบิกจะเผยแพร่มันได้จริง พวกเขาก็ต้องกู้ต้นทุนจากลูกศรดอกแรกที่รับไปก่อน เราควรมองนี่ไม่ใช่เป็นเหตุการณ์เดียว แต่เป็น จุดเริ่มต้นของกระบวนการ
ถ้าดูจากเอกสาร บั๊กที่แพลตฟอร์มนี้ออกแบบมาเพื่อค้นหาคือบั๊กประเภทหยาบ ๆ ที่ “ทำซ้ำไม่ได้” และเกิดขึ้นไม่บ่อยในโปรดักชัน
ทีมส่วนใหญ่ยังต้องแก้ปัญหาที่ใหญ่กว่านั้นมากและบั๊กที่เห็นชัดกว่านั้นด้วยซ้ำ ที่จริงแล้วซอฟต์แวร์โปรดักชันส่วนใหญ่ทุกวันนี้แทบจะมีแค่ unit test อย่างพอถูไถ
ฉันสงสัยว่าในกรณีใช้งานจริง ต้นทุนจะคูณออกมาเป็นอย่างไร
ปีนี้ฉันได้เจอ Antithesis ที่งาน Strangeloop และคุยกับพนักงานของบริษัท แล้วเมื่อเทียบกับ state of the art ของ การฉีดความขัดข้องอัตโนมัติ ที่ฉันเคยตามอยู่ตอนทำงานที่ Amazon ฉันมองว่าผลิตภัณฑ์นี้ก้าวกระโดดอย่างมหาศาลเหนือกว่าระบบ formal verification จำนวนมากที่ใช้อยู่ในปัจจุบัน
ฉันได้ติดตามกระบวนการไล่บั๊กของประเด็นที่พวกเขาค้นพบใน Apache Spark streaming จริง ๆ จากเอกสารแล้วดูเหมือนว่าพวกเขาพบข้อผิดพลาดด้านความถูกต้องที่ละเอียดและร้ายกาจในงานที่พบได้ทั่วไป และมันเป็นปัญหาชายขอบที่มองเห็นได้ยากซึ่งอาจสร้างความปวดหัวอยู่นานหลายปี
ท้ายที่สุดมันจบลงที่เอกสารต่างหากที่ผิด แต่หลังจากได้เห็นกระบวนการนั้นแล้ว ก็แทบยากจะจินตนาการว่าภายในบริษัทที่สร้าง distributed system เครื่องมืออย่าง Antithesis จะสำคัญขึ้นได้แค่ไหน
หวังว่าจะมีบล็อกโพสต์ที่ลงลึกด้านเทคนิคออกมาในเร็ว ๆ นี้ อยากรู้ว่าพวกเขามาถึงแนวทางปัจจุบันได้อย่างไร
แม้จะพยายามไม่กระโดดเข้าไปในวงจรความคาดหวังที่ร้อนแรงทันที แต่นี่ฟังดูเหมือน จอกศักดิ์สิทธิ์ เลย ถ้าใช้แอปพลิเคชันเดิมได้ตามนั้น และสมมติว่ามันถูกทำเป็น container แล้ว ก็แค่ตรวจสอบ property บนมันไม่ใช่หรือ?
จุดที่ติดขัดมาตลอดคือฐานของเครื่อง นั่นคือ CPU และระบบปฏิบัติการที่ไม่เป็น deterministic
การสร้างสแตกคอมพิวติ้งแนวตั้งทั้งหมดขึ้นมาใหม่แทบเป็นไปไม่ได้ ดังนั้นดูเหมือนว่าพวกเขาจะหลบปัญหานั้นด้วยการสร้าง deterministic simulator ที่มีความสมจริงสูง
แต่ฉันก็สงสัยว่าเขาตรวจสอบความเท่าเทียมกันระหว่าง simulator กับระบบปฏิบัติการเดิมอย่างไร ฟังดูไม่ใช่งานง่าย ถึงอย่างนั้นก็ยังค่อนข้างเชื่อในไอเดียนี้
จากนั้นก็รันการทดสอบพร้อมฉีดความล้มเหลวสารพัดแบบเข้าไป เช่น ความขัดข้องของระบบปฏิบัติการ ปัญหาเครือข่าย race condition กับเงื่อนไขด้านจังหวะเวลา ปัญหาเครื่องสร้างเลขสุ่ม ฯลฯ
นี่น่าจะเป็นวิธีเดียวที่ใช้ได้จริงในการทดสอบสิ่งเหล่านี้อย่างน่าเชื่อถือในปัจจุบัน แต่ถึงอย่างนั้นก็ยังต้องเขียนการทดสอบทั้งหมดและกำหนดสถานะแอปพลิเคชันอยู่ดี
บอกว่าเป็น “แพลตฟอร์มที่รับซอฟต์แวร์มาแล้วล่าบั๊กข้างในนั้น” แล้วจริง ๆ แล้วมันคืออะไรกันแน่?
ดูเหมือนบริการคลาวด์ที่รันการทดสอบแบบบูรณาการให้
เหมือนว่าจะต้องหาวิธีดีพลอยไปยังสภาพแวดล้อมพิเศษนี้ และน่าจะยังต้องเขียนการทดสอบแบบบูรณาการโดยใช้ไลบรารีเฉพาะอยู่ดี
แต่ถึงจะรีแฟกเตอร์การทดสอบแบบบูรณาการทั้งหมดแบบนั้นแล้ว ก็ยังไม่เข้าใจว่ามันจะช่วยหาบั๊กจริงที่การทดสอบแบบบูรณาการของฉันในสภาพแวดล้อมของฉันหาไม่เจอได้อย่างไร
แต่ Antithesis ไม่ได้ต้องการการทดสอบแบบแมนนวลหรือการเขียนการทดสอบแบบบูรณาการ
คุณต้องแพ็กระบบซอฟต์แวร์เป็นคอนเทนเนอร์ ซึ่งค่อนข้างง่าย แล้วจากนั้นเขียน เวิร์กโหลด ที่เลียนแบบการทำงานปกติของระบบ ตัวอย่างเช่น ถ้าเป็นเว็บไซต์อีคอมเมิร์ซก็อาจเป็นการดูสินค้า เพิ่มลงรถเข็น และชำระเงิน
จากนั้น Antithesis จะรันเวิร์กโหลด เปลี่ยนอินพุต และฉีดความขัดข้องเข้าไป พร้อมเริ่มทดสอบซอฟต์แวร์และค้นหาการละเมิดคุณสมบัติการทดสอบ
มีคุณสมบัติการทดสอบพื้นฐานให้มากกว่า 60 รายการ เช่น crash, หน่วยความจำไม่พอ เป็นต้น ถ้าต้องการเผยปัญหาเฉพาะของระบบให้มากขึ้น ก็สามารถกำหนดคุณสมบัติแบบกำหนดเองได้ และในทางปฏิบัติก็ควรทำแบบนั้น
ระหว่างที่การทดสอบทำงาน จะมีการรายงานการละเมิดคุณสมบัติ พร้อมข้อมูลดีบักที่มีประโยชน์จำนวนมาก โดยเฉพาะการรันทดสอบที่น่าสนใจสามารถย้อนกลับ เปลี่ยนอินพุต เก็บ artifacts เพิ่ม logging และวิเคราะห์ต่อได้อีกมาก
ตอนนี้ที่รู้ก็ประมาณนั้น คาดว่าน่าจะมีการ fuzzing บางรูปแบบ การวิเคราะห์แบบสถิต หรือไม่ก็นิยามของพฤติกรรมที่ซอฟต์แวร์สามารถทำได้
พูดตรง ๆ ว่าดูเหมือนจะซ้อนทับกับสิ่งที่ภาษา Vale กำลังพยายามแก้อยู่มาก: https://vale.dev/
เพียงแต่แทนที่จะสร้างภาษาใหม่เพื่อให้ซอฟต์แวร์ใหม่มีสภาพแบบนั้นโดยพื้นฐาน ดูเหมือนจะเน้นทำให้ซอฟต์แวร์เดิมเข้าใกล้สภาพนั้นมากกว่า
มันใช้ไฮเปอร์ไวเซอร์เพื่อเปลี่ยน random seed ทำให้ HTTP request ล้มเหลวหรือช้าผิดปกติ ตัดการเชื่อมต่อระหว่างเซิร์ฟเวอร์ สลับลำดับการตอบสนองของเซิร์ฟเวอร์ ฯลฯ เพื่อสร้างสารพัดเหตุการณ์ที่ในโลกจริงเกิดขึ้นได้แต่ปกติควบคุมไม่ได้
จากนั้นก็เทียบกับการตอบสนองของเวิร์กโหลดที่คาดหวัง เพื่อดูว่าเงื่อนไขแบบไหนทำให้ระบบพัง
เพราะงั้นถึงขายแบบสัญญารายปี โครงสร้างราคาคือให้คุณจ่ายเพื่อให้มันรันเวิร์กโหลดต่อเนื่องตลอดทั้งปี และลองชุดค่าผสมความล้มเหลวทุกแบบ
ตื่นเต้นมากเลยลองไล่อ่านเอกสารนิดหน่อย แต่ยังไม่ค่อยเข้าใจว่ามันต่างจาก unit test แบบสุ่ม อย่างไร
ถ้ามีชุด unit test อยู่แล้ว นั่นก็เหมือนทำงานไป 99% แล้วไม่ใช่หรือ? หรือว่าฉันเข้าใจผิด?
นี่เป็นข้อสรุปที่ได้หลังอ่านชุดเอกสารเริ่มต้น โดยเฉพาะส่วน Workloads https://antithesis.com/docs/getting_started/workload.html
ถ้าดูหน้า How Antithesis Works อาจตอบได้ว่ามันต่างจากการเอา unit test มามัดรวมกันเฉย ๆ อย่างไร: https://antithesis.com/docs/introduction/how_antithesis_works.html
สรุปคือ unit test อาจช่วยประกอบเป็นเวิร์กโหลดได้ แต่ไม่จำเป็น
เราสำรวจ execution path ของระบบซอฟต์แวร์อย่างอัตโนมัติด้วยการใส่อินพุตและความขัดข้องที่แตกต่างกัน เพื่อค้นหาพฤติกรรมที่ผู้เขียน unit test อาจคาดไม่ถึง
ถ้าคุณเขียนการทดสอบสำหรับฟังก์ชันที่เรียก network call และเขียนผลลงดิสก์ การทดสอบจะล้มเหลวถ้าโค้ดรับมือกับกรณีอย่าง network call ล้มเหลวหรือค้างไม่มีกำหนด ดิสก์เต็ม หรือไฟดับก่อนปิดไฟล์ไม่สำเร็จไม่ได้
ดังนั้นก็ใช่ แต่เป็นการขยายพื้นที่ที่ทดสอบได้ง่ายแบบ unit test ไปสู่ระดับความซับซ้อนที่น่าสนใจกว่ามาก