php 如何實現 數據庫 連接池


php 如何實現 數據庫 連接池

一、總結

一句話總結:

php+sqlrelay+mysql實現連接池及讀寫負載均衡
master-slave模式增加並發。
sqlrelay 解決連接池問題以及實現讀寫分離的均衡負載。

為了有效的解決並發訪問的瓶頸,利用多台數據庫master-slave的模式來增加web的並發訪問量

sqlrelay配置3個instance A/B/C,A負責從Master和slave讀取數據,B負責寫數據,且只寫Master,C為router負責調度應用。php通過A還是通過B連接 數據庫。在實際配置中,由於master承擔了讀寫操作,那么在instance A的配置中,可以把從Master的連接稍微降小,把從slave連接讀取數據的連接數稍稍增大以此進行平衡。

 

 

1、php能做數據庫連接池么?

php腳本不能:php 腳本本身的確是不能做連接池的,因為php腳本在解釋執行完畢后會釋放所有內存資源,當然其中用到的數據庫連接也會被釋放
php中間件可以:但一些中間件也是可以做為連接 池的,只要提供php的相關驅動,所以可以自己做php的連接池,但是絕對作不了100% pure php的連接池。
比如mysql_pconnect:mysql_pconnect是php內建的一個模擬連接池,但這套機制不是用php腳本實現的。 但是一次請求可以復用鏈接,減少new帶來的消耗。

 

2、數據庫連接池節約時間的原因是什么?

數據庫連接池的作用主要是節省打開數據庫的時間

 

3、數據庫連接池原理是什么?

緩存數據庫連接

數據庫連接池機制預先打開N個數據庫連接,把它們緩存起來,當需要使用數據庫的時候就直接使用這些已經打開的連接,從而節省了時間。連接池的存在基本上消除了數據庫連接斷開的時間與cpu開銷。

 

4、php數據庫連接池解決方案有哪些?

1、pconnect(持久連接):pconnect的原理,和連接池差不多的,都是程序關閉連接,但PHP並不真正關閉,再次打開時,直接使用可用的連接。如果因為訪問量太大出現Mysql應該配置 Mysql 數據庫服務的my.cnf 里的 max_connection 的值,如max_connections = 2000。
2、mysql proxy。
3、memcache:針對mysql的一個數據庫緩存實現。
4、SQL Relay:一個開源的數據庫池連接代理服務器。支持Oracle、MySQL、mSQL、PostgreSQL、Sybase、MS SQL Server、IBM DB2、Sybase、SQLite、Lago、 ODBC、MS Access等。

 

 

 

二、PHP連接池詳解

轉自:PHP連接池詳解-php教程-PHP中文網
http://www.php.cn/php-weizijiaocheng-390224.html

 

php 腳本本身的確是不能做連接池的,因為php腳本在解釋執行完畢后會釋放所有內存資源,當然其中用到的數據庫連接也會被釋放,但一些中間件也是可以做為連接 池的,只要提供php的相關驅動,所以可以自己做php的連接池,但是絕對作不了100% pure php的連接池。mysql_pconnect是php內建的一個模擬連接池,但這套機制不是用php腳本實現的。 但是一次請求可以復用鏈接,減少new帶來的消耗。

  1. 1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    <?php 

         class ConnecToDB 

         {   

             private static $instance=array(); 

             //防止外部創建新的數據庫連接類 

             private function _constuct(){} 

             static public function Connect() 

             {     

                 //連接類不夠100,創建新類 

                 if(count(self::$instance)<100) 

                 

                     $newDb=new self(); 

                     self::$instance[]=$newDb

                     return $newDb::ConDB(); 

                 

                 else 

                 {     

                     //隨機數保證數據庫連接均衡 

                     $i=rand(0,99); 

                     $new_obj=self::$instance[$i]; 

                     return $new_obj::ConDB(); 

                 

             

             static private function ConDB() 

             

                 try 

                 

                     $connec=mysql_connect("127.0.0.1","數據庫賬戶","數據庫密碼"); 

                     mysql_select_db("數據庫名");//選擇數據庫   

         

                 

                 catch(Exception $e

                 

                     $errors[]=$e->getMessage(); 

                   }

    }

連接池的作用主要是節省打開數據庫的時間。連接池機制預先打開N個數據庫連接,把它們緩存起來,當需要使用數據庫的時候就直接使用這些已經打開的連接,從而節省了時間。連接池的存在基本上消除了數據庫連接斷開的時間與cpu開銷。 
連接池解決方案:
1、pconnect(持久連接):pconnect的原理,和連接池差不多的,都是程序關閉連接,但PHP並不真正關閉,再次打開時,直接使用可用的連接。
如果因為訪問量太大出現Mysql應該配置 Mysql 數據庫服務的my.cnf 里的 max_connection 的值,如max_connections = 2000。
2、mysql proxy。
3、memcache:針對mysql的一個數據庫緩存實現。
4、SQL Relay:一個開源的數據庫池連接代理服務器。支持Oracle、MySQL、mSQL、PostgreSQL、Sybase、MS SQL Server、IBM DB2、Sybase、SQLite、Lago、 ODBC、MS Access等。
安裝與配置[SQL SERVER](http://blog.sina.com.cn/s/blog_4dd475390100hbck.html),安裝SQL Relay需要先安裝Rudiments:
1、安裝Rudiments:
# tar vxzf rudiments-0.28.2.tar.gz
# cd rudiments-0.28.2
# ./configure --prefix=/usr/local/rudiments
# make
# make install
2、安裝SQL Relay:
# tar vxzf sqlrelay-0.36.4.tar.gz
# cd sqlrelay-0.36.4
# ./configure --prefix=/usr/local/sqlrelay --with-rudiments-prefix=/usr/local/rudiments --with-mysql-prefix=MySQL安裝路徑 --with-freetds-prefix=FreeTDS安裝路徑 --with-oracle-home=Oracle安裝路徑 --with-php-prefix=PHP安裝路徑
# make
# make install
3、 設置PHP:修改 php.ini中extension_dir = "./",把以上內容修改為:extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20050922"。
根據PHP安裝的路徑來修改,並不是每個版本的PHP都是這個路徑,在php.ini中添加如下內容extension=sql_relay.so。
4、修改SQL Relay的配置文件
# cd /usr/local/sqlrelay/etc
# cp sqlrelay.conf.example sqlrelay.conf
把sqlrelay.conf的內容改為:

1

2

3

4

5

6

7

8

9

10

11

12

<?xml version="1.0"?>

<!DOCTYPE instances SYSTEM "sqlrelay.dtd">

<instances>

<instance id="msdetest" port="9000" socket="/tmp/msdetest.socket" dbase="freetds" connections="5" maxconnections="10" maxqueuelength="0" growby="1" ttl="60" endofsession="commit" sessiontimeout="5" runasuser="nobody" runasgroup="nobody" cursors="5" authtier="listener" handoff="pass">

<users>

<user user="sa" password="sa"/>

</users>

<connections>

<connection connectionid="msdetest" string="server=msde;db=pubs;user=sa;password=sa;" metric="1"/>

</connections>

</instance>

</instances>

啟動SQL Relay,並測試;
1、啟動 SQL Relay
# export PATH=$PATH:/usr/local/sqlrelay/bin
# sqlr-start -id msdetest
2、使用SQL工具:
# sqlrsh -id msdetest
可以直接輸入SQL語句停止SQL Relay:# sqlr-stop msdetest
3、測試PHP,寫一個PHP文 件,內容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<?

$con=sqlrcon_alloc("msdetest",9000,"/tmp/msdetest.socket","sa","sa",0,1);

$cur=sqlrcur_alloc($con);

sqlrcur_sendQuery($cur,"select * from t_gifts");

for ($row=0; $row<sqlrcur_rowCount($cur); $row++) {

for ($col=0; $col<sqlrcur_colCount($cur); $col++) {

echo sqlrcur_getField($cur,$row,$col);

echo ",";

}

echo "<br>\n";

}

sqlrcur_free($cur);

sqlrcon_free($con);

?>


php+sqlrelay+mysql實現連接池及讀寫負載均衡:
為了有效的解決並發訪問的瓶頸,利用多台數據庫master-slave的模式來增加web的並發訪問量。master-slave模式是為了數據同步的問題。
sqlrelay 解決連接池問題以及實現讀寫分離的均衡負載。sqlrelay配置3個instance A/B/C,A負責從Master和slave讀取數據,B負責寫數據,且只寫Master,C為router負責調度應用。php通過A還是通過B連接 數據庫。在實際配置中,由於master承擔了讀寫操作,那么在instance A的配置中,可以把從Master的連接稍微降小,把從slave連接讀取數據的連接數稍稍增大以此進行平衡。
配置與應用(http://blog.163.com/lgh_2002/blog/static/4401752620107393057989/):

一、MySQL master/slave配置
################
#mster/slave配置
################
master:192.168.1.51
slave:192.168.1.50
1、master配置
/etc/my.cnf 中加入
binlog-do-db=book book為數據庫名確保
server-id=1
log-bin=mysql-bin
授權給rep用戶進行復制操作
GRANT REPLICATION SLAVE ON book.* TO rep@192.168.1.50 IDENTIFIED BY '123456';
重啟master服務
2、配置slave
vi /etc/my.cnf
設置下面4行
server-id = 2
master-host = 192.168.1.51
master-user = rep
master-password = 123456
重啟slave
3、把master的原始數據導入slave。


二、sqlrelay配置
當前行業中比較流行的連接池解決方案幾乎都不支持php,經過多番努力終於在找到了一個開源的連接池技術--------sqlrelay。
sqlreplay支持的語言:C C++ Perl Python PHP Ruby Java TCL Zope。
sqlreplay支持的數據庫:Oracle MySQL mSQL PostgreSQL Sybase MS SQL Server IBM DB2 Interbase Sybase SQLite ODBC MS Access
基本思路:
1、配置2個實例用以最終處理業務
clubs-read
clubi-write
其中讀取的 instance分別配置兩個連接,且兩個連接啟動對等的連接數。
2、配置一個instance來調度讀寫操作,即clubr
通過router來區分讀寫連接不同的mysql數據庫。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<?xml version="1.0"?>

<!DOCTYPE instances SYSTEM "sqlrelay.dtd">

<instances>

<!-- club Instance -->

<instance id="clubs" port="9002" socket="/tmp/clubs.socket" dbase="mysql" connections="10" maxconnections="20" maxqueuelength="5" growby="1" ttl="60" endofsession="commit" sessiontimeout="600" runasuser="nobody" runasgroup="nobody" cursors="5" authtier="listener" handoff="pass" deniedips="" allowedips="" debug="none" maxquerysize="65536" maxstringbindvaluelength="4000" maxlobbindvaluelength="71680" idleclienttimeout="-1" maxlisteners="-1" listenertimeout="0">

<users>

<user user="club" password="edb:club"/>

</users>

<connections>

<connection connectionid="master51" string="host=192.168.1.51;port=3306;db=book;user=club;password=club;" metric="1" behindloadbalancer="no"/>

<connection connectionid="slave50" string="host=192.168.1.50;port=3306;db=book;user=club;password=club;" metric="1" behindloadbalancer="no"/>

</connections>

</instance>

<instance id="clubi" port="9003" socket="/tmp/clubi.socket" dbase="mysql" connections="10" maxconnections="40" maxqueuelength="5" growby="1" ttl="60" endofsession="commit" sessiontimeout="600" runasuser="nobody" runasgroup="nobody" cursors="5" authtier="listener" handoff="pass" deniedips="" allowedips="" debug="none" maxquerysize="65536" maxstringbindvaluelength="4000" maxlobbindvaluelength="71680" idleclienttimeout="-1" maxlisteners="-1" listenertimeout="0">

<users>

<user user="club" password="edb:club"/>

</users>

<connections>

<connection connectionid="master51" string="host=192.168.1.51;port=3306;db=book;user=club;password=club;" metric="1" behindloadbalancer="no"/>

</connections>

</instance>

php.ini文件在系統中的優先級:PhpIniDir、注冊表鍵值、環境變量%PHPRC%、PHP5的根目錄(For CLI),或者WWW的根目錄(For SAPI moudles)、Windows目錄(C:\windows)。
PHP5特征:加入了面向對象機制、對於XML的復雜處理、異常處理機制。
PHP6特征:
支持Unicode:雖然Unicode占用較多的空間,但Unicode帶來的便利性,遠超過占用空間的缺點。PHP也可以在.ini文件中設定是否開啟支持Unicode。
命名空間:命名空間是一種避免因函數或者類之間的命名沖突,而使你的函數和類以及方法無法讀取,而不使用前綴命名慣例的一種方法。
PHP6.0令人激動的Web 2.0特性。
SOAP: 簡單對象訪問協議 (SOAP:Simple Object Access Protocol)SOAP 可以和現存的許多因特網協議和格式結合使用,包括:HTTP、SMTP、MIME、RPC。
XML: 從PHP 5.1版本開始,XMLReader和XMLWriter就已經包含在PHP內核,它可以讓它可以讓XML編程更加輕松。
Register Globals 將被移除:它雖滿方便的,但是卻忽略會帶來程序上安全性的隱患,PHP4.3.x版開始時,此項默認設置值即是關閉狀態,PHP6后PHP3將完全無法使用。
Magic Quotes 將消失:Magic Quotes主要是自動轉義需要轉義的字符,此項功能移除葉符合大多數PHP開發者的心聲。
Safe Mode 取消。
’var’ 別名為 ‘public’:在類中的var聲明變成public的別名,相信是為了兼容PHP5而作的決定,PHP6現在也可以稱作為OO語言了。
通過引用返回將出錯:現在透過引用返回編譯器將會報錯 例如$a =& new b()、function &c(),OO語言默認就是引用,所以不需要再使用&了。 
zend.ze1 compatbility mode 將被移去 Zend.ze1相容模式將被移去PHP5是為兼容舊有PHP4,所以在.ini中可選擇是否開啟相容模式。
Freetype 1 and GD 1 support 將不見這兩個是很久的Libs,所以不再支持,GD1早已被現在的GD2取代了。
dl() 被移到 SAPI 中dl()主要是讓設計師加載extension Libs,現在被移到 SAPI 中。
Register Long Array 去除從PHP5起默認是關閉,再PHP6中正式移除。
Extension的變更:如XMLReader、XMLWriter將不再是以Extension的方式出現,他們將被移入到PHP的核心之中默認是開啟。
ereg extension將被放入PECL,代表着它將被移出PHP核心,這也是為了讓路給新的正則表達式extension,此外,Fileinfo extension 也將被導入PHP的核心之中。
APC將被導入核心:這是一個提高PHP性能的功能,現在它將被放入PHP核心中,並且可以選擇是否啟用APC。
告別ASP風格的起始標簽:原來是為了取悅ASP開發者轉向使用PHP,現今已經不再需要這種做法了。
PHP6.0除了增加新特性,一些會給系統帶來不穩定因素和安全隱患的特性也將被取消,取消列表:magic_quotes、register_globals、register_long_arrays、safe_mode、magic_quotes。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM