เราควรเมานท์กับ data = writeback และ barrier = 0 ใน ext3 หรือไม่?


13

เราได้ใช้งานเซิร์ฟเวอร์บน VM ที่ บริษัท โฮสติ้งและเพิ่งลงทะเบียนสำหรับโฮสต์เฉพาะ (AMD Opteron 3250, 4 คอร์, 8GB RAM, 2 x 1TB ในซอฟต์แวร์ RAID, ext3)

ในขณะที่ใช้การทดสอบประสิทธิภาพเราสังเกตว่าการเปลี่ยนแปลงของ SQLite บางอย่าง (การรวมกันของการแทรกการลบและ / หรือการปรับปรุง) นั้นใช้เวลานานกว่า 10x ถึง 15 เท่าใน MacBook Pro ของฉัน

หลังจาก googling และการอ่านมากมายเราต้องดูที่ตัวเลือกการติดตั้งซึ่งก็คือ:

    data=ordered,barrier=1

เราได้ทำการทดลองและได้รับประสิทธิภาพที่ดีที่สุดแล้ว

    data=writeback,barrier=0

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

คำถาม

การกำหนดค่าข้างต้นมีเหตุผลที่จะต้องพิจารณาสำหรับบริการโฮสต์หรือไม่

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

มีตัวเลือกอื่น ๆ ที่เราควรพิจารณาหรือไม่?

ขอบคุณ


มีหลายปัจจัยที่เกี่ยวข้อง คุณคาดหวังว่าจะเกิดปัญหาฮาร์ดไดรฟ์จำนวนมากหรือไม่ คุณมี UPS (หรือสิ่งที่เทียบเท่า) เชื่อมต่อกับเครื่องโฮสต์ของคุณหรือไม่ คุณเคยทำการเปรียบเทียบกับระบบไฟล์อื่น (เช่น ext4, XFS เป็นต้น) บ้างไหม? คุณสามารถควบคุม (() เปิดใช้งาน) แคช HDD ได้หรือไม่ คุณกำหนดค่าซอฟต์แวร์ RAID ของคุณอย่างไร คุณจัดแนว HDD ให้ถูกต้อง (ถ้ามีบล็อก 4K)?
— Huygens

เราไม่คาดหวังว่าจะเกิดปัญหาฮาร์ดไดรฟ์จำนวนมาก เราไม่มี UPS ข้อมูลจำเพาะของเครื่องเป็นมาตรฐาน "ปิดชั้นวาง" จาก บริษัท โฮสติ้งดังนั้น: เราไม่ได้มาตรฐาน fs อื่น ๆ ext3 คือสิ่งที่เราได้รับ ไม่ทราบเกี่ยวกับแคช HDD จะตรวจสอบและจัดแนว RAID และ HDD ในทำนองเดียวกัน ขอบคุณ
— NeilB

อีกคำถามที่ฉันลืมไปว่าคุณมีค่าพอที่จะเสียประวัติศาสตร์ไปได้มากแค่ไหน? หรือคุณไม่สามารถสูญเสียใด ๆ หมายเหตุ: SQLite รองรับสแน็ปช็อตหรือกล่าวอีกนัยหนึ่งคือสำรองข้อมูลฐานข้อมูลที่รันอยู่ sqlite.org/backup.html
— Huygens

เคอร์เนลรุ่นของคุณคืออะไร? ปัญหาและอุปสรรคที่ได้รับเกียรติจาก md ตั้งแต่ 2.6.33 ไม่ได้อยู่ในเคอร์เนลรุ่นก่อนหน้า
— Huygens

uname -r รายงาน "2.6.32-220.2.1.el6.x86_64" "md" คืออะไร หากปัญหาและอุปสรรคที่ไม่ได้รับการยอมรับในเคอร์เนลรุ่นนี้เหตุใดฉันจึงเห็นการปรับปรุงประสิทธิภาพเมื่อปิดอุปสรรค
— NeilB

คำตอบ:


15

คำแนะนำแรก
หากคุณไม่สามารถสูญเสียข้อมูลใด ๆ (ฉันหมายถึงเมื่อผู้ใช้ป้อนข้อมูลใหม่หากไม่สามารถสูญหายได้ในไม่กี่วินาทีข้างหน้า) และเนื่องจากคุณไม่มีสิ่งใดเช่น UPS ดังนั้นฉันจะไม่ลบอุปสรรคการเขียน ฉันจะไม่เปลี่ยนไปเขียนกลับ

การลบการกีดกันการเขียน
หากคุณลบการเขียนอุปสรรคจากนั้นในกรณีที่เกิดความผิดพลาดหรือการสูญเสียพลังงานระบบไฟล์จะต้องทำ fsck เพื่อซ่อมแซมโครงสร้างของดิสก์ (โปรดทราบว่าแม้จะมีสิ่งกีดขวางเปิดอยู่ แม้ว่าการเล่นซ้ำของวารสารควรจะเพียงพอ) เมื่อลบสิ่งกีดขวางการเขียนขอแนะนำให้ลบดิสก์แคช (ที่ฮาร์ดแวร์) หากเป็นไปได้ซึ่งจะช่วยลดความเสี่ยงให้น้อยที่สุด คุณควรเปรียบเทียบผลกระทบของการเปลี่ยนแปลงดังกล่าว คุณสามารถลองคำสั่งนี้ hdparm -W0 /dev/<your HDD>(ถ้าฮาร์ดแวร์ของคุณสนับสนุน)
โปรดทราบว่า ext3 ใช้ 2 อุปสรรคเกี่ยวกับการเปลี่ยนแปลงข้อมูลเมตาในขณะที่การใช้ ext4 journal_async_commitเพียงหนึ่งเมื่อใช้ตัวเลือกติด

แม้ว่าTed T'so อธิบายว่าทำไมความเสียหายของข้อมูลบางอย่างที่เกิดขึ้นในช่วงแรก ๆ ของ ext3 (สิ่งกีดขวางถูกปิดโดยปริยายจนกระทั่งเคอร์เนล 3.1 ) วารสารถูกวางไว้ในลักษณะที่ว่าเว้นแต่จะมีการห่อหุ้มบันทึกประจำวัน ข้อมูลจะถูกเขียนไปยังดิสก์ในลำดับที่ปลอดภัย - เจอร์นัลแรกข้อมูลที่สอง - แม้จะมีฮาร์ดดิสก์ที่สนับสนุนการเรียงลำดับของการเขียนใหม่
โดยทั่วไปจะโชคไม่ดีที่ระบบขัดข้องหรือการสูญเสียพลังงานเกิดขึ้นเมื่อบันทึกประจำวันถูกล้อมรอบ data=orderedแต่คุณจำเป็นต้องให้ ลองเกณฑ์มาตรฐานด้วยdata=ordered,barrier=0นอกเหนือจาก

หากคุณสามารถสูญเสียข้อมูลไปสองสามวินาทีคุณสามารถเปิดใช้งานตัวเลือกทั้งสองdata=writeback,barrier=0แต่ลองทดสอบด้วยcommit=<nrsec>พารามิเตอร์เช่นกัน ตรวจสอบคู่มือสำหรับพารามิเตอร์นี้ที่นี่ โดยทั่วไปคุณให้จำนวนวินาทีซึ่งเป็นระยะเวลาที่ระบบไฟล์ ext3 จะซิงค์ข้อมูลและข้อมูลเมตาของมัน
คุณสามารถลองเล่นซอและทำเบนช์มาร์กด้วยเคอร์เนล tunables บางอันเกี่ยวกับเพจสกปรก (ที่ต้องเขียนลงดิสก์) มีบทความที่ดีที่จะอธิบายทุกอย่างเกี่ยวกับ tunables เหล่านี้และวิธีเล่นกับพวกเขา

สรุปเกี่ยวกับอุปสรรค
คุณควรเปรียบเทียบชุดค่าผสมที่ปรับได้อีกสองสาม:

  1. ใช้data=writeback,barrier=0ร่วมกับhdparm -W0 /dev/<your HDD>
  2. ใช้ data=ordered,barrier=0
  3. ใช้data=writeback,barrier=0ร่วมกับตัวเลือกการเมาท์อื่นcommit=<nrsec>และลองใช้ค่าที่แตกต่างกันสำหรับ nrsec
  4. ใช้ตัวเลือก 3 และลองปรับเพิ่มเติมในระดับเคอร์เนลเกี่ยวกับหน้าสกปรก
  5. ใช้ safe data=ordered,barrier=1แต่ลอง tunables อื่น ๆ : โดยเฉพาะอย่างยิ่งลิฟท์ระบบไฟล์ (CFQ, Deadline หรือ Noop) และการปรับค่าได้ของ respecitve

เมื่อพิจารณาถึงการย้ายไปยัง ext4 และการเปรียบเทียบมัน
ตามที่กล่าวไว้ว่า ext4 ต้องการกำแพงกั้นน้อยกว่า ext3 สำหรับการเขียน นอกจากนี้ ext4 ยังรองรับ extents ซึ่งสำหรับไฟล์ขนาดใหญ่อาจทำให้ประสิทธิภาพดีขึ้น ดังนั้นจึงเป็นทางออกที่ควรค่าแก่การสำรวจโดยเฉพาะอย่างยิ่งเนื่องจากง่ายต่อการโยกย้ายจาก ext3 ไปยัง ext4 โดยไม่ต้องติดตั้งใหม่: เอกสารทางการ ; ฉันทำอย่างนั้นในระบบเดียว แต่ใช้คู่มือ Debianนี้ Ext4 นั้นเสถียรจริงๆตั้งแต่เคอร์เนล 2.6.32 ดังนั้นจึงปลอดภัยที่จะใช้ในการผลิต

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


ขอบคุณ - มีสิ่งที่มีประโยชน์มากมาย ฉันได้อ่าน ext3 doc ที่ kernel.org แล้วและลองเปลี่ยนคอมมิชชัน แต่ก็ไม่เข้าใจว่าอะไรมีค่ามาก ตั้งค่าเป็น 15 มากกว่า 5 วินาทีที่ฉันไม่เห็นการเปลี่ยนแปลง ฉันจะทำการเปรียบเทียบเพิ่มเติมเพื่อครอบคลุมวิธีเรียงสับเปลี่ยนที่คุณแนะนำ ขอบคุณอีกครั้ง.
— NeilB

นั่นเป็นความคิดที่ดีที่จะลองเพิ่มเวลาการส่งมอบพร้อมกับรักษาค่าเริ่มต้นที่ปลอดภัย เป็นไปได้ว่า SQLite เป็นหนึ่งเดียวในการล้าง / ซิงค์ซึ่งอาจเป็นคำอธิบายว่าทำไมคุณไม่ได้วัดประสิทธิภาพการเปลี่ยนแปลงใด ๆ โดยใช้ตัวเลือกกระทำ
— Huygens

@ NeilB เพียงสะดุดกับบทความเหล่านี้: 1. sqlite.org/draft/lockingv3.htmlมองหาext3มัน มันอาจจะง่ายกว่าที่จะเข้าใจ (หรือง่าย) คำอธิบายของสิ่งที่ฉันพยายามที่จะตอบในคำตอบของฉัน 2. sqlite.1065341.n5.nabble.com/คุณสามารถลองใช้ค่าเริ่มต้นที่ปลอดภัย ext3 (สั่ง + สิ่งกีดขวาง +) แต่ลบการซิงค์ใน SQLite ฉันจะอัปเดตคำตอบของฉันเกี่ยวกับด้านที่สองนี้ในไม่ช้า
— Huygens

ขอบคุณสำหรับสิ่งเหล่านั้น ฉันกำลังจะจัดการกับพีชคณิตทั้งหมดและเรียกใช้การทดสอบประสิทธิภาพกับพวกเขาในทางกลับกัน ก่อนหน้านี้ฉันลองซิงค์ใน SQLite และได้ตัวเลขประสิทธิภาพที่ดี ฉันต้องเขียนโค้ดบางอย่างเพื่อรวบรวมช่วงข้อมูลสำหรับชุดการเขียนที่แตกต่างกันก่อน ฉันจะโพสต์ข้อมูลสรุปที่นี่ แต่ถ้าคุณต้องการรายละเอียดเพิ่มเติมฉันจะอยู่ที่ bowers dot com
— NeilB

10

Caveat: อาจมีความไม่ถูกต้องด้านล่าง ฉันได้เรียนรู้เกี่ยวกับสิ่งนี้มากมายเมื่อฉันไปพร้อมกับเกลือ นี่ค่อนข้างนาน แต่คุณสามารถอ่านพารามิเตอร์ที่เราเล่นด้วยจากนั้นข้ามไปที่บทสรุปในตอนท้าย

มีหลายเลเยอร์ที่คุณสามารถกังวลเกี่ยวกับประสิทธิภาพการเขียนของ SQLite:

ระดับที่แตกต่างกันสำหรับการคิดเกี่ยวกับประสิทธิภาพ

เราดูสิ่งที่ถูกเน้นเป็นตัวหนา พารามิเตอร์เฉพาะคือ

  • แคชเขียนดิสก์ ดิสก์ที่ทันสมัยมีแคช RAM ซึ่งใช้ในการเพิ่มประสิทธิภาพการเขียนดิสก์ตามดิสก์หมุน ด้วยการเปิดใช้งานนี้ข้อมูลสามารถเขียนในบล็อกที่ไม่เรียบร้อยดังนั้นหากเกิดความผิดพลาดคุณสามารถจบลงด้วยไฟล์ที่เขียนบางส่วน ตรวจสอบการตั้งค่าด้วย hdparm -W / dev / ... และตั้งค่าด้วย hdparm -W1 / dev / ... (เพื่อเปิดใช้งานและ -W0 เพื่อปิด)
  • อุปสรรค = (0 | 1) ความคิดเห็นออนไลน์จำนวนมากพูดว่า "ถ้าคุณทำงานด้วย barrier = 0 ดังนั้นอย่าเปิดใช้งานแคชการเขียนดิสก์" คุณสามารถค้นหาการอภิปรายเกี่ยวกับอุปสรรคได้ที่http://lwn.net/Articles/283161/
  • data = (เจอร์นัล | ​​สั่ง | writeback) ดูhttp://www.linuxtopia.org/HowToGuides/ext3JournalingFilesystem.htmlเพื่อดูคำอธิบายของตัวเลือกเหล่านี้
  • กระทำ = N บอก ext3 เพื่อซิงค์ข้อมูลและข้อมูลเมตาทุก N วินาที (ค่าเริ่มต้น 5)
  • SQLite pragma synchronous = ON | ปิด เมื่อเปิด SQLite จะตรวจสอบให้แน่ใจว่าการทำธุรกรรมเป็น "เขียนไปยังดิสก์" ก่อนดำเนินการต่อ การปิดการตั้งค่านี้ทำให้การตั้งค่าอื่น ๆ ไม่เกี่ยวข้องเป็นอย่างมาก
  • SQLite pragma cache_size ควบคุมจำนวนหน่วยความจำ SQLite ที่จะใช้สำหรับแคชในหน่วยความจำ ฉันลองสองขนาด: หนึ่งที่ฐานข้อมูลทั้งหมดจะพอดีกับแคชและที่หนึ่งซึ่งแคชนั้นมีขนาดครึ่งหนึ่งของขนาด DB สูงสุด

อ่านข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือก ext3 ในเอกสาร ext3

ฉันรันการทดสอบประสิทธิภาพกับชุดค่าผสมหลายตัวของพารามิเตอร์เหล่านี้ ID คือหมายเลขสถานการณ์อ้างอิงตามด้านล่าง

สถานการณ์ที่ฉันพยายาม

ฉันเริ่มต้นด้วยการรันด้วยการกำหนดค่าเริ่มต้นบนเครื่องของฉันเป็นสถานการณ์ที่ 1 สถานการณ์ที่ 2 คือสิ่งที่ฉันคิดว่าเป็น "ปลอดภัยที่สุด" จากนั้นลองใช้ชุดค่าผสมต่าง ๆ ตามความเหมาะสม / ได้รับข้อความ นี่อาจจะง่ายที่สุดในการทำความเข้าใจกับแผนที่ที่ฉันใช้:

แม็พสถานการณ์ที่เกี่ยวข้องกับพารามิเตอร์

ฉันเขียนสคริปต์ทดสอบที่ทำธุรกรรมจำนวนมากโดยมีการแทรกการอัปเดตและการลบทั้งหมดอยู่ในตารางที่มีทั้ง INTEGER เท่านั้น, TEXT เท่านั้น (พร้อมคอลัมน์ id) หรือผสม ฉันใช้จำนวนครั้งนี้ในการกำหนดค่าแต่ละอย่างด้านบน:

พล็อตแสดงการกำหนดเวลาสำหรับสถานการณ์

สถานการณ์สองสถานการณ์ด้านล่างคือ # 6 และ # 17 ซึ่งมี "pragma synchronous = off" ดังนั้นไม่น่าแปลกใจเลยที่พวกเขาจะเร็วที่สุด คลัสเตอร์ถัดไปของสามคือ # 7, # 11 และ # 19 สามสิ่งนี้ถูกเน้นด้วยสีน้ำเงินบน "แผนที่การกำหนดค่า" ด้านบน โดยพื้นฐานแล้วการกำหนดค่าคือแคชการเขียนดิสก์, barrier = 0 และชุดข้อมูลเป็นสิ่งอื่นที่ไม่ใช่ 'journal' การเปลี่ยนการมอบหมายระหว่าง 5 วินาที (# 7) และ 60 วินาที (# 11) ดูเหมือนจะสร้างความแตกต่างเล็กน้อย ในการทดสอบเหล่านี้ดูเหมือนจะไม่มากถ้าความแตกต่างระหว่าง data = สั่งและ data = writeback ซึ่งทำให้ฉันประหลาดใจ

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

ฉันมีการทดสอบเวลาอื่นซึ่งทำให้เม็ดมีดที่แตกต่างกันมากขึ้นอัปเดตและลบในการผสมประเภทต่างๆ สิ่งเหล่านี้ใช้เวลานานกว่ามากซึ่งเป็นสาเหตุที่ฉันไม่ได้รวมไว้ในแผนด้านบน:

ประเภทผสมและแทรก / อัพเดต / ลบ

ที่นี่คุณจะเห็นว่าการกำหนดค่าการเขียนกลับ (# 19) ช้ากว่าการสั่งซื้อ (# 7 และ # 11) เล็กน้อย ฉันคาดว่าการเขียนกลับจะเร็วขึ้นเล็กน้อย แต่อาจขึ้นอยู่กับรูปแบบการเขียนของคุณหรือบางทีฉันอาจจะยังไม่อ่าน ext3 มากพอ :-)

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

ข้อสรุป

  • กระทำพารามิเตอร์ดูเหมือนจะสร้างความแตกต่างเล็ก ๆ น้อย ๆ เพื่อให้เรากำลังจะออกจากที่ที่ 5s
  • เรากำลังจะมีการเขียนดิสก์แคชบนอุปสรรค = 0และข้อมูล = สั่งซื้อ ฉันอ่านบางสิ่งออนไลน์ที่คิดว่านี่เป็นการตั้งค่าที่ไม่ดีและอื่น ๆ ที่ดูเหมือนว่าจะคิดว่านี่เป็นค่าเริ่มต้นในหลาย ๆ สถานการณ์ ฉันเดาว่าสิ่งที่สำคัญที่สุดคือคุณต้องตัดสินใจอย่างชาญฉลาดโดยรู้ว่าการแลกเปลี่ยนใดที่คุณกำลังทำอยู่
  • เราจะไม่ใช้ pragma แบบซิงโครนัสใน SQLite
  • การตั้งค่า SQLite cache_size pragma ดังนั้นฐานข้อมูลจะพอดีกับหน่วยความจำที่ปรับปรุงประสิทธิภาพการทำงานบางอย่างตามที่เราคาดไว้
  • การกำหนดค่าข้างต้นหมายความว่าเรามีความเสี่ยงเพิ่มขึ้นเล็กน้อย เราจะใช้SQLite backup APIเพื่อลดอันตรายจากความล้มเหลวของดิสก์ในการเขียนบางส่วน: ถ่ายภาพทุกๆ N นาทีและเก็บ M สุดท้ายไว้ ฉันทดสอบ API นี้ขณะใช้การทดสอบประสิทธิภาพและทำให้เรามั่นใจในการใช้วิธีนี้
  • หากเรายังต้องการมากกว่านี้เราสามารถดูการล้อเลียนด้วยเคอร์เนล แต่เราปรับปรุงสิ่งต่าง ๆ ให้ดีพอโดยไม่ต้องไปที่นั่น

ขอบคุณ @Huygens สำหรับเคล็ดลับและคำแนะนำต่างๆ

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