เกี่ยวกับประสิทธิภาพของฐานข้อมูลแบบเธรดเดียวกับเธรดแบบมัลติเธรด


58

H2 เป็นฐานข้อมูลเธรดเดียวที่มีชื่อเสียงที่ดีเกี่ยวกับประสิทธิภาพ ฐานข้อมูลอื่นเป็นแบบมัลติเธรด

คำถามของฉันคือ: ฐานข้อมูลแบบหลายเธรดน่าสนใจกว่าฐานข้อมูลเธรดเดียวเมื่อใด มีผู้ใช้กี่คน? มีกี่กระบวนการ ทริกเกอร์คืออะไร? ใครบ้างมีประสบการณ์แบ่งปัน

สรุป

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

เธรดหมายถึง "เธรดหรือกระบวนการ" สำหรับจุดประสงค์ของคำถามนี้เท่าที่ฉันสามารถบอกได้ - เช่นpostgres ไม่ใช่มัลติเธรดแต่คำถามไม่พยายามเปรียบเทียบ (H2, postgres) เปรียบเทียบกับ (Oracle, SQL Server ฯลฯ )
แจ็ค ดักลาส

คำตอบ:


31

นี่คือความคิดเห็นของฉัน:

โดยปกติแล้วคอขวด (หรือส่วนที่ช้าที่สุด) ของระบบ DB คือดิสก์ CPU spikes เท่านั้นในระหว่างการดำเนินการทางคณิตศาสตร์การประมวลผลหรืองานอื่น ๆ ที่ CPU ทำ ด้วยสถาปัตยกรรมที่เหมาะสมมัลติเธรดสามารถช่วยชดเชยภาระการสืบค้นลงบน CPU แทนการอ่าน / เขียนดิสก์ที่ช้า มีหลายกรณีที่การคำนวณค่าโดยใช้รอบของ CPU นั้นเร็วกว่าการสร้างคอลัมน์จากการคำนวณ (ซึ่งถูกบันทึกไว้ในดิสก์ก่อนหน้านี้) และอ่านคอลัมน์นี้จากดิสก์

ใน RDBMS บางตัวจะมี DB ชั่วคราว (tempdb) ที่ใช้โดย DBs ทั้งหมดบนอินสแตนซ์นั้นสำหรับการเรียงลำดับการแฮชตัวแปรชั่วคราว ฯลฯ ... การมัลติเธรดและการแยกไฟล์ tempdb นี้สามารถใช้เพื่อปรับปรุงทรูพุตของ tempdb ดังนั้นจึงปรับปรุงประสิทธิภาพโดยรวมของเซิร์ฟเวอร์

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

เธรดที่พร้อมใช้งานกับฐานข้อมูลนั้นถูกใช้เพื่อวัตถุประสงค์หลายประการ: การอ่าน / เขียนไปยังดิสก์การเชื่อมต่อผู้ใช้งานพื้นหลังการล็อก / การล็อคเครือข่าย IO ฯลฯ ... ขึ้นอยู่กับสถาปัตยกรรมระบบปฏิบัติการ จัดการโดยใช้การรอและรอ หากซีพียูสามารถกระทืบเธรดเหล่านี้ได้อย่างรวดเร็วเวลารอจะต่ำ ฐานข้อมูลแบบมัลติเธรดจะเร็วกว่าฐานข้อมูลแบบเธรดเดียวเนื่องจากในฐานข้อมูลแบบเธรดเดียวจะมีค่าใช้จ่ายในการรีไซเคิลเพียงหนึ่งเธรดแทนที่จะมีดอกยางชนิดอื่นพร้อมใช้งาน

ความสามารถในการปรับขยายก็กลายเป็นปัญหาด้วยเนื่องจากจะต้องมีเธรดเพิ่มเติมเพื่อจัดการและดำเนินการระบบฐานข้อมูลที่ปรับขนาด


ขอบคุณสำหรับความเข้าใจ ฉันได้ยินคนยกย่องการขับรถอย่างมั่นคง ฉันเดาว่าการลงทุนในสิ่งเหล่านี้น่าจะเป็นสิ่งที่ดีที่สุดที่จะทำหลังจากตรวจสอบให้แน่ใจว่าข้อความค้นหานั้นเขียนได้ดีและแอปพลิเคชันนั้นขนานกันอย่างสมเหตุสมผล
Jérôme Verstrynge

@ สแตน - ฉันคิดว่าmultithreadedในบริบทนี้หมายถึงสิ่งที่แตกต่างนั่นคือธุรกรรมทั้งหมดได้รับการจัดลำดับตามที่ลุคกล่าวถึงในคำตอบของเขา
Jack Douglas

@JVerstry ~ ไม่ไม่ได้จริงๆ ไปอ่านความคิดเห็นของ Jeff Atwood เกี่ยวกับ SSD ... พวกเขามีอัตราความล้มเหลวสูง สิ่งที่ดีที่สุดที่ต้องทำคือการจัดทำดัชนีข้อมูลอย่างถูกต้องและมีข้อความค้นหาที่เขียนได้ดี
jcolebrand

@ jcolebrand Ok ดูเหมือนว่าเขาจะสนับสนุนพวกเขาเพื่อความรวดเร็วด้วยระบบสำรองข้อมูลที่แข็งแกร่งเมื่อพวกเขาล้มเหลว
Jérôme Verstrynge

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

47

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

innodb_thread_concurrencyตั้งค่าขอบเขตบนของจำนวนเธรดที่เกิดขึ้นพร้อมกันที่ InnoDB สามารถเปิดค้างไว้ จำนวนรอบที่ดีที่สุดสำหรับการตั้งค่านี้คือ (2 X จำนวน CPUs) + จำนวนดิสก์ อัปเดต : เมื่อฉันเรียนรู้โดยตรงจากการประชุม Percona NYC คุณควรตั้งค่านี้เป็น 0 เพื่อแจ้งเตือน InnoDB Storage Engine เพื่อค้นหาจำนวนเธรดที่ดีที่สุดสำหรับสภาพแวดล้อมที่ทำงานอยู่

innodb_concurrency_ticketsตั้งค่าจำนวนเธรดที่สามารถข้ามการตรวจสอบพร้อมกันด้วยการไม่ต้องรับโทษ หลังจากถึงขีด จำกัด นั้นการตรวจสอบการทำงานพร้อมกันของเธรดจะกลายเป็นบรรทัดฐานอีกครั้ง

innodb_commit_concurrencyตั้งค่าจำนวนธุรกรรมที่เกิดขึ้นพร้อมกันที่สามารถยืนยันได้ เนื่องจากค่าเริ่มต้นคือ 0 การตั้งค่านี้ไม่อนุญาตให้มีจำนวนการทำธุรกรรมใด ๆ พร้อมกัน

innodb_thread_sleep_delayตั้งค่าจำนวนมิลลิวินาทีที่เธรด InnoDB สามารถหยุดทำงานก่อนที่จะป้อนคิว InnoDB อีกครั้ง ค่าเริ่มต้นคือ 10000 (10 วินาที)

innodb_read_io_threadsและinnodb_write_io_threads (ทั้งตั้งแต่ MySQL 5.1.38) จัดสรรจำนวนเธรดที่ระบุสำหรับการอ่านและเขียน ค่าเริ่มต้นคือ 4 และสูงสุดคือ 64

innodb_replication_delayกำหนดให้การหน่วงเวลาของเธรดบนสมาร์ทคือถึง innodb_thread_concurrency

innodb_read_ahead_thresholdอนุญาตการอ่านเชิงเส้นของจำนวน extents ที่กำหนด (64 หน้า [หน้า = 16K]) ก่อนที่จะเปลี่ยนเป็นการอ่านแบบอะซิงโครนัส

เวลาจะหนีฉันถ้าฉันตั้งชื่อตัวเลือกเพิ่มเติม คุณสามารถอ่านเกี่ยวกับพวกเขาในเอกสารของ MySQL

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

ฉันได้เล่นกับ MySQL 5.5 Multiple Buffer Pool Instances (162GB ในอินสแตนซ์ของ Pool buffer 9 รายการ) และได้พยายามที่จะแบ่งพาร์ติชันข้อมูลโดยอัตโนมัติในหน่วยความจำด้วยวิธีนี้ ผู้เชี่ยวชาญบางคนบอกว่าสิ่งนี้จะช่วยให้คุณปรับปรุงประสิทธิภาพได้ 50% สิ่งที่ฉันได้รับคือการล็อคเธรดมากมายที่ทำให้ InnoDB คลาน ฉันเปลี่ยนเป็น 1 บัฟเฟอร์ (162GB) และทุกอย่างก็ดีขึ้นอีกครั้งในโลก ฉันคิดว่าคุณต้องการผู้เชี่ยวชาญ Percona ในการกำจัดของคุณเพื่อตั้งค่านี้ ฉันจะเข้าร่วมการประชุม Percona MySQL ที่นิวยอร์กในวันพรุ่งนี้และจะถามเกี่ยวกับสิ่งนี้หากมีโอกาสเกิดขึ้น

โดยสรุปแล้ว InnoDB ทำงานได้ดีในเซิร์ฟเวอร์ CPU หลายตัวเนื่องจากการตั้งค่าเริ่มต้นสำหรับการทำงานแบบมัลติเธรด พวกเขาใช้ความระมัดระวังอย่างมากอดทนอย่างยิ่งเอกสารที่ยอดเยี่ยมและกาแฟที่ยอดเยี่ยม (หรือ Red Bull, Jolt ฯลฯ )

สวัสดีตอนเช้าสวัสดีตอนเย็นและราตรีสวัสดิ์ !!!

ปรับปรุง 2011-05-27 20:11

กลับมาจากการประชุม MySQL Percona ที่นิวยอร์กในวันพฤหัสบดี เป็นการประชุมอะไร เรียนรู้มากมาย แต่ฉันได้รับคำตอบฉันจะพิจารณาเกี่ยวกับ InnoDB ฉันได้รับแจ้งจากRonald Bradfordว่าการตั้ง innodb_thread_concurrency เป็น 0 จะทำให้ InnoDB เป็นผู้กำหนดแนวทางที่ดีที่สุดในการดำเนินการภายในพร้อมกับการทำงานพร้อมกันของเธรด ฉันจะทดลองเพิ่มเติมใน MySQL 5.5

อัพเดท 2011-06-01 11:20

เท่าที่หนึ่งแบบสอบถามยาวไป InnoDB เป็นกรดที่สอดคล้องและดำเนินงานได้เป็นอย่างดีโดยใช้Multiversion Concurrency ควบคุม ธุรกรรมควรมีระดับการแยก (อ่านซ้ำโดยค่าเริ่มต้น) ที่ป้องกันการบล็อกผู้อื่นจากการเข้าถึงข้อมูล

สำหรับระบบมัลติคอร์นั้น InnoDB นั้นมาไกล ในอดีต InnoDB ไม่สามารถทำงานได้ดีในสภาพแวดล้อมแบบมัลติคอร์ ฉันจำได้ว่าต้องรันหลายอินสแตนซ์ mysql บนเซิร์ฟเวอร์เดียวเพื่อให้ได้หลายคอร์เพื่อแจกจ่ายโพรเซส mysqld หลาย ๆ ตัวในซีพียู นี่ไม่จำเป็นอีกต่อไปขอบคุณ Percona และต่อมา MySQL (eh, Oracle บอกว่ายังคงทำให้ฉันปิดปาก) เนื่องจากพวกเขาได้พัฒนา InnoDB เป็นเครื่องมือเก็บข้อมูลที่เป็นผู้ใหญ่มากขึ้นที่สามารถเข้าถึงแกนด้วยความเรียบง่าย อินสแตนซ์ปัจจุบันของ InnoDB ในวันนี้สามารถทำงานได้ดีในเซิร์ฟเวอร์แกนเดียว


11

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

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

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

หากคุณกำลังใช้ H2 ในโครงการของคุณฉันขอแนะนำให้คุณเรียกใช้ตัวสร้างโปรไฟล์กับโค้ดเบสของคุณภายใต้สถานการณ์การโหลด (เพิ่งเริ่มหัวข้อจำนวน x จำนวนที่กดรหัสของคุณพร้อมกันโดยใช้ usecases ทั่วไป) สิ่งนี้จะให้ตัวชี้วัดที่แท้จริงเกี่ยวกับประสิทธิภาพและคอขวดในโค้ดเบสของคุณแทนที่จะเป็นเพียงการทำให้เป็นทฤษฎี หากสิ่งนี้แสดงให้เห็นว่าคำขอของคุณใช้เวลาเป็นจำนวนมากรอให้เข้าถึงฐานข้อมูลก็ถึงเวลาที่จะย้ายไปยังฐานข้อมูลแบบเธรด


H2 เป็นอนุกรมคำขอทั้งหมด - หรือเพียงแค่ DML?
Jack Douglas

8

จากสิ่งที่ฉันสามารถบอกได้ว่า "single-threaded" เป็นชื่อเรียกผิดของ H2 ประเด็นก็คือว่ามันเป็นอันดับการทำธุรกรรมทั้งหมด (เช่นพวกเขาทีละครั้ง)

คำถามสำคัญเกี่ยวกับว่า "ตกลง" หรือไม่สำหรับการสมัครของคุณไม่ใช่ "ผู้ใช้กี่คน" หรือแม้แต่ "มีกระบวนการกี่กระบวนการ" แต่ "ธุรกรรมของฉันจะใช้เวลานานเท่าใด"

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

--EDIT

ดูเหมือนว่า H2 ไม่ได้ทำธุรกรรมเป็นอันดับจริงๆ - เพียงแค่ DML ในคำอื่น ๆ จำนวนมากการปรับปรุงสั้นภายในธุรกรรมนานเดียวจะไม่ปิดกั้นการปรับปรุงอื่นอย่างไรก็ตามหากคุณไม่ได้ใช้คุณสมบัติ MVCC แบบทดลองการล็อกตารางหมายความว่าสิ่งนี้มีผลในทางปฏิบัติคล้ายกัน นอกจากนี้ยังมีคุณลักษณะ "multi_threaded" ทดลองแต่ไม่สามารถใช้พร้อมกันกับ MVCC


5

การอ้างถึงบิตและส่วนต่าง ๆ จากไซต์ PostgreSQL ... โปรดทราบว่าฉันไม่ทราบถึงข้อดีของข้อโต้แย้งเหล่านี้ - พวกมันไม่เหมาะกับความคิดเห็น

จากคำถามที่พบบ่อยของนักพัฒนา ("ทำไมไม่ใช้เธรด ... "):

http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_here.3E.3F

เธรดไม่ได้ถูกใช้แทนกระบวนการหลายอย่างสำหรับแบ็กเอนด์เนื่องจาก: (... )

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

จากรายการสิ่งที่ต้องทำ ("คุณสมบัติที่เราไม่ต้องการ"):

http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want

แบ็กเอนด์ทั้งหมดทำงานเป็นกระทู้ในกระบวนการเดียว (ไม่ต้องการ)

สิ่งนี้จะกำจัดการป้องกันกระบวนการที่เราได้รับจากการตั้งค่าปัจจุบัน การสร้างเธรดมักจะเป็นค่าใช้จ่ายเช่นเดียวกับการสร้างกระบวนการในระบบที่ทันสมัยดังนั้นจึงดูเหมือนว่าไม่ฉลาดที่จะใช้เธรดแบบบริสุทธิ์และ MySQL และ DB2 ได้แสดงให้เห็นว่า ( ... )

ดังนั้นอีกครั้ง ... ฉันไม่ทราบความจริงเกี่ยวกับข้อดีข้างต้น มันนานเกินไปที่จะแสดงความคิดเห็น


-3

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

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

นี่เป็นคำตอบของคุณหรือไม่?


7
ฐานข้อมูลแบบมัลติเธรดมีประโยชน์แม้ในระบบแกนเดี่ยว จะช่วยป้องกันการแบบสอบถามยาวทำงานเดียวจากการปิดกั้นการเข้าถึงฐานข้อมูลอื่น ๆ ทั้งหมดรวมทั้งคุณอาจมีหลายกระทู้รอในดิสก์หรือเครือข่าย I / O ในขณะที่หัวข้ออื่นเป็นอย่างแข็งขันในการแยกวิเคราะห์แบบสอบถามข้อมูลที่ดึงข้อมูลล่วงหน้าในการประมวลผลอื่น ๆ

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