เราควรเมานท์กับ 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.