← กลับไปหน้าบทความ
ส่ง Conversion กลับ

Event ID ไม่ตรงกัน ทำให้ระบบ Dedup พังทั้งสองทาง: นับซ้ำหรือหายไปเลย

02 ส.ค. 04:23 · อ่าน 1 นาที
Event ID ไม่ตรงกัน ทำให้ระบบ Dedup พังทั้งสองทาง: นับซ้ำหรือหายไปเลย

สรุปสั้น ๆ

Deduplication key หรือ event ID คือกลไกที่บอกปลายทางว่า event นี้เคยเห็นแล้วหรือยัง ถ้าออกแบบผิด จะเกิดปัญหาได้สองแบบตรงข้ามกัน คือนับซ้ำ (ถ้า ID ไม่ซ้ำทั้งที่ควรซ้ำ) หรือยอดหาย (ถ้า ID ซ้ำกันทั้งที่ควรต่างกัน) หลักการที่ถูกต้องคือ ID ต้องคำนวณจากข้อมูลของออเดอร์เอง ไม่ใช่ค่าสุ่มหรือเวลาปัจจุบัน

ทีมพัฒนาระบบหนึ่งเจอปัญหาแปลกที่ทำให้งงอยู่พักหนึ่ง คือลูกค้าสองคนที่ปิดการขายห่างกันแค่ไม่กี่วินาทีในช่วงเวลาเดียวกัน ถูกระบบนับเป็น conversion แค่รายการเดียว อีกรายหายไปเลย ทั้งที่เป็นออเดอร์คนละคน คนละสินค้ากันจริง ๆ

หลังไล่ดูโค้ดจึงพบว่าต้นตอคือการสร้าง event ID จากการรวมชื่อสินค้ากับเวลาปัจจุบันแบบปัดเศษเป็นวินาที พอมีสองออเดอร์เกิดขึ้นในวินาทีเดียวกันพอดี ID ที่คำนวณออกมาจึงซ้ำกันโดยบังเอิญ ทำให้ปลายทางเข้าใจว่าเป็น event เดียวกันแล้วรับแค่รายการแรก

Event ID หรือ Deduplication Key คืออะไรกันแน่

หลักการง่าย ๆ คือทุก event ที่ส่งเข้าไปต้องมีรหัสเฉพาะตัวติดไปด้วย เพื่อให้ปลายทางเช็คได้ว่าเคยเห็นรหัสนี้มาก่อนหรือยัง ถ้าเคยเห็นแล้วก็จะข้ามไม่บันทึกซ้ำ กลไกนี้คือสิ่งที่ป้องกันการนับซ้ำเวลามีการ retry หรือส่งข้อมูลซ้ำโดยไม่ตั้งใจ

แต่กลไกนี้จะทำงานถูกต้องก็ต่อเมื่อ ID ถูกออกแบบมาให้ ‘เหมือนกันเสมอสำหรับเหตุการณ์เดียวกัน’ และ ‘ต่างกันเสมอสำหรับเหตุการณ์ที่ต่างกัน’ ถ้าออกแบบผิดพลาดไปในทางใดทางหนึ่ง ปัญหาที่ตามมาจะตรงข้ามกันโดยสิ้นเชิง

สองรูปแบบความล้มเหลวที่เกิดจากจุดเดียวกัน

  • ID ไม่ซ้ำทั้งที่ควรซ้ำ — เช่นใช้เวลาปัจจุบันหรือค่าสุ่มเป็นส่วนหนึ่งของ ID ทำให้ทุกครั้งที่ retry event เดิม ID เปลี่ยนไปเรื่อย ๆ ปลายทางจึงไม่รู้ว่าซ้ำ นำไปสู่ปัญหานับซ้ำ
  • ID ซ้ำกันทั้งที่ควรต่างกัน — เช่นคำนวณจากข้อมูลที่หยาบเกินไป (อย่างชื่อสินค้ากับเวลาปัดเศษเป็นวินาที) ทำให้เหตุการณ์คนละเหตุการณ์บังเอิญได้ ID เดียวกัน ปลายทางจึงคิดว่าซ้ำแล้วปฏิเสธรายการที่สอง ทำให้ยอดหาย

ตัวอย่างการออกแบบที่ดีเทียบกับที่มีปัญหา

วิธีออกแบบ IDปัญหาที่มักเจอควรใช้หรือไม่
ค่าสุ่ม (random UUID) ทุกครั้งที่ยิงretry แล้ว ID เปลี่ยน ทำให้นับซ้ำไม่ควรใช้เดี่ยว ๆ
เวลาปัจจุบันปัดเศษเป็นวินาทีเหตุการณ์พร้อมกันชนกัน ทำให้ยอดหายไม่ควรใช้
รหัสออเดอร์ + ประเภทเหตุการณ์แทบไม่มีปัญหา เพราะผูกกับข้อมูลจริงที่ไม่ซ้ำแนะนำให้ใช้
รหัสออเดอร์ + ประเภทเหตุการณ์ + เวอร์ชันข้อมูลรองรับกรณีต้องอัปเดตข้อมูล event เดิมด้วยแนะนำสำหรับระบบที่ซับซ้อนขึ้น

ขั้นตอนออกแบบ Event ID ให้ถูกต้องตั้งแต่ต้น

  1. ระบุข้อมูลที่ไม่ซ้ำกันจริงของแต่ละเหตุการณ์ เช่นรหัสออเดอร์ที่ระบบสร้างขึ้นเองอยู่แล้ว แทนที่จะพึ่งเวลาหรือค่าสุ่ม
  2. รวมประเภทของเหตุการณ์เข้าไปด้วย เช่น ‘purchase’ หรือ ‘lead’ เพื่อให้ ID ต่างกันถ้าออเดอร์เดียวกันมีหลายเหตุการณ์เกิดขึ้น
  3. ทดสอบด้วยการจำลองสองเหตุการณ์ที่เกิดขึ้นพร้อมกันจริง ๆ (ไม่ใช่แค่ทดสอบทีละตัว) เพื่อยืนยันว่า ID ที่ได้ไม่ชนกัน ผ่านtest event toolของปลายทาง
  4. ทดสอบการ retry event เดิมซ้ำหลายครั้ง เพื่อยืนยันว่า ID ที่ได้เหมือนเดิมทุกครั้ง ไม่เปลี่ยนไปตามเวลาที่ยิง กันไม่ให้เกิดปัญหาจาก webhook ที่ยิงซ้ำตามมา
  5. เอกสารบันทึกวิธีคำนวณ ID ไว้ให้ทีมอื่นเข้าใจตรงกัน เพื่อไม่ให้มีการเปลี่ยนวิธีคำนวณโดยไม่รู้ผลกระทบภายหลัง

สรุป

event ID ที่ออกแบบดีคือสิ่งที่ป้องกันปัญหาได้ตั้งแต่ต้นทาง ทั้งปัญหานับซ้ำและปัญหายอดหายที่ดูเหมือนเป็นคนละเรื่องกัน แต่จริง ๆ แล้วมีรากมาจากจุดเดียวกัน

การลงทุนเวลาออกแบบ ID ให้ถูกต้องตั้งแต่แรกใช้เวลาไม่มาก แต่ประหยัดเวลาไล่ดีบักปัญหาที่ซับซ้อนกว่ามากในภายหลัง

  • event ID ต้องเหมือนกันเสมอสำหรับเหตุการณ์เดียวกัน และต่างกันเสมอสำหรับเหตุการณ์ต่างกัน
  • อย่าใช้ค่าสุ่มหรือเวลาปัจจุบันปัดเศษเป็นส่วนประกอบหลักของ ID
  • ใช้รหัสออเดอร์ร่วมกับประเภทเหตุการณ์เป็นฐานในการคำนวณ ID
  • ทดสอบทั้งกรณี retry ซ้ำและกรณีเหตุการณ์พร้อมกันก่อนใช้งานจริง

คำถามที่พบบ่อย

ทำไมใช้ค่าสุ่มถึงไม่ปลอดภัยสำหรับ event ID ทั้งที่ค่าสุ่มไม่ค่อยชนกัน

ประเด็นไม่ได้อยู่ที่ค่าสุ่มชนกันเอง แต่อยู่ที่ค่าสุ่มเปลี่ยนไปทุกครั้งที่ระบบพยายามส่งใหม่ (retry) ทำให้ปลายทางไม่มีทางรู้ว่านี่คือความพยายามส่งซ้ำของเหตุการณ์เดิม จึงรับไว้เป็นสองรายการแยกกัน

ควรใช้รหัสออเดอร์เพียงอย่างเดียวเป็น event ID ได้เลยไหม

ได้ถ้าออเดอร์หนึ่งมีแค่หนึ่งเหตุการณ์ที่ต้องส่ง แต่ถ้าออเดอร์เดียวอาจมีหลายเหตุการณ์ (เช่นทั้งเหตุการณ์เพิ่มสินค้าและเหตุการณ์ชำระเงิน) ควรรวมประเภทเหตุการณ์เข้าไปด้วยเพื่อแยกความแตกต่างให้ชัดเจน

ตรวจสอบยังไงว่าระบบปัจจุบันมีปัญหาการออกแบบ ID แบบนี้อยู่หรือเปล่า

ลองสุ่มตรวจ event ที่เกิดขึ้นในช่วงเวลาใกล้เคียงกันมาก ๆ (ห่างกันไม่ถึงวินาที) แล้วดูว่า ID ที่คำนวณได้ต่างกันจริงหรือไม่ ถ้าพบว่ามี ID ซ้ำกันทั้งที่เป็นคนละเหตุการณ์ นั่นคือสัญญาณว่าการออกแบบมีปัญหา

ปัญหานี้กระทบกับ event ประเภทไหนมากที่สุด

กระทบมากที่สุดกับธุรกิจที่มีปริมาณ event สูงและเกิดขึ้นถี่ในเวลาใกล้เคียงกัน เช่นธุรกิจที่มีลูกค้าปิดการขายพร้อมกันหลายรายในช่วงเวลาสั้น ๆ อย่างช่วงแคมเปญโปรโมชันใหญ่ ยิ่งปริมาณสูงยิ่งมีโอกาสชนกันมากขึ้น

ถ้าพบว่าออกแบบผิดมาตั้งแต่ต้น ควรแก้ทันทีหรือรอจังหวะที่เหมาะสม

ควรแก้โดยเร็วที่สุดเท่าที่ทำได้ เพราะยิ่งปล่อยไว้นาน ข้อมูลที่คลาดเคลื่อนสะสมยิ่งมากขึ้นเรื่อย ๆ และกระทบการตัดสินใจด้านงบโฆษณาต่อเนื่อง แต่ควรทดสอบให้รอบคอบก่อนเปลี่ยนวิธีคำนวณ ID เพราะการเปลี่ยนกลางทางอาจทำให้ event เดิมที่เคยส่งไปแล้วกับ event ใหม่ไม่ต่อเนื่องกัน

อยากวัดผลโฆษณาเข้า LINE ให้ถึงยอดขาย?

ทดลองใช้ linli ฟรี 14 วัน ไม่ต้องใช้บัตรเครดิต

เริ่มทดลองใช้ฟรี

บทความที่เกี่ยวข้อง

คู่มือเริ่มต้น LINE Conversion Tracking ในไทย ตั้งแต่ติดตั้งจนวัดยอดขายจริง
คู่มือเริ่มต้น LINE Conversion Tracking ในไทย ตั้งแต่ติดตั้งจนวัดยอดขายจริง
สำหรับคนที่เพิ่งเริ่มทำ LINE Conversion Tracking บทความนี้รวมทุกขั้นตอนตั้งแต่นิยาม Funnel ติดตั้งระบบ เชื่อมแพลตฟอร์ม จนถึงวางแผนช่วงทดลองใช้ให้ตัดสินใจได้จริงก่อนหมด Trial
LINE Tracking กับ PDPA ธุรกิจไทยควรเก็บข้อมูลอย่างไรให้เหมาะสม
LINE Tracking กับ PDPA ธุรกิจไทยควรเก็บข้อมูลอย่างไรให้เหมาะสม
ระบบ Tracking ไม่ได้ทำให้ธุรกิจผ่าน PDPA โดยอัตโนมัติ บทความนี้อธิบายว่าธุรกิจยังต้องรับผิดชอบอะไรเองบ้าง ตั้งแต่ Legal Basis ไปจนถึงการจำกัดข้อมูลที่ส่งไปแพลตฟอร์มโฆษณา
วิธีติดตั้ง Tracking Link และ Tracking Script สำหรับปุ่ม LINE บนเว็บไซต์
วิธีติดตั้ง Tracking Link และ Tracking Script สำหรับปุ่ม LINE บนเว็บไซต์
ก่อนติดตั้ง Tracking Link หรือ Script บนปุ่ม LINE ต้องเตรียมอะไรบ้าง บทความนี้เล่าขั้นตอนจริงตั้งแต่สิทธิ์เข้าถึงเว็บ ไปจนถึง Test Journey ก่อนเปิดใช้งาน ไม่ใช่แค่ก็อปโค้ดไปวาง