ล้างแคชของเซิร์ฟเวอร์ SQL และดิสก์ I / O


11

เรากำลังยุ่งกับการทดสอบระบบ OLTP ที่เราพัฒนาขึ้นใน. NET 4.0 และรัน SQL Server 2008 R2 ที่ด้านหลัง ระบบใช้คิวตัวแทนการบริการเซิร์ฟเวอร์ SQL ซึ่งมีประสิทธิภาพมาก แต่เรากำลังประสบกับแนวโน้มที่แปลกประหลาดขณะประมวลผล

การร้องขอการประมวลผลของ SQL Server ที่อัตราการพองตัวเป็นเวลา 1 นาทีตามด้วยกิจกรรมการเขียนดิสก์ที่เพิ่มขึ้น ~ 20 วินาที กราฟต่อไปนี้แสดงให้เห็นถึงปัญหา

ระบบ SQL OLTP - ตัวนับประสิทธิภาพ

Yellow = Transactions per second
Blue   = Total CPU usage
Red    = Sqlsrv Disk Write Bytes/s
Green  = Sqlsrv Disk Read Bytes/s

ในระหว่างการแก้ไขปัญหาเราลองทำสิ่งต่อไปนี้โดยไม่มีการเปลี่ยนแปลงที่สำคัญในรูปแบบ:

  • บริษัท ตัวแทนการเซิร์ฟเวอร์ SQL ที่หยุดทำงาน
  • เสียชีวิตเกือบทุกกระบวนการทำงานอื่น ๆ (ไม่มี A / V, SSMS, VS, Windows Explorer และอื่น ๆ )
  • ลบฐานข้อมูลอื่นทั้งหมด
  • ปิดใช้งานตัวจับเวลาการสนทนาทั้งหมด (เราไม่ใช้ทริกเกอร์ใด ๆ )
  • ย้ายออกไปจากวิธีการที่คิวข้อความขับเคลื่อนไปยังการออกแบบการตรวจสอบตารางที่เรียบง่าย / น้ำมันดิบ
  • ใช้โหลดที่แตกต่างจากแสงถึงหนัก
  • แก้ไขการหยุดชะงักทั้งหมด

ดูเหมือนว่า SQL Server อาจสร้างแคชและเขียนลงดิสก์ตามช่วงเวลาที่กำหนด แต่ฉันไม่พบสิ่งใดทางออนไลน์เพื่อสนับสนุนทฤษฎีนี้

ต่อไปฉันวางแผนที่จะย้ายโซลูชันไปยังสภาพแวดล้อมการทดสอบเฉพาะของเราเพื่อดูว่าฉันสามารถจำลองปัญหาได้หรือไม่ ความช่วยเหลือใด ๆ ในระหว่างกาลจะได้รับการชื่นชมอย่างมาก

อัปเดต 1 ตามที่ร้องขอพร้อมกราฟที่มีCheckpoint Pages / Sec , Page Life Expectancyและตัวนับเวลาแฝงของดิสก์

ระบบ SQL OLTP - ตัวนับประสิทธิภาพ - จุดตรวจสอบ

ดูเหมือนว่าจุดตรวจ (เส้นสีฟ้าอ่อน) เป็นสาเหตุของประสิทธิภาพที่ลดลง (เส้นสีเหลือง) ที่เรากำลังสังเกตอยู่ ^

เวลาในการตอบสนองของดิสก์ค่อนข้างคงที่ในระหว่างการประมวลผลและอายุการใช้งานของหน้ากระดาษดูเหมือนจะไม่มีผลกระทบใด ๆ นอกจากนี้เรายังปรับจำนวน ram สำหรับ SQL Server ซึ่งไม่ได้มีผลกระทบใหญ่ การเปลี่ยนรูปแบบการกู้คืนจากSIMPLEเป็นFULLยังสร้างความแตกต่างเล็กน้อย

อัปเดต 2 โดยการเปลี่ยน "ช่วงเวลาการกู้คืน" ดังนี้เราได้จัดการเพื่อลดช่วงเวลาที่จุดตรวจสอบเกิดขึ้น:

EXEC sp_configure 'show advanced options',1
GO 

RECONFIGURE
GO

EXEC sp_configure 'recovery interval', '30'
GO

RECONFIGURE 
GO

EXEC sp_configure 'show advanced options',0
GO
RECONFIGURE

ฉันไม่แน่ใจว่านี่เป็นการฝึกที่ไม่ดีใช่ไหม?


1
เพิ่มหน้าด่าน / วินาทีตัวนับ และทดสอบอีกครั้งและแสดงกราฟ และในขณะที่ธุรกรรมของคุณลดลงและเขียนขึ้นคุณเห็นปัญหาด้านประสิทธิภาพหรือไม่ ฉันยังเพิ่มตัวนับเวลาในการตอบสนองของดิสก์ - เฉลี่ยต่อวินาที / อ่านและเฉลี่ยต่อวินาที / เขียน
Mike Walsh

และเมื่อคุณโพสต์กราฟถัดไปคุณสามารถรวมตัวเลข กราฟนั้นไม่แสดงสเกลใด ๆ
Mike Walsh

5
และสิ่งสุดท้าย (ขออภัย!) - หน่วยความจำบนเซิร์ฟเวอร์นี้คืออะไร? คุณสามารถเพิ่มตัวนับอายุขัยของหน้าได้หรือไม่? คุณสามารถอธิบายการตั้งค่าทางกายภาพ (หน่วยความจำการตั้งค่า IO คุณแบ่งบันทึกและไฟล์ข้อมูลของคุณ ฯลฯ ) หรือไม่
Mike Walsh

2
โมเดลการกู้คืนใดที่เป็นฐานข้อมูล ดูเหมือนว่าการตรวจสอบอัตโนมัติเมื่อบันทึกธุรกรรมเต็ม โปรดทราบว่าแม้ว่าฐานข้อมูลจะอยู่ในFULLหรือBULK_LOGGEDยังคงทำงานเหมือนอยู่ในฐานข้อมูลSIMPLEจนกว่าคุณจะสำรองข้อมูลเต็มรูปแบบ
Jon Seigel

2
จอน - จุดตรวจจะยังคงเกิดขึ้นโดยไม่คำนึงถึงรูปแบบการกู้คืน แบบง่าย: ความแตกต่างเพียงอย่างเดียวคือสิ่งที่เกิดขึ้นกับข้อมูลในบันทึกหลังจากจุดตรวจสอบในรูปแบบการกู้คืน .. เต็มมันจะอยู่ในบันทึกและจำเป็นต้องสำรอง ง่าย ๆ ก็สามารถถูกตัดทอน (หรือทำเครื่องหมายสำหรับการตัดทอน .. นำมาใช้ใหม่) แต่จุดตรวจยังคงต้องเกิดขึ้น
Mike Walsh

คำตอบ:


11

คนอื่น ๆ ได้ชี้ให้เห็นว่าผู้ร้าย: SQL Server สะสมการปรับปรุงในหน่วยความจำ (ในกลุ่มของบัฟเฟอร์) และจะล้างออกเป็นระยะ ๆ เท่านั้น (ที่จุดตรวจ) ตัวเลือกสองตัวเลือกที่แนะนำ (-k และช่วงเวลาจุดตรวจสอบ) เป็นส่วนเสริม:

แต่ฉันไม่ได้ตอบสนองเพียงเพื่อสำรอกความคิดเห็นที่ดีที่คุณได้รับทำได้ :)

สิ่งที่คุณเห็นคือขออภัยเป็นพฤติกรรมปกติมากของการประมวลผลการจัดคิว ไม่ว่าคุณจะใช้คิวการให้บริการของนายหน้าหรือเลือกใช้ตารางเป็นวิธีการเข้าคิวระบบมีแนวโน้มที่จะเกิดพฤติกรรมเช่นนี้ นี่เป็นเพราะการประมวลผลแบบอิงคิวกำลังเขียนหนักมากยิ่งเขียนหนักกว่าการประมวลผล OLTP ทั้งการenqueueและdequeueเป็นการดำเนินการเขียนและแทบจะไม่มีการอ่าน เพียงแค่ใส่การประมวลผลคิวจะสร้างการเขียนมากที่สุด (= หน้าสกปรกมากที่สุดและบันทึกส่วนใหญ่) เมื่อเทียบกับภาระงานอื่น ๆ แม้กระทั่ง OLTP (เช่น. TPC-Cเช่นปริมาณงาน)

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

  • enqueue เป็นส่วนแทรกมันจะสร้างหน้าสกปรก
  • dequeue เป็นการลบมันจะสกปรกหน้าเดิมอีกครั้ง (มันอาจจะโชคดีและจับหน้าก่อนจุดตรวจดังนั้นมันจะหลีกเลี่ยงการลบสองครั้ง แต่ถ้าโชคดีเท่านั้น)
  • การล้างผีจะล้างหน้าทำให้สกปรกอีกครั้ง

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

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

ผลที่ตามมาบางประการมีดังนี้:

  • จุดตรวจกลายเป็นประเด็นร้อนแรง (ไม่แปลกใจสำหรับคุณอีกต่อไป)
  • คุณจะเห็นการแตกแฟรกเมนต์จำนวนมาก(การแตกแฟรกเมนต์ต่อ se ไม่สำคัญเท่าที่คุณจะไม่ทำการสแกนช่วง แต่ประสิทธิภาพ IO ของคุณทนทุกข์ทรมานและการล้างข้อมูลบนผีมีมากขึ้นทำงานช้าลงมากยิ่งขึ้น)
  • MDF ของคุณที่จัดเก็บแบบสุ่ม IO ปริมาณงานจะเป็นคอขวดของคุณ

คำแนะนำของฉันมี 3 ตัวอักษร: S, S และ D. ย้าย MDF ของคุณไปยังที่เก็บข้อมูลที่สามารถจัดการ IO แบบสุ่มได้อย่างรวดเร็ว SSD Fusion-IOถ้าคุณมีเงิน น่าเสียดายที่นี่เป็นหนึ่งในอาการที่ไม่สามารถแก้ไขได้ด้วย RAM ราคาถูกกว่า ...

แก้ไข:

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


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

รีมัสทำตอบอย่างดีมาก
Mark Storey-Smith

3
เมื่อดูที่เคาน์เตอร์ perfmon ที่ระบุไว้ฉันสงสัยว่าคุณอาจถูกข้อมูลและบันทึกอยู่ในไดรฟ์หรืออาร์เรย์เดียวกัน
Mark Storey-Smith

@ MarkStorey-Smith: ฉันคิดว่าคุณพูดถูก OP มีC:และD:ดิสก์แบบลอจิคัลที่สำรองไว้โดยฟิสิคัลดิสก์เดียวกัน ฉันสงสัยว่าดิสก์ทางกายภาพนั้นเป็นแบตเตอรี่ที่มีแกนสั้นลาย 100 อันดังนั้นนี่น่าจะเป็นต้นเหตุ
Remus Rusanu

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