Try using it in your preferred language.

English

  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • ไทย
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar
translation

นี่คือโพสต์ที่แปลด้วย AI

제이온

[DB] เกณฑ์การตั้งค่าแคช

เลือกภาษา

  • ไทย
  • English
  • 汉语
  • Español
  • Bahasa Indonesia
  • Português
  • Русский
  • 日本語
  • 한국어
  • Deutsch
  • Français
  • Italiano
  • Türkçe
  • Tiếng Việt
  • Polski
  • Nederlands
  • हिन्दी
  • Magyar

สรุปโดย AI ของ durumis

  • แคชเป็นเทคนิคในการจัดเก็บข้อมูลที่อ่านบ่อยและเขียนน้อยเพื่อเพิ่มประสิทธิภาพของบริการ และสามารถเลือกเป้าหมายของการแคชโดยการวิเคราะห์ประวัติการเรียกใช้คิวรีของ RDB ผ่านทาง APM เช่น DataDog
  • การแคชแบบโลคัลเป็นวิธีการจัดเก็บข้อมูลแคชในหน่วยความจำของเซิร์ฟเวอร์แอปพลิเคชัน ซึ่งมีความเร็วสูง แต่ปัญหาคือการซิงค์ข้อมูลแคชระหว่างอินสแตนซ์ ในขณะที่การแคชแบบโกลบอลใช้เซิร์ฟเวอร์แยกต่างหาก เช่น Redis เพื่อจัดเก็บข้อมูลแคช ซึ่งทำให้สามารถแชร์กันระหว่างอินสแตนซ์ แต่ความเร็วอาจช้าลงเนื่องจากการจราจรทางเครือข่าย
  • ใช้ TTL (Time To Live) เพื่ออัปเดตแคช และโดยทั่วไปแล้วจะตั้งค่า TTL เป็นหน่วยเวลาขึ้นไปหาก read/write เกิดขึ้นบนเซิร์ฟเวอร์เดียว และตั้งค่า TTL เป็นหน่วยวินาทีหรือหน่วยนาที หากเกิดขึ้นบนเซิร์ฟเวอร์หลายเครื่อง

สวัสดีครับ ผมเจย์ออน

วันนี้ผมจะมาอธิบายเกณฑ์การตั้งค่าแคชนะครับ เนื่องจากเป็นบทความที่ผมเขียนจากประสบการณ์ทำงานจริง ดังนั้นโปรดรับทราบว่าเป็นเพียงข้อมูลอ้างอิง เท่านั้น ㅎㅎ


แคชคืออะไร?

แคชหมายถึงการเก็บผลลัพธ์ของการร้องขอไว้ล่วงหน้าเพื่อให้บริการได้รวดเร็วขึ้น นั่นคือ การเก็บผลลัพธ์ไว้ล่วงหน้าแล้วเมื่อมีการร้องขอ จะไม่ต้องอ้างอิง DB หรือ API แต่เข้าถึงแคชเพื่อประมวลผลการร้องขอ หลักการของแคชนี้เกิดขึ้นจากกฎของ Pareto

กฎของ Pareto หมายถึง 80% ของผลลัพธ์เกิดจาก 20% ของสาเหตุ คุณอาจจะดูรูปภาพด้านล่างเพื่อให้เข้าใจได้ง่ายขึ้น!



นั่นคือ แคชไม่จำเป็นต้องแคชผลลัพธ์ทั้งหมด แต่แคชเพียง 20% ที่ใช้บ่อยที่สุดในเวลาให้บริการ เพื่อเพิ่มประสิทธิภาพโดยรวม


ควรแคชข้อมูลอะไร?

ตามกฎของ Pareto เราไม่ควรแคชข้อมูลทั้งหมด แต่ควรแคชเฉพาะข้อมูลที่จำเป็น แล้วข้อมูลประเภทไหนที่ควรแคช?


ข้อมูลที่ต้องอ่านบ่อย แต่เขียนน้อย

โดยทั่วไปมักพูดกันว่า “ควรแคชข้อมูลที่ต้องอ่านบ่อย แต่เขียนน้อย” แต่เกณฑ์ “อ่านบ่อย” และ “เขียนน้อย” นั้นคลุมเครือมาก


ดังนั้น ผมจึงตรวจสอบข้อมูลที่จะแคชโดยใช้ขั้นตอนต่อไปนี้


  • ตรวจสอบประวัติการเรียกใช้แบบสอบถาม RDB TOP 5 ผ่าน APM เช่น DataDog
  • จากนั้นค้นหาแบบสอบถามการค้นหาและตรวจสอบว่าแบบสอบถามนั้นมาจากตารางใด
  • ตรวจสอบจำนวนการเรียกใช้แบบสอบถามการอัปเดตในตารางนั้น


การทำเช่นนี้จะช่วยให้เห็นว่าแบบสอบถามการค้นหาเกิดขึ้นบ่อย แต่แบบสอบถามการอัปเดตเกิดขึ้นน้อย ตารางที่ผมตรวจสอบในงานจริงมีแบบสอบถาม การค้นหาเกิดขึ้นวันละ 1.74 ล้านครั้ง แต่แบบสอบถามการอัปเดตมีเพียง 500 ครั้งเท่านั้น นี่อาจถือว่าเป็นเงื่อนไขที่เหมาะสมกับการแคช ㅎㅎ


ข้อมูลที่ไวต่อการอัปเดต

ข้อมูลที่ไวต่อการอัปเดตหมายความว่าความไม่ตรงกันระหว่าง RDB และแคชต้องสั้น ดังนั้น แม้ข้อมูลจะตรงกับเงื่อนไขการแคชด้านบน แต่ก็ต้อง พิจารณาอย่างรอบคอบสำหรับข้อมูลที่เกี่ยวข้องกับการชำระเงิน เนื่องจากข้อมูลประเภทนี้ไวต่อการอัปเดตมาก


ผมต้องแคชตารางที่เกี่ยวข้องกับการชำระเงินที่ตรงกับลักษณะทั้งสองข้อข้างต้น ดังนั้น ผมจึงไม่ได้ใช้แคชในทุกตรรกะที่ใช้ตาราง ที่เกี่ยวข้องกับการชำระเงิน แต่ได้ตัดสินใจที่จะใช้แคชบางส่วนกับตรรกะที่ปลอดภัยกว่า ซึ่งไม่มีการชำระเงินจริง


การแคชแบบโลคัลเทียบกับการแคชแบบทั่วโลก

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


การแคชแบบโลคัล

การแคชแบบโลคัลคือวิธีการเก็บข้อมูลแคชไว้ในหน่วยความจำของเซิร์ฟเวอร์แอปพลิเคชัน โดยทั่วไปมักใช้ Guava cache หรือ Caffeine cache


ข้อดี

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


ข้อเสีย

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


การแคชแบบทั่วโลก

การแคชแบบทั่วโลกคือวิธีการใช้เซิร์ฟเวอร์แยกต่างหาก เช่น Redis เพื่อเก็บข้อมูลแคช


ข้อดี

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


ข้อเสีย

  • ต้องผ่านการรับส่งข้อมูลบนเครือข่าย จึงทำให้ความเร็วช้ากว่าการแคชแบบโลคัล
  • ต้องใช้เซิร์ฟเวอร์แคชแยกต่างหาก จึงทำให้เกิดค่าใช้จ่ายในการดูแลระบบ
    • ค่าใช้จ่ายในการดูแลระบบ? → ค่าใช้จ่ายของเซิร์ฟเวอร์ เวลาในการตั้งค่าและบำรุงรักษาอินฟราสตรักเจอร์ การวางแผนการจัดการความผิดพลาด ฯลฯ


ผมเลือกแบบไหน?

ปัจจุบันเซิร์ฟเวอร์แอปพลิเคชันของบริษัทของผมมีการเปิดหลาย ๆ อินสแตนซ์ แต่ผมเลือกใช้การแคชแบบโลคัล

เหตุผลหลัก ๆ มี 3 ประการ


  • ข้อมูลที่จะแคชใน RDB มีประมาณ 40,000 รายการ ดังนั้นการนำข้อมูลทั้งหมดขึ้นบนหน่วยความจำจะใช้พื้นที่ไม่เกิน 4 MB
  • ต้องการให้ประสิทธิภาพการค้นหาข้อมูลที่เกี่ยวข้องกับการชำระเงินดีขึ้น
  • มี Redis อยู่แล้ว แต่การเก็บแคชใหม่ไว้ใน Redis จะทำให้เกิดค่าใช้จ่ายในการดูแลระบบ


จะอัปเดตแคชอย่างไร?

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


ดังนั้น เราจำเป็นต้องกำหนดค่าให้แต่ละอินสแตนซ์ลบแคชโดยอัตโนมัติเพื่อค้นหาข้อมูลจาก RDB ในกรณีนี้มักใช้ TTL


ควรตั้งค่า TTL เป็นเท่าไหร่?

TTL ย่อมาจาก Time To Live ซึ่งเป็นการตั้งค่าที่ใช้ลบแคชเมื่อเวลาผ่านไป ตัวอย่างเช่น หากตั้งค่า TTL เป็น 5 วินาที ข้อมูลแคชจะถูกลบโดยอัตโนมัติหลังจาก 5 วินาที จากนั้นจะเกิดแคช miss และจะค้นหาข้อมูลจาก RDB และบันทึกไว้

แล้วควรตั้งค่า TTL เป็นเท่าไหร่?


read/write เกิดขึ้นในเซิร์ฟเวอร์แคชเดียว

หาก read/write เกิดขึ้นในเซิร์ฟเวอร์แคชทั่วโลก เช่น Redis เพียงเซิร์ฟเวอร์เดียว หรือเกิดขึ้นในเซิร์ฟเวอร์แอปพลิเคชันเพียง เซิร์ฟเวอร์เดียวที่มีการแคชแบบโลคัล การตั้งค่า TTL เป็นหน่วยเวลาหรือมากกว่านั้นก็ไม่เป็นไร เพราะเมื่อใดก็ตามที่มีการ write แคชเก่าจะถูกแก้ไข และเซิร์ฟเวอร์ที่ดึงข้อมูลจากแคชนั้นจะได้รับข้อมูลล่าสุดเสมอ


ในกรณีนี้ เราสามารถกำหนดค่าให้เซิร์ฟเวอร์แคชลบแคชออกทีละน้อยโดยใช้ Algorithm LRU เมื่อแคชเต็มโดยไม่ต้องตั้งค่า TTL


read/write เกิดขึ้นในเซิร์ฟเวอร์แคชหลาย ๆ เซิร์ฟเวอร์

หาก read/write เกิดขึ้นในเซิร์ฟเวอร์แคชแบบกระจายหลาย ๆ เซิร์ฟเวอร์ หรือเกิดขึ้นในเซิร์ฟเวอร์แอปพลิเคชันหลาย ๆ เซิร์ฟเวอร์ที่ใช้ การแคชแบบโลคัล การตั้งค่า TTL เป็นหน่วยวินาทีถึงนาทีจะดีกว่า เพราะอาจมีโอกาสที่เซิร์ฟเวอร์แคชจะอ่านข้อมูลเก่าที่ยังไม่ได้ อัปเดต


การตั้งค่า TTL ในกรณีนี้จะขึ้นอยู่กับหลาย ๆ ปัจจัย ยิ่งข้อมูลสำคัญและมีโอกาสเปลี่ยนแปลงค่ามากเท่าไหร่ ก็ยิ่งต้องตั้งค่า TTL ให้สั้นลง และยิ่งข้อมูลไม่สำคัญและมีโอกาสเปลี่ยนแปลงค่าน้อยเท่าไหร่ ก็ยิ่งสามารถตั้งค่า TTL ให้ยาวขึ้นได้


ผมตั้งค่า TTL อย่างไร?

ข้อมูลที่ผมจะแคชนั้นเป็นข้อมูลที่เกี่ยวข้องกับการชำระเงิน และแม้ว่าผมจะไม่ได้ใช้แคชในตรรกะที่เกิดการชำระเงินจริง ๆ แต่โดยธรรมชาติของการชำระเงินนั้น ต้องอัปเดตข้อมูลให้ทันเวลา แต่เนื่องจากมีโอกาสอัปเดตน้อย ดังนั้นผมจึงตั้งค่า TTL เป็น 5 วินาทีเพื่อความปลอดภัย


สรุป

สรุปแล้ว วิธีการแคชที่ผมเลือกคือ


  • ข้อมูลที่เกี่ยวข้องกับการชำระเงิน
  • มีการค้นหาบ่อยมาก แต่แทบไม่มีการแก้ไข
  • ใช้แคชเฉพาะตรรกะที่ไม่มีการชำระเงินจริง แต่มีการค้นหาข้อมูล
  • ใช้การแคชแบบโลคัลและตั้งค่า TTL เป็น 5 วินาที


สิ่งที่ต้องทำต่อไปคือการทดสอบประสิทธิภาพสำหรับวิธีการแคชที่ใช้จริง ขณะนี้ยังไม่ได้วางแผนว่าจะทำการทดสอบประสิทธิภาพ อย่างไร ดังนั้นผมจะเขียนบทความต่อไปเพื่ออธิบายขั้นตอนการทดสอบประสิทธิภาพ!

제이온
제이온
제이온
제이온
[Java] Synchronized Collection vs Concurrent Collection การวิเคราะห์เปรียบเทียบข้อดีข้อเสียของวิธีการต่างๆ ในการแก้ไขปัญหาการซิงโครไนซ์เมื่อใช้คอลเลกชันในสภาพแวดล้อมมัลติเธรดใน Java Vector, Hashtable, Collections.synchronizedXXX และคอลเลกชันแบบซิงโครไนซ์อื่น ๆ เช่น CopyOnWriteArrayList, ConcurrentHashMap, Con

25 เมษายน 2567

[Effective Java] รายการ 6. หลีกเลี่ยงการสร้างอ็อบเจ็กต์ที่ไม่จำเป็น คู่มือเกี่ยวกับวิธีลดการสร้างอ็อบเจ็กต์ที่ไม่จำเป็นใน Java อ็อบเจ็กต์แบบไม่เปลี่ยนแปลง เช่น String, Boolean ควรใช้ลิเทอรัล และควรแคชอินสแตนซ์ Pattern สำหรับนิพจน์ทั่วไป นอกจากนี้ การออโต้บอกซ์อาจทำให้ประสิทธิภาพลดลง ดังนั้นจึงควรใช้ประเภทพื้นฐาน รายละเอีย

28 เมษายน 2567

[Spring] วิธีการใช้ @Async เรียนรู้วิธีการใช้ Spring @Async ในการนำไปใช้กับการประมวลผลแบบอะซิงโครนัสใน Java ได้อย่างง่ายดาย ด้วยการใช้ประโยชน์จากแอโนเทชัน @Async เพื่อแปลงเมธอดแบบซิงโครนัสให้เป็นแบบอะซิงโครนัส และปรับปรุงประสิทธิภาพ ด้วยการตั้งค่าพูลสレッド คุณจะได้เรียนรู้วิธีการจัดก

25 เมษายน 2567

Redis 7.4 - เปลี่ยนแปลงนโยบายใบอนุญาต Redis เป็นฐานข้อมูลในหน่วยความจำที่มีข้อดีคือความเร็วสูงและการประมวลผลข้อมูลที่ง่าย เมื่อเร็ว ๆ นี้ได้มีการเปลี่ยนแปลงนโยบายใบอนุญาต ทำให้ผู้ให้บริการคลาวด์ที่โฮสต์ผลิตภัณฑ์ Redis ต้องทำข้อตกลงใบอนุญาต นักพัฒนาทั่วไปสามารถใช้ Redis Community Edition ได้
해리슨 블로그
해리슨 블로그
해리슨 블로그
해리슨 블로그

21 มีนาคม 2567

การสร้างแบบจำลองข้อมูลเชิงตรรกะ การสร้างแบบจำลองข้อมูลเชิงตรรกะคือกระบวนการแปลงแบบจำลองข้อมูลเชิงแนวคิดให้สอดคล้องกับรูปแบบฐานข้อมูลเชิงสัมพันธ์ โดยใช้กฎการแมป ซึ่งเกี่ยวข้องกับ การจัดการความสัมพันธ์ 1:1, 1:N, N:M และการทำให้เป็นปกติเพื่อให้ได้มาซึ่งความสมบูรณ์ของข้อมูล 1NF, 2NF, 3NF ผ่
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그
제이의 블로그

9 เมษายน 2567

[ไม่มีพื้นฐานทางวิศวกรรมคอมพิวเตอร์ การอยู่รอดในฐานะนักพัฒนา] 14. สรุปเนื้อหาการสัมภาษณ์ทางเทคนิคที่นักพัฒนาหน้าใหม่ถามบ่อย คู่มือเตรียมตัวสัมภาษณ์งานเทคนิคสำหรับนักพัฒนาหน้าใหม่ บทความนี้จะอธิบายแนวคิดที่มักปรากฏใน การสัมภาษณ์งาน เช่น พื้นที่หน่วยความจำหลัก โครงสร้างข้อมูล RDBMS และ NoSQL การเขียนโปรแกรมเชิงโครงสร้างและเชิงวัตถุ การโอเวอร์ไรด์และการโอเวอร์โหลด อัลกอริทึมการเป
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

3 เมษายน 2567

สร้างระบบแจ้งเตือนแบบเรียลไทม์โดยใช้ Supabase และ FCM เรียนรู้วิธีสร้างระบบแจ้งเตือนแบบเรียลไทม์โดยใช้ Deno, Supabase และ Firebase Cloud Messaging (FCM) บทความนี้จะอธิบายถึงการตรวจจับการเปลี่ยนแปลงของฐานข้อมูล การส่งการแจ้งเตือนแบบพุช พร้อมตัวอย่างรหัสจริง
Kofsitho
Kofsitho
สร้างระบบแจ้งเตือนแบบเรียลไทม์โดยใช้ Deno, Supabase และ Firebase Cloud Messaging
Kofsitho
Kofsitho

8 กุมภาพันธ์ 2567

อะไรคือการเติมช่อง (Slot-Filling) การเติมช่องเป็นการที่แชทบอทถามคำถามซ้ำๆ จนกว่าจะได้รับข้อมูลทั้งหมดที่ต้องการจากผู้ใช้ ตัวอย่างเช่น เมื่อสั่งกาแฟ แชทบอทจะถามเกี่ยวกับประเภท อุณหภูมิ และปริมาณน้ำ แล้วจะไม่เสร็จสิ้นการสั่งซื้อจนกว่าผู้ใช้จะป้อนข้อมูลทั้งหมด
꿈많은청년들
꿈많은청년들
ภาพที่มีคำว่า การเติมช่อง เขียนไว้ขนาดใหญ่
꿈많은청년들
꿈많은청년들

13 พฤษภาคม 2567

[Concurrency] Atomic Operation: Memory Fence และ Memory Ordering บล็อกโพสต์นี้จะอธิบายวิธีการพิจารณาลำดับหน่วยความจำใน Atomic Operations และความสำคัญของตัวเลือก Ordering ตัวเลือก Ordering ที่หลากหลาย เช่น Relaxed, Acquire, Release, AcqRel และ SecCst จะถูกอธิบายพร้อมกับข้อดีข้อเสีย และข้อควรระวังในการใช้งานพร้อมกับตัวอย
곽경직
곽경직
곽경직
곽경직
곽경직

12 เมษายน 2567