PHP -> การเชื่อมต่อแบบต่อเนื่องของ Mysql ยังไม่มี mysql_pconnect - เป็นไปได้ไหม


12

ฉันพยายามหาวิธีที่ดีในการทำสิ่งนี้มาระยะหนึ่งแล้ว แต่มีเวลายากที่จะหาชิ้นส่วนที่เหมาะสมในการทำเช่นนี้ ฉันเดาว่าสิ่งนี้จะต้องเป็นไปได้

หากต้องการกล่าวอย่างง่าย ๆ นี่คือสิ่งที่ฉันต้องการจะทำให้สำเร็จ:

PHP / Other front end -> [SOCKET] ->

Locally hosted 'pooler' -> [Pool of persistent TCP/IP connection(s)]->

Externally hosted MySQLD

มีเครื่องมือ / วิธีการทำสิ่งต่าง ๆ อยู่หรือไม่?

เราต้องการใช้การเชื่อมต่อ mysql แบบคงที่โดยไม่ต้องใช้ mysql_pconnect

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

ดังนั้นใช่เพื่อสรุป ... เราจะใช้ poolq การเชื่อมต่อ mysql ที่ซ็อกเก็ตตามปลายท้องถิ่นและยังคงเชื่อมต่อที่ทำกับ (mysql) เซิร์ฟเวอร์ mysql โฮสต์ภายนอก

เราไม่ใช้ธุรกรรมหรือสิ่งอื่นใดที่จะได้รับผลกระทบจากการเชื่อมต่อ mysql ที่ถูกรีไซเคิล

เรากำลังเรียกใช้ linux ที่ส่วนหน้าด้วยคลัสเตอร์ master + master percona 5.5

ขอบคุณ!

คำตอบ:


12

หลังจากค้นหามากในที่สุดฉันก็พบทางออก

ฉันไม่ได้เป็นนักเขียนมากนักดังนั้นฉันจะพยายามทำให้ดีที่สุดเพื่อให้กระชับที่สุด

เท่าที่ฉันจะหาได้มีวิธีแก้ปัญหา 2 ข้อ:

รีเลย์ SQL

http://sqlrelay.sourceforge.net/

นี่เป็นคำถามที่ถามมาและอีกมากมาย ฉันจะไม่ลงรายละเอียดมากเกินไปในสิ่งที่ฉันสามารถค้นหาเกี่ยวกับเรื่องนี้ แต่จะพูดถึงว่ามันไม่ใช่วิธีแก้ปัญหาที่ทำงานได้เพราะมันไม่โปร่งใส ความหมายที่ไหลเป็นดังนี้:

PHP -> Queries -> SQL Relay Extension -> SQL Relay -> Externally hosted MySQL

ดังนั้นสิ่งนี้จะเกี่ยวข้องกับการเขียนโค้ดทั้งหมดของเราใหม่จาก mysql ถึง sql relay ไม่ใช่ตัวเลือกในกรณีของเรา

ทั้งหมดที่ถูกกล่าวว่าถ้ามีคนมีการวางแผนสดโครงการขนาดใหญ่ที่ต้องใช้ใด ๆ ของคุณสมบัติมากมายที่ SQL Relay มีมันเสียงที่สวยงาม

proxy Mysql

http://forge.mysql.com/wiki/MySQL_Proxy

นี่คือทางออกที่เราใช้

กุญแจสำคัญในการทำสิ่งนี้สิ่งที่เราต้องการให้ทำคือการรวมสคริปต์ LUA สำหรับพรอกซี mysql

ส่วนขยาย LUA นี้สามารถดูได้ที่:

https://github.com/cwarden/mysql-proxy/blob/315ab806bb95b8223f5afd3d238eff2a40af03d8/lib/ro-pooling.lua

นี่คือสถิติพื้นฐานบางอย่าง ... โปรดจำไว้ว่านี่คือการทดสอบที่เวลาใช้งานต่ำ:

[root@HOSTNAME etc]# netstat -na | grep ":3306 " | grep TIME_WAIT | wc
   6433   38598  572537

หลังจากเปลี่ยนมาใช้ mysql-proxy และให้สิ่งต่าง ๆ สงบลง:

[root@HOSTNAME etc]# netstat -na | grep ":3306 " | grep TIME_WAIT | wc
     32     192    2848

อย่างที่คุณเห็นได้ชัดเจนว่าพอร์ต TIME_WAIT ไปยัง mysql ได้ลดลงไปเกือบไม่มีเลย

ขณะนี้การเชื่อมต่อยังคงอยู่โดยไม่ใช้ mysql_pconnect / mysqli_connect (... p: hostname ... )

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

ท้องถิ่น min_idle_connections

และ

max_idle_connections ท้องถิ่น

สิ่งเหล่านี้ดูเหมือนจะอธิบายได้ด้วยตนเอง ยกเว้นว่า: มันจะปรากฏว่าชุดค่าผสมชื่อผู้ใช้แต่ละคน (และรหัสผ่าน? ยังไม่ได้ทดสอบ ... ส่วนใหญ่ไม่ใช่สรรพสิ่ง) สร้างชุดการเชื่อมต่อแบบถาวรของตัวเอง

max_idle_connections ดังนั้นคูณด้วยจำนวนผู้ใช้ mysql ที่ไม่ซ้ำใครที่จะเชื่อมต่อกับฐานข้อมูล และนั่นควรให้ความคิดเกี่ยวกับจำนวนการเชื่อมต่อที่ไม่ใช้งานที่คุณจะได้รับ

ดังนั้นฉันขอย้ำอีกครั้งเพื่อให้สิ่งเล็ก ๆ น้อย ๆ นี้กระทบกับคำหลักบางคำสำหรับผู้ที่ค้นหาผ่าน google:

เมื่อใช้ PHP เป็นไปได้หรือไม่ที่จะมีการเชื่อมต่อ mysql แบบต่อเนื่องโดยไม่ต้อง mysql_pconnect?

ใช่สิ่งนี้สามารถทำได้ผ่าน SQL Relay หากคุณไม่ต้องการสร้างรหัสส่วนใหญ่ของคุณอีกครั้งเพื่อส่งคำสั่งของคุณผ่านส่วนขยายหรือโปร่งใสโดยใช้ mysql-proxy พร้อมกับสคริปต์ ro-pooling.lua

เราต้องการสิ่งนี้มาประมาณหนึ่งปีแล้ว

สนุก!


ทำไมไม่เพียงแค่ใช้ฟังก์ชั่นการทำความสะอาด (ตามที่ระบุไว้โดยคำตอบด้านล่าง) ให้บริการโดยฟังก์ชั่นถาวร mysqli ของ ? หากคุณไม่สามารถเข้าถึง mysqli ทำไมไม่ใช้mysql_pconnectและเริ่มการเชื่อมต่อแต่ละครั้งด้วย "ฟังก์ชั่นการล้างข้อมูล" บ้าง
Pacerier

4
  1. การสนับสนุนการเชื่อมต่อแบบต่อเนื่องถูกนำมาใช้ใน PHP 5.3 สำหรับmysqliส่วนขยาย มีการสนับสนุนอยู่ใน PDO MYSQL และ ext / mysql แนวคิดเบื้องหลังการเชื่อมต่อแบบถาวรคือการเชื่อมต่อระหว่างกระบวนการไคลเอนต์และฐานข้อมูลสามารถนำกลับมาใช้โดยกระบวนการไคลเอนต์แทนที่จะถูกสร้างและทำลายหลายครั้ง สิ่งนี้จะลดค่าใช้จ่ายในการสร้างการเชื่อมต่อใหม่ทุกครั้งที่ต้องการเนื่องจากการเชื่อมต่อที่ไม่ได้ใช้จะถูกแคชและพร้อมที่จะนำกลับมาใช้ใหม่

  2. แตกต่างจากส่วนขยาย mysql mysqliไม่ได้มีฟังก์ชั่นแยกต่างหากสำหรับการเปิดการเชื่อมต่อแบบถาวร ในการเปิดการเชื่อมต่อแบบถาวรคุณต้องใส่ p: ไปยังชื่อโฮสต์เมื่อทำการเชื่อมต่อ

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

การเชื่อมต่อแบบต่อเนื่องของส่วนขยาย mysqli ให้รหัสการจัดการการล้างข้อมูลในตัว การทำความสะอาดดำเนินการโดย mysqli รวมถึง:

Rollback active transactions

Close and drop temporary tables

Unlock tables

Reset session variables

Close prepared statements (always happens with PHP)

Close handler

Release locks acquired with `GET_LOCK()`

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

ส่วนขยาย mysqli mysql_change_user()ไม่ล้างข้อมูลนี้โดยการเรียกฟังก์ชัน

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

เป็นไปได้ที่จะปิดรหัสการทำความสะอาดอัตโนมัติโดยรวบรวม PHP MYSQLI_NO_CHANGE_USER_ON_PCONNECTตามที่กำหนดไว้

บันทึก:

นามสกุล mysqli รองรับการเชื่อมต่อแบบต่อเนื่องเมื่อใช้ MySQL Native Driver หรือ MySQL Client Library

นอกจากนี้คุณสามารถอ้างอิงลิงค์เหล่านี้: http://www.mysqlperformanceblog.com/2006/11/12/are-php-persistent-connections-evil/

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