Sphinx
什么是Sphinx
為什么要用Sphinx?
原因1: MySQL不支持中文全文檢索,模糊查詢(like)慢
原因2: sphinx支持中文全文檢索,并且支持分詞高亮
什么是Sphinx
就是一個軟件,用來代替MySQL全文檢索
sphinx的特性
強,快
特性
高速的建立索引(峰值達(dá)10M/s)
高性能的搜索(2-4G的文件數(shù)據(jù)上,平均每次檢索0.1秒左右)
可處理海量數(shù)據(jù) (字符串,布爾..)
優(yōu)勢
sphinx單一索引最大可包含1億條記錄,在1千萬記錄情況下的查詢速度為0.x秒(毫秒級)
sphinx創(chuàng)建索引的速度為: 創(chuàng)建100萬條記錄的索引只需3~4分鐘,創(chuàng)建1000萬條記錄的索引可以在50分鐘內(nèi)完成,而值包含最新10萬條記錄增量索引,重建一次只需十幾秒
sphinx執(zhí)行的過程
步驟1:通過sphinx去MySQL中獲取并建立索引文件
步驟2:通過php去sphinx中查詢數(shù)據(jù)并返回ID
步驟3:根據(jù)ID去MySQL中查詢具體數(shù)據(jù)
安裝Sphinx
什么是Coreseek
Coreseek是一款中文全文檢索/搜索軟件,基于Sphinx研發(fā)并獨立發(fā)布.專攻中文搜索和信息處理領(lǐng)域,使用于行業(yè)/垂直搜索,論壇/站內(nèi)搜索,數(shù)據(jù)庫搜索,文檔/文獻(xiàn)檢索,信息檢索,數(shù)據(jù)挖掘等應(yīng)用場景
簡單的來說就是中文版的sphinx
Coreseek和sphinx的關(guān)系
sphinx默認(rèn)支持英文和俄文,但是它提供了一種方法可以支持任意一種語言,但是需要自己寫相關(guān)語言詞庫
Coreseek是在sphinx的基本上添加了中文詞庫的二次開發(fā)
簡單概括: sphinx由俄國人開發(fā),默認(rèn)不支持中文,但是提供了接口,coreseek基于該接口開發(fā)
下載地址
Sphinx官網(wǎng):http://www.sphinxsearch.com
coreseek官網(wǎng):http://www.coreseek.com
安裝Coreseek
安裝包目錄文件
coreseek-3.2.14-win32\bin\indexer.exe 創(chuàng)建索引
coreseek-3.2.14-win32\bin\searchd.exe 服務(wù)器端
coreseek-3.2.14-win32\etc\csft_mysql.conf 配置文件
配置sphinx
創(chuàng)建數(shù)據(jù)庫
將etc/csft_mysql.conf復(fù)制并更名為sphinx.conf
將shpinx.conf中內(nèi)容更換為一下代碼
#數(shù)據(jù)源:數(shù)據(jù)來源定義(數(shù)據(jù)庫信息、數(shù)據(jù)源SQL語句)
source music
{
#下面是sql數(shù)據(jù)庫特有的端口刃鳄,用戶名,密碼,數(shù)據(jù)庫名等。
type = mysql
sql_host = localhost
sql_user = root
sql_pass = admin
sql_db = youhua3
sql_port = 3306
sql_query_pre = SET NAMES utf8
#sql_query屬性:取出要創(chuàng)建索引的數(shù)據(jù)
#要求1:SELECT的第一個字段必須是主鍵谦纱、
#要求2:第一個字段的名字(別名)必須是id
#要求3:其他的字段就是要創(chuàng)建索引的字段
#需 求:為歌曲表中的title和author和content字段創(chuàng)建索引
sql_query = SELECT id, title, author, content FROM music
}
#索引的定義(索引文件存放的位置,索引文件的名字)
#每個index對應(yīng)一個數(shù)據(jù)源,用來定義這個數(shù)據(jù)源生成的索引文件的信息
index music
{
#該索引對應(yīng)哪個數(shù)據(jù)源
source = music
#索引文件存放的目錄和名字(存到E:/sphinx/var/data/目錄下鉴竭,索引文件的名字是music)
path = E:/sphinx/var/data/music
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
#詞庫文件所在的目錄
charset_dictpath = E:/sphinx/etc/
#字符集編碼類型歧譬,可以為:(sbcs,utf-8,zh_cn.utf-8,zh_ch.gbk,zh_ch.big5)
charset_type = zh_cn.utf-8
}
#全局index定義
indexer
{
#建立索引的時候,索引內(nèi)存限制
mem_limit = 128M
}
#searchd服務(wù)定義
searchd
{
listen = 9312
read_timeout = 5
max_children = 30
max_matches = 1000
seamless_rotate = 0
preopen_indexes = 0
unlink_old = 1
# 進(jìn)程id文件
pid_file = E:/sphinx/var/log/searchd_mysql.pid
# 系統(tǒng)日志存放的位置
log = E:/sphinx/var/log/searchd_mysql.log
# 查詢?nèi)罩敬娣诺奈恢? query_log = E:/sphinx/var/log/query_mysql.log
}
注: 修改路徑和數(shù)據(jù)庫賬號密碼
Findex music 創(chuàng)建music索引(和source一一對應(yīng)搏存,表示該索引通過哪些數(shù)據(jù)創(chuàng)建)
source music1 創(chuàng)建music數(shù)據(jù)源
創(chuàng)建索引
sphinx\bin> 創(chuàng)建指定索引語法 : indexer.exe -c 配置路徑/文件 索引名
sphinx\bin> 創(chuàng)建全部索引語法 : indexer.exe -c 配置路徑/文件 --all
使用PHP API操作Sphinx
創(chuàng)建Sphinx服務(wù)
bin>創(chuàng)建服務(wù) : searche.exe -c 配置路徑/文件 --install
刪除服務(wù) : sc delete 服務(wù)名
啟動服務(wù): net start 服務(wù)名
關(guān)閉服務(wù): net stop 服務(wù)名
PHP操作
復(fù)制sphinx\api目錄中的接口文件sphinxapi.php放到站點目錄
在站點目錄創(chuàng)建test.php引入該文件
<?php
#步驟1:引入sphinx接口文件
require './sphinxapi.php';
#步驟2:實例化對象
$sp = new SphinxClient;
#步驟3:設(shè)置服務(wù)
$sp->SetServer('localhost', 9312);
#步驟4:設(shè)置匹配模式
#步驟5:設(shè)置查詢條數(shù)
$sp->SetLimits(0, 5000);
#步驟6:發(fā)送查詢
$rs = $sp->query('冬天', 'music');
echo '<pre>';
print_r($rs);
匹配模式
語法: $sp -> SetMatchMode(常量)
SPH_MATCH_ALL 匹配所有詞(默認(rèn))
SPH_MATCH_ANY 匹配一個詞
SPH_MATCH_PHRASE 匹配整一個詞
SPH_MATCH_BOOLEAN 將查詢看作一個布爾表達(dá)式
SPH_MATCH_EXTENDED 查詢看做一個sphinx的表達(dá)式
舉例: 我喜歡PHP
分詞: 我 喜歡 PHP
準(zhǔn)備工作: 先停止服務(wù)-> 創(chuàng)建索引->啟動服務(wù)
匹配所有詞(SPH_MATCH_ALL)
說明:我 喜歡 PHP 字段都要存在, 位置不限
<?php
#步驟1:引入sphinx接口文件
require './sphinxapi.php';
#步驟2:實例化對象
$sp = new SphinxClient;
#步驟3:設(shè)置服務(wù)
$sp->SetServer('localhost', 9312);
#步驟4:設(shè)置匹配模式
$sp->SetMatchMode(SPH_MATCH_ALL);
#步驟5:設(shè)置查詢條數(shù)
$sp->SetLimits(0, 5000);
#步驟6:發(fā)送查詢
$rs = $sp->query('我喜歡PHP', 'music');
echo '<pre>';
print_r($rs); #
匹配一個詞(SPH_MATCH_ANY)
說明: 我 喜歡 PHP 只要有一個存在,就匹配
#步驟4:設(shè)置匹配模式
$sp->SetMatchMode(SPH_MATCH_ANY);
匹配整個詞(SPH_MATCH_PHRASE)
說明: 我 喜歡 PHP 都必須存在 位置必須一致
#步驟4:設(shè)置匹配模式
$sp->SetMatchMode(SPH_MATCH_PHRASE);
將查詢看作一個布爾表達(dá)式(SPH_MATCH_BOOLEAN)
#步驟4:設(shè)置匹配模式
$sp->SetMatchMode(SPH_MATCH_BOOLEAN);
查詢看做一個sphinx的表達(dá)式(SPH_MATCH_EXTENDED)
說明: 查詢指定字段的內(nèi)容 @字段 內(nèi)容
舉例: @title 內(nèi)容 @content 內(nèi)容 @author 內(nèi)容
#步驟4:設(shè)置匹配模式
$sp->SetMatchMode(SPH_MATCH_EXTENDED);
#步驟5:設(shè)置查詢條數(shù)
$sp->SetLimits(0, 5000);
#步驟6:發(fā)送查詢
$rs = $sp->query('@content PHP @author 校長'); #內(nèi)容=PHP并作者=校長
echo '<pre>';
print_r($rs); #
將Sphinx的結(jié)果轉(zhuǎn)為具體信息
步驟1:通過sphinx去mysql中獲取數(shù)據(jù)并建立索引文件
步驟2:通過php去sphinx匹配數(shù)據(jù)ID
步驟3:根據(jù)ID去數(shù)據(jù)庫中查詢數(shù)據(jù)
查詢
<?php
#步驟1:引入sphinx接口文件
require './sphinxapi.php';
#步驟2:實例化對象
$sp = new SphinxClient;
#步驟3:設(shè)置服務(wù)
$sp->SetServer('localhost', 9312);
#步驟4:設(shè)置匹配模式
$sp->SetMatchMode(SPH_MATCH_ALL);
#步驟5:設(shè)置查詢條數(shù)
$sp->SetLimits(0, 5000);
#步驟6:發(fā)送查詢
$rs = $sp->query('我喜歡PHP', 'music');
//獲取所有數(shù)據(jù)庫數(shù)據(jù)ID
$ids = array_keys($rs['matches']);
$ids = implode(',', $ids);
//獲取數(shù)據(jù) select * from 表名 where id in (1,2,4,5)
$pdo = new PDO('mysql:dbname=youhua3', 'root', 'root');
$pdoStatementObj = $pdo->query("select * from music where id in ($ids)");
$musics = $pdoStatementObj->fetchAll(PDO::FETCH_ASSOC);
//循環(huán)顯示數(shù)據(jù)
foreach ($musics as $music) {
echo $music['id'] . '__' . $music['author'] . '<hr />';
}
高亮顯示搜索詞
#將上面代碼foreach改為以下代碼
foreach ($musics as $music) {
echo $music['id'] . '<br />';
echo str_replace('冬天', '<font color=red>冬天</font>', $music['title']) . '<br />';
echo str_replace('冬天', '<font color=red>冬天</font>', $music['author']) . '<br />';
echo str_replace('冬天', '<font color=red>冬天</font>', $music['content']) . '<br />';
}
增量索引(Sphinx索引更新)
什么是增量索引
就是更新sphinx索引文件的表現(xiàn)稱之為增量索引
為什么要學(xué)習(xí)增量索引
因為數(shù)據(jù)庫每天數(shù)據(jù)都在變化,所以需要在原索引的基礎(chǔ)上繼續(xù)增加索引
使用indexer.exe生成增量索引
創(chuàng)建索引語法: indexer -c 配置文件 索引名
合并索引語法: indexer -c 配置文件 --merge 主索引名 新索引名 --rotate(強制合并)
操作
先創(chuàng)建數(shù)據(jù)表 用于記錄那些數(shù)據(jù)已經(jīng)被創(chuàng)建索引
create table sphinx
(
max_id int unsigned not null default 0
)
#該表作用:用于記錄music表哪些數(shù)據(jù)已被創(chuàng)建索引瑰步,哪些數(shù)據(jù)未被創(chuàng)建索引
#獲取未創(chuàng)建索引數(shù)據(jù):select * from music where id > sphinx表記錄的數(shù)字
修改配置文件(記錄已創(chuàng)建索引的數(shù)據(jù))
一 打開shpinx.conf 配置文件
二 將下述代碼粘貼到sphinx.conf中
source music
{
#下面是sql數(shù)據(jù)庫特有的端口,用戶名璧眠,密碼缩焦,數(shù)據(jù)庫名等。
type = mysql
sql_host = localhost
sql_user = root
sql_pass = admin
sql_db = youhua3
sql_port = 3306
sql_query_pre = SET NAMES utf8
#sql_query屬性:取出要創(chuàng)建索引的數(shù)據(jù)
#要求1:SELECT的第一個字段必須是主鍵蛆橡、
#要求2:第一個字段的名字(別名)必須是id
#要求3:其他的字段就是要創(chuàng)建索引的字段
#需 求:為歌曲表中的title和author和content字段創(chuàng)建索引
sql_query = SELECT id, title, author, content FROM music
#★ 該部分代碼放到music數(shù)據(jù)源中
#目的:記錄已經(jīng)創(chuàng)建索引的數(shù)據(jù)
#建完索引這后 舌界,把最后一條記錄的id存到sphinx表中
#在主查詢(sql_query)之后執(zhí)行的SQL
sql_query_post = INSERT INTO sphinx SELECT MAX(id) FROM music
}
#索引的定義(索引文件存放的位置掘譬,索引文件的名字)
#每個index對應(yīng)一個數(shù)據(jù)源泰演,用來定義這個數(shù)據(jù)源生成的索引文件的信息
index music
{
#該索引對應(yīng)哪個數(shù)據(jù)源
source = music
#索引文件存放的目錄和名字(存到E:/sphinx/var/data/目錄下,索引文件的名字是music)
path = E:/sphinx/var/data/music
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
#詞庫文件所在的目錄
charset_dictpath = E:/sphinx/etc/
#字符集編碼類型葱轩,可以為:(sbcs,utf-8,zh_cn.utf-8,zh_ch.gbk,zh_ch.big5)
charset_type = zh_cn.utf-8
}
#全局index定義
indexer
{
#建立索引的時候睦焕,索引內(nèi)存限制
mem_limit = 128M
}
#searchd服務(wù)定義
searchd
{
listen = 9312
read_timeout = 5
max_children = 30
max_matches = 1000
seamless_rotate = 0
preopen_indexes = 0
unlink_old = 1
# 進(jìn)程id文件
pid_file = E:/sphinx/var/log/searchd_mysql.pid
# 系統(tǒng)日志存放的位置
log = E:/sphinx/var/log/searchd_mysql.log
# 查詢?nèi)罩敬娣诺奈恢? query_log = E:/sphinx/var/log/query_mysql.log
}
修改配置文件(增加新索引)
打開shpinx.conf文件
將下述代碼追加 (記得修改密碼和路徑)
# 數(shù)據(jù)源
source music_add
{
# 下面是sql數(shù)據(jù)庫特有的端口,用戶名靴拱,密碼垃喊,數(shù)據(jù)庫名等。
type = mysql
sql_host = localhost
sql_user = root
sql_pass = admin
sql_db = youhua3
sql_port = 3306
sql_query_pre = SET NAMES utf8
# (SELECT MAX(max_id) FROM sphinx) 目的袜炕,規(guī)避重復(fù)創(chuàng)建索引
sql_query = SELECT id, title, author,content FROM music WHERE id > (SELECT MAX(max_id) FROM sphinx)
# 建完索引這后 本谜,把最后一條記錄的id存到sphinx表中
# 在主查詢(sql_query)之后執(zhí)行的SQL
sql_query_post = UPDATE sphinx SET max_id = (SELECT MAX(id) FROM music)
}
# 數(shù)據(jù)索引
index music_add
{
# 對應(yīng)的source數(shù)據(jù)來源名稱
source = music_add
path = E:/sphinx/var/data/music_add
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
# 詞庫文件所在的目錄
charset_dictpath = E:/sphinx/etc/
charset_type = zh_cn.utf-8
}
記錄已創(chuàng)建索引的數(shù)據(jù)(初始化一把)
停止服務(wù)->創(chuàng)建music索引->開啟服務(wù)->查看sphinx表
測試錄入新數(shù)據(jù)自動跟新索引
創(chuàng)建sphinx.bat文件 ,并輸入下屬內(nèi)容(路徑注意)
E:\sphinx\bin\indexer -c E:\sphinx\etc\sphinx.conf music_add #用于給music表未創(chuàng)建索引數(shù)據(jù)增加索引
E:\sphinx\bin\indexer -c E:\sphinx\etc\sphinx.conf --merge music music_add --rotate #將music_add索引合并到music索引中
打開music表新錄入數(shù)據(jù)
雙擊運行sphinx.bat更新索引(注: 用管理員身份運行)
通過PHP代碼測試查詢新增數(shù)據(jù)
定時任務(wù)
把這個sphinx.bat文件添加到windows系統(tǒng)上的計劃任務(wù),讓系統(tǒng)定時執(zhí)行這個文件中的兩個任務(wù)
打開控制面板 ->找到管理工具->任務(wù)計劃程序->創(chuàng)建任務(wù)
勾選最高權(quán)限運行 在操作中新建程序
觸發(fā)器中建立執(zhí)行時間
MySQL讀寫分離技術(shù)linux
讀寫分離(主從復(fù)制)
什么是主從復(fù)制,讀寫分離
主從復(fù)制: 當(dāng)主服務(wù)器有寫入(增/刪/改)語句的時候,從服務(wù)器自動獲取數(shù)據(jù)并同步
讀寫分離: 增/刪/改 語句操作在一臺服務(wù)器,select另一臺服務(wù)器
實現(xiàn)原理
主服務(wù)器開啟binlog日志(記錄主服務(wù)寫sql語句)
從服務(wù)器監(jiān)聽日志,只要改變就同步執(zhí)行
bin-log 日志
什么是bin-log日志
即二進(jìn)制日志,它記錄了數(shù)據(jù)庫上的所有改變并以二進(jìn)制的形式保存在磁盤中
,它可以用來查看數(shù)據(jù)庫的更變歷史,數(shù)據(jù)庫增量備份和恢復(fù),MySQL的復(fù)制(主從數(shù)據(jù)庫的復(fù)制)
主要作用: 就是記錄MySQL數(shù)據(jù)庫增/刪/改sql語句
-) 實現(xiàn)主從復(fù)制
-) 災(zāi)難恢復(fù)
開啟binlog日志
打開mysql 配置文件/etc/my.conf并修改
vi /etc/my.cnf
在[mysqld] 下一行
#新增 log-bin=mysql-bin
重啟服務(wù)
ps -A | grep mysql #查看
killall mysqld #殺死進(jìn)程
/php/server/mysql/bin/mysqld_safe --user=mysql & #啟動
登錄mysql查看bin-log日志是否開啟
/php/server/mysql/bin/mysql -u賬號 -p密碼
show variables like 'log_bin' #查看日志是否開啟
查看binlog日志里的內(nèi)容
查看列表( show master logs)
清空( reset master )
刷新( flush logs ) 會生成一個新文件存儲
查看指定日志( show binlog events in '日志名' )
創(chuàng)建d1數(shù)據(jù)庫和t1表
create database d1;
use d1;
create table t1 (id int);
查看binlog日志中的sql語句
show binlog events in '日志名'
具體配置
配置主服務(wù)器
一, 修改配置文件,開啟binlog日志
二, 修改配置文件,設(shè)置一個server-id=數(shù)字(注: 數(shù)字唯一)
三, 重啟服務(wù)
killall mysqld
/php/server/mysql/bin/mysqld_safe --user=mysql & #啟動
四, 創(chuàng)建mysql用戶
create user 'xiaoze'@'%' IDENTIFIED BY 'admin888';
grant all on *.* to 'xiaoze'@'%';
FLUSH PRIVILEGES;
五,關(guān)閉防火墻
service iptables stop
從服務(wù)器配置
一 : 修改配置文件,設(shè)置一個server-id=數(shù)字 (數(shù)字唯一)
二 : 重啟服務(wù)
三 : 通過change master 語句指定同步主位置
四 : 重啟
驗證
如果通過克隆服務(wù)器會報錯 應(yīng)該三臺服務(wù)器mysql一樣
解決: 刪除mysql數(shù)據(jù)目錄下auto.cnf 重啟 (重啟后會自動創(chuàng)建一個唯一的uid)
TP框架里實現(xiàn)讀寫分離
配置
將tp5解壓到站點目錄下并訪問
修改tp5數(shù)據(jù)庫配置文件
'deploy' => 1,
'rw_separate' => true,
'hostname' => '主服務(wù)器ip,從1,從2',
'database' => 'd8',
'username' => 'nanoha'
切換到主服務(wù)區(qū)創(chuàng)建d8數(shù)據(jù)庫和t1表
create database d8 charset=utf8;
use d8;
create table t1 (id int primary key auto_increment,name char(30));
切換到所有從服務(wù)器創(chuàng)建nanoha用戶
create user 'xiaoze'@'%' IDENTIFIED BY 'admin888';
grant all on *.* to 'xiaoze'@'%';
FLUSH PRIVILEGES;
所有從服務(wù)器關(guān)閉3306防火墻
主服務(wù)器負(fù)責(zé)寫,從服務(wù)器自動同步
public function index()
{
$rs = \think\Db::table('t1)->insert([
'name'=>'a1'
]);
}
到主,從服務(wù)器查看
驗證:從服務(wù)器負(fù)責(zé)讀
給從1插入一條數(shù)據(jù),給從2插入一條數(shù)據(jù)
控制器讀取
$data = \think\Db::table("t1")->select();
dump($data);
刷新頁面查看
MySQL管理命令
【mysql配置文件】
/etc/my.cnf
【開啟mysql服務(wù)】
/php/server/mysql/bin/mysqld_safe --user=mysql &
【關(guān)閉mysql服務(wù)】
ps -A | grep mysql # 查看mysql進(jìn)程
kill -9 進(jìn)程PID 進(jìn)程PID # 結(jié)束進(jìn)程 關(guān)閉mysql服務(wù)
【登陸MySQL數(shù)據(jù)庫】
/php/server/mysql/bin/mysql -uroot -p