2 คะแนน โดย GN⁺ 2025-11-08 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ชี้ให้เห็นปัญหาการใช้สถาปัตยกรรมระบบที่ซับซ้อนเกินความจำเป็น ทั้งที่มีผู้ใช้จริงน้อย
  • ยกตัวอย่างการนำเทคโนโลยีหลายอย่างอย่าง Redis, MongoDB, Kubernetes, ไมโครเซอร์วิส มาผสมกันแบบไร้ทิศทาง
  • เน้นว่าสถานการณ์แบบนี้ใช้เพียง Postgres อินสแตนซ์เดียวและเซิร์ฟเวอร์ที่เรียบง่าย ก็เพียงพอ
  • ย้ำว่า ความซับซ้อนไม่ใช่คุณธรรม และควรขยายก็ต่อเมื่อพิสูจน์แล้วว่าจำเป็น
  • เป็นเนื้อหาที่เตือนสตาร์ทอัพและทีมพัฒนาให้ยึดหลัก การออกแบบที่เรียบง่ายให้เหมาะกับขนาด

การใช้เทคโนโลยีสแตกเกินจำเป็น

  • วิจารณ์ การจับคู่เทคโนโลยีที่ถูกเลือกแบบสุ่ม เช่น ใช้ Redis และ MongoDB พร้อมกัน
    • ตั้งคำถามว่า “ทำไม Redis ถึงคุยกับ MongoDB?” และ “ทำไมถึงใช้ MongoDB?”
  • ชี้ว่ามีการนำ ระบบกระจายศูนย์ มาใช้ ทั้งที่จำนวนผู้ใช้จริงมีเพียง 12 คน (ในนั้น 6 คนเป็นบัญชีทดสอบ)
  • กล่าวถึงกรณีที่เลือกขยายระบบเกินความจำเป็น ทั้งที่ Postgres อินสแตนซ์เดียว ก็เพียงพอ

ความฟุ่มเฟือยของโครงสร้างการดีพลอยและอินฟรา

  • โครงสร้างปัจจุบัน: ไมโครเซอร์วิส 15 ตัว, ฐานข้อมูล 8 ตัว, Kubernetes คลัสเตอร์ 3 สภาพแวดล้อม, เมสเสจคิว 4 ตัว, service mesh, CI/CD pipeline ที่ใช้เวลา 2 ชั่วโมง
  • ส่วนโครงสร้างที่จำเป็นจริงมีเพียง เซิร์ฟเวอร์เครื่องเดียว, Postgres, และ Redis สำหรับแคช เท่านั้น
  • เปรียบเทียบให้เห็นชัดเจนถึง ความซับซ้อนของอินฟราที่มากเกินไป เมื่อเทียบกับความต้องการจริง

ความซับซ้อนของระบบและความสามารถในการอธิบาย

  • ชี้ว่าถ้าต้องใช้ ไดอะแกรมที่พันกันเหมือนสปาเกตตี เพื่ออธิบายระบบให้ junior developer เข้าใจ แสดงว่ามีปัญหา
  • สรุปสารหลักด้วยประโยคว่า ความซับซ้อนไม่ใช่คุณธรรม
  • เน้นว่าควรเริ่มต้นอย่างเรียบง่าย และ เพิ่มความซับซ้อนเฉพาะเมื่อพิสูจน์แล้วว่าจำเป็น

บทเรียนสำคัญ

  • การเลือกเทคโนโลยีและออกแบบระบบควร ทำให้เรียบง่ายตามขนาดและปริมาณการใช้งานจริง
  • การขยายระบบแบบไร้ทิศทางและการเพิ่มเทคโนโลยีสแตกมากเกินไป ทำลายทั้งการบำรุงรักษาและประสิทธิภาพ
  • สำหรับสตาร์ทอัพหรือทีมขนาดเล็ก การรักษา “ความเรียบง่ายที่เหมาะกับขนาด” เป็นสิ่งสำคัญ

1 ความคิดเห็น

 
GN⁺ 2025-11-08
ความคิดเห็นจาก Hacker News
  • บางครั้งพฤติกรรมแบบนี้ก็ดูเหมือนแค่ การผัดวันประกันพรุ่ง (procrastination)
    เพราะไม่อยากคุยกับคนอย่างลูกค้า นักลงทุน หรือทีมกฎหมาย ก็เลยไปทำ “งานสนุกๆ” ในมุมของวิศวกรแทน
    ภายนอกอาจดูเหมือนกำลังทำงานอย่างมีประสิทธิภาพ แต่จริงๆ คือกำลังย่ำอยู่กับที่

    • ท้ายที่สุดมันเหมือนกระบวนการที่พัฒนาไปเป็น การเสพติดความสนุก
      ถ้าไม่ฝืนทำงานที่น่าอึดอัดบ้างทุกวัน คนเราจะค่อยๆ ถดถอย แล้วสุดท้ายก็เจอปัญหาใหญ่ที่เดิมทีหลีกเลี่ยงได้
      เรื่องนี้ไม่ใช่แค่กับซอฟต์แวร์ แต่ใช้ได้กับชีวิตโดยรวมด้วย
    • ตอนที่ฉันทำ บูตสแตรป อยู่ช่วง 5 ปีแรกก็เป็นแบบนั้นเหมือนกัน
      ได้เรียนรู้ว่าถ้าอยากหาเงิน ต้องทำ งานที่ลำดับความสำคัญถูกต้อง ไม่ใช่งานที่สนุกกว่า
    • แต่นี่เป็นเพราะ “ความสนุก” จริงหรือ?
      หรือจริงๆ แล้วเป็นการตอบสนอง ความอยากได้สถาปัตยกรรมในอุดมคติ ของ CTO หรือ VPE ที่ห่างไกลจากความเป็นจริงกันแน่
      ฉันจำได้ว่าเคยมีเกมหยั่งเชิงเรื่อง monolithic vs microservices ในการสัมภาษณ์ system design
      สุดท้ายแล้วคนที่มีอำนาจก็มักชัดเจนว่าต้องการไปทางไหน และการขัดทางนั้นก็คือการเผาทุนทางการเมือง
    • บางคนก็ใช้เรื่องพวกนี้เพื่อ โอ้อวดตัวเอง
      ประมาณว่า “ฉันเคยเชื่อม ABC กับ XYZ มาแล้วนะ” แล้วก็ไล่โชว์ tech stack ของตัวเอง
  • มันยังมีแรงจูงใจแบบอยากทำให้เรซูเม่ดูเท่ด้วย
    ที่จริงโปรเจกต์ส่วนใหญ่ใช้เทคโนโลยียุค 1990 ก็ทำได้สบาย แต่พอมีคำอย่าง distributed systems มันจะดู ‘คูล’ กว่ามาก
    เป็นผลจากวัฒนธรรมการจ้างงานที่ผิดเพี้ยนของวงการ จนกลายเป็นว่าเชฟไม่ได้ถูกยอมรับจากการใช้มีดเก่ง แต่ต้องใช้ ‘มีดแบรนด์เฉพาะ’ ถึงจะได้รับการยอมรับ

    • บริษัทที่ดีจะไม่บังคับ เงื่อนไขประสบการณ์ภาษา แบบนี้
      เช่น DuckDuckGo ขอแค่ algorithm กับ data structure แล้วแค่บอกว่า “อนึ่ง เราใช้ Perl”
      Stream มีคอร์ส 10 สัปดาห์ให้ผู้สมัครที่ยังไม่รู้ Go และ Jane Street ก็ไม่ได้บังคับว่าต้องมีประสบการณ์ OCaml
      ส่วน bevuta IT GmbH ที่ฉันทำงานอยู่ก็เปิดโอกาสให้เรียน Clojure หลังเข้าทำงาน
      แนวทางแบบนี้ต่างจากประกาศรับสมัครงานล้าสมัยประเภท “ต้องมีประสบการณ์ Ruby on Rails 10 ปี” อย่างสิ้นเชิง
    • พูดตามตรง ฉันเองก็เคยออกแบบ สถาปัตยกรรมที่ซับซ้อนเกินจำเป็น
      เพราะอยากลองของใหม่และอยากเปรียบเทียบมันดู
    • ถ้าใช้เวลาในสัมภาษณ์ไปกับการปกป้อง โซลูชันที่อิง Postgres แบบเรียบง่าย ก็จะไม่มีโอกาสพูดเรื่อง distributed systems ตามที่ผู้สัมภาษณ์คาดหวัง
      สุดท้ายความจริงของวงการก็คือ ต้องมานั่งพูดถึง ความซับซ้อนที่ไม่จำเป็น เพื่อรองรับผู้ใช้แค่ไม่กี่ร้อยคน
  • คำว่า “แคชด้วย Redis” ถูกพูดกันบ่อยมาก ทั้งที่จริงๆ Postgres ก็พอแล้ว
    การยืนยันว่าจะต้องใช้ Redis ให้ได้ ดูเหมือนแม้แต่ผู้เขียนเองก็ยังต้าน แรงกระตุ้นในการ overengineering ไม่ไหว

    • ส่วนตัวฉันไม่อยากเอาแคชไปใส่ใน Postgres
      ถ้าระบบยังเล็กก็ยังไม่จำเป็นต้องมีแคช และการเก็บ ข้อมูลชั่วคราว ไว้ในระบบแยกก็ดูน่าสนใจกว่า
      abstraction เรื่องแคชของ framework ส่วนใหญ่ก็ออกแบบมาโดยนึกถึง Redis อยู่แล้ว
      เริ่มจาก in-memory cache ก่อน แล้วค่อยเพิ่ม Redis ตอนจำเป็นจะดีกว่า
    • ถึงระบบจะเล็ก แคชก็ยังมีประโยชน์ได้
      แต่ Redis/Valkey ก็ยังเกินไปหน่อย memcached เรียบง่ายและใช้งานได้จริงกว่ามาก
      มันไม่เก็บสถานะแบบ Redis จึงช่วยหลีกเลี่ยง รูปแบบการออกแบบที่ไม่ดี ที่ไปพึ่งพาความสอดคล้องของแคช
      แคชใน DB ช้ากว่าเพราะต้องผ่าน file system
    • Redis เหมาะจะใช้เป็น ตัวกันกระแทกชั่วคราว ตอนที่ Postgres เริ่มช้า
      การเขียน query ให้มีประสิทธิภาพเป็นอีกปัญหาหนึ่งโดยสิ้นเชิง
      ถ้าทำให้ Postgres กลับมาเร็วได้ ก็อาจถอด Redis ออกได้ แต่ส่วนใหญ่ก็มักปล่อยทิ้งไว้แบบนั้น
    • มีคำถามว่า Postgres มี in-memory cache แบบ eventually consistent หรือเปล่า
    • พอระบบโตขึ้น Redis ก็สร้างความต่างได้ชัดเจน
      ตอนทำเว็บแอปบน AWS Lambda ที่ต้องรับ 1,000 requests ต่อวินาที Postgres เอาไม่อยู่ แต่ Redis รับได้สบาย
      เพราะความ เรียบง่าย ของมัน จึงมีคุณค่าให้ใช้ในบางกรณีพิเศษ
  • น่าสนใจที่ผู้เขียนพูดเรื่อง “ความเรียบง่าย” แต่กลับทำหน้าเว็บด้วย Tailwind + JS framework + bundler
    ทั้งที่จริงจะทำด้วย HTML แบบง่ายๆ ก็ได้

    • ฉันเองก็เห็นด้วยกับปรัชญาของผู้เขียน
      เลยขอแนะนำเว็บเฟรมเวิร์กเรียบง่ายที่สร้างเองได้อย่าง MastroJS
    • ถึงอย่างนั้น Tailwind ก็ไม่ได้เป็น เฟรมเวิร์กขนาดยักษ์
      ในทางปฏิบัติมันจะ generate CSS ตาม utility class ที่ใช้จริงเท่านั้น
    • React, Tailwind, bundler, Google Font… มนุษย์นี่ช่างเป็น สิ่งมีชีวิตที่เต็มไปด้วยความย้อนแย้ง
  • ทวีตต้นฉบับมาจาก ทวีตของ Jeff Atwood ในปี 2013

    • เพราะงั้นควรเติม (2013) ลงในชื่อบทความ
  • ตอนนี้ฉันเองก็กำลังชั่งใจเรื่องการตัดสินใจคล้ายๆ กันอยู่
    ถ้าเป็นผลิตภัณฑ์ที่ยังไม่ผ่านการพิสูจน์ตลาด ก็ควรเริ่มเล็ก เริ่มเร็ว และทำ MVP ที่ pivot ได้
    ในทางกลับกัน ถ้าต้องแสดงให้นักลงทุนหรือองค์กรใหญ่เห็นถึง ความสามารถในการออกแบบที่รองรับการขยายตัว ก็ควรเลือกโครงสร้างที่ scale ได้ตั้งแต่แรก
    ถ้าโมเดลธุรกิจจะเวิร์กได้ก็ต่อเมื่อมันโตเกินกว่าที่ DB เดียวจะรับไหว การไปทาง สถาปัตยกรรมที่ขยายได้ตั้งแต่ต้น ก็อาจคุ้มกว่าในระยะยาว

  • สำหรับคนที่ทำงานอยู่ท่ามกลางฝันร้ายด้านอินฟรา ความเรียบง่ายอาจฟังดูเพ้อฝัน
    แต่ความซับซ้อนจำนวนมากไม่ได้มีไว้แก้ปัญหาเชิงเทคนิคเท่านั้น มันมีไว้แก้ ปัญหาเชิงองค์กร ด้วย
    deployment automation, redundancy เพื่อรับมือเหตุขัดข้อง, CI pipeline, การจัดการ secrets, การทำแคช ล้วนเป็นอุปกรณ์ป้องกันเพื่อคุ้มครองทีม
    การมองข้ามสิ่งเหล่านี้ถือว่าเสี่ยงเมื่อทำงานกันเป็นทีม

    • จริงๆ แล้วข้อกำหนดพวกนี้ก็ยังทำได้ด้วย เซิร์ฟเวอร์ monolithic + Postgres
    • เรื่องอย่าง CI หรือการจัดการ secrets เป็นคนละเรื่องกับ ความซับซ้อนของสถาปัตยกรรม
      แม้แต่ SQLite ก็ยังใช้ใน production ได้สบาย แต่มีอคติแพร่หลายว่ามัน “เหมาะแค่สำหรับทดสอบ”
      บางครั้งค่าเริ่มต้นของ PaaS ก็ซับซ้อนเกินจำเป็น
    • ไม่จำเป็นต้องทำ CI pipeline ให้ใหญ่โตตั้งแต่วันแรก
      เริ่มจาก build process แบบอิง checklist ก่อน แล้วพอมันนิ่งค่อยขยายไปสู่ automation ก็ได้
    • ปัญหาอย่าง cache invalidation ซึ่งเป็น ปัญหายากของวิทยาการคอมพิวเตอร์ ก็ยังคงมีอยู่
      ฉันอยากเห็นกรณีใช้งานจริงที่ microservices จำเป็นจริงๆ สำหรับบริการที่ไม่ใช่ระดับ FAANG
    • ท้ายที่สุดแล้วโครงสร้างองค์กรก็สะท้อนออกมาในแบบระบบ ตาม กฎของ Conway
  • หลายคนเอาแต่เดินตาม tech stack มาตรฐาน เพราะกลัวการคิดเอง
    การใช้ Kafka, Mongo, Redis แบบไม่ตั้งคำถามนี่แหละคือปัญหา
    ที่จริงการลงมือทำเฉพาะฟีเจอร์ที่ต้องใช้เองอาจดีกว่า และ ความสามารถในการเลือกองค์ประกอบให้น้อยที่สุด คือหัวใจของวิศวกร
    ของอย่าง Kafka นี่บางทีก็แค่เผาเงินเปล่าๆ

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

  • ไม่นานมานี้ฉันก็เพิ่งเจอประสบการณ์คล้ายกันในบทสัมภาษณ์
    ตลอด 10 ปีที่ผ่านมา ฉันโฟกัสกับการหา PMF (Product-Market Fit) ไม่ใช่หมกมุ่นกับการ scale ตั้งแต่ต้น
    ถ้าผลิตภัณฑ์เข้ากับตลาด ปัญหาเรื่องการขยายระบบก็แก้ได้ด้วยเงิน
    แต่พอถูกถามในการสัมภาษณ์ว่า “จะ scale บริการ Django ให้รองรับ 10 ล้าน requests ต่อวันได้อย่างไร”
    ฉันตอบไปว่า “ก็เพิ่มสเปกเซิร์ฟเวอร์สิ” แล้วดูเหมือนพวกเขาจะไม่ค่อยพอใจนัก