主机名 | ip | 配置 |
---|---|---|
server1 | 172.25.55.1 | lnmp |
server2 | 172.25.55.2 | redis |
server3 | 172.25.55.3 | mariadb |
client -> app -> redis -> mysql(如果在redis找不到再访问mysql) -> redis -> client
nginx的安装
[root@server1 ~]# yum install gcc gcc-c++ zlib-devel pcre-devel -y
[root@server1 ~]# tar zxf nginx-1.14.2.tar.gz
[root@server1 nginx-1.14.2]# ./configure --prefix=/usr/local/nginx
[root@server1 nginx-1.14.2]# make && make install
[root@server1 nginx-1.14.2]# cd /usr/local/nginx/
[root@server1 nginx]# vim conf/nginx.conf
43 location / {
44 root html;
45 index index.php index.html index.htm;
46 }
62 location ~*\.(jpg|png|css|js)?$ {
63 expires 60d;
64 }
65
66
67 # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
68 #
69 location ~ \.php$ {
70 root html;
71 fastcgi_pass 127.0.0.1:9000;
72 fastcgi_index index.php;
73 # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
74 include fastcgi.conf;
75 }
[root@server1 nginx]# /usr/local/nginx/sbin/nginx
安装php
[root@server1 ~]# ls
gearmand-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
libgearman-devel-1.1.12-18.el7.x86_64.rpm
libzip-0.10.1-8.el7.x86_64.rpm
openssl-1.0.2k-16.el7.x86_64.rpm
openssl-libs-1.0.2k-16.el7.x86_64.rpm
php-cli-5.4.16-46.el7.x86_64.rpm
php-common-5.4.16-46.el7.x86_64.rpm
php-fpm-5.4.16-46.el7.x86_64.rpm
php-mysql-5.4.16-46.el7.x86_64.rpm
php-pdo-5.4.16-46.el7.x86_64.rpm
php-pecl-gearman-1.1.2-1.el7.x86_64.rpm
php-pecl-igbinary-1.2.1-1.el7.x86_64.rpm
php-pecl-redis-2.2.8-1.el7.x86_64.rpm
php-process-5.4.16-46.el7.x86_64.rpm
php-xml-5.4.16-46.el7.x86_64.rpm
[root@server1 ~]# yum install * -y
[root@server1 nginx]# systemctl start php-fpm
[root@server1 html]# ls
50x.html index.html test.php
[root@server1 html]# mv test.php index.php
[root@server1 html]# vim index.php (完整代码,可使用)
connect('172.25.55.2',6379) or die ("could net connect redis server");#修改ip为redis所在主机ip。
# $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.55.3','redis','westos');#修改ip为mariadb所在主机ip。
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 "
";
for ($key = 1; $key < 10; $key++)
{
echo "number is $key";
echo "
";
echo "name is $data[$key]";
echo "
";
}
?>
安装redis
[root@server2 ~]# ls
redis-5.0.3.tar.gz
[root@server2 ~]# tar zxf redis-5.0.3.tar.gz
[root@server2 ~]# cd redis-5.0.3
[root@server2 redis-5.0.3]# ls
[root@server2 redis-5.0.3]# yum install gcc gcc-c++ -y
[root@server2 redis-5.0.3]# make && make install
[root@server2 redis-5.0.3]# cd utils/
[root@server2 utils]# ./install_server.sh
[root@server2 utils]# vim /etc/redis/6379.conf
70 bind 0.0.0.0
[root@server2 utils]# systemctl start redis_6379(开启服务)
[root@server3 ~]# yum install mariadb-server
[root@server3 ~]# systemctl start mariadb
[root@server3 ~]# mysql_secure_installation
登录mysql做如下设置:
MariaDB [(none)]> create database test;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> grant all on test.* to redis@'%' identified by 'westos' ;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
[root@server3 ~]# 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 ;
[root@server3 ~]# mysql -predhat < test.sql (导入数据库)
redis查看数据:(redis可以查看到数据,redis作为mariadb的缓存服务已经做好)
网页访问:
修改server3端的数据库里的信息。
修改数据后,redis数据不同步,仍然是原数据,网页访问数据也不同步,因为网页数据来自redis。
要使数据同步,我们需要配置gearman来实现数据同步。
我们借用已经比较成熟的MySQL UDF,将MySQL数据首先放入Gearman中,然后通过一个自己编写的PHP Gearman Worker,将数据同步到Redis。比分析binlog的方式增加了不少流程,但是实现成本更低,更容易操作。
Gearman Job Server:Gearman核心程序,需要编译安装并以守护进程形式运行在后台。
Gearman Client:可以理解为任务的收件员,比如我要在后台执行一个发送邮件的任务,可以在程序中调用一个Gearman Client并传入邮件的信息,然后就可以将执行结果立即展示给用户,而任务本身会慢慢在后台运行。
Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行,Gearman Worker接收到Gearman Client传递的任务内容后,会按顺序处理。
Gearman Job Server:对应Resque的Redis部分
Gearman Client:对应Resque的Queue操作
Gearman Worker:对应Resque的Worker和Job
这里之所以选择Gearman而不是Resque是因为Gearman提供了比较好用的MySQL UDF,工作量更小。
在mariadb端:
[root@server3 ~]# yum install -y master-devel
[root@server3 ~]# cd lib_mysqludf_json-master/
[root@server3 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
[root@server3 ~]# cp lib_mysqludf_json-master/lib_mysqludf_json.so /usr/lib64/mysql/plugin/
[root@server3 ~]# cd /usr/lib64/mysql/plugin/
[root@server3 ~]# yum install libgearman-devel-1.1.12-18.el7.x86_64.rpm libgearman-1.1.12-18.el7.x86_64.rpm libevent-devel-2.0.21-4.el7.x86_64.rpm -y
[root@server3 ~]# tar zxf gearman-mysql-udf-0.6.tar.gz
[root@server3 ~]# cd gearman-mysql-udf-0.6
[root@server3 gearman-mysql-udf-0.6]# ./configure --libdir=/usr/lib64/mysql/plugin/ --with-mysql
[root@server3 gearman-mysql-udf-0.6]# make && make install
MariaDB [(none)]> create function json_object returns string soname 'lib_mysqludf_json.so';
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> create function gman_do_background returns string soname 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> create function gman_servers_set returns string soname 'libgearman_mysql_udf.so';
Query OK, 0 rows affected (0.00 sec)
[root@server3 ~]# 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 ;
[root@server3 ~]# mysql -predhat < test.sql
[root@server1 ~]# systemctl start gearmand
[root@server1 ~]# cat /usr/local/worker.php
addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');
$redis = new Redis();
$redis->connect('172.25.55.2', 6379); #(redis端的ip)
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);
}
?>
[root@server1 ~]# nohup php /usr/local/worker.php &> /dev/null &
在server3(mariadb端)登录数据库修改test数据库信息。
查看server2(redis端)的redis存储系统的数据已经改变。
访问网页,数据已经更新。