ในหน้านี้
- 1. อ่านจากที่คั่นหน้า และเลื่อนมันก็ต่อเมื่อแบตช์ไปถึงแล้ว
- 2. ให้ทุกการเขียนมีคีย์ที่รอดจากการล่ม
- 3. การรันเดียวเป็นเจ้าของการซิงค์ และพิสูจน์สิ่งนั้นก่อนการเขียนทุกครั้ง
- 4. ลองใหม่กับสิ่งที่ผ่านไปเอง หยุดสิ่งที่ไม่ใช่
- 5. ถือว่าความเงียบเป็นสิ่งที่ค้นพบ
- 6. ตัดสินครั้งเดียวว่าการซิงค์เขียนอะไรได้บ้าง และให้ทุกการรันพิสูจน์สิ่งนั้น
- อะไรสร้างแล้ว และอะไรยังไม่ได้สร้าง
เมื่อวันที่ 8 ตุลาคม 2026 Lance Martin และ CJ Avilla เผยแพร่บทอธิบายเกี่ยวกับเอเจนต์ตัวหนึ่ง ที่อ่าน Slack และ GitHub ทุกเช้าแล้วโพสต์สรุปลงใน Slack ไม่มีใครเฝ้าดูมันทำงาน ย่อหน้าที่มีประโยชน์ที่สุดของพวกเขาพูดถึงความล้มเหลวที่ดูเหมือนความสำเร็จ เมื่อเซิร์ฟเวอร์ของแหล่งข้อมูลล่มหรือโทเค็นหมดอายุ “เอเจนต์จะไม่เห็นอะไรจากแหล่งนั้นเลย และรายงานว่า ‘ไม่มีอะไรใหม่’”
การซิงค์ผู้ติดต่อจาก Shopify ไป Brevo ก็มีความล้มเหลวแบบเดียวกัน การซิงค์ตามกำหนดเวลาทุกตัวระหว่างเครื่องมือ SaaS สองตัวก็เช่นกัน การอ่านที่ล้มเหลวแบบเงียบ ๆ ดูเหมือนร้านค้าที่วันนี้ไม่มีใครสมัครเลยทุกประการ
บทความของพวกเขาปิดท้ายด้วยหกกฎสำหรับเอเจนต์ที่ทำงานโดยไม่มีคนดูแล ลองอ่านในฐานะคนที่ดูแลการซิงค์ แล้วแต่ละข้อก็คือกฎของ reverse ETL บทความ เวิร์กเกอร์ล่ม แต่การซิงค์ไม่ล่ม ติดตามผู้ติดต่อหนึ่งรายผ่านการล่มของระบบ หน้านี้คือเช็กลิสต์ที่อยู่เหนือบทความนั้น หกกฎสำหรับการซิงค์ข้อมูลอัตโนมัติ สิ่งที่ตัวรันของ Tajo ทำกับแต่ละข้อในวันนี้ และจุดที่ยังทำได้ไม่ครบ ฝั่งของตัวรันเขียนไว้ในกู้คืนการซิงค์ที่ค้างหรือล้มเหลว
1. อ่านจากที่คั่นหน้า และเลื่อนมันก็ต่อเมื่อแบตช์ไปถึงแล้ว
กฎข้อแรกของพวกเขา: “อ่านแต่ละแหล่งจากที่คั่นหน้า ไม่ใช่จากช่วงเวลาตายตัว” ช่วงเวลาแบบ “24 ชั่วโมงล่าสุด” ทิ้งช่องว่างไว้เมื่อการรันเริ่มช้า และอ่านเรคคอร์ดซ้ำเมื่อเริ่มเร็ว
การซิงค์ของ Tajo อ่านแหล่งข้อมูลเป็นแบตช์จากเคอร์เซอร์ที่บันทึกไว้ เคอร์เซอร์เลื่อนเมื่อจบแบตช์ และเฉพาะเมื่อทุกเรคคอร์ดในแบตช์นั้นไปถึงแล้วเท่านั้น การรันที่ล้มเหลวจะเก็บตำแหน่งที่เรียบร้อยล่าสุดไว้ การรันครั้งถัดไปจึงอ่านแบตช์ที่ถูกขัดจังหวะอีกครั้งแทนที่จะข้ามไป
คำสั่งซื้อมีที่คั่นหน้าของตัวเอง การซิงค์คำสั่งซื้อ Shopify ตามกำหนดเวลา เริ่มที่การรันตามกำหนดเวลาครั้งแรก และส่งสิ่งที่เปลี่ยนไปตั้งแต่การรันครั้งก่อน คำสั่งซื้อในอดีตจะถูกส่งก็ต่อเมื่อมีคนสั่งรันการซิงค์เท่านั้น การรันตามกำหนดเวลาและการรันที่คนเริ่มเองใช้เคอร์เซอร์แยกกัน การเติมข้อมูลย้อนหลังหรือแบตช์ทดสอบจึงย้อนเคอร์เซอร์ตามกำหนดเวลากลับไม่ได้
ราคาที่ต้องจ่ายคือแบตช์ที่ถูกขัดจังหวะจะถูกอ่านสองครั้ง กฎข้อ 2 คือสิ่งที่ทำให้เรื่องนี้ปลอดภัย
2. ให้ทุกการเขียนมีคีย์ที่รอดจากการล่ม
กฎข้อที่สี่ของพวกเขานับว่าโพสต์ถูกส่งแล้ว “เมื่อ Slack ยืนยันเท่านั้น” และเมื่อนั้นจึงอัปเดตที่คั่นหน้าและสมุดบัญชี จดหมายลงทะเบียนทำงานแบบนี้ ถือว่าส่งถึงเมื่อใบตอบรับที่มีลายเซ็นกลับมา ไม่ใช่เมื่อออกจากเคาน์เตอร์
ก่อนที่ Tajo จะเขียนเรคคอร์ด เรคคอร์ดจะได้รับคีย์การส่ง คีย์คือค่าแฮชของการซิงค์ แหล่งข้อมูล เคอร์เซอร์ของหน้า ตำแหน่งในหน้า และตัวเรคคอร์ดเอง จึงไม่มีข้อมูลส่วนบุคคลอยู่ในนั้น คีย์จะถูกจองก่อนเรียกปลายทาง และถูกทำเครื่องหมายว่าเสร็จเมื่อการเขียนสำเร็จ คีย์ที่เสร็จแล้วถูกเก็บไว้เจ็ดวัน การลองใหม่ หรือการรันตามกำหนดเวลาครั้งหลัง จะสร้างคีย์เดิมสำหรับเรคคอร์ดเดิม พบว่าเสร็จแล้ว และไม่เรียกปลายทางอีก
มีราคาสองอย่างที่ตามมา หลังเจ็ดวัน สมุดบัญชีจะลืม และการรันซ้ำจากเคอร์เซอร์ที่เก่ากว่านั้นอาจเขียนอีกครั้ง และการเขียนที่หมดเวลาจะทิ้งข้อสงสัยที่สมเหตุสมผลไว้ ระบบอีกฝั่งอาจบันทึกไปแล้วโดยไม่ได้ตอบกลับ Tajo จะลองเขียนนั้นใหม่ในความพยายามครั้งถัดไป แทนที่จะบันทึกว่าล้มเหลวไว้เจ็ดวัน คอนเนกเตอร์ที่ส่งคีย์ idempotency ของตัวเองให้ปลายทางจะปิดข้อสงสัยนั้นได้ ส่วนคอนเนกเตอร์ที่ทำไม่ได้ ยังมีโอกาสเกิดข้อมูลซ้ำหนึ่งรายการ
3. การรันเดียวเป็นเจ้าของการซิงค์ และพิสูจน์สิ่งนั้นก่อนการเขียนทุกครั้ง
กฎข้อที่สามของพวกเขา: “ตรวจทุกรายการอีกครั้งก่อนโพสต์ทันที” สำหรับการซิงค์ สิ่งที่มีแนวโน้มจะเปลี่ยนมากที่สุดระหว่างการอ่านกับการเขียนคือ ใครมีสิทธิ์เขียน
การซิงค์แต่ละรายการของ Tajo มีสิทธิ์เช่า (lease) หนึ่งรายการ ซึ่งมีโทเค็นของตัวเองและอายุ 15 นาทีที่ต่ออายุทุกห้านาที การรันจะตรวจว่ายังถือสิทธิ์เช่าอยู่ก่อนเรียกปลายทาง และตรวจอีกครั้งก่อนเลื่อนเคอร์เซอร์ การรันที่เสียสิทธิ์เช่าไปแล้วจะหยุด และหน้าของการรันนั้นแสดงว่า “การรันเสียช่องการรันไประหว่างทาง และหยุดเพื่อไม่ให้เขียนซ้ำ” การรันที่สองที่ชนกับการรันที่กำลังทำงานอยู่จะจบลงแทนที่จะต่อคิวอยู่ข้างหลัง
เรคคอร์ดก็ถูกตรวจด้วย ระหว่างการอ่านกับการเขียน เรคคอร์ดจะผ่านตัวกรองความยินยอม ผู้ติดต่อที่จะถูกเขียนเข้ากลุ่มเป้าหมายทางการตลาดโดยไม่มีความยินยอมที่พิสูจน์ได้จะถูกปฏิเสธแทนการเดา ตามคำของหน้าช่วยเหลือ รูปแบบความล้มเหลวคือ “ระมัดระวังเกินไป” ไม่ใช่ “ส่งข้อมูลเกินความจำเป็น”
4. ลองใหม่กับสิ่งที่ผ่านไปเอง หยุดสิ่งที่ไม่ใช่
หกกฎของพวกเขาไม่ได้พูดถึงเลยว่าควรลองใหม่บ่อยแค่ไหน การซิงค์ต้องมีกฎนี้ เพราะความล้มเหลวที่พบบ่อยที่สุดคือการจำกัดอัตรา และนาทีแย่ ๆ ของผู้ให้บริการ
การรันของ Tajo ที่อยู่ในคิวและล้มเหลวจะได้ความพยายามห้าครั้ง เวลารอระหว่างแต่ละครั้งคือ 60, 120, 240 และ 480 วินาที รวมประมาณสิบห้านาที ความล้มเหลวบางอย่างไม่ถูกลองใหม่เลย เพราะการลองใหม่แก้ไม่ได้ การรันที่ชนกับการรันที่กำลังทำงานอยู่จะไม่ถูกลองใหม่ และการรันที่เวอร์ชันที่เผยแพร่หรือการเชื่อมต่อใช้ไม่ได้แล้วก็เช่นกัน
ความล้มเหลวต่อเนื่องต่างจากการสะดุดครั้งเดียว ถ้าการรันห้าครั้งล่าสุดที่เสร็จสิ้นนับจากที่การซิงค์ถูกเปลี่ยนครั้งล่าสุดล้มเหลวทั้งหมด Tajo จะหยุดการซิงค์ชั่วคราว และแสดงข้อผิดพลาดล่าสุดบนหน้าของการซิงค์ ความสำเร็จหนึ่งครั้งจะรีเซ็ตการนับ ไม่มีอะไรเริ่มการซิงค์ที่หยุดชั่วคราวใหม่เอง คนต้องแก้สาเหตุแล้วเผยแพร่อีกครั้ง บทความเรื่องเวิร์กเกอร์ล่มเล่าถึงเหตุการณ์ที่ทำให้เกิดกฎข้อนี้
5. ถือว่าความเงียบเป็นสิ่งที่ค้นพบ
“รายงานการอ่านที่ล้มเหลวว่าอ่านไม่ได้ ไม่ใช่วันที่เงียบสงบ” ข้อนี้ยากที่สุดในหกข้อ และเป็นข้อเดียวที่เราทำได้เพียงบางส่วน
จุดที่ทำได้: การอ่านที่เกิดข้อผิดพลาดทำให้การรันล้มเหลว โทเค็นที่ถูกปฏิเสธหรือเซิร์ฟเวอร์ที่ไม่ตอบ จะไม่ส่งอะไรไปที่ปลายทาง ทิ้งเคอร์เซอร์ไว้ที่เดิม และถูกนับรวมในการหยุดชั่วคราวหลังการรันล้มเหลวห้าครั้ง และทุกชั่วโมง ที่นาทีที่ 13 Tajo จะตรวจทุกเวิร์กสเปซที่มีการซิงค์ที่ใช้งานอยู่ และแจ้งเตือนทีมของตัวเองเมื่อไม่มีการรันที่สำเร็จใน 24 ชั่วโมงล่าสุด รวมถึงเวิร์กสเปซที่ไม่มีการรันถูกบันทึกเลย นั่นคือการตรวจรายชั่วโมง
จุดที่ทำไม่ได้: การอ่านแบบเงียบที่ผู้เขียนพูดถึง คือการอ่านที่ตอบว่า “OK” โดยไม่มีเรคคอร์ดเลย ตัวรันของเรานับว่าเป็นความสำเร็จ สำหรับแหล่งข้อมูลอย่างลูกค้า Shopify การตรวจแยกต่างหากจะเตือนทีมของ Tajo หลังการรันสำเร็จสิบครั้งติดกันโดยได้ศูนย์เรคคอร์ด หากการซิงค์นั้นเคยให้เรคคอร์ดมาก่อน คำสั่งซื้อ Shopify อ่านตามเวลาอัปเดต การรันที่ว่างเปล่าจึงเป็นเรื่องปกติ และการตรวจนั้นไม่ทำงาน แหล่งข้อมูลที่ส่งเรคคอร์ดกลับมาบ้าง แต่น้อยกว่าที่ควร จะไม่ถูกจับได้เลย
ข้อโต้แย้งมักเป็นแบบนี้: “การรันว่างสิบครั้งคือสองชั่วโมงครึ่งเมื่อรันทุก 15 นาที ทำไมไม่แจ้งเตือนตั้งแต่ครั้งแรก?” การซิงค์ผู้ติดต่อรันทุก 15 นาทีโดยค่าเริ่มต้นจริง และร้านค้าที่ไม่มีลูกค้าใหม่ในสิบห้านาทีก็เป็นเรื่องธรรมดา การแจ้งเตือนตั้งแต่การรันว่างครั้งแรกจะดังทุกคืน และการแจ้งเตือนที่ดังตลอดเวลาไม่มีใครอ่าน เส้นแบ่งนั้นแลกความเร็วกับความน่าเชื่อถือ แต่มันยังเป็นการเดาเรื่องความเงียบ ไม่ใช่กฎของผู้เขียน
6. ตัดสินครั้งเดียวว่าการซิงค์เขียนอะไรได้บ้าง และให้ทุกการรันพิสูจน์สิ่งนั้น
กฎข้อที่ห้าของพวกเขาเก็บค่ากำหนดของเอเจนต์ไว้ “ในที่จัดเก็บที่เอเจนต์แก้ไขไม่ได้” ข้อที่หกให้เอเจนต์มีสิทธิ์อ่านอย่างเดียวในทุกที่ที่มันแค่อ่าน และจำกัดว่าการรันแต่ละครั้งใช้จ่ายได้เท่าไร ทั้งสองข้อมีอยู่เพราะเอเจนต์อ่านข้อความที่คนอื่นเขียน และข้อความนั้นอาจพยายามสั่งมัน
สิ่งที่เทียบเท่าไฟล์ค่ากำหนดในการซิงค์คือกฎที่เผยแพร่แล้ว การเผยแพร่การซิงค์ของ Tajo ผูกมันไว้กับ digest ของกฎที่ถูกพรีวิวไว้ตรงตัว การแก้ไขมันจะส่งกลับไปเป็นฉบับร่าง และต้องผ่านการพรีวิวอีกครั้งก่อนจะรันได้ ทุกการรันจะตรวจก่อนเปลี่ยนแปลงอะไรว่า กำลังรันเวอร์ชันที่เผยแพร่นั้นด้วยการเชื่อมต่อชุดเดียวกับตอนที่เผยแพร่ การรันที่ไม่ผ่านการตรวจนี้จะไม่ถูกลองใหม่ ทิศทางก็ถูกกำหนดตายตัว กฎการซิงค์เขียนทางเดียว และไม่เคยเขียนกลับเข้า Shopify
เพดานค่าใช้จ่ายไม่มีสิ่งที่เทียบเท่า การรันการซิงค์ของเราไม่มีเพดานค่าใช้จ่ายต่อการรัน ขีดจำกัดการลองใหม่และการหยุดชั่วคราวจำกัดว่าความล้มเหลวจะยืดเยื้อได้นานแค่ไหน ไม่ใช่ว่าการรันหนึ่งครั้งมีค่าใช้จ่ายเท่าไร
อะไรสร้างแล้ว และอะไรยังไม่ได้สร้าง
สร้างแล้ว ณ ขณะที่เขียน:
- เคอร์เซอร์ ที่เลื่อนเฉพาะหลังแบตช์ที่ทุกเรคคอร์ดไปถึงแล้ว และเคอร์เซอร์คำสั่งซื้อตามกำหนดเวลาที่การรันซึ่งคนเริ่มเองย้อนกลับไม่ได้
- คีย์การส่งต่อเรคคอร์ด ที่ถูกตรวจเทียบกับสมุดบัญชีของการเขียนที่เสร็จแล้วซึ่งเก็บไว้เจ็ดวัน
- สิทธิ์เช่าหนึ่งรายการต่อการซิงค์ ที่ถูกตรวจก่อนการเขียนและก่อนเคอร์เซอร์เลื่อน
- ความพยายามห้าครั้งต่อการรัน รอ 60 วินาที แล้วตามด้วย 120, 240 และ 480 โดยไม่ลองใหม่เมื่อชนกันหรือเมื่อการเผยแพร่ใช้ไม่ได้
- การหยุดชั่วคราวหลังการรันล้มเหลวห้าครั้งติดกัน ซึ่งแสดงบนหน้าของการซิงค์
- การแจ้งเตือนรายชั่วโมง เมื่อไม่มีการรันใดสำเร็จใน 24 ชั่วโมงล่าสุด
- ตัวกรองความยินยอมขณะรันสำหรับผู้ติดต่อที่ถูกเขียนเข้ากลุ่มเป้าหมายทางการตลาด และการตรวจในทุกการรันว่าเป็นเวอร์ชันที่เผยแพร่แล้ว
ยังไม่ได้สร้าง และควรรู้ไว้ก่อนจะพึ่งพา:
- การอ่านที่สำเร็จโดยได้ศูนย์เรคคอร์ดไม่ถูกรายงานว่าอ่านไม่ได้ คำเตือนสิบการรันครอบคลุมได้ส่วนหนึ่ง แต่ไม่ครอบคลุมคำสั่งซื้อ Shopify หรือแหล่งข้อมูลที่ส่งเรคคอร์ดกลับมาน้อยเกินไป
- การแจ้งเตือน 24 ชั่วโมงไปถึง Tajo ไม่ใช่คุณ และคำเตือนสิบการรันก็เช่นกัน ส่วนการหยุดชั่วคราวแสดงบนหน้าของการซิงค์
- การตรวจรายชั่วโมงดูที่เวิร์กสเปซ ไม่ใช่การซิงค์แต่ละรายการ การซิงค์ที่ปกติดีหนึ่งรายการจะบังการซิงค์ที่เงียบอยู่ข้าง ๆ
- ไม่มีเพดานค่าใช้จ่ายต่อการรัน
- ไม่มีอะไรเริ่มการซิงค์ที่หยุดชั่วคราวใหม่ คนต้องทำเอง
- การหยุดหลังล้มเหลวห้าครั้งและการตรวจ 24 ชั่วโมง ถูกตั้งค่าไว้สำหรับการติดตั้ง Tajo ทั้งระบบ ไม่ใช่ต่อการซิงค์
เมื่อเรื่องใดเรื่องหนึ่งเหล่านี้เกิดขึ้นกับการซิงค์ของคุณ กู้คืนการซิงค์ที่ค้างหรือล้มเหลว จะบอกว่าคุณจะเห็นอะไรและต้องทำอะไร
ผู้เขียนเขียนหกกฎสำหรับสรุปที่คนอ่านทุกเช้า การซิงค์ไม่มีผู้อ่านตอนเช้าเลย และนั่นคือเหตุผลที่มันต้องการกฎเหล่านี้มากกว่า กฎข้อหนึ่งถึงสี่และกฎข้อหกเป็นโค้ดในตัวรันของเราแล้ววันนี้ กฎข้อห้าเขียนไว้ได้ครึ่งเดียว การซิงค์ที่อ่านแหล่งข้อมูลของตัวเองไม่ได้ ควรบอกออกมา
คำถามที่พบบ่อย
การซิงค์ข้อมูลอัตโนมัติต้องมีอะไรบ้างจึงจะทำงานได้อย่างปลอดภัยเมื่อไม่มีใครเฝ้าดู?
หกอย่าง เคอร์เซอร์ที่เลื่อนก็ต่อเมื่อแบตช์ทั้งหมดไปถึงแล้ว คีย์การส่งต่อเรคคอร์ดที่การลองใหม่สร้างขึ้นซ้ำได้ และถูกตรวจเทียบกับสมุดบัญชีของการเขียนที่เสร็จแล้ว การรันทีละครั้งต่อการซิงค์ จำนวนการลองใหม่ที่มีขีดจำกัด แล้วหยุดชั่วคราวเมื่อการรันยังล้มเหลวต่อเนื่อง การแจ้งเตือนเมื่อไม่มีอะไรสำเร็จเลยตลอดหนึ่งวัน และกฎที่เผยแพร่แล้วซึ่งทุกการรันต้องพิสูจน์ว่ากำลังรันกฎนั้นอยู่
ทำไมการซิงค์จึงไม่ควรอ่านช่วงเวลาตายตัว เช่น 24 ชั่วโมงล่าสุด?
เพราะการรันไม่ได้ตรงเวลาเสมอ การรันที่เริ่มช้าจะทิ้งช่องว่างที่ช่วงเวลานั้นไม่เคยครอบคลุม และการรันที่เริ่มเร็วจะอ่านเรคคอร์ดซ้ำสองครั้ง เคอร์เซอร์ที่บันทึกไว้ทำให้ทุกการรันเริ่มตรงจุดที่แบตช์ที่เรียบร้อยล่าสุดจบลงพอดี ไม่ว่าการรันจะเริ่มเมื่อใด
Tajo ป้องกันไม่ให้การซิงค์ที่ถูกลองใหม่เขียนเรคคอร์ดเดิมซ้ำสองครั้งได้อย่างไร?
ทุกเรคคอร์ดได้รับคีย์การส่ง ซึ่งเป็นค่าแฮชของการซิงค์ แหล่งข้อมูล เคอร์เซอร์ของหน้า ตำแหน่งในหน้า และตัวเรคคอร์ดเอง คีย์จะถูกจองไว้ก่อนเรียกปลายทาง และถูกทำเครื่องหมายว่าเสร็จเมื่อการเขียนสำเร็จ คีย์ที่เสร็จแล้วถูกเก็บไว้เจ็ดวัน การลองใหม่หรือการรันครั้งหลังจะสร้างคีย์เดิมขึ้นมาและไม่เรียกปลายทางอีก
Tajo สังเกตเห็นไหม เมื่อแหล่งข้อมูลไม่ส่งอะไรกลับมาเพราะการอ่านล้มเหลวแบบเงียบ ๆ?
เพียงบางส่วน การอ่านที่เกิดข้อผิดพลาดทำให้การรันล้มเหลว และการรันนั้นถูกนับรวมในการหยุดชั่วคราวหลังการรันล้มเหลวห้าครั้งติดกัน การอ่านที่สำเร็จโดยได้ศูนย์เรคคอร์ดถูกนับเป็นความสำเร็จ สำหรับแหล่งข้อมูลอย่างลูกค้า Shopify ทีมของ Tajo จะได้รับคำเตือนหลังการรันสำเร็จสิบครั้งติดกันโดยได้ศูนย์เรคคอร์ด หากการซิงค์นั้นเคยให้เรคคอร์ดมาก่อน สำหรับคำสั่งซื้อ Shopify ซึ่งอ่านตามเวลาอัปเดต การตรวจนี้ไม่ทำงาน