ใช้ MySQL ทำการเชื่อมต่อแบบหลายทางบนตาราง 100+ GB เป็นประจำหรือไม่


11

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

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

ด้วยจำนวนผู้ใช้ค่อนข้างมาก แต่ไม่มีอะไรเหมือนหมายเลข Facebook ฉันคาดว่าจะมีฐานข้อมูลที่มีลักษณะดังนี้:

หนึ่ง "โต๊ะใหญ่":

  • 250 ล้านแผ่น
  • 20 คอลัมน์
  • ข้อมูลประมาณ 100 GB
  • มีคีย์ต่างประเทศที่มีการจัดทำดัชนี (20)
  • มีคอลัมน์ string_id varchar (500) ที่จัดทำดัชนี
  • มีคอลัมน์ "ค่า" int (11)

4 ตารางอื่น ๆ :

  • 10 ล้านแผ่นต่อแผ่น
  • แต่ละข้อมูลประมาณ 2 - 4 GB
  • แต่ละตารางเหล่านี้มี 4 - 8 คอลัมน์
  • หนึ่งคอลัมน์คือวันที่และเวลา dat_created
  • หนึ่งคอลัมน์คือคอลัมน์ varchar (500) string_id
  • หนึ่งหรือสองคอลัมน์จากแต่ละตารางเหล่านี้จะถูกเลือกในการเข้าร่วม

หนึ่งในตารางเหล่านี้ใช้สำหรับจัดเก็บค่าเฉลี่ย - สคีมาคือ bigint (20) id, varchar (20) string_id, วันที่และเวลา dat_created, float average_value

ฉันต้องการทำอะไร - มีข้อความค้นหาสองรายการที่ค่อนข้างแพง:

  1. คำนวณค่าเฉลี่ยใหม่:

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

    • ใช้รหัสต่างประเทศเพื่อเลือกจาก 1,000-40,000 รายการจากตารางใหญ่
    • เข้าร่วมกับตารางสี่ตารางอื่น ๆ ในระเบียนใหม่ล่าสุดด้วยคอลัมน์ id สตริง
    • แทรกผลลัพธ์ลงในตารางที่ถูกทำให้เป็นมาตรฐาน
    • ระเบียนเหล่านี้ใช้สำหรับส่วนหน้าเพื่อแสดงข้อมูลแก่ผู้ใช้
    • ตามที่สร้างขึ้นในปัจจุบันแบบสอบถามนี้ใช้การรวมสี่รายการ

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

แต่ละคำสั่งเหล่านี้ทำงานในไม่กี่วินาทีใน MySQL บนเครื่องต่ำสุดที่มีชุดข้อมูลที่มีการบันทึก 100K ใน“ ตารางใหญ่” ฉันกังวลเกี่ยวกับความสามารถในการขยายและต้นทุนการปรับขนาด

คำถาม :

  1. วิธีนี้ดูดีไหม? เห็นได้ชัดว่ามีอะไรผิดปกติกับมุมมองภาพใหญ่หรือไม่?
  2. RDBMS เป็นเครื่องมือที่เหมาะสมหรือฉันควรดูโซลูชัน "ข้อมูลขนาดใหญ่" อื่น ๆ เช่นบางอย่างในตระกูล Hadoop หรือไม่? ความชอบของฉันคือการใช้ RDBMS เพราะข้อมูลมีโครงสร้างและเหมาะสมกับโมเดลเชิงสัมพันธ์ ถึงจุดหนึ่งมันเป็นความเข้าใจของฉันว่าฉันอาจไม่สามารถใช้ RDBMS ได้อีกต่อไป มันเป็นเรื่องจริงเหรอ? สวิตช์นี้จำเป็นเมื่อใด
  3. มันจะทำงานอย่างไร คำค้นหาเหล่านี้สามารถทำงานในระยะเวลาที่เหมาะสมได้หรือไม่? ฉันสามารถรอคิวชั่วโมง # 1 ได้ แต่แบบสอบถาม # 2 ควรเสร็จในไม่กี่นาที
  4. ฉันควรพิจารณาอะไรจากมุมมองของฮาร์ดแวร์ คอขวด RAM และ CPU ของฉันมีแนวโน้มที่จะเป็นอย่างไร ฉันถือว่าการเก็บดัชนีใน RAM เป็นสิ่งสำคัญ มีอะไรอีกบ้างที่ฉันควรพิจารณาอีก
  5. ในบางครั้งฉันอาจต้องแบ่งพาร์ติชั่นข้อมูลของฉันและใช้เซิร์ฟเวอร์หลายเครื่อง กรณีการใช้งานของฉันดูเหมือนว่ามีอยู่แล้วในหมวดหมู่นั้นหรือไม่หรือฉันจะสามารถปรับขนาดเครื่องเดียวในแนวตั้งได้ชั่วขณะ สิ่งนี้จะทำงานกับข้อมูล 10 เท่าหรือไม่ 100x?

อันนี้ยากที่จะตอบอย่างละเอียด บางทีคุณอาจจะดีกว่าในการค้นคว้าเกี่ยวกับคุณสมบัติการสืบค้น MySQL ทั่วไปเพื่อให้คุณรู้ว่าคุณคาดหวังอะไร สิ่งหนึ่งที่คุณสามารถทำได้ตลอดเวลาคือใส่ดิสก์ 20 แผ่นในเซิร์ฟเวอร์เพื่อให้คุณสามารถอ่านได้ที่ 3GB / s หรือมากกว่านั้น แต่ฉันคิดว่าคุณเป็นคำตอบเฉพาะซอฟต์แวร์อย่างละเอียด
usr

คำตอบ:


4

คุณได้ลองซ้อนข้อมูลเพิ่มและทำการเปรียบเทียบหรือไม่? 100K แถวไม่สำคัญ ลอง 250M หรือ 500M เหมือนที่คุณคาดหวังว่าคุณจะต้องจัดการและดูว่าคอขวดอยู่ที่ไหน

RDBMS สามารถทำสิ่งต่าง ๆ ได้มากมายหากคุณให้ความสนใจกับข้อ จำกัด และพยายามทำงานกับจุดแข็งของระบบ มันยอดเยี่ยมในบางสิ่งและน่ากลัวสำหรับคนอื่นดังนั้นคุณจะต้องทดสอบเพื่อให้แน่ใจว่ามันเหมาะสม

สำหรับงานการประมวลผลแบบแบตช์คุณไม่สามารถเอาชนะไฟล์แฟล็ตโหลดข้อมูลลงใน RAM ทุบอย่างแรงโดยใช้ชุดของลูปและตัวแปรชั่วคราวและทิ้งผลลัพธ์ MySQL จะไม่สามารถจับคู่ความเร็วนั้นได้ แต่ถ้าปรับให้ถูกต้องและใช้งานอย่างถูกต้องมันจะอยู่ในลำดับความสำคัญ

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

จากมุมมองของฮาร์ดแวร์คุณจะต้องทดสอบเพื่อดูว่าแพลตฟอร์มของคุณทำงานอย่างไร บางครั้งความจำเป็นสิ่งจำเป็น บางครั้งก็เป็นดิสก์ I / O มันขึ้นอยู่กับสิ่งที่คุณทำกับข้อมูลจริงๆ คุณจะต้องใส่ใจกับการใช้งานซีพียูของคุณอย่างใกล้ชิดและมองหา IO ระดับสูงเพื่อรอดูว่าปัญหาอยู่ตรงไหน

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


@tadman ขอบคุณสำหรับคำแนะนำของคุณ ฉันรู้ว่าไม่มีสิ่งใดมาทดแทนการทดลองใช้จริง ฉันไม่ได้เปรียบเทียบกับแถว 250M เพราะฉันต้องการให้แน่ใจว่าไม่มีอะไรผิดปกติเกี่ยวกับวิธีการของฉัน ดูเหมือนว่าจะไม่มี นอกจากนี้การได้รับข้อมูลจำนวนมากและการทำในลักษณะที่ค่อนข้างสมจริงเป็นความท้าทายที่ฉันยังไม่ได้คิดวิธีการแก้ยัง ฉันมีวิธีที่เป็นไปได้บางอย่างในการแบ่งข้อมูล ฉันเดาว่าฉันจะลองเพิ่มข้อมูลของฉันและดูว่ามันจะทำอย่างไรในจุดตรวจที่แตกต่างกัน - 1M, 10M, 100M, ฯลฯ
xnickmx

1

ตารางสรุป

ทุกวันคำนวณข้อมูลรวมสำหรับข้อมูลของวัน วางลงในตาราง "สรุป" ทำแบบสอบถามของคุณกับพวกเขา ง่ายดายเร็วขึ้น 10 เท่า

สำหรับการอภิปรายเพิ่มเติมโปรดระบุ

  • แสดงตาราง (เหมือนตอนนี้)
  • ขนาดโต๊ะ (ที่คุณพูดถึง)
  • ข้อเสนอที่เลือก

บางสิ่งที่ชัดเจน ...

  • BIGINT ไม่รับประกัน ใช้เวลา 8 ไบต์ INT UNSIGNED ใช้เวลา 4 และอนุญาตค่า 0..4 พันล้าน และมี MEDIUMINT ฯลฯ
  • ดัชนีหลายรายการในตาราง 'ข้อเท็จจริง' มักเป็นปัญหาด้านประสิทธิภาพที่ร้ายแรงโดยเฉพาะอย่างยิ่งสำหรับ INSERT คุณมีปัญหาที่นั่นหรือไม่?
  • DATETIME คือ 8 ไบต์; TIMESTAMP คือ 4
  • ข้อ จำกัด ที่สำคัญของต่างประเทศชัดเจนดี แต่มีค่าใช้จ่ายสูง
  • เข้าร่วมอาจจะใช่หรือไม่ใช่ปัญหาเรื่องประสิทธิภาพ ต้องดูการเลือกและสร้าง
  • 100GB เป็นขนาดที่ดีสำหรับฐานข้อมูล MySQL 'ใหญ่' ฉันสงสัยว่ามันสามารถทำงานได้โดยไม่ต้อง Hadoop ฯลฯ ฉันจัดการกับหนึ่งฐานข้อมูลนี้ - หน้า UI ส่วนใหญ่ตอบสนองภายในไม่กี่วินาทีแม้ว่าข้อมูลจะเกี่ยวข้องกันมาก
  • คุณจะล้างข้อมูลในบางจุดหรือไม่? (สิ่งนี้นำไปสู่กรณีการใช้งานหลักสำหรับการแบ่งพาร์ติชัน)

"เล็กลง -> แคชได้มากกว่า -> เร็วขึ้น


0

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

ฉันเห็นด้วยกับ tadman วิธีที่ดีที่สุดคือการจัดทำโปรไฟล์ด้วยข้อมูลที่คุณคาดหวังในประเภทของระบบที่คุณต้องการ


ดังที่ฉันพูดถึงในโพสต์ของฉันมุมมองขึ้นอยู่กับแบบสอบถามที่ใช้การรวมสี่รายการในตารางที่มีระเบียนเป็นสิบล้านรายการดังนั้นฉันจึงไม่เห็นว่ามุมมองที่เป็นรูปธรรมจะช่วยอย่างไร
xnickmx

ทริกเกอร์อาจไม่เร็วพอสำหรับฐานข้อมูลขนาดนี้ มี INSERT กี่วินาทีต่อวินาที
Rick James

1
@xnickmx หากไม่มีการแทรก / อัปเดตจำนวนมากทริกเกอร์ทำให้ง่าย / นักแสดงในการซิงค์ข้อมูลที่ผิดปกติ หากต้องการแทรก / อัปเดตเร็วขึ้นให้จัดคิวสิ่งเหล่านี้ด้วย: blog.shlomoid.com/2008/04/…หรืออบด้วยตัวคุณเอง วิธีนี้คุณไม่ต้องเข้าร่วมกับตารางแถว 100 ล้านที่มีอยู่เพื่อรับข้อมูลใหม่ตั้งแต่เมื่อทริกเกอร์เริ่มทำงานคุณจะได้รับประโยชน์จากข้อเท็จจริงที่ว่าคุณรู้ข้อมูลใหม่แล้วและสามารถทำให้มันเป็นส่วนหนึ่งของ tx ได้ หรือรอคิวเพื่อ denormalization ในภายหลัง
wes.stueve

@RickJames ตกลง คุณต้องคำนึงถึงจำนวนเม็ดมีดสำหรับกลยุทธ์ประเภทนี้และวิธีการที่ต้องดำเนินการอย่างรวดเร็ว
wes.stueve
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.