แนวทางที่ดีที่สุดสำหรับตาราง Sharding MySQL คืออะไร แนวทางที่ฉันคิดได้คือ:
- การแบ่งระดับแอปพลิเคชัน?
- Sharding ที่ MySQL proxy layer?
- เซิร์ฟเวอร์การค้นหาส่วนกลางสำหรับการชาร์ด?
คุณรู้จักโครงการหรือเครื่องมือที่น่าสนใจในพื้นที่นี้หรือไม่?
แนวทางที่ดีที่สุดสำหรับตาราง Sharding MySQL คืออะไร แนวทางที่ฉันคิดได้คือ:
คุณรู้จักโครงการหรือเครื่องมือที่น่าสนใจในพื้นที่นี้หรือไม่?
คำตอบ:
แนวทางที่ดีที่สุดในการแตกตาราง MySQL ที่จะไม่ทำเว้นแต่จะไม่สามารถหลีกเลี่ยงได้โดยสิ้นเชิงที่จะทำ
เมื่อคุณเขียนแอปพลิเคชันคุณมักจะต้องการทำในลักษณะที่เพิ่มความเร็วความเร็วของนักพัฒนา คุณปรับให้เหมาะสมสำหรับเวลาในการตอบสนอง (เวลาจนกว่าคำตอบจะพร้อม) หรือปริมาณงาน (จำนวนคำตอบต่อหน่วยเวลา) เมื่อจำเป็นเท่านั้น
คุณแบ่งพาร์ติชันจากนั้นกำหนดพาร์ติชันให้กับโฮสต์ที่แตกต่างกัน (= ชาร์ด) ก็ต่อเมื่อผลรวมของพาร์ติชันทั้งหมดเหล่านี้ไม่พอดีกับอินสแตนซ์เซิร์ฟเวอร์ฐานข้อมูลเดียวอีกต่อไป - สาเหตุของการเขียนหรืออ่าน
กรณีการเขียนคือ a) ความถี่ของการเขียนทำให้เซิร์ฟเวอร์นี้ทำงานหนักเกินไปหรือ b) มีการเขียนมากเกินไปจนทำให้การจำลองแบบล่าช้าอย่างถาวรในลำดับชั้นการจำลองแบบนี้
กรณีการอ่านสำหรับการชาร์ดคือเมื่อขนาดของข้อมูลมีขนาดใหญ่มากจนชุดการทำงานของข้อมูลนั้นไม่พอดีกับหน่วยความจำอีกต่อไปและการอ่านข้อมูลจะเริ่มกดดิสก์แทนการรับจากหน่วยความจำเกือบตลอดเวลา
เฉพาะเมื่อคุณต้องแบ่งคุณทำ
ทันทีที่คุณแบ่งคุณจะจ่ายเงินสำหรับสิ่งนั้นในหลายวิธี:
SQL ส่วนใหญ่ของคุณไม่มีการเปิดเผยอีกต่อไป
โดยปกติใน SQL คุณกำลังบอกฐานข้อมูลว่าต้องการข้อมูลใดและปล่อยให้เครื่องมือเพิ่มประสิทธิภาพเพื่อเปลี่ยนข้อกำหนดนั้นให้เป็นโปรแกรมเข้าถึงข้อมูล นั่นเป็นสิ่งที่ดีเพราะมีความยืดหยุ่นและเนื่องจากการเขียนโปรแกรมเข้าถึงข้อมูลเหล่านี้เป็นงานที่น่าเบื่อและเป็นอันตรายต่อความเร็ว
ด้วยสภาพแวดล้อมที่แตกออกคุณอาจรวมตารางบนโหนด A กับข้อมูลบนโหนด B หรือคุณมีตารางที่ใหญ่กว่าโหนดบนโหนด A และ B และกำลังเชื่อมโยงข้อมูลจากข้อมูลนั้นกับข้อมูลที่อยู่บนโหนด B และ C คุณกำลังเริ่มเขียนความละเอียดการรวมที่ใช้แฮชฝั่งแอปพลิเคชันด้วยตนเองเพื่อแก้ไขปัญหานั้น (หรือคุณกำลังสร้างคลัสเตอร์ MySQL ใหม่) ซึ่งหมายความว่าคุณจะมี SQL จำนวนมากที่ไม่ได้ประกาศอีกต่อไป แต่กำลังแสดงฟังก์ชันการทำงานของ SQL ในขั้นตอน (เช่นคุณกำลังใช้คำสั่ง SELECT ในลูป)
คุณมีเวลาแฝงของเครือข่ายจำนวนมาก
โดยปกติแล้วแบบสอบถาม SQL สามารถแก้ไขได้ภายในเครื่องและเครื่องมือเพิ่มประสิทธิภาพจะทราบเกี่ยวกับค่าใช้จ่ายที่เกี่ยวข้องกับการเข้าถึงดิสก์ภายในเครื่องและแก้ไขแบบสอบถามด้วยวิธีที่ช่วยลดต้นทุนสำหรับสิ่งนั้นให้น้อยที่สุด
ในสภาพแวดล้อมที่แยกส่วนการสืบค้นจะได้รับการแก้ไขโดยการเรียกใช้การเข้าถึงคีย์ - ค่าข้ามเครือข่ายไปยังหลายโหนด (หวังว่าจะมีการเข้าถึงคีย์เป็นกลุ่มและไม่ใช่การค้นหาคีย์แต่ละรายการต่อการเดินทางไปกลับ) หรือโดยการผลักดันบางส่วนของWHERE
อนุประโยคไปยังโหนดที่สามารถทำได้ ถูกนำไปใช้ (ซึ่งเรียกว่า 'condition pushdown') หรือทั้งสองอย่าง
แต่ในกรณีที่ดีที่สุดสิ่งนี้เกี่ยวข้องกับการเดินทางไปกลับเครือข่ายอีกมากมายซึ่งเป็นสถานการณ์ในท้องถิ่นและมีความซับซ้อนมากขึ้น โดยเฉพาะอย่างยิ่งเนื่องจากเครื่องมือเพิ่มประสิทธิภาพ MySQL ไม่รู้อะไรเลยเกี่ยวกับเวลาแฝงของเครือข่ายเลย (ตกลงคลัสเตอร์ MySQL เริ่มดีขึ้นอย่างช้าๆ แต่สำหรับวานิลลา MySQL นอกคลัสเตอร์นั้นยังคงเป็นจริง)
คุณกำลังสูญเสียพลังในการแสดงออกของ SQL ไปมาก
โอเคอาจมีความสำคัญน้อยกว่า แต่ข้อ จำกัด ของคีย์ต่างประเทศและกลไก SQL อื่น ๆ สำหรับความสมบูรณ์ของข้อมูลไม่สามารถครอบคลุมหลายส่วนได้
MySQL ไม่มี API ที่อนุญาตให้มีการสืบค้นแบบอะซิงโครนัสที่อยู่ในลำดับการทำงาน
เมื่อข้อมูลประเภทเดียวกันอยู่ในหลายโหนด (เช่นข้อมูลผู้ใช้บนโหนด A, B และ C) การสืบค้นแนวนอนมักจะต้องได้รับการแก้ไขกับโหนดเหล่านี้ทั้งหมด ("ค้นหาบัญชีผู้ใช้ทั้งหมดที่ไม่ได้เข้าสู่ระบบเป็นเวลา 90 วัน หรือมากกว่า"). เวลาในการเข้าถึงข้อมูลจะเพิ่มขึ้นเป็นเชิงเส้นตามจำนวนโหนดเว้นแต่จะสามารถถามหลายโหนดพร้อมกันได้และผลลัพธ์จะรวมกันเมื่อเข้ามา ("แผนที่ - ลด")
เงื่อนไขเบื้องต้นสำหรับนั้นคือ API การสื่อสารแบบอะซิงโครนัสซึ่งไม่มีสำหรับ MySQL ในรูปแบบที่ใช้งานได้ดี อีกทางเลือกหนึ่งคือการฟอร์กและการเชื่อมต่อจำนวนมากในกระบวนการย่อยซึ่งกำลังมาเยือนโลกแห่งการดูดซับฤดูกาล
เมื่อคุณเริ่มการชาร์ดโครงสร้างข้อมูลและโทโพโลยีเครือข่ายจะปรากฏให้เห็นเมื่อประสิทธิภาพชี้ไปที่แอปพลิเคชัน เพื่อให้ทำงานได้ดีพอสมควรแอปพลิเคชันของคุณจำเป็นต้องตระหนักถึงสิ่งเหล่านี้และนั่นหมายความว่าเฉพาะการแบ่งระดับแอปพลิเคชันเท่านั้นที่สมเหตุสมผล
คำถามมีมากกว่านี้หากคุณต้องการสร้างชาร์ดอัตโนมัติ (การกำหนดว่าแถวใดจะไปยังโหนดใดโดยการแฮชคีย์หลักเป็นต้น) หรือหากคุณต้องการแยกการทำงานด้วยวิธีแมนนวล ("ตารางที่เกี่ยวข้องกับเรื่องราวของผู้ใช้ xyz ไปที่นี้ master ในขณะที่ตารางที่เกี่ยวข้องกับ abc และ def จะไปที่ master นั้น ")
การแบ่งฟังก์ชันมีข้อได้เปรียบที่หากทำถูกต้องนักพัฒนาส่วนใหญ่จะมองไม่เห็นเนื่องจากตารางทั้งหมดที่เกี่ยวข้องกับเรื่องราวของผู้ใช้จะพร้อมใช้งานในเครื่อง ซึ่งช่วยให้พวกเขายังคงได้รับประโยชน์จาก SQL ที่เปิดเผยได้นานที่สุดและจะมีเวลาแฝงของเครือข่ายน้อยลงเนื่องจากจำนวนการถ่ายโอนข้ามเครือข่ายมีน้อย
การแบ่งส่วนการทำงานมีข้อเสียคือไม่อนุญาตให้ตารางเดียวมีขนาดใหญ่กว่าหนึ่งอินสแตนซ์และต้องได้รับการเอาใจใส่จากผู้ออกแบบด้วยตนเอง
Functional sharding มีข้อดีคือทำได้ค่อนข้างง่ายกับ codebase ที่มีอยู่โดยมีการเปลี่ยนแปลงจำนวนมากที่ไม่มากเกินไป http://Booking.comได้ทำหลายครั้งในช่วงหลายปีที่ผ่านมาและได้ผลดีสำหรับพวกเขา
เมื่อมองไปที่คำถามของคุณฉันเชื่อว่าคุณกำลังถามคำถามผิดหรือฉันเข้าใจคำชี้แจงปัญหาของคุณโดยสิ้นเชิง
การแบ่งระดับแอปพลิเคชัน: dbShards เป็นผลิตภัณฑ์เดียวที่ฉันรู้ว่า "แอปพลิเคชันตระหนักถึงการชาร์ด" มีบทความดีๆบนเว็บไซต์ ตามคำจำกัดความแอปพลิเคชันที่รับรู้การชาร์ดจะมีประสิทธิภาพมากขึ้น หากแอปพลิเคชันรู้ว่าจะไปที่ใดพร้อมกับธุรกรรมโดยไม่ต้องค้นหาหรือถูกเปลี่ยนเส้นทางโดยพร็อกซีสิ่งนั้นจะเร็วขึ้น และความเร็วมักเป็นหนึ่งในข้อกังวลหลักหากไม่ใช่ปัญหาเดียวเมื่อมีคนมองหาการทำลายล้าง
บางคน "ชาร์ด" ด้วยพร็อกซี แต่ในสายตาของฉันที่เอาชนะจุดประสงค์ของการชาร์ด คุณกำลังใช้เซิร์ฟเวอร์อื่นเพื่อบอกธุรกรรมของคุณว่าจะหาข้อมูลได้จากที่ใดหรือเก็บไว้ที่ใด แอปพลิเคชันของคุณรู้ว่าจะไปที่ใดด้วยตัวเอง มีประสิทธิภาพมากขึ้น
นี่เหมือนกับ # 2 จริงๆ
คุณรู้จักโครงการหรือเครื่องมือที่น่าสนใจในพื้นที่นี้หรือไม่?
โครงการใหม่หลายโครงการในพื้นที่นี้:
Shard-Queryเป็นโซลูชันการจัดเรียงข้อมูลแบบ OLAP สำหรับ MySQL ช่วยให้คุณสามารถกำหนดการรวมกันของตารางที่แตกและตารางที่ไม่มีการชาร์ต ตารางที่ไม่มีการชาร์ด (เช่นตารางการค้นหา) สามารถเชื่อมต่อกับตารางที่ชาร์ดได้อย่างอิสระและตารางที่ชาร์ดอาจเชื่อมต่อกันได้ตราบใดที่ตารางนั้นเชื่อมโยงกันด้วยคีย์ชาร์ด (ไม่มีส่วนแบ่งส่วนข้ามหรือการรวมตัวเองที่ข้ามขอบเขตของชาร์ด) ในฐานะที่เป็นโซลูชัน OLAP นั้น Shard-Query มักจะมีเวลาตอบสนองขั้นต่ำที่ 100ms หรือน้อยกว่าแม้สำหรับการสืบค้นแบบธรรมดาดังนั้นจึงไม่สามารถใช้ได้กับ OLTP Shard-Query ออกแบบมาเพื่อวิเคราะห์ชุดข้อมูลขนาดใหญ่ควบคู่กัน
OLTP Sharding มีโซลูชันสำหรับ MySQL เช่นกัน การแก้ปัญหาการปิดแหล่งรวมScaleDB , DBShards โซลูชัน OLTP แบบโอเพ่นซอร์ส ได้แก่JetPants , CubridหรือFlock / Gizzard (โครงสร้างพื้นฐานของ Twitter)
ระดับการสมัครของหลักสูตร
แนวทางที่ดีที่สุดที่ฉันเคยพบในหนังสือเล่มนี้
MySQL ประสิทธิภาพสูง http://www.amazon.com/High-Performance-MySQL-Jeremy-Zawodny/dp/0596003064
คำอธิบายสั้น ๆ : คุณสามารถแบ่งข้อมูลของคุณออกเป็นหลายส่วนและจัดเก็บ ~ 50 ส่วนในแต่ละเซิร์ฟเวอร์ มันจะช่วยให้คุณหลีกเลี่ยงปัญหาใหญ่อันดับสองของการทำให้เสียสมดุล - การปรับสมดุลใหม่ เพียงแค่ย้ายบางส่วนไปยังเซิร์ฟเวอร์ใหม่และทุกอย่างจะดี :)
ฉันขอแนะนำให้คุณซื้อและอ่านส่วน "mysql scaling"
ในปี 2018 ดูเหมือนว่าจะมีโซลูชัน MySql-native สำหรับสิ่งนั้น จริงๆแล้วมีอย่างน้อย 2 - InnoDB ClusterและNDB Cluster (มีเวอร์ชันเชิงพาณิชย์และเวอร์ชันชุมชน)
เนื่องจากคนส่วนใหญ่ที่ใช้ MySql community edition คุ้นเคยกับ InnoDB engine มากกว่านี่คือสิ่งที่ควรสำรวจเป็นอันดับแรก รองรับการจำลองแบบและการแบ่งพาร์ติชัน / ชาร์ดนอกกรอบและใช้ MySql Router สำหรับตัวเลือกการกำหนดเส้นทาง / โหลดบาลานซ์ที่แตกต่างกัน
ไวยากรณ์สำหรับการสร้างตารางของคุณจะต้องเปลี่ยนแปลงตัวอย่างเช่น:
CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH ( YEAR(col3) );
(นี่เป็นเพียงหนึ่งในสี่ประเภทการแบ่งพาร์ติชัน )
ข้อ จำกัด ที่สำคัญอย่างหนึ่ง:
คีย์ต่างประเทศ InnoDB และการแบ่งพาร์ติชัน MySQL เข้ากันไม่ได้ ตาราง InnoDB ที่แบ่งพาร์ติชันไม่สามารถมีการอ้างอิงคีย์นอกและไม่สามารถมีคอลัมน์ที่อ้างอิงโดยคีย์ต่างประเทศได้ ตาราง InnoDB ที่มีหรือที่อ้างอิงโดยคีย์นอกไม่สามารถแบ่งพาร์ติชันได้
PARTITION BY HASH(YEAR...)
จะสแกนพาร์ติชันทั้งหมดหากคุณมีช่วงวันที่ Yuck.