mysql_with_redis_with_php_with_nginx大結合:
本版本mysql使用系統自帶的版本
redis,php,nginx等軟件及依賴性見官網及pkgs.org
server1.example.com :172.25.33.1 mysql
server2.example.com : 172.25.33.2 nginx +php
server3.example.com :172.25.33.3 redis
所需要的依賴包:
[root@server2 redis]# ls
gearman-1.1.2.tgz php-devel-5.3.3-38.el6.x86_64.rpm
gearmand-1.1.8-2.el6.x86_64.rpm php-fpm-5.3.3-38.el6.x86_64.rpm
gearman-mysql-udf-0.6.tar.gz php-gd-5.3.3-38.el6.x86_64.rpm
jemalloc-3.6.0-1.el6.x86_64.rpm php-mbstring-5.3.3-38.el6.x86_64.rpm
jemalloc-devel-3.6.0-1.el6.x86_64.rpm php-mysql-5.3.3-38.el6.x86_64.rpm
libevent-1.4.13-4.el6.x86_64.rpm php-pdo-5.3.3-38.el6.x86_64.rpm
libevent-devel-1.4.13-4.el6.x86_64.rpm phpredis-master.zip
libevent-doc-1.4.13-4.el6.noarch.rpm redis-3.0.2.tar.gz
libevent-headers-1.4.13-4.el6.noarch.rpm redis-3.2.5.tar.gz
libgearman-1.1.8-2.el6.x86_64.rpm redis-3.3.1.gem
libgearman-devel-1.1.8-2.el6.x86_64.rpm rhel6 Redis.pdf
lib_mysqludf_json-master.zip test
nginx-1.8.0-1.el6.ngx.x86_64.rpm test.php
php-5.3.3-38.el6.x86_64.rpm test.sql
php-cli-5.3.3-38.el6.x86_64.rpm tokyocabinet-1.4.33-6.el6.x86_64.rpm
php-common-5.3.3-38.el6.x86_64.rpm worker.php
server1上安裝mysql-server
server2上安裝nginx和php及其擴展。
nginx所在的服務器需要和mysql,redis等溝通,相當於橋樑的作用,所以需要和他們相關的插件:
php-mysql
php-redis
[root@server2 redis]# ll phpredis-master.zip
-rwxr-xr-x 1 root root 83734 Oct 21 00:18 phpredis-master.zip
[root@server2 redis]# unzip phpredis-master.zip
-bash: unzip: command not found
安裝unzip解壓:
[root@server2 phpredis-master]# ls
common.h debian.control mkdeb-apache2.sh redis_session.c
config.m4 igbinary php_redis.h redis_session.h
CREDITS library.c README.markdown serialize.list
debian library.h redis.c tests
發現其中並沒有可執行文件,需要php的開發包php-devel
[root@server2 redis]# yum install -y php-devel-5.3.3-38.el6.x86_64.rpm
然後在當前目錄下執行phpize
phpize 的作用是偵測當前的php環境,並根據環境生成一個configure。
[root@server2 phpredis-master]# phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
[root@server2 phpredis-master]# ls
acinclude.m4 config.sub library.c README.markdown
aclocal.m4 configure library.h redis.c
autom4te.cache configure.in ltmain.sh redis_session.c
build CREDITS Makefile.global redis_session.h
common.h debian missing run-tests.php
config.guess debian.control mkdeb-apache2.sh serialize.list
config.h.in igbinary mkinstalldirs tests
config.m4 install-sh php_redis.h
編譯安裝:
編譯完成後並不會生成redis.ini文件,需要自己手動生成,php.ini 在php-common的目錄下邊:[root@server2 modules]# rpm -ql php-common
/etc/php.d
/etc/php.d/curl.ini
/etc/php.d/fileinfo.ini
/etc/php.d/json.ini
/etc/php.d/phar.ini
/etc/php.d/zip.ini
/etc/php.ini
[root@server2 php.d]# cp mysql.ini redis.ini
[root@server2 php.d]# vim redis.ini
[root@server2 php.d]# pwd
/etc/php.d
[root@server2 php.d]# cat redis.ini
; Enable mysql extension module
extension=redis.so
或者直接將redis.ini寫入php.ini中。
重起php-fpm,發現redis插件已經插入
[root@server2 php.d]# php -m |grep redis
redis
[root@server2 redis]# rpm -qa |grep php
php-cli-5.3.3-38.el6.x86_64
php-fpm-5.3.3-38.el6.x86_64
php-mysql-5.3.3-38.el6.x86_64
php-common-5.3.3-38.el6.x86_64
php-5.3.3-38.el6.x86_64
php-pdo-5.3.3-38.el6.x86_64
修改nginx的配配置文件:
[root@server2 redis]# !vi
vim /etc/nginx/conf.d/default.conf
8 location / {
9 root /usr/share/nginx/html;
10 index index.php index.html index.htm;
11 }
28 #pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
29
30 location ~ \.php$ {
31 root html;
32 fastcgi_pass 127.0.0.1:9000;
33 fastcgi_index index.php;
34 fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/$fastcgi_script_name;
35 include fastcgi_params;
36 }
在/usr/share/nginx/html下編寫php的測試頁:
[root@server2 html]# ls
50x.html index.html index.php
[root@server2 html]# cat index.php
<?php
phpinfo()
?>
啓動php-fpm服務。
[root@server2 html]# service php-fpm start
Starting php-fpm: [ OK ]
重起nginx服務
[root@server2 html]# service nginx restart
Stopping nginx: [ OK ]
Starting nginx: [ OK ]
然後即可通過網頁訪問php的測試頁:
***注意:在nginx的配置文件中定義的首頁是有順序的。
在server3.example.com 上安裝redis
解壓,直接make&& make install
有寫情況下可能需要安裝環境:(根據提示走)
jemalloc-3.6.0-1.el6.x86_64.rpm
jemalloc-devel-3.6.0-1.el6.x86_64.rpm
然後進入當前目錄的utils
安裝redis
[root@server3 utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
然後一路回車
修改redis-server的配置文件:
[root@server3 utils]# vim /etc/redis/6379.conf
~~~~~~~~~~
62 bind 0.0.0.0
重起
[root@server3 utils]# /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...
[root@server3 utils]# netstat -antlp |grep redis
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 4534/redis-server 0
redis監聽在所有端口,
測試:
數據庫和php的連接需要程序的支持:
[root@server2 redis]# cat test.php
<?php
$redis = new Redis();
$redis->connect('172.25.33.3',6379) or die ("could net connect redis server");
# $query = "select * from test limit 9";
$query = "select * from test";
for ($key = 1; $key < 10; $key++)
{
if (!$redis->get($key))
{
$connect = mysql_connect('172.25.33.1','redis','westos');
mysql_select_db(test);
$result = mysql_query($query);
//如果沒有找到$key,就將該查詢sql的結果緩存到redis
while ($row = mysql_fetch_assoc($result))
{
$redis->set($row['id'],$row['name']);
}
$myserver = 'mysql';
break;
}
else
{
$myserver = "redis";
$data[$key] = $redis->get($key);
}
}
echo $myserver;
echo "<br>";
for ($key = 1; $key < 10; $key++)
{
echo "number is <b><font color=#FF0000>$key</font></b>";
echo "<br>";
echo "name is <b><font color=#FF0000>$data[$key]</font></b>";
echo "<br>";
}
?>
[root@server2 redis]#
將這個頁面作爲php的首頁。
[root@server2 redis]# cp test.php /usr/share/nginx/html/index.php
cp: overwrite `/usr/share/nginx/html/index.php'? y
在server1.example.com中插入數據
mysql> select * from test.test
-> ;
+----+-------+
| id | name |
+----+-------+
| 1 | test1 |
| 2 | test2 |
| 3 | test3 |
| 4 | test4 |
| 5 | test5 |
| 6 | test6 |
| 7 | test7 |
| 8 | test8 |
| 9 | test9 |
+----+-------+
爲index.php中的用戶授權
mysql> grant update on test.* to redis@'172.25.33.2' identified by 'westos' ;
在瀏覽器上測試:
即可得到數據庫響應的數據
此時有一個很大的缺陷:內容的一致性,redis在得到結果後,如果查找內容在其內存中存在,那麼,他就不會返回數據庫取數據,會造成數據的不一致性,所以需要添加一個觸發器:
配置gearman 實現數據同步
gearman 是一個支持分佈式的任務分發框架
gearman job server 作爲gearman的核心程序,需要編譯安裝並以守護進程形式運行在後臺。
gearman client 任務的請求者
gearman worker 任務執行着
在nginx所在的服務器安裝gearman
[root@server2 redis]# yum install -y gearmand-1.1.8-2.el6.x86_64.rpm
libgearman-1.1.8-2.el6.x86_64.rpm
[root@server2 redis]# yum install -y libgearman-devel-1.1.8-2.el6.x86_64.rpm libevent-devel-1.4.13-4.el6.x86_64.rpm libevent-headers-1.4.13-4.el6.noarch.rpm libevent-doc-1.4.13-4.el6.noarch.rpm
安裝php的gearman的擴展
安裝開發包。系統自帶
[root@server2 redis]# yum install -y db*-devel
編譯安裝gearman job server
[root@server2 redis]# tar -xf gearman-1.1.2.tgz
[root@server2 redis]# cd gearman-1.1.2
[root@server2 gearman-1.1.2]# ls
ChangeLog CREDITS LICENSE php_gearman.h test_client.php test_worker.php
config.m4 examples php_gearman.c README tests
[root@server2 gearman-1.1.2]# phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
[root@server2 gearman-1.1.2]# ./configure --with-php-config=/usr/bin/php-config
make && make install
[root@server2 gearman-1.1.2]# cd /etc/php.d/
[root@server2 php.d]# ls
curl.ini json.ini mysql.ini pdo_mysql.ini phar.ini sqlite3.ini
fileinfo.ini mysqli.ini pdo.ini pdo_sqlite.ini redis.ini zip.ini
[root@server2 php.d]# cp mysql.ini gearman.ini
[root@server2 php.d]# vim gearman.ini
[root@server2 php.d]# vim /etc/php
php.d/ php-fpm.conf php-fpm.d/ php.ini
[root@server2 php.d]# vim /etc/php.ini
[root@server2 php.d]# cat gearman.ini
; Enable mysql extension module
extension=gearman.so
或
[root@server2 php.d]# grep ^extension /etc/php.ini
extension = gearman.so
重起Php-fpm
在server1.example.com添加udf用戶自定義函數
由於要對數據庫進行操作,所以要安裝數據庫開發包
[root@server1 lib_mysqludf_json-master]# unzip lib_mysqludf_json-master.zip
[root@server1 lib_mysqludf_json-master]# cd lib_mysqludf_json-master
[root@server1 lib_mysqludf_json-master]# yum install -y mysql-devel
[root@server1 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
登陸數據庫,使用mysql> show global variables like 'plugin_dir';
+---------------+-------------------------+
| Variable_name | Value |
+---------------+-------------------------+
| plugin_dir | /usr/lib64/mysql/plugin |
+---------------+-------------------------+
1 row in set (0.00 sec)
找到數據庫插件所在的位置
[root@server1 lib_mysqludf_json-master]# ls
lib_mysqludf_json.c lib_mysqludf_json.so README.md
lib_mysqludf_json.html lib_mysqludf_json.sql
[root@server1 lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/
將用戶自定義函數考入插件庫
安裝gearman-mysql用戶自定義函數:
[root@server1 redis]# yum install -y libgearman-1.1.8-2.el6.x86_64.rpm libgearman-devel-1.1.8-2.el6.x86_64.rpm libevent-devel-1.4.13-4.el6.x86_64.rpm libevent-doc-1.4.13-4.el6.noarch.rpm libevent-headers-1.4.13-4.el6.noarch.rpm
解壓gearman-mysql-udf-0.6
編譯安裝
[root@server1 gearman-mysql-udf-0.6]# ./configure --with-mysql=/usr/bin/mysql_config --libdir=/usr/lib64/mysql/plugin/
make && make install
註冊用戶自定義函數:
CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';
註冊用戶自定義函數:
CREATE FUNCTION gman_do_background RETURNS STRING SONAME
'libgearman_mysql_udf.so';
CREATE FUNCTION gman_servers_set RETURNS STRING SONAME
'libgearman_mysql_udf.so';
mysql> CREATE FUNCTION gman_do_background RETURNS STRING SONAME
-> 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME
-> 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.00 sec)
mysql> select * from mysql.func;
+--------------------+-----+-------------------------+----------+
| name | ret | dl | type |
+--------------------+-----+-------------------------+----------+
| json_object | 0 | lib_mysqludf_json.so | function |
| gman_do_background | 0 | libgearman_mysql_udf.so | function |
| gman_servers_set | 0 | libgearman_mysql_udf.so | function |
+--------------------+-----+-------------------------+----------+
指定gearman的服務信息
mysql> select gman_servers_set('172.25.33.2:4730');
+--------------------------------------+
| gman_servers_set('172.25.33.2:4730') |
+--------------------------------------+
| 172.25.33.2:4730 |
+--------------------------------------+
1 row in set (0.00 sec)
編寫觸發器:
[root@server1 redis]# cat test.sql
use test;
#CREATE TABLE `test` (`id` int(7) NOT NULL AUTO_INCREMENT, `name` char(8) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#INSERT INTO `test` VALUES (1,'test1'),(2,'test2'),(3,'test3'),(4,'test4'),(5,'test5'),(6,'test6'),(7,'test7'),(8,'test8'),(9,'test9');
#
DELIMITER $$
CREATE TRIGGER datatoredis AFTER UPDATE ON test FOR EACH ROW BEGIN
SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`));
END$$
DELIMITER ;
查看觸發器:
mysql> SHOW TRIGGERS FROM test;
+-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
| datatoredis | UPDATE | test | BEGIN
SET @RECV=gman_do_background('syncToRedis', json_object(NEW.id as `id`, NEW.name as `name`));
END | AFTER | NULL | | root@localhost | latin1 | latin1_swedish_ci | latin1_swedish_ci |
+-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)
mysql>
編寫gearman 的worker端
[root@server2 redis]# cat worker.php
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');
$redis = new Redis();
$redis->connect('172.25.33.3', 6379);
while($worker->work());
function syncToRedis($job)
{
global $redis;
$workString = $job->workload();
$work = json_decode($workString);
if(!isset($work->id)){
return false;
}
$redis->set($work->id, $work->name);
}
?>
直接後臺運行worker
[root@server2 redis]# nohup php worker.php &>/dev/null &
mysql> update test.test set name ='ginkgo';
Query OK, 9 rows affected (0.12 sec)
Rows matched: 9 Changed: 9 Warnings: 0
"westos"
127.0.0.1:6379> MONITOR
OK
1489902207.604830 [0 172.25.33.2:57867] "SET" "1" "ginkgo"
1489902207.605362 [0 172.25.33.2:57867] "SET" "2" "ginkgo"
1489902207.605802 [0 172.25.33.2:57867] "SET" "3" "ginkgo"
1489902207.606244 [0 172.25.33.2:57867] "SET" "4" "ginkgo"
1489902207.606688 [0 172.25.33.2:57867] "SET" "5" "ginkgo"
1489902207.607052 [0 172.25.33.2:57867] "SET" "6" "ginkgo"
1489902207.607333 [0 172.25.33.2:57867] "SET" "7" "ginkgo"
1489902207.607773 [0 172.25.33.2:57867] "SET" "8" "ginkgo"
1489902207.608201 [0 172.25.33.2:57867] "SET" "9" "ginkgo"