한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

คู่มือเกมแลค › L12 ฐานข้อมูล

connection pool หมด Connection pool exhaustion

ID สาเหตุ db-pool · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟรา DB (ทีมอินฟรา)

เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →

จำนวนการเชื่อมต่อที่เปิดไว้กับ DB มีจำกัด ถ้าคิวรีที่ช้าถือครองการเชื่อมต่อไว้ คำขอที่เหลือต้องรอ

ทำไม ทุกการเชื่อมต่อถูกใช้หมดเพราะคิวรีช้าหรือคำขอทะลัก → ผลคือ คำขอใหม่ต้องรอจนกว่าจะมีการเชื่อมต่อว่าง → บนหน้าจอ ล็อกอินโหลดไม่จบ, เซฟช้า, ไทม์เอาต์

อาการ
เข้าเกมไม่ได้/โหลดไม่จบ, อินพุตดีเลย์
ปัจจัย
การหยุดชะงัก, ความหน่วง
ใครเจอ
ทั้งเซิร์ฟเวอร์, เฉพาะบางฟีเจอร์
เกิดเมื่อไร
หลังล็อกอิน/หลังปิดปรับปรุง, ตอนคนแห่มารวมกัน
ผู้รับผิดชอบ
ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟรา DB (ทีมอินฟรา)
งานฝั่งทีมพัฒนาเกม
กำจัดคิวรีที่ช้า, ปรับขนาด pool และไทม์เอาต์การรอ (อย่าขยาย pool ไปเรื่อย ๆ), แยก pool ตามฟีเจอร์
งานฝั่งทีมอินฟรา
ตรวจจำนวนการเชื่อมต่อสูงสุดของ DB และ CPU กับ IOPS ที่เหลือ, ก่อนเพิ่มเครื่องหรือทำ autoscaling ให้ตรวจว่าจำนวนเซิร์ฟเวอร์ × ขนาด pool ไม่เกินจำนวนการเชื่อมต่อสูงสุด, เพิ่มเมตริกการรอ connection และการรอล็อกเข้าในการมอนิเตอร์
ตัวเลขที่ควรรู้
จำนวนการเชื่อมต่อที่ต้องใช้ประมาณได้จาก “คำขอต่อวินาที × เวลาที่คำขอหนึ่งถือครองการเชื่อมต่อ” ถ้า 2,000 รายการใน 1 วินาที รายการละ 5 ms จะมีการเชื่อมต่อที่ยุ่งตลอดเฉลี่ย 10 ตัว เพื่อเผื่อช่วงที่คำขอแห่เข้ามา ปกติจะตั้งไว้สองสามเท่าของค่านั้น ถ้าคิวรีช้าลงเป็น 150 ms คำขอปริมาณเท่าเดิมจะต้องใช้ 300 ตัว
บนกราฟ
ชนเพดานแล้วแบนราบ · จำนวนการเชื่อมต่อ DB ที่ใช้อยู่, เวลารอ connection
จุดที่ต้องดู
นับสถานะการเชื่อมต่อแยกตามเซิร์ฟเวอร์เกมจากฝั่ง DB MySQL ดู Host, Command (การเชื่อมต่อที่ว่างคือ Sleep) และ Time ใน SHOW PROCESSLIST กับ Threads_connected, Threads_running และจำนวนการเชื่อมต่อที่ถูกปฏิเสธ Connection_errors_max_connections ส่วน PostgreSQL นับ pg_stat_activity โดยจัดกลุ่มตาม client_addr และ state ถ้าไลบรารี connection pool ของเซิร์ฟเวอร์เกมส่งออกจำนวนที่รอและเวลารอ ให้ดูคู่กันด้วย
สัญญาณว่าใช่
การเชื่อมต่อของเซิร์ฟเวอร์เกมตัวหนึ่งกำลังรันคิวรีครบเท่าขนาด pool และการเชื่อมต่อว่างเป็น 0 ระหว่างนั้นล็อกอินและเซฟต้องรอ หรือจำนวนการเชื่อมต่อทั้งหมดของ DB แตะ max_connections จนการเชื่อมต่อใหม่ถูกปฏิเสธ
สัญญาณว่าไม่ใช่
มีการเชื่อมต่อว่างเหลือพอแต่ยังช้า: น่าจะเป็นดีเลย์ของตัวคิวรีเอง (db-no-index, db-hot-row) หรือทรัพยากร DB อิ่มตัว
วิธีตรวจ
ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
รายละเอียดเพิ่มเติม
ถ้าขยาย pool ไปเรื่อย ๆ จะมีแต่ CPU ของ DB และการแย่งล็อกที่เพิ่มขึ้น จนทุกอย่างช้าลงพร้อมกัน และถ้าจำนวนเซิร์ฟเวอร์ × ขนาด pool เกินจำนวนการเชื่อมต่อสูงสุดของ DB เซิร์ฟเวอร์ที่เพิ่มเข้ามาหรือเพิ่งรีสตาร์ตจะเชื่อมต่อไม่ได้เลย มักเกิดตอน autoscaling หรือทันทีหลังปิดปรับปรุง

แหล่งอ้างอิง

  1. Number Of Database Connections PostgreSQL
    เมื่อทรัพยากร DB ถูกใช้เต็มแล้ว การเพิ่มการเชื่อมต่อกลับทำให้ throughput ลดลง, จำกัดการเชื่อมต่อที่ทำงานอยู่ให้พอดีกับทรัพยากรแล้วให้ที่เหลือรอในคิว ได้ผลดีกว่าทั้งด้านดีเลย์และ throughput
  2. Too many connections MySQL
    เมื่อใช้ max_connections ครบแล้ว การเชื่อมต่อใหม่จะถูกปฏิเสธด้วยข้อผิดพลาด Too many connections
  3. Connections and Authentication (PostgreSQL Documentation) PostgreSQL
    max_connections: เพดานจำนวนการเชื่อมต่อพร้อมกัน ค่าเริ่มต้นมักเป็น 100
  4. SHOW PROCESSLIST Statement MySQL
    Host (ที่อยู่ไคลเอนต์), Command (เซสชันที่ว่างคือ Sleep), Time, State
  5. Server Status Variables MySQL
    Threads_connected และ Threads_running, Connection_errors_max_connections (จำนวนการเชื่อมต่อที่ถูกปฏิเสธเพราะแตะ max_connections)
  6. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    pg_stat_activity: client_addr และ state (active, idle, idle in transaction ฯลฯ) ของแต่ละการเชื่อมต่อ

สาเหตุที่ควรดูประกอบ

ชั้นเดียวกัน: L12 ฐานข้อมูล

สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (เข้าเกมไม่ได้/โหลดไม่จบ)

ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง