全文索引Sphinx+binlog日誌+Grant用戶受權+讀寫分離和主從複製

.全文索引Sphinx

1.什麼是Sphinx

Sphinx是由俄羅斯人Andrew Aksyonoff開發的一個全文檢索引擎。它是基於C語言開發出來的.中文翻譯爲斯芬克司斯芬克司.php

Sphinx最好的應用操做系統是Linuxhtml

2.Sphinx的優點

Sphinx是一個基於SQL的全文檢索引擎,能夠結合MySQL,PostgreSQL作全文搜索,它能夠提供比數據庫自己更專業的搜索功能,使得應用程序更容易實現專業化的全文檢索。Sphinx特別爲一些腳本語言設計搜索API接口,如PHP,Python,Perl,Ruby等,同時爲MySQL也設計了一個存儲引擎插件。mysql

Sphinx 單一索引最大可包含1億條記錄,在1千萬條記錄狀況下的查詢速度爲0.x秒(毫秒級)。Sphinx建立索引的速度爲:建立100萬條記錄的索引只需 3~4分鐘,建立1000萬條記錄的索引能夠在50分鐘內完成,而只包含最新10萬條記錄的增量索引,重建一次只需幾十秒。linux

3.Sphinx的主要特性

高速索引 (在新款CPU上,近10 MB/秒);c++

高速搜索 (2-4G的文本量中平均查詢速度不到0.1秒);面試

高可用性 (單CPU上最大可支持100 GB的文本,100M文檔);算法

提供良好的相關性排名sql

支持分佈式搜索;數據庫

提供文檔摘要生成;apache

提供從MySQL內部的插件式存儲引擎上搜索

支持布爾,短語, 和近義詞查詢;

支持每一個文檔多個全文檢索域(默認最大32個);

支持每一個文檔多屬性;

支持斷詞;

支持單字節編碼與UTF-8編碼;

4.Sphinx必須的編譯工具gcc

因爲安裝sphinx必需要使用到gcc等編譯工具,所以不管你是否已經有安裝,爲了保證準確性,都應該執行如下安裝

yum -y install make gcc g++ gcc-c++ libtool autoconf automake imake mysql-devel libxml2-devel expat-devel

Sphinx分詞技術:是一種C語言的算法技術.

好比說: 海南三亞國際大酒店

海南 海南三亞 海南酒店 海南國際

三亞 三亞國際 三亞酒店

國際 國際酒店 大酒店 國際酒

大酒店

算法比咱們人工拆分的能力更強,速度更快,搜索更精準

5.安裝Sphinx的源碼包的步驟

1步:Sphinx源碼包的說明

 

 

2步:Sphinx的源碼安裝包規定上傳到/usr/local/src

這個目錄在Linux操做系統是專門用於放置第3方軟件包或者腳本的,因此若是Sphinx不在該目錄下,那麼你編譯就會失敗,使用ftp工具進行上傳.

 

 

3步:把install_sphinx.sh修改成777的權限

 

 

4步:執行安裝的腳本文件./install_sphinx.sh

 

 

在安裝過程當中出現警告信息咱們所有均可以忽略,若是出現error就只能從新恢復快照進行編譯了.回車就會進行編譯執行,出現如下界面表明sphinx安裝成功:

 

 

6.Sphinx的重要文件

sphinx的配置文件路徑

/usr/local/sphinx/etc/sphinx.conf

sphinx的客戶端命令工具

/usr/local/sphinx/bin

sphinx的示例數據庫腳本

/usr/local/sphinx/etc/example.sql

7.導入Sphinx的測試示例庫到test數據庫中

語法命令: mysql -u登陸名 -p登陸密碼 test < /usr/local/sphinx/etc/example.sql

這時使用命令把sphinx的sphinx的示例數據庫腳本進行導入,執行命令以下:

mysql -uroot -p123456 test < /usr/local/sphinx/etc/example.sql

效果以下:

導入完成,在test數據能夠下documents表以下圖所示

 

 

使用select * from documents獲取如下數據,發現這些測試數據所有是英文:

 

 

因此咱們須要額外加上一些中文的測試數據在裏面,方便咱們學習和測試,中文的數據建議插入以下這幾條:

 

 

執行結果以下:

 

 

 

8.配置Sphinx的數據源

sphinx的配置文件路徑

/usr/local/sphinx/etc/sphinx.conf

使用vim打開配置文件

 

 

內容以下所示:

 

 

 

理解以上的幾項以後,咱們就能夠對test數據庫的documents表進行數據源的配置了,修改內容以下:

 

 

保存並退出(:x),sphinx若是沒有連接php以前不須要作任何重啓工做

 

9.Sphinx的生成索引工具./indexer

sphinx的客戶端命令工具在該目錄下:/usr/local/sphinx/bin

而生成索引工具indexer是屬於sphinx的客戶端命令工具

語法規則以下:./indexer [--all][--rotate]

--all 選項:

這個選項用於生成數據源中全部數據索引,這個選項是必須填寫的選項

--rotate選項:

這個選項用於生成鏈接php的增量索引api,若是sphinx和php進行綁定操做,那麼咱們就須要使用這個選項,若是sphinx只是單獨操做,咱們不須要使用該選項

注意:這個工具必須在/usr/local/sphinx/bin目錄下執行,不然這個工具是無法成功創建全文索引的

 

使用sphinx的./indexer工具生成test數據庫下的documents表中的全部數據的全文索引,執行的命令代碼以下,注意目錄必定要/usr/local/sphinx/bin下完成:

命令:./indexer --all

因爲咱們配置的sphinx數據源自己就是test數據庫的documents表,因此該命令就會自動去這張表中把數據進行全文索引,執行效果以下:

 

 

 

 

上圖的出現就是表明sphinx創建全文因此成功了

10.搜索索引工具./search

sphinx的客戶端命令工具在該目錄下:/usr/local/sphinx/bin

而生成索引工具search是屬於sphinx的客戶端命令工具

語法規則以下:./search 搜索關鍵字

1)若是但願搜索documents表中含有four關鍵字的數據,那麼執行如下命令就能夠搜索

命令:./search four

執行效果以下:

 

 

2)若是但願搜索documents表中含有itcast關鍵字的數據,那麼執行如下命令就能夠搜索

命令:./search itcast

執行效果以下:

 

 

這時若是你細心觀察能夠知道,當前咱們進行搜索的關鍵字所有都是英文的,若是你但願搜索關鍵字爲中文會出現怎麼樣的結果呢??

2)若是但願搜索documents表中含有廣州關鍵字的數據,那麼執行如下命令就能夠搜索

命令:./search 廣州

執行效果以下:

 

 

這時若是使用sphinx搜索中文,你會發覺沒法搜索出對應的內容,這個其實緣由咱們還滅有爲sphinx打入中文詞庫,因此若是但願解決這個問題那麼咱們就須要打入coreseek中文詞庫,其做者是高春輝。

.中文分詞庫CoreSeek

1.coreseek的簡介

Coreseek爲應用提供全文檢索功能,目前的版本(2.x 3.x)基於Sphinx 0.9.8,支持使用Python定義數據源,支持中文分詞。

2.安裝Coreseek

第一步:包說明

 

 

 

2步:上傳文件到/usr/local/src下

 

 

3步:修改install_coreseek.sh權限爲777

 

 

4步:執行./install_coreseek.sh進行安裝,安裝成功結果以下圖所示:

 

 

3.Coreseek的重要文件

Coreseek的配置文件

/usr/local/coreseek/etc/csft.conf

Coreseek的命令工具

/usr/local/coreseek/bin

4.配置Coreseek的數據源

Coreseek的配置文件

/usr/local/coreseek/etc/csft.conf

使用vim打開

 

 

配置以下圖所示:

 

 

 

5.測試coreseek

Coreseek它有本身命令行工具,跟sphinx的命令工具是一致,但若是你想搜索是中文,那麼必須使用coreseek命令行工具

Coreseek的命令工具在如下目錄當中,若是但願執行indexer和search都必須在該目錄中完成,不然就會失敗

/usr/local/coreseek/bin

測試中文搜索的結果以下:

若是但願搜索documents表中含有廣州關鍵字的數據,那麼執行如下命令就能夠搜索

詳細步驟以下:

①必須使用coreseek的indexer從新生成一次中文分詞的全文索引,執行命令以下

./indexer --all ,該命令必須在/usr/local/coreseek/bin執行,不然就會失敗.效果以下所示

 

 

②使用命令:./search 廣州

看下是否能夠中文檢索出documents當中的內容

執行效果以下:

 

 

測試英文結果以下,嘗試使用coreseek來全文索引documents當中的itheima關鍵字,結果以下:

 

 

所以咱們可知若是咱們作sphinx的開發其實,咱們使用的就coreseek,由於咱們中國人不多使用原生sphinx,然而咱們剛纔的全部操做都發生在命令行客戶端,若是咱們要使用php操做coreseek能夠嗎?若是但願用php操做coreseek那麼咱們就須要作兩件事:

1)安裝php的sphinx拓展

2)啓動coreseek的9312端口

.SphinxPHPAPI(擴展庫)

1.安裝sphinxphp擴展庫

1步:包說明

 

 

 

 

2步:上傳文件到/usr/local/src

 

 

上傳結果以下:

 

 

 

3步:修改install_php_coreseek.sh的權限爲7777

 

 

修改後的結果:

 

 

 

4步:執行./install_php_coreseek.sh進行安裝

 

 

成功安裝,界面以下圖所示:

 

 

5步:重啓apache服務器

執行命令:service httpd restart

 

 

接下來在/var/www/html編寫phpinfo.php腳本內容以下:

 

 

保存並退出,而後在瀏覽器種看phpinfo,phpinfo測試結果以下

 

 

表明sphinx擴展安裝成功了

注意:必須關閉selinux的配置選項,不然php沒法連接sphinx擴展,修改方法以下:

使用vim /etc/selinux/config

 

 

打開後修改內容以下:

 

 

修改完成後必須使用reboot命令,重啓linux服務器selinux才能正常關閉,這個關閉是永久性的,就算你關閉selinux你會發覺php依然沒法連接sphinx的中文詞庫coreseek,緣由是若是你但願搜索中文的coreseek詞庫,必需要在linux當中創建coreseek服務器端服務器進程,而進程須要你開啓9312端口,不然沒法使用。開啓的方法很簡單,使用coreseek的命令工具./searchd就能夠開啓,以下所示:

2.開啓coreseek9312端口

Coreseek的命令工具在如下目錄當中,若是但願執行searchd都必須在/usr/local/coreseek/bin目錄中完成,不然就會失敗

執行命令以下:./searchd

 

 

 

3.Linux查看端口和殺死進程的方法(拓展)

查看9312端口的方法: netstat -tunlp | grep 【端口名稱|進程名稱】

 

若是但願查看80端口是否被apache佔有那麼可使用如下方法:

 

 

 

殺死進程的方法:   pkill 進程名

若是但願殺死9312端口,那麼咱們就須要殺死searchd服務進程

 

 

 

若是但願肯定是否殺死進程,那麼須要從新查看9312端口的佔用狀況:

 

 

.使用php操做sphinx

0.兩個很實用php函數(array_keysjoin)

代碼詳細參考:php/arr_join.php,上傳到/var/www/html下進行測試

 

 

 

 

執行結果以下:

 

 

若是我但願當前返回的數組形式變成字符串的格式爲「1,2,3」咱們應該怎麼樣才能作到?

implode(替代函數join),搜索php的手冊發現implode有個別名叫join

 

 

使用join去替代implode會使得代碼更爲直觀,代碼以下:

 

 

執行結果以下:

 

 

1.使用php鏈接sphinx(coreseek9312端口)

代碼詳細參考:php/coreseek.php,上傳到/var/www/html下進行測試

 

 

執行結果以下:

 

 

 

2.php的多種搜索sphinx的模式

SPH_MATCH_ANY  最精準的匹配模式,匹配查詢詞中的任意一個(重點)

SPH_MATCH_PHRASE   將整個查詢看做一個詞組,要求按順序完整匹配(瞭解)

SPH_MATCH_BOOLEAN  使用布爾搜索模式(瞭解)

SPH_MATCH_EXTENDED 兼容模式,主要是爲兼容php5.2(瞭解)

SPH_MATCH_ALL 匹配全部查詢詞(默認模式)(瞭解)

3.SPH_MATCH_ANY模式

代碼詳細參考:php/setMatchMode.php,上傳到/var/www/html下進行測試

若是但願使用sphinx的coreseek進行全文索引那麼建議使用SPH_MATCH_ANY的模式去精準搜索,可是咱們該如何設置這精準模式呢?答案是使用sphinx的setMatchMode方法,方法簡介以下:

 

 

模式有不少,但咱們只會使用SPH_MATCH_ANY

代碼編寫以下所示:

 

 

執行效果以下:

 

 

然而若是你只是設置模式,但你不去使用模式搜索,那麼設置模式有什麼用呢?所以咱們就須要經過設定的模式去查找數據,那麼又該如何查找數據呢?答案是經過使用sphinx的query方法,query方法簡介以下 :

 

 

參數$query:搜索關鍵字

參數$index:搜索coreseek搜索名稱,默認是coreseekDocsIndex

參數$comment : 備註信息,通常咱們不會使用

返回值是array數組形式

編寫代碼以下:

 

 

執行結果以下所示:

 

 

 

然而這個主鍵的id是matches這個數組的鍵名,那麼咱們應該如何獲取matches數組的鍵名呢?答案使用array_keys函數,所以咱們須要把代碼修改稱如下形式,獲取matches數組的鍵名:

 

 

執行結果以下:

 

 

可是咱們只是獲取了數據庫當中的主鍵,那麼如何把主鍵轉換成爲數據庫當中具體的記錄信息呢?這時咱們就須要使用pdo來進行預處理操做了,由於主鍵是數據庫當中最具效率的索引所以經過主鍵來查找數據速度是很快的,pdo就是出場的時候了.

4.使用pdo操做sphinxmatches選項id

代碼詳細參考:php/pdoSphinx.php,上傳到/var/www/html下進行測試

須要組合sql的in語句使用join函數轉化ids數組變量

 

 

執行結果以下所示:

 

 

雖然咱們可以使用pdo操做sphinx中的matches的id選項,然而咱們是把關鍵字寫死了,而且關鍵字該如何高亮顯示呢?這時咱們就須要進一步修改代碼,而且要增長一個搜索的頁面叫(index.html)和高亮顯示的方法buildExcerpts

 

 

5.高亮顯示sphinx的搜索關鍵字

代碼詳細參考:php/build.php,上傳到/var/www/html下進行測試

 

Sphinx的高亮方法buildExcerpts簡介以下:

 

 

編寫代碼以下:

 

 

執行後,查看源代碼以下:

 

 

若是咱們但願修改keyswords的傳值,那麼咱們就須要增長一個叫作index.html的頁面,頁面的代碼以下,在index.html當中查看,是一個很是簡單的搜索框樣式:

 

 

action修改成pdoSphinx.php,所以在pdoSphinx.php接收keywordsget傳值參數,代碼修改以下:

 

 

從新上傳index.htmlpdoSphinx.php文件進行測試,以下:

 

 

6.php操做sphinx的增量索引

若是如今在數據庫當中在插入一條信息的數據,以下:

 

 

緣由就是php若是須要獲取coreseek當中的全文索引,必需要使用增量索引,是方法以下,這些必須在/usr/local/coreseek/bin目錄下進行:

直接使用./indexer --all就會出現錯誤

 

 

咱們應該使用./indexer --all --rotate讓php能夠操做sphinx增量索引api,結果以下:

 

 

執行結果以下,發現再次成功

 

 

那麼在pdoSphinx.php頁面中機會出現全部與中心關鍵字相關的記錄:

 

 

7.crontab命令定時更新sphinx增量索引api(拓展)

crontab命令實際上是linux當中定時器,最先用於軍事,因此這個命令不是什麼新的技術

其格式以下:

 

 

crontab經常使用使用方法以下:

編輯命令 crontab -e

查看命令 crontab -l

格式:  * * * * * [命令的詳細路徑]

需求:若是須要每1分更新一次sphinx的增量索引api那麼咱們應該怎麼作呢?詳細步驟以下:

使用crontab -e命令進入crontab的編輯模式,編寫如下內容:

 

 

保存並退出(:x),就會1分鐘定時執行一次,並且linux是很是聽話和穩定的執行。

咱們執行只是爲了學習方便看到效果,因此咱們使用1分鐘,建議在實際網站開發中定義15分鐘更新一次增量索引api

*/15 * * * *  /usr/local/coreseek/bin/indexer --all --rotate

若是使用crontab -l就能夠查看crontab的執行狀況

 

 

 

 

通常定時命令不會影響cpu,因此通常工程師不會常常刪除,若是你真要刪除就使用crontab -e命令編輯這個命令爲空便可

5.使用union all優化in語句

 

 

優化手段來自此書的in性能優化對比.

mysql的當中若是使用in語句只有一種狀況可使用到索引,就是當mysql數據庫認爲當前的檢索爲一個範圍時,就可使用索引,以下圖所示:

 

 

 

其餘的in語句狀況若是不是一個範圍的檢索,那麼mysql就認爲它等同於or條件的集合,這時他們發生的性能問題所有屬於全表掃描ALL

 

 

 

因此不建議使用in語句在查詢大數據量,建議使用union all取代in,union all使用explain執行計劃查看會帶來一個ALL的性能選項,以下圖所示:

 

 

但要要注意的時這個ALL檢索的數據是union all合併後的結果而非全表掃描,這時性能遠遠優於全表掃描,雖然咱們知道可使用union all來代替in語句,那麼這時咱們在sphinx當中應該如何組合這條語句呢,修改代碼以下:

詳細代碼參考:code/pdoSphinx2.php

 

 

.MySql數據中的binlog日誌

binlog日誌的簡介

:在現實開發當中,網站天天運行其實都會發生不少操做,但假設數據庫發生了更改(delete,insert,update,alter語句的發生),咱們想實時捕捉這些語句何時發生,那麼應該怎麼作呢?

:在MySql當中有一種日誌叫binlog,該日誌是記錄對數據發生或潛在發生更改的SQL語句,並以二進制的形式保存在磁盤中,該日誌對數據獲取(select)不起做用binlog日誌其實主要用於主從複製,因此若是你須要配置主從複製和讀寫分離,那麼就必須學會binlog日誌相關函數(命令)

.binlog日誌的相關函數

以前咱們學過的MySql的慢查詢日誌有一些專門管理慢查詢日誌的函數(命令),那麼binlog一樣屬於MySql當中的一種日誌類型,那麼MySql有專門管理binlog日誌的函數(命令)嗎?這個答案是確定的。

①在MySql當中查看binlog日誌的是否已經開啓

使用命令: show variables like 'log_bin'

執行命令結果以下:

 

 

在默認的狀況下MySql通常不會開啓binlog日誌,因此該選項爲OFF(表明binlog日誌沒有開啓),若是但願開啓binlog日誌就須要把該選項設置爲ON,那麼如何才能把該選項設置爲ON呢?這時就必須又要去修改mysql的配置文件了,mysql的配置文件路徑(/etc/my.cnf)

 

②在配置文件(/etc/my.cnf)中開啓binlog日誌的詳細步驟

使用vim打開/etc/my.cnf配置文件,內容以下所示:

 

 

找到以下配置:

 

 

修改binlog日誌以下:

 

該選項必須寫成binlog,保存並退出(:x),這時咱們還需重啓mysqld服務

使用命令: service mysqld restart

 

 

重啓完成後,binlong日誌就打開:

 

 

你會發如今/var/lib/mysql下多了2個這樣的文件:

 

 

咱們只須要關係binglog.000001文件便可

③查看binlog日誌的當前狀況

使用命令:show master status

 

 

 

選項詳解:

File:表示當前正在使用的binlog日誌文件是哪一個,該文件存放在/var/lib/mysql目錄中

Position:當前binlog日誌操做的步伐,這個選項主要是在主從同步的時候拿來作參考

Binlog_Do_DB:當前正在作binlog主從複製的數據庫是哪個,若是爲空表明當前並無開啓binlog主從複製的數據庫

Binlog_Ignore_DB:該選項的做用跟Binlog_Do_DB同樣,但這個選項向來都不知道意義何在,通常沒人使用.

這時若是咱們使用查詢語句binlog會有變化嗎?是不會改變的,然而若是作了寫操做(更新)它的postion就會發生改變:

 

 

 

若是使用vim查看binlog日誌文件中的內容,發覺是亂碼,沒法查看其內容,以下所示:

 

 

 

④查看binlog日誌的二進制內容

使用命令: mysqlbinlog [binlog文件路徑] | less

 

 

執行效果以下:

 

 

binlog日誌開啓後,可以實時捕捉你的更新操做(寫操做)

難道每一次都只使用一個binlog文件嗎?若是咱們操做不少,一個文件就會逐漸變大,所以binlog其實有一系列的管理文件供開發者操做.

⑤保留舊的binlog日誌文件,建立新的binlog日誌文件

使用命令:flush logs

 

 

flush logs命令能夠保存當前binlog.00001文件而且建立一個新的binlog文件來使用

只要你flush logs就會產生一個新的文件,不會刪除任何舊的文件:

 

 

④刪除全部的binlong日誌文件,binlog日誌從頭開始

使用命令:reset master

執行命令以下:

 

 

發覺舊文件被刪除,而建立了一個從頭開始binlog日誌文件.

注意:若是但願刪除binlog日誌文件讓binlong文件從00001開始是不能使用rm命令,不然問題很嚴重,會致使數據庫錯亂

 

 

總結:其實binlog除了記錄更新操做以外,那麼咱們在現實開發當中拿binlog幹嗎呢?咱們說通常咱們是使用binlog來作主從同步(讀寫分離),也叫主從複製.

.Grant用戶受權

1.MySqlGrant用戶受權簡介和服務器的克隆

MySql當中默認存在一個安全的機制,即本地訪問機制(localhost)。假設你想在本地之外訪問MySql就須要經過Grant受權一個用戶和IP地址。爲了方便學習,咱們能夠經過克隆一臺新的Linux服務器來進行Grant用戶受權測試,詳細的克隆服務器創建步驟以下所示:

1步:要克隆必須先關機.

 

 

2步:打開虛擬機找你要克隆的服務器(Master),右鍵選擇管理->克隆

 

 

3,4步:默認操做下一步

 

 

 

5步:選擇完整克隆而後下一步,在克隆過程中有可能會死機,速度根據計算機的設備配置而定,耐心等待

 

 

6步:設置克隆服務器的名稱和存放的路徑

 

 

點擊完成後耐心等待:

 

 

等待完成後就關閉

 

 

出現slave虛擬機就表明克隆成功

 

 

注意:這時千萬不要啓動slave服務器,不然會很奇葩,如今只能啓動master服務器

2.Grant用戶受權的設置

這個技術主要也是拿來作主從複製爲主的

這時Grant用戶受權必須發生在Master服務器當中,而且保證Slave服務器在設置完成才能開啓,不然話可能會有意想不到的bug產生.

語法規則:

GRANT ALL PRIVILEGES ON *.* TO 受權用戶名@被受權服務器的IP IDENTIFIED BY '受權密碼';

FLUSH PRIVILEGES; 

設置Grant用戶受權的詳細步驟以下:

1步:進入Master服務器的mysql數據庫當中

 

 

2步:開啓slave服務器,而且肯定slave服務器的ip地址,然而slave不能作任何的ip調整和修改,由於它是一個克隆品,遺傳Master的網卡配置信息.(這個過程若是你電腦比較通常,整個系統會卡爆),經過ifconfig獲取slave服務器的ip以下(192.168.84.82):

 

 

 

3步:在master服務器當中進行Grant用戶受權,執行如下命令配置:

 

 

這樣就對slave服務器進行了一個名爲pengjin的Grant用戶受權,其受權密碼爲123456

執行完成後,咱們還需刷新受權

 

 

 

若是不出現任何的錯誤就表明grant受權成功了咱們須要在Slave服務器當中進行測試

4步:在slave服務器當中經過如下命令對grant用戶受權進行測試:

mysql -u受權的用戶名 -p受權的密碼 -h master服務器的ip

執行命令以下:

 

 

測試結果以下:

 

 

證實了master的Grant用戶受權給Slave服務器成功

3.查看Grant用戶受權結果

因爲mysql自己有一個系統數據庫叫mysql數據庫,因此當咱們完成了受權後,

能夠經過如下命令查看受權的結果,該命令要在master服務器中執行:

select host,user,password from mysql.user where user=’受權用戶的名稱’;

 

 

 

 

注意:Grant用戶受權主要是爲設置讀寫分離和主從複製,而Grant受權的測試結果不是所謂主從複製,由於其實在Slave服務器當中鏈接的數據庫是Master而不是本身自己的數據庫.

 

.讀寫分離和主從複製

MySQL主從複製(Master-Slave)與讀寫分離能夠說是數據庫當中重要的環節,也是目前世界上全部大型網站當中必須擁有的優化手段.

若是你把數據庫比喻成一個很優秀的人,它可以很好很優秀地完成不少不一樣的工做。但你有沒想過再優秀的人都有體力耗盡的時候。

數據庫也是同樣的,不管你對這個數據庫作了多少的優化工做,網站全部的數據響應工做都靠一個數據庫去完成的話,其實數據庫也會有扛不住過大訪問量的時候,這就跟人同樣。

可是咱們若是咱們有多個優秀的人一塊兒協同工做那麼是否是面對大工做量的時候咱們的效率就會高了不少,也不會只有一我的累死累活的,數據庫也是同樣的若是有多於1個以上的數據庫那麼扛住大訪問量就確定提升效率。

然而多個數據庫也是有代價成本的,由於這樣話要有多臺服務器,而服務器的費用是挺貴,多臺服務器若是須要維護那麼還須要有一個比較專業的運維技術團隊,而運維技術團隊裏面的成員工資也是不低的,因此對於小成本的公司通常的老闆是玩不起主從複製和讀寫分離。

那麼什麼是讀寫分離和主從複製呢,其實讀寫分離和主從複製是一個總體,讀寫分離是爲了減輕數據庫的壓力,主從複製是爲了數據庫的數據進行同步.

讀寫分離和主從複製的架構圖:

 

 

 

上圖中,咱們把負責寫操做的數據庫稱爲主數據庫,該數據庫所在的服務器咱們稱爲主服務器,使用ip爲192.168.1.1來表示,使用英文名就是Master,因爲這臺服務器只有寫的過程沒有讀的過程,也就是隻有insert,update,delete的過程沒有select的過程,這時其實它要完成的工做就少了select,天然就壓力就比原來小了.

咱們把負責讀操做的數據庫稱爲從數據庫,該數據庫所在的服務器咱們稱爲主服務器,使用ip爲192.168.1.2來表示,使用英文名就是Slave,因爲這臺服務器只有讀的過程沒有寫的過程,也就是隻有select的過程沒有insert,update,delete的過程,這時其實它要完成的工做就少了insert,update,delete,天然就壓力也比原來小了.

然而讀寫分離以後,最大的問題就是,讀和寫的數據分佈在兩臺不一樣的服務器中,因此若是但願兩臺服務器的數據是同樣的那麼就須要把主服務的數據同步複製一份到從服務器上,咱們把這個複製的過程稱爲主從複製,也有人叫作主從同步.

若是你明白了讀寫分離和主從複製的架構以後,其實咱們還須要理解一個問題就是主從複製的原理是什麼?也就是說憑MySql懂得把主服務器當中寫操做的數據同步複製到讀數據庫當中呢?其實這個答案就是主從同步的原理,實際上是主服務器把本身的binlog日誌同步給從服務器,由於binlog日誌是記錄主服務器的寫操做的日誌文件.所以主從複製的原理以下:

 

 

 

 

 

讀寫分離的誤區和注意事項(面試當中很喜歡跟你討論這個問題,看看你技術是否靠譜)

有不少人認爲讀的數據就是隻讀不寫,寫的數據庫就是隻寫不讀,這是錯誤的,寫的數據庫一樣能夠讀,讀的數據庫也能夠寫,可是若是你往讀的數據庫裏面添加數據,往寫的數據庫不斷的讀取數據,那麼讀寫分離的意義就不存在了,因此玩讀寫分離的時候技術人員必定要靠譜,不能隨便亂讀亂寫.

 

2.主服務器(Master)的配置選項

作這個實驗以前,由於比較容易被其餘東西所影響,因此最好恢復到一個比較乾淨完整的狀態當中,建議恢復一下快照.

使用vim打開/etc/my.cnf文件,修改如下幾個簡單的配置選項

 

 

修改結果以下:

 

 

這時若是你沒有php25這個數庫,保存退出(:x),不要立刻重啓mysqld服務,咱們須要在master中建立php25這個數據庫.

 

 

 

建立完成後,咱們還須要創建Grant用戶受權,所以咱們須要從新克隆一臺新的Slave服務器,保證明驗的完整性,肯定Slave服務器的Ip地址爲(192.168.84.30).

 

 

查看受權結果以下:

 

 

 

3.從服務器(Slave)的配置選項

使用vim打開/etc/my.cnf文件,修改如下幾個配置選項:

 

 

修改結果以下:

①關閉Slave服務器中的binlog日誌

 

 

②修改其餘配置選項以下:

 

 

保存並退出(:x),可以重啓服務器:

 

 

4.查看從服務器的狀態

 

登陸slave服務器,以下圖所示;

 

 

命令: show slave status \G

 

 

若是設置成功,那麼咱們還要測試主從複製的結果是否生效,注意咱們測試的數據庫名爲php25,其餘的數據庫是不會進行主從複製的.

 

 

以上結果測試成功,就表明主從複製同步成功了.

 

九.使用php操做主從數據庫實現讀寫分離

代碼參看:code/slave.php

若是但願使用php操做主從數據庫的讀寫分離,那麼就必需要在Slave服務器中再進一次Grant用戶受權,緣由是由於Mysql默認狀況下只有localhost的訪問機制,若是你把php的文件放在master服務中去讀取Slave是不可能成功,除非Slave受權一個用戶給Master服務器,若是編寫的代碼以下,這時咱們會出現什麼樣的狀況:

 

 

把代碼上傳到Master服務器中,若是沒有受權的狀況下是會出現白屏現象,不能讀取Slave的數據,若是但願可以讀取Slave中的數據,就必須進行受權操做

 

 

因此就會出現錯誤(白屏現象),通常受權的時候,咱們通常不會受權一個root用戶,但若是有受權root用戶默認也能夠受權的服務地址的,若是用root去訪問就危險了,因此通常運維會授予一個用戶和密碼給你訪問,而不會告訴你root的密碼,受權以下:

 

 

以上操做必需要在slave服務器中,完成,受權成功,獲取如下信息:

 

 

這時咱們修改slave.php代碼以下 :

 

 

上傳到master服務器的/var/www/html,從新進行測試以下:

 

 

十.使用php實現會員註冊到主從數據庫中

代碼:users/users.sql

 

 

以上的代碼放在master數據庫當中進行操做,由於master負責寫,建表也屬於寫操做

 

代碼:users/register.php

 

 

上傳到master服務中,進行測試,結果以下:

 

 

若是註冊成功,必定是插入了Master才能同步到Slave

若是註冊不成功提示出現,就證實讀取slave的鏈接沒有問題

 

 

 

這時發覺register會同時操做兩臺服務器,服務器在pdo中間進行切換操做

代碼:users/login.php

 

 

上傳到master服務器中,進行測試,結果以下;

 

 

 

相關文章
相關標籤/搜索