วิธีกำหนดค่า MongoDB Java driver MongoOptions สำหรับการใช้งานจริง


100

ฉันได้ค้นหาเว็บเพื่อหาแนวทางปฏิบัติที่ดีที่สุดในการกำหนดค่า MongoOptions สำหรับไดรเวอร์ MongoDB Java และฉันไม่ได้คิดอะไรมากไปกว่า API การค้นหานี้เริ่มต้นขึ้นหลังจากที่ฉันพบข้อผิดพลาด "com.mongodb.DBPortPool $ SemaphoresOut: Out of semaphores to get db connection" และด้วยการเพิ่มการเชื่อมต่อ / ตัวคูณฉันก็สามารถแก้ปัญหานั้นได้ ฉันกำลังมองหาลิงก์ไปยังหรือแนวทางปฏิบัติที่ดีที่สุดของคุณในการกำหนดค่าตัวเลือกเหล่านี้สำหรับการใช้งานจริง

ตัวเลือกสำหรับไดรเวอร์ 2.4 ได้แก่ : http://api.mongodb.org/java/2.4/com/mongodb/MongoOptions.html

  • autoConnectRetry
  • การเชื่อมต่อ
  • connectTimeout
  • maxWaitTime
  • socketTimeout
  • threadsAllowedToBlockForConnectionMultiplier

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

คำตอบ:


160

อัปเดตเป็น 2.9:

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

  • connectionsPerHostมีจำนวนของการเชื่อมต่อทางกายภาพเช่น Mongo เดียว (มันเดี่ยวดังนั้นคุณจึงมักจะมีหนึ่งต่อใช้งาน) สามารถสร้างให้เป็น mongod กระบวนการ / mongos ในขณะที่เขียนโปรแกรมควบคุม java จะสร้างจำนวนการเชื่อมต่อในที่สุดแม้ว่าปริมาณการสืบค้นจริงจะต่ำก็ตาม (ตามลำดับคำคุณจะเห็นสถิติ "conn" ใน mongostat เพิ่มขึ้นจนกว่าจะถึงจำนวนนี้ต่อเซิร์ฟเวอร์ของแอป)

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

    db.serverStatus().connections.available

    ในการผลิตเรามีสิ่งนี้ที่ 40

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

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

  • socketTimeout ค่าการหมดเวลาของซ็อกเก็ตมาตรฐาน ตั้งค่าเป็น 60 วินาที (60000)

  • threadsAllowedToBlockForConnectionMultiplier ตัวคูณสำหรับการเชื่อมต่อ PerHost ที่แสดงถึงจำนวนเธรดที่ได้รับอนุญาตให้รอให้การเชื่อมต่อพร้อมใช้งานหากพูลหมดในขณะนี้ นี่คือการตั้งค่าที่จะทำให้เกิดข้อยกเว้น "com.mongodb.DBPortPool $ SemaphoresOut: Out of semaphores to get db connection" มันจะโยนข้อยกเว้นนี้เมื่อคิวเธรดนี้เกินค่า threadsAllowedToBlockForConnectionMultiplier ตัวอย่างเช่นถ้า connectionsPerHost เป็น 10 และค่านี้คือ 5 ถึง 50 เธรดสามารถบล็อกได้ก่อนที่ข้อยกเว้นดังกล่าวจะถูกโยนทิ้ง

    หากคุณคาดว่าจะมีปริมาณงานสูงสุดที่อาจทำให้คิวจำนวนมากเพิ่มค่านี้ชั่วคราว เรามีมันที่ 1500 ในขณะนี้ด้วยเหตุผลนั้น หากการสืบค้นของคุณโหลดแซงหน้าเซิร์ฟเวอร์อย่างสม่ำเสมอคุณควรปรับปรุงสถานการณ์ฮาร์ดแวร์ / การปรับขนาดให้เหมาะสม

  • readPreference (อัปเดต 2.8+)ใช้เพื่อกำหนดการอ่านค่าเริ่มต้นและแทนที่ "slaveOk" ตั้งค่า ReadPreference ผ่านหนึ่งในเมธอดคลาสโรงงาน สามารถดูคำอธิบายทั้งหมดของการตั้งค่าทั่วไปได้ที่ท้ายโพสต์นี้

  • . (อัปเดต 2.6+)ค่านี้กำหนด "ความปลอดภัย" ของการเขียน เมื่อค่านี้เป็น -1 การเขียนจะไม่รายงานข้อผิดพลาดใด ๆ โดยไม่คำนึงถึงข้อผิดพลาดของเครือข่ายหรือฐานข้อมูล WriteConcern.NONE คือ WriteConcern ที่กำหนดไว้ล่วงหน้าที่เหมาะสมสำหรับสิ่งนี้ ถ้า w เป็น 0 ข้อผิดพลาดของเครือข่ายจะทำให้การเขียนล้มเหลว แต่ข้อผิดพลาด mongo จะไม่เกิดขึ้น โดยทั่วไปเรียกว่าการเขียนแบบ "fire and forget" และควรใช้เมื่อประสิทธิภาพสำคัญกว่าความสม่ำเสมอและความทนทาน ใช้ WriteConcern.NORMAL สำหรับโหมดนี้

    หากคุณตั้งค่า w เป็น 1 หรือสูงกว่าการเขียนจะถือว่าปลอดภัย Safe เขียนดำเนินการเขียนและติดตามโดยการร้องขอไปยังเซิร์ฟเวอร์เพื่อให้แน่ใจว่าการเขียนประสบความสำเร็จหรือดึงค่าความผิดพลาดหากไม่ได้ (กล่าวอีกนัยหนึ่งคือส่งคำสั่ง getLastError () หลังจากที่คุณเขียน) โปรดสังเกตว่าจนกว่าคำสั่ง getLastError () นี้จะเสร็จสิ้นการเชื่อมต่อจะถูกสงวนไว้ ด้วยเหตุนี้และคำสั่งเพิ่มเติมปริมาณงานจะต่ำกว่าการเขียนด้วย w <= 0 อย่างมีนัยสำคัญด้วยค่า aw เท่ากับ 1 MongoDB รับประกันว่าการเขียนสำเร็จ (หรือตรวจสอบไม่ได้) บนอินสแตนซ์ที่คุณส่งการเขียนไป

    ในกรณีของชุดการจำลองคุณสามารถใช้ค่าที่สูงขึ้นเพื่อให้ wcih บอก MongoDB ให้ส่งการเขียนไปยังสมาชิก "w" ของชุดการจำลองอย่างน้อยก่อนที่จะส่งคืน (หรือให้ถูกต้องมากกว่านั้นให้รอการจำลองการเขียนของคุณถึงสมาชิก "w" ). คุณยังสามารถตั้งค่า w เป็นสตริง "ส่วนใหญ่" ซึ่งบอกให้ MongoDB ดำเนินการเขียนไปยังสมาชิกชุดการจำลองส่วนใหญ่ (WriteConcern.MAJORITY) Typicall คุณควรตั้งค่านี้เป็น 1 เว้นแต่คุณต้องการประสิทธิภาพดิบ (-1 หรือ 0) หรือการเขียนที่จำลองแบบ (> 1) ค่าที่สูงกว่า 1 มีผลอย่างมากต่อปริมาณงานเขียน

  • fsync ตัวเลือกความทนทานที่บังคับให้ mongo ล้างลงในดิสก์หลังจากการเขียนแต่ละครั้งเมื่อเปิดใช้งาน ฉันไม่เคยมีปัญหาด้านความทนทานใด ๆ ที่เกี่ยวข้องกับการเขียนค้างดังนั้นเราจึงมีสิ่งนี้เป็นเท็จ (ค่าเริ่มต้น) ในการผลิต

  • j * (ใหม่ 2.7+) *. บูลีนที่เมื่อตั้งค่าเป็นจริงบังคับให้ MongoDB รอให้กลุ่มบันทึกการบันทึกสำเร็จก่อนที่จะกลับมา หากคุณเปิดใช้งานการเจอร์นัลคุณสามารถเปิดใช้งานสิ่งนี้เพื่อความทนทานเพิ่มเติม อ้างถึงhttp://www.mongodb.org/display/DOCS/Journalingเพื่อดูว่าการทำเจอร์นัลใดทำให้คุณได้รับ (และสาเหตุที่คุณอาจต้องการเปิดใช้แฟล็กนี้)

ReadPreference คลาส ReadPreference ช่วยให้คุณกำหนดค่าสิ่งที่แบบสอบถามอินสแตนซ์ mongod ถูกกำหนดเส้นทางหากคุณกำลังทำงานกับชุดข้อมูลจำลอง มีตัวเลือกดังต่อไปนี้:

  • ReadPreference.primary () : การอ่านทั้งหมดไปที่สมาชิกหลักที่ตั้งค่าใหม่เท่านั้น ใช้สิ่งนี้หากคุณต้องการให้แบบสอบถามทั้งหมดส่งคืนข้อมูลที่สอดคล้องกัน (ที่เขียนล่าสุด) นี่คือค่าเริ่มต้น

  • ReadPreference.primaryPreferred () : การอ่านทั้งหมดไปที่สมาชิกหลัก repset หากเป็นไปได้ แต่อาจสอบถามสมาชิกรองหากโหนดหลักไม่พร้อมใช้งาน ด้วยเหตุนี้หากการอ่านหลักไม่พร้อมใช้งานในที่สุดการอ่านจะกลายเป็นความสอดคล้องกันในที่สุด แต่ก็ต่อเมื่อส่วนหลักไม่พร้อมใช้งาน

  • ReadPreference.secondary () : การอ่านทั้งหมดไปที่สมาชิก repset รองและสมาชิกหลักใช้สำหรับการเขียนเท่านั้น ใช้สิ่งนี้ต่อเมื่อคุณสามารถใช้ชีวิตด้วยการอ่านที่สอดคล้องกันในที่สุด สมาชิก repset เพิ่มเติมสามารถใช้เพื่อขยายประสิทธิภาพการอ่านแม้ว่าจะมีการ จำกัด จำนวนสมาชิก (การโหวต) ที่ repset สามารถมีได้

  • ReadPreference.secondaryPreferred () : การอ่านทั้งหมดจะไปที่สมาชิก repset รองหากมีอยู่ สมาชิกหลักใช้สำหรับการเขียนโดยเฉพาะเว้นแต่สมาชิกรองทั้งหมดจะไม่พร้อมใช้งาน นอกเหนือจากทางเลือกสำหรับสมาชิกหลักสำหรับการอ่านสิ่งนี้จะเหมือนกับ ReadPreference.secondary ()

  • ReadPreference.nearest () : Reads ไปที่สมาชิก repset ที่ใกล้ที่สุดพร้อมใช้งานสำหรับไคลเอ็นต์ฐานข้อมูล ใช้เฉพาะเมื่อยอมรับการอ่านที่สอดคล้องกันในที่สุด สมาชิกที่ใกล้ที่สุดคือสมาชิกที่มีเวลาแฝงต่ำที่สุดระหว่างไคลเอนต์และสมาชิก repset ต่างๆ เนื่องจากในที่สุดสมาชิกที่ไม่ว่างจะมีเวลาแฝงที่สูงขึ้นสิ่งนี้จึงควรทำให้โหลดการอ่านสมดุลโดยอัตโนมัติแม้ว่าในประสบการณ์รองของฉัน (ที่ต้องการ) ดูเหมือนจะทำได้ดีกว่าหากเวลาแฝงของสมาชิกค่อนข้างสม่ำเสมอ

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


6
การปล่อยให้ socketTimeout และ connectTimeout เป็นค่าเริ่มต้น (infinite) เป็นอันตรายหรือไม่? หากการเชื่อมต่อค้างด้วยเหตุผลบางประการแอปของคุณ (หรืออย่างน้อยเธรดนั้น) จะค้างตลอดไป ไม่ควรตั้งค่าสิ่งเหล่านี้ให้สูงมาก (เช่น 30 วินาทีสำหรับการเชื่อมต่อ 2 นาทีสำหรับซ็อกเก็ต)?
Idris Mokhtarzada

Idris จริงมาก ในโพสต์ของฉันฉันเข้าใจผิดว่า MongoOptions มีค่าเริ่มต้นของเรา เลเยอร์ Mongo ORM ของเรามีสิ่งเหล่านี้ที่ 15 วินาทีและ 1 นาทีตามลำดับและในขณะที่เขียนฉันถือว่าสิ่งเหล่านี้เป็นค่าเริ่มต้น การหมดเวลาที่ไม่มีที่สิ้นสุดเป็นความคิดที่ไม่ดีอย่างแน่นอน ขอบคุณสำหรับข้อมูลเพิ่มเติมฉันแก้ไขในโพสต์
Remon van Vliet

ขณะนี้ตัวเลือก "slaveOk" เลิกใช้งานแล้วหากคุณต้องการให้สิ่งนี้เทียบเท่าจริงให้ทำ: mongoOptions.readPreference = ReadPreference.secondaryPreferred ();
Gubatron

คำตอบที่ดี แต่คำจำกัดความของเธรดของคุณAllowedToBlockForConnectionMultiplierไม่ถูกต้อง (ตัวคูณคำหลัก) ตามเอกสาร: "ตัวคูณสำหรับการเชื่อมต่อ PerHost สำหรับ # ของเธรดที่สามารถบล็อกได้หาก connectionsPerHost เป็น 10 และ threadsAllowedToBlockForConnectionMultiplier คือ 5 จากนั้น 50 เธรดสามารถบล็อกได้มากกว่านั้นและจะมีการโยนข้อยกเว้น"
Tyler Zale

3
ดูเหมือนจะเป็นคำตอบยอดนิยม หากใครสนใจให้ฉันอัปเดตสิ่งนี้เพื่อแสดงการเปลี่ยนแปลงในไดรเวอร์ล่าสุดโปรดแจ้งให้เราทราบ
Remon van Vliet
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.