วิธีการกำหนดจุดที่น่าสนใจระหว่างขนาดพูลและการเชื่อมต่อฐานข้อมูลใน PostgreSQL


14

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

แอปพลิเคชั่นที่เรากำลังทำอยู่นั้นเป็นเกมแบบผู้เล่นหลายคนเทิร์นเบสสำหรับสมาร์ทโฟนโดยแบ็กเอนด์ประกอบด้วยRails ที่มียูนิคอร์นและPostgreSQL 9.1เป็นฐานข้อมูล ขณะนี้เรามีผู้ใช้งานที่ลงทะเบียนแล้ว 600,000 คนและเนื่องจากสถานะเกมถูกเก็บไว้ในฐานข้อมูลหลายพันการเขียนจะทำทุกสองสามวินาที เราได้วิเคราะห์ล็อกไฟล์จากPostgreSQLโดยใช้PgBadgerและในช่วงเวลาวิกฤติที่เราได้รับจำนวนมาก

FATAL: remaining connection slots are reserved for non-replication superuser connections

วิธีการแก้ปัญหาไร้เดียงสาไปที่เคาน์เตอร์ปัญหานี้จะเพิ่มmax_connections (ซึ่งปัจจุบันคือ 100) ใน postgresql.conf ฉันได้อ่านhttp://wiki.postgresql.org/wiki/Number_Of_Database_Connectionsซึ่งแสดงว่านี่อาจไม่ใช่สิ่งที่ถูกต้อง ในบทความดังกล่าวข้างต้นก็เรียกหาจุดหวานระหว่าง max_connections และขนาดสระว่ายน้ำ

สิ่งที่สามารถทำได้เพื่อหาจุดหวานนี้ มีเครื่องมือที่ดีในการวัดประสิทธิภาพ I / O สำหรับค่าต่าง ๆ ของmax_connectionsและขนาดพูลหรือไม่?

การตั้งค่าปัจจุบันของเราคือเซิร์ฟเวอร์เกม 4 ตัวแต่ละตัวมียูนิคอร์น 16 คนและขนาดพูล 5

นี่คือการตั้งค่า postgres-settings ที่ไม่ใช่ค่าเริ่มต้นที่เราใช้:

version                      | PostgreSQL 9.1.5 on x86_64-unknown-linux-gnu,compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit
checkpoint_completion_target | 0.9
checkpoint_segments          | 60
checkpoint_timeout           | 6min
client_encoding              | UTF8
effective_cache_size         | 2GB
lc_collate                   | en_US.UTF-8
lc_ctype                     | en_US.UTF-8
log_destination              | csvlog
log_directory                | pg_log
log_filename                 | postgresql-%Y-%m-%d_%H%M%S.log
log_line_prefix              | %t
log_min_duration_statement   | 200ms
log_rotation_age             | 1d
log_rotation_size            | 10MB
logging_collector            | on
max_connections              | 100
max_stack_depth              | 2MB
server_encoding              | UTF8
shared_buffers               | 1GB
ssl                          | on
TimeZone                     | localtime
wal_buffers                  | 16MB
work_mem                     | 8MB

คุณเป็นคนที่ถามเรื่องนี้ในรายชื่อผู้รับจดหมายในช่วงสองสามสัปดาห์ที่ผ่านมาหรือไม่ ถ้าเป็นเช่นนั้นฉันจะเพิ่มลิงก์ย้อนกลับไปยังการสนทนานั้น ยัง: ฮาร์ดแวร์เซิร์ฟเวอร์ DB และการกำหนดค่าของคุณคืออะไร? wiki.postgresql.org/wiki/Slow_Query_Questions รวมถึงการตั้งค่าที่ไม่ใช่ค่าเริ่มต้น: wiki.postgresql.org/wiki/Server_Configuration คุณอ่านwiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server แล้วหรือยัง ชุดคุณทำงานเป็นธุรกรรมขนาดใหญ่ที่เป็นไปได้? คุณใช้เลเยอร์แคชและหากเป็นเช่นนั้นจะเกิดอะไรขึ้น คุณใช้synchronous_commit = offหรือcommit_delayไม่?
Craig Ringer

ดังนั้นคุณมีการเชื่อมต่อกับเซิร์ฟเวอร์ PostgreSQL ทั้งหมด 20 รายการใช่หรือไม่ 5 ต่อเซิร์ฟเวอร์เกม? ด้วย 5 conns จากเซิร์ฟเวอร์เกมแต่ละตัวจะถูกแชร์กับคนงานยูนิคอร์นทั้ง 16 คน?
Craig Ringer

โอ้คุณบันทึกการสืบค้นช้าหรือไม่ ถ้าเป็นเช่นนั้นฮอตสปอตของคุณคืออะไร? ง่ายINSERTๆ สคีมาของคุณเป็นอย่างไร - แบ่งพาร์ติชันหรือไม่ อะไรคือexplain analyzeการค้นหาตัวอย่างบางอย่าง? จุดตรวจของคุณบ่อยแค่ไหนและใช้เวลานานเท่าไหร่? (ดูตัวเลือกการบันทึกจุดตรวจ) และจริงจังรุ่น PostgreSQL ของคุณคืออะไร (อัปเดต: ดูเหมือนว่าคุณจะแสดงฮาร์ดแวร์ของคุณที่นี่: dba.stackexchange.com/questions/28061/ … )
Craig Ringer

อย่างไรก็ตามสำหรับการปรับขนาดสระโดยเฉพาะคำตอบที่แท้จริงคือการตั้งค่าการวัดปริมาณงานและปริมาณงานของเซิร์ฟเวอร์ DB ที่มีประสิทธิภาพจากนั้นเริ่มปรับขึ้นและลงจนกว่าคุณจะพบจุดที่น่าสนใจ
Craig Ringer

@CraigRinger ไม่ฉันไม่ใช่คนนั้น แต่ขอบคุณสำหรับลิงก์ย้อนกลับ! ฉันได้อ่านปรับเซิร์ฟเวอร์ PostgreSQL ของคุณแล้วและปฏิบัติตามคำแนะนำที่กล่าวมา ตอนนี้ฉันได้รวมการตั้งค่าที่ไม่ใช่ค่าเริ่มต้นแล้ว ตอนนี้เรากำลังมองหาการทำธุรกรรมและการทดสอบที่มากขึ้นsynchronous_commit = off
lorgartzor

คำตอบ:


14

คำตอบสั้น ๆ ที่นี่คือ "การทดลองและข้อผิดพลาดที่ชี้นำโดยการตรวจสอบและการวัดประสิทธิภาพ"

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

สิ่งที่คุณต้องทำคือรับเมตริกประสิทธิภาพที่แข็งแกร่งสำหรับแอปพลิเคชันของคุณ เริ่มบันทึกสถิติ

มีวิธีการรวมเครื่องมือไม่มากในเรื่องนี้ มีหลายอย่างเช่นcheck_postgresสคริปต์nagios , การบันทึกตัวนับประสิทธิภาพของระบบ Cacti, ตัวรวบรวมสถิติ PostgreSQL ฯลฯ ... แต่มีไม่มากที่รวมเข้าด้วยกัน น่าเศร้าที่คุณจะต้องทำสิ่งนั้นเอง สำหรับด้าน PostgreSQL ดูการตรวจสอบในคู่มือ PostgreSQL ตัวเลือกของบุคคลที่สามบางคนอยู่เหมือนEnterpriseDB Postgres ขององค์กรตรวจสอบ

สำหรับตัวชี้วัดระดับแอปพลิเคชันที่กล่าวถึงที่นี่คุณจะต้องบันทึกไว้ในโครงสร้างข้อมูลที่ใช้ร่วมกันหรือในฐานข้อมูลภายนอกที่ไม่คงทนเช่น Redis และรวมเข้าด้วยกันในขณะที่คุณบันทึกหรือก่อนที่จะเขียนลงใน PostgreSQL DB การพยายามลงชื่อเข้าใช้โดยตรงกับ Pg จะทำให้การวัดของคุณบิดเบือนด้วยค่าใช้จ่ายที่สร้างขึ้นโดยการบันทึกการวัดและทำให้ปัญหาแย่ลง

ตัวเลือกที่ง่ายที่สุดน่าจะเป็นซิงเกิลตันในแต่ละแอพเซิร์ฟเวอร์ที่คุณใช้บันทึกสถิติแอปพลิเคชัน คุณอาจต้องการปรับปรุง min, max, n, total และ mean อย่างต่อเนื่อง ด้วยวิธีนี้คุณไม่จำเป็นต้องจัดเก็บจุดสแตติกแต่ละจุดเพียงแค่ผลรวม ซิงเกิลนี้สามารถเขียนสถิติรวมถึง Pg ทุก ๆ x นาทีซึ่งเป็นอัตราที่ต่ำพอที่ผลกระทบต่อประสิทธิภาพจะน้อยที่สุด

เริ่มกับ:

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

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

  • ปริมาณงานของคุณเป็นอย่างไร ใน x นาทีใด ๆ แบบสอบถามของแอปพลิเคชันของคุณที่เรียกใช้บริการจากฐานข้อมูลจำนวนเท่าใด

  • สำหรับช่วงเวลาเดียวกันของ x นาทีมีคำขอของไคลเอ็นต์กี่รายการ

  • สุ่มตัวอย่างทุกสองสามวินาทีและรวมกันบนหน้าต่าง x นาทีเดียวกันในฐานข้อมูลมีการเชื่อมต่อฐานข้อมูลกี่อัน มีกี่คนที่ไม่ได้ใช้งาน มีการใช้งานกี่คน ในส่วนแทรก? อัพเดท? เลือก? ลบ? มีการทำธุรกรรมกี่ครั้งในช่วงเวลานั้น? ดูเอกสารประกอบของตัวรวบรวมสถิติ

  • การสุ่มตัวอย่างและการรวมอีกครั้งในช่วงเวลาเดียวกันการวัดประสิทธิภาพของระบบโฮสต์เป็นอย่างไร มีการอ่านและเขียนดิสก์กี่ IOs / วินาที เมกะไบต์ต่อวินาทีของการอ่านและเขียนดิสก์? การใช้ CPU หรือไม่ โหลดเฉลี่ยหรือไม่ แรมใช้หรือไม่

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

คุณอาจเรียนรู้ว่าระบบของคุณเปิดใช้งานคอขวดINSERTและUPDATEมีอัตราการทำธุรกรรมสูงถึงแม้ว่า I / O ของดิสก์จะค่อนข้างต่ำในหน่วยเมกะไบต์ต่อวินาที นี่จะเป็นคำใบ้ที่คุณต้องปรับปรุงประสิทธิภาพการล้างดิสก์ด้วยคอนโทรลเลอร์ RAID เขียนสำรองหลังแบตเตอรี่หรือ SSD ที่ป้องกันไฟคุณภาพสูง นอกจากนี้คุณยังสามารถใช้synchronous_commit = offหากตกลงเพื่อทำธุรกรรมบางอย่างเกี่ยวกับเซิร์ฟเวอร์ล่มและ / หรือ a commit_delayเพื่อทำการโหลดการซิงค์บางส่วน

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

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

ดูpg_test_fsyncเครื่องมือที่จะช่วยคุณพิจารณาว่าอาจเป็นปัญหาสำหรับคุณหรือไม่ แพ็คเกจ PostgreSQL ส่วนใหญ่ติดตั้งเครื่องมือนี้เป็นส่วนหนึ่งของ contrib ดังนั้นคุณไม่จำเป็นต้องรวบรวมมัน หากคุณได้รับน้อยกว่าสองสามพัน ops / วินาทีในpg_test_fsyncคุณจำเป็นเร่งด่วนในการอัพเกรดระบบจัดเก็บข้อมูลของคุณ แล็ปท็อปที่ติดตั้ง SSD ของฉันได้รับ 5,000-7,000 เวิร์กสเตชันของฉันทำงานกับอาร์เรย์ RAID 10 ดิสก์ 4 แผ่นของดิสก์ SATA 7200rpm และการเขียนผ่าน (ไม่มีการแคชการเขียน) ได้รับประมาณ 80 ops / วินาทีในf_datasyncลดลงถึง 20 ops / วินาทีสำหรับfsync(); มันเป็นหลายร้อยครั้งช้า เปรียบเทียบ: แล็ปท็อปที่มี ssdเทียบกับเวิร์กสเตชันที่มีการเขียนข้อมูล (ไม่ใช่การแคช) RAID 10. SSD ของแล็ปท็อปราคาถูกและฉันไม่จำเป็นต้องเชื่อถือมันเพื่อล้างแคชการเขียนในการสูญเสียพลังงาน ฉันทำการสำรองข้อมูลที่ดีและจะไม่ใช้ข้อมูลที่ฉันสนใจ SSD คุณภาพดีทำงานได้ดีหากไม่ดีขึ้นและทนทานต่อการเขียน

ในกรณีที่ใบสมัครของคุณฉันขอแนะนำให้คุณดู:

  • ระบบย่อยหน่วยเก็บข้อมูลที่ดีพร้อมฟลัชเร็ว ฉันไม่สามารถความเครียดนี้พอ SSD คุณภาพดีที่ใช้พลังงานไม่ได้ปลอดภัยและ / หรือตัวควบคุม RAID พร้อมแคชป้องกันการเขียนกลับ
  • ใช้UNLOGGEDตารางสำหรับข้อมูลที่คุณสามารถจะสูญเสีย รวมเป็นระยะ ๆ ลงในตารางที่บันทึก ตัวอย่างเช่นเก็บเกมที่กำลังดำเนินการในตารางที่ไม่ถูกบล็อกและเขียนคะแนนลงในตารางความทนทานปกติ
  • การใช้commit_delay(มีประโยชน์น้อยกว่ากับที่เก็บข้อมูลแบบฟลัช - คำแนะนำ)
  • การปิดsynchronous_commitการทำธุรกรรมที่คุณสามารถเสียได้ (มีประโยชน์น้อยลงด้วยการจัดเก็บข้อมูลที่รวดเร็ว - คำใบ้คำแนะนำ)
  • การแบ่งพาร์ติชันตารางโดยเฉพาะตารางที่ข้อมูล "มีอายุการใช้งานนาน" และถูกล้างข้อมูล แทนที่จะลบจากตารางที่แบ่งพาร์ติชันให้วางพาร์ติชัน
  • ดัชนีบางส่วน
  • การลดจำนวนดัชนีที่คุณสร้าง ทุกดัชนีมีต้นทุนการเขียน
  • การแบตช์ทำงานเป็นธุรกรรมที่ใหญ่กว่า
  • การใช้แบบจำลองการสแตนด์บายแบบอ่านอย่างเดียวเพื่อถอดโหลดฐานข้อมูลออก
  • การใช้เลเยอร์แคชเช่น memcached หรือ Redis สำหรับข้อมูลที่เปลี่ยนแปลงน้อยลงหรือสามารถค้างได้ คุณสามารถใช้LISTENและNOTIFYทำการตรวจสอบแคชโดยใช้ทริกเกอร์ในตาราง PostgreSQL

หากมีข้อสงสัย: http://www.postgresql.org/support/professional_support/

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