環境設定
base2 172.25.78.12 nginx+php
base3 172.25.78.13 redis端
base4 172.25.78.14 mysql端
# 1.在base2(nginx+php)上
配置nginx和php(這里的nginx只是提供了負載均衡,所以版本要求不高)
[root@base2 ~]# killall redis-server
[root@base2 ~]# ls
gearmand-1.1.12-18.el7.x86_64.rpm
php-fpm-5.4.16-46.el7.x86_64.rpm
libevent-devel-2.0.21-4.el7.x86_64.rpm
php-mysql-5.4.16-46.el7.x86_64.rpm
libgearman-1.1.12-18.el7.x86_64.rpm
php-pdo-5.4.16-46.el7.x86_64.rpm
libgearman-devel-1.1.12-18.el7.x86_64.rpm
php-pecl-gearman-1.1.2-1.el7.x86_64.rpm
libzip-0.10.1-8.el7.x86_64.rpm
php-pecl-igbinary-1.2.1-1.el7.x86_64.rpm
openssl-1.0.2k-16.el7.x86_64.rpm
php-pecl-redis-2.2.8-1.el7.x86_64.rpm
openssl-libs-1.0.2k-16.el7.x86_64.rpm
php-process-5.4.16-46.el7.x86_64.rpm
php-cli-5.4.16-46.el7.x86_64.rpm
php-xml-5.4.16-46.el7.x86_64.rpm
php-common-5.4.16-46.el7.x86_64.rpm
[root@base2 ~]# yum install -y *.rpm # 安裝php
注:當服務器上有openssl-devel開發包時,會有沖突,所以要先刪除
[root@base2 ~]# tar zxf nginx-1.14.2.tar.gz
[root@base2 ~]# cd nginx-1.14.2
[root@base2 nginx-1.14.2]# vim auto/cc/gcc
171 # debug
172 #CFLAGS="$CFLAGS -g"
[root@base2 nginx-1.14.2]# vim src/core/nginx.h
14 #define NGINX_VER "nginx/"
[root@base2 nginx-1.14.2]# ./configure --prefix=/usr/local/nginx
[root@base2 nginx-1.14.2]# make && make install
[root@base2 ~]# cd /usr/local/nginx/conf/
[root@base2 conf]# vim nginx.conf
location / {
root html;
index index.php index.html index.htm;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi.conf;
}
[root@base2 conf]# ln -s /usr/local/nginx/sbin/nginx /sbin
[root@base2 conf]# nginx -t
[root@base2 conf]# nginx # 開啟nginx服務
[root@base2 conf]# vim /etc/php.ini
878 date.timezone =Asia/Shanghai
[root@base2 conf]# vim /etc/php-fpm.d/www.conf
39 user = nginx
41 group = nginx
[root@base2 conf]# systemctl start php-fpm
[root@base2 conf]# systemctl status php-fpm # 開啟php服務
[root@base2 conf]# netstat -antlp # 查看php的端口
# nginx服務搭建成功
[root@base2 conf]# cd /usr/local/nginx/html/
[root@base2 html]# vim index.php # 編寫php網頁,測試php
<?php
phpinfo()
?>
# php配置成功
[root@server1 html]# vim index.php # 重新編寫php頁面,把redis服務器和mysql服務器建立練習
<?php
$redis = new Redis();
$redis->connect('172.25.78.13',6379) or die ("could net connect redis server"); # 這是redis服務器
# $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.78.14','redis','redhat'); # 這是數據庫服務器,用戶以及密碼
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>";
}
# 2.redis服務端
[root@base3 ~]# tar zxf redis-5.0.3.tar.gz
[root@base3 ~]# cd redis-5.0.3
[root@base3 redis-5.0.3]# yum install gcc -y
[root@base3 redis-5.0.3]# make && make install
[root@base3 redis-5.0.3]# cd utils/
[root@base3 utils]# ./install_server.sh
[root@base3 utils]# vim /etc/redis/6379.conf
70 bind 0.0.0.0
[root@base3 ~]# systemctl restart redis_6379
[root@base3 ~]# redis-cli
127.0.0.1:6379> info replication
[root@base3 ~]# netstat -antlp
# 3.mysql服務端
[root@base4 ~]# yum install -y mariadb-server
[root@base4 ~]# systemctl start mariadb
[root@base4 ~]# mysql_secure_installation
[root@base4 ~]# mysql -p
Enter password:
MariaDB [(none)]> show databases;
MariaDB [(none)]> create database test;
MariaDB [(none)]> grant all on test.* to redis@'%' identified by 'redhat';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> quit
Bye
[root@base4 ~]# vim 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; # 在test數據庫里創建表
INSERT INTO `test` VALUES (1,'test1'),(2,'test2'),(3,'test3'),(4,'test4'),(5,'test5'),(6,'test6'),(7,'test7'),(8,'test8'),(9,'test9'); # 給表里添加內容
[root@base4 ~]# mysql -predhat < test.sql
[root@base4 ~]# mysql -p
Enter password:
MariaDB [(none)]> select * from test.test;
# 測試:
這是mysql服務器通過php頁面利用redis緩存來顯示數據庫中的內容
# 但是有一個問題,mysql更新后,redis無法同步
MariaDB [(none)]> use test;
MariaDB [test]> update test set name='lala' where id=1;
MariaDB [test]> select * from test.test;
[root@base3 ~]# redis-cli # 發現redis服務器並沒有同步mysql上的數據
2.gearman 實現redis和mysql的數據同步
Gearman 是一個支持分布式的任務分發框架:
Gearman Job Server: Gearman 核心程序,需要編譯安裝並以守護進程形式運行在后台。
Gearman Client:可以理解為任務的請求者。
Gearman Worker:任務的真正執行者,一般需要自己編寫具體邏輯並通過守護進程方式
運行,Gearman Worker 接收到 Gearman Client 傳遞的任務內容后,會按順序處理。
大致流程:下面要編寫的 mysql 觸發器,就相當於 Gearman 的客戶端。修改表,插入表就相當於直接
下發任務。然后通過 lib_mysqludf_json UDF 庫函數將關系數據映射為 JSON 格式,然后
在通過 gearman-mysql-udf 插件將任務加入到 Gearman 的任務隊列中,最后通過
[root@base2 ~]# systemctl start gearmand
[root@base2 ~]# netstat -antlp
安裝 php 的 gearman 擴展,安裝 lib_mysqludf_json,lib_mysqludf_json UDF 庫函數將關系數據映射為 JSON 格式。通常,數據庫中的數據映射為 JSON 格式,是通過程序來轉換的。
[root@base4 ~]# ls
lib_mysqlud_json-master.zip
[root@base4 ~]# yum install -y unzip
[root@base4 ~]# unzip lib_mysqludf_json-master.zip
[root@base4 ~]# cd lib_mysqludf_json-master
[root@base4 lib_mysqludf_json-master]# yum install -y gcc
[root@base4 lib_mysqludf_json-master]# yum list mariadb-devel
[root@base4 lib_mysqludf_json-master]# yum install -y mariadb-devel.x86_64
[root@base4 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
[root@base4 ~]# cp lib_mysqludf_json-master/lib_mysqludf_json.so /usr/lib64/mysql/plugin/
[root@base4 lib_mysqludf_json-master]# cd /usr/lib64/mysql/
[root@base4 ~]# cd /usr/lib64/mysql/plugin/
[root@base4 plugin]# mysql -p
Enter password:
MariaDB [(none)]> show global variables like 'plugin_dir'; # 查看 mysql 的模塊目錄:
MariaDB [(none)]> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so'; # 注冊 UDF 函數
MariaDB [(none)]> select * from mysql.func;
MariaDB [(none)]> quit
Bye
# 安裝 gearman-mysql-udf,這個插件是用來管理調用 Gearman 的分布式的隊列。
[root@base4 ~]# ls
gearman-mysql-udf-0.6.tar.gz
[root@base4 ~]# cd gearman-mysql-udf-0.6
[root@base4 gearman-mysql-udf-0.6]# ./configure --with-mysql=/usr/bin/mysql_config --libdir=/usr/lib64/mysql/plugin/ # 有報錯,依賴性沒解決完
[root@base4 gearman-mysql-udf-0.6]# cd
[root@base4 ~]# yum install -y libgearman-devel-1.1.12-18.el7.x86_64.rpm libevent-devel-2.0.21-4.el7.x86_64.rpm libgearman-1.1.12-18.el7.x86_64.rpm # 解決依賴性
[root@base4 ~]# cd gearman-mysql-udf-0.6
[root@base4 gearman-mysql-udf-0.6]# ./configure --with-mysql=/usr/bin/mysql_config --libdir=/usr/lib64/mysql/plugin/
[root@base4 gearman-mysql-udf-0.6]# make && make install
[root@base4 gearman-mysql-udf-0.6]# mysql -p
Enter password:
# 注冊 UDF 函數
MariaDB [(none)]> CREATE FUNCTION gman_do_background RETURNS STRING SONAME 'libgearman_mysql_udf.so';
MariaDB [(none)]> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME 'libgearman_mysql_udf.so';
MariaDB [(none)]> select * from mysql.func; # 查看函數
MariaDB [(none)]> SELECT gman_servers_set('172.25.78.12:4730'); # 指定 gearman 的服務信息
mysql> Bye
# 編寫 mysql 觸發器(根據實際情況編寫)
[root@base4 gearman-mysql-udf-0.6]# cd
[root@base4 ~]# vim test.sql
use test;
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 ;
[root@base4 ~]# mysql -predhat < test.sql
[root@base4 ~]# mysql -p
Enter password:
MariaDB [(none)]> SHOW TRIGGERS FROM test\G; # 查看觸發器
# 在base2上,編寫 gearman 的 worker 端
[root@base2 ~]# cd /usr/local/
[root@base2 local]# vim worker.php
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');
$redis = new Redis();
$redis->connect('172.25.78.13', 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);
# 這條語句就是將 id 作 KEY 和name 作 VALUE 分開存儲,需要和前面寫的 php 測試代碼的存取一致。
}
?>
[root@base2 ~]# nohup php /usr/local/worker.php &> /dev/null &
3.測試:
# 在mysql端(base4)更新 mysql 中的數據
MariaDB [test]> update test set name='lala' where id=1;
MariaDB [test]> update test set name='lala' where id=2;
MariaDB [test]> update test set name='lala' where id=3;
MariaDB [test]> select * from test;
# 在redis端(base3)查看是否同步成功
# 刷新測試頁面數據同步