然而,通常需要數據的可靠性。使用MySQL作為數據存儲,不會因為內存問題造成數據丟失,同時利用關系數據庫的特性可以實現很多功能。
所以很自然的想到MySQL是否可以作為數據存儲引擎,Redis作為緩存。但是目前對於這種需求還沒有特別成熟的解決方案或工具,所以采用Gearman+PHP+MySQL UDF的組合來實現從MySQL到Redis的數據異步復制。
從MySQL到Redis的數據復制方案
MySQL和Redis都有自己的數據同步機制。MySQL的主/從模式是通過在從端解析主的binlog實現的。這樣的數據復制實際上是壹個異步過程,但是當服務器都在同壹個內網時,異步延遲幾乎可以忽略不計。
那麽理論上也可以分析MySQL的binlog文件,用同樣的方法將數據插入Redis。但是,這需要對binlog文件和MySQL有很深的理解。同時由於binlog有各種形式的語句/行/Mixedlevel,所以分析binlog的同步是很繁重的。
所以這裏選擇壹種開發成本更低的方式。借用成熟的MySQL UDF,先將MySQL數據放入Gearman,然後通過壹個自己編寫的PHP Gearman Worker將數據同步到Redis。與分析binlog的方法相比,增加了很多流程,但實現成本更低,操作更容易。
Gearman的安裝和使用
Gearman是壹個分布式任務分配框架。設計簡單,贏得了廣泛支持。典型的Gearman應用程序包括以下部分:
Gear Man作業服務器:Gear Man的核心程序,需要作為守護進程在後臺編譯安裝運行。
Gearman客戶端:可以理解為壹個任務的接收者。例如,在後臺執行發送電子郵件的任務。妳可以在程序中調用壹個Gearman客戶端,傳入郵件信息,然後就可以立刻把執行結果展示給用戶,任務本身也會在後臺慢慢運行。
Gearman Worker:任務的真正執行者通常需要自己編寫特定的邏輯,並通過守護進程運行。Gearman Worker收到Gearman客戶端發送的任務內容後,會按順序進行處理。
之前也介紹過類似的後臺任務處理項目Resque。兩者的設計其實很接近,簡單性可以類比為:
Gearman作業服務器:對應於Resque的Redis部分。
Gearman客戶端:對應於Resque的隊列操作。
Gearman Worker:對應於Resque的工人和作業
這裏之所以選擇Gearman而不是Resque,是因為Gearman以更少的工作量提供了更好的MySQL UDF。
安裝Gearman和PHP Gearman擴展
以Ubuntu12.04為例。
apt-get安裝gear man gear man-server libgear man-dev
檢查Gearman的運行情況:
/etc/init . d/gear man-job-服務器狀態
* gearmand正在運行
意味著Gearman已經安裝成功。
PHP的Gearman擴展可以直接通過pecl安裝。
pecl安裝齒輪工
echo " extension = gearman.so " & gt/etc/php5/conf.d/gearman.ini
服務php5-fpm重啟
但是發現ubuntu安裝的gearman默認版本太低,直接運行pecl install gearman會出錯。
配置:錯誤:需要libgearman版本1.1.0或更高版本
所以建議通過編譯安裝Gearman+PHP擴展。這裏,為了簡單說明,選擇安裝舊版本擴展:
pecl安裝gearman-1.0.3
Gearman+PHP實例
為了更容易理解Gearman的操作過程,這裏我們不妨從壹個最簡單的Gearman的例子來說明。例如,要執行壹個文件處理操作,首先編寫壹個Gearman客戶端,並將其命名為client.php:
& lt?服務器端編程語言(Professional Hypertext Preprocessor的縮寫)
$ client = newGearmanClient();
$ client->;addServer();
$ client->;doBackground('writeLog ',' Log content ');
Echo“文件已在後臺操作”;
運行該文件相當於模擬用戶請求網頁並在處理後返回信息:
PHP client.php
檢查Gearman的情況:
(回聲狀態;睡眠0.1)| netcat 127 . 0 . 0 . 14730
您可以看到輸出是
寫日誌100。
它顯示在Gearman中創建了壹個名為writeLog的任務,有1個任務在隊列中等待。
以上四列分別代表Gearman當前的運行狀態:
任務名稱
等待隊列中的任務
運行任務
運行工作進程
手表可用於實時監控:
watch -n 1”(回聲狀態;睡眠0.1)| NC 127 . 0 . 0 . 1 4730 "
然後我們需要編寫壹個名為worker.php的Gearman Worker:
& lt?服務器端編程語言(Professional Hypertext Preprocessor的縮寫)
$ worker = newGearmanWorker();
$ worker-& gt;addServer();
$ worker-& gt;addFunction('writeLog ',' writeLog ');while($ worker-& gt;work());函數寫日誌($job){
$ log = $ job-& gt;工作量();文件內容(__目錄_ _。/gearman.log ',$log。" \n ",FILE _ APPEND | LOCK _ EX);}
Worker使用while無限循環來實現守護進程並運行它。
PHP worker.php
您可以看到Gearman狀態變為:
寫日誌001
同時查看同壹個目錄下的gearman.log,內容應該是客戶端傳入的值log內容。
通過MySQL UDF+觸發器將數據同步到Gearman。
MySQL與外部程序通信的最佳方式是通過MySQL UDF (MySQL用戶自定義函數)。為了讓MySQL向Gearman傳輸數據,這裏使用了lib_mysqludf_json和gearman-mysql-udf的組合。
安裝lib_mysqludf_json
之所以使用lib_mysqludf_json,是因為Gearman只接受字符串作為入口參數,MySQL中的數據可以通過lib_mysqludf_json編碼成json字符串。
apt-get安裝libmysqlclient-dev
wget/MySQL UDF/lib _ MySQL UDF _ JSON/archive/master . zip
解壓縮master.zip
cd lib_mysqludf_json-master/
rm lib_mysqludf_json.so
gcc $(MySQL _ config-cflags)-shared-fPIC-o lib _ MySQL UDF _ JSON . so lib _ MySQL UDF _ JSON . c
可以看到lib_mysqludf_json.so文件已經被重新編譯。此時,您需要檢查MySQL插件的安裝路徑:
mysql -u root -pPASSWORD - execute= "顯示類似“%plugin%”的變量;"+--+|變量名稱|值|+ - + - +|插件目錄|/usr/lib/MySQL/plugin/|+-++
然後將lib_mysqludf_json.so文件復制到相應的位置:
CP lib _ MySQL UDF _ JSON . so/usr/lib/MySQL/plugin/
最後,登錄MySQL,運行語句註冊UDF函數:
CREATE函數json_object返回字符串SONAME ' lib _ mysqludf _ json.so
安裝gearman-mysql-udf
方法幾乎是壹樣的:
apt-get安裝libgearman-dev
wget/gear man-MySQL-UDF/trunk/0.6/+下載/gear man-mysql-udf-0.6.tar.gz
塔爾-xzf gearman-mysql-udf-0.6.tar.gz
cd gearman-mysql-udf-0.6。/configure-with-MySQL =/usr/bin/MySQL _ config?
-libdir=/usr/lib/mysql/plugin/
制造和銷售。& amp進行安裝
登錄MySQL,運行語句註冊UDF函數:
CREATE函數gman_do_background返回字符串SONAME ' libgearman _ MySQL _ UDF . so ';
CREATE函數gman_servers_set返回字符串SONAME ' libgearman _ MySQL _ UDF . so ';
最後,指定Gearman服務器的信息:
SELECT gman _ servers _ set(' 127 . 0 . 0 . 1:4730 ');
通過MySQL觸發器實現數據同步
最終會同步什麽數據,同步的條件還是需要根據實際情況來決定。比如數據表data中的數據,每次更新都會同步。然後按如下方式編寫觸發器:
分隔符$$
更新數據後創建觸發器datatoredis
對於每壹行開始
SET @ ret = gman _ do _ background(' syncToRedis ',json_object(NEW.id為` id ',NEW.volume為` volume `);結束$$
分隔符;
嘗試更新數據庫中的壹條數據,看看Gearman是否有效。
Gearman PHP Worker將MySQL數據異步復制到Redis。
Redis作為壹種流行的NoSQL緩存解決方案,無需介紹,其安裝和使用非常簡單:
apt-get安裝redis服務器
pecl安裝redis
echo " extension = redis.so " & gt/etc/php5/conf.d/redis.ini
然後寫壹個gear man工人:redis _ worker.php。
#!/usr/bin/env PHP & lt;?
$ worker = newGearmanWorker();
$ worker-& gt;addServer();
$ worker-& gt;addFunction('syncToRedis ',' syncToRedis ');
$ redis = new redis();
$ redis-& gt;連接(' 127.0.0.1 ',6379);while($ worker-& gt;work());函數syncToRedis($ job){ global $ redis;
$ workString = $ job-& gt;工作量();
$ work = JSON _ decode($ workString);如果(!isset($ work-& gt;id)){ return false;}
$ redis-& gt;設置($ work->;id,$ workString);}
最後,您需要在後臺運行Worker:
nohup php redis_worker .
通過這種方式將MySQL數據復制到Redis,測試的單工基本可以瞬間完成。