为了实现mysql在nginx平台的缓存
应用平台:
环境部署:server1——–>nginx(80);php(9000)
server2——–>redis(6379)
server3——–>mysql
[root@server1 redis]# vim /etc/php.ini #修改时区Asia/Shanghai
[root@server1 redis]# vim /etc/php-fpm.conf
[root@server1 redis]# id nginx
uid=498(nginx) gid=499(nginx) groups=499(nginx)
[root@server1 redis]# cd /etc/php-fpm.d/
[root@server1 php-fpm.d]# vim www.conf
[root@server1 php-fpm.d]# /etc/init.d/php-fpm start
Starting php-fpm: [ OK ]
[root@server1 php-fpm.d]# netstat -anulp
[root@server1 php-fpm.d]# vim /etc/nginx/nginx.conf#查看nginx用户
[root@server1 redis]# vim /etc/php-fpm.conf
[root@server1 redis]# id nginx
uid=498(nginx) gid=499(nginx) groups=499(nginx)
[root@server1 redis]# cd /etc/php-fpm.d/
[root@server1 php-fpm.d]# vim www.conf #修改php用户为nginx
[root@server1 php-fpm.d]# vim /etc/nginx/conf.d/default.conf
#支持php环境将nginx默认发布文件次序设置为index.php
[root@server1 php-fpm.d]# /etc/init.d/nginx start
Starting nginx: [ OK ]
[root@server1 php-fpm.d]# netstat -antlp
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1864/nginx
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 1836/php-fpm
tcp 0 0 172.25.30.1:22 172.25.30.250:34814 ESTABLI
[root@server1 php-fpm.d]# vim /usr/share/nginx/html/index.php#编辑php文件在nginx发布目录下面访问测试nginx-php:
[root@server1 php-fpm.d]# nginx -s reload
2.编写php建立和redis,mysql的连接.
-------------------------
[root@server1 redis]# cp test.php /usr/share/nginx/html/index.php
cp: overwrite `/usr/share/nginx/html/index.php'? y
[root@server1 redis]# vim /usr/share/nginx/html/index.php
$redis->connect('172.25.30.2',6379) or die ("could net connect redis server");
for ($key = 1; $key < 10; $key++)
{
if (!$redis->get($key))
{
$connect = mysql_connect('172.25.30.3','redis','westos');
mysql_select_db(test);
$result = mysql_query($query);
//如果没有找到$key,就将该查询sql的结果缓存到redis
[root@server1 redis]# php -m
[PHP Modules] #该php_modules中没有redis模块我们需要重新编译添加:
[root@server1 redis]# yum install unzip -y
[root@server1 redis]# unzip phpredis-master.zip
#rpm包编译安装
[root@server1 phpredis-master]# ./configure
[root@server1 phpredis-master]# make
[root@server1 phpredis-master]# make install
Installing shared extensions: /usr/lib64/php/modules/
[root@server1 modules]# cd /etc/php.d/
[root@server1 php.d]# cp mysql.ini redis.ini
[root@server1 php.d]# vim redis.ini #在redis配置文件中添加redis.so#模块.刷新配置php-fpm将redis模块添加成功
Index.php中访问的是172.25.30.2的redis—–>6379端口.
我们要查看该后台服务器是否有6379端口,redis部署我们已经在之前的学习中学习了:
安装部署mysql:
在安装之前把服务器中高可用mysql数据清空重新安装mysql这里我们安装的是mysql----rpm;
[root@server3 ~]# rpm -e --nodeps `rpm -qa|grep mysql`
warning: /etc/my.cnf saved as /etc/my.cnf.rpmsave #取消依赖性卸载
[root@server3 ~]# yum install -y mysql-server #安装初始化
[root@server3 ~]# vim /etc/my.cnf
[root@server3 ~]# /etc/init.d/mysqld start
Initializing MySQL database: Installing MySQL system tables...
[root@server3 ~]# mysql #mysql-server可以免密登陆
mysql> grant all on test.* to redis@'%' identified by 'westos'; #登陆授权在test库上用户redis密码westos;
[root@server3 ~]# vim test.sql #编辑了一个脚本可以在mysql中插入数据
[root@server3 ~]# mysql < test.sql
所有部署安装完毕访问测试平台:在redis还没有缓存到数据之前得到的数据是从mysql源中取出来的,刷新之后redis将mysql的数据缓存下来之后nginx只奔redis中取数据.
在redis上访问:
但是客户端从浏览器获取到的数据没有发生变化,因为缓存还在,先找缓存再找mysql不能实现同步更新.到这里,我们已经实现了 redis 作为 mysql 的缓存服务器,但是如果更新mysql,redis中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情况。所以接下来就要通过 mysql 触发器将改变的数据同步到 redis 中。
Gearman 是一个支持分布式的任务分发框架:
Gearman Job Server:Gearman 核心程序,需要编译安装并以守护进程形式运行在后台。
Gearman Client:可以理解为任务的请求者。
Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式
运行,Gearman Worker 接收到 Gearman Client 传递的任务内容后,会按顺序处理。
大致流程:
下面要编写的 mysql 触发器,就相当于 Gearman 的客户端。修改表,插入表就相当于直接下发任务。然后通过 lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式,然后在通过 gearman-mysql-udf 插件将任务加入到 Gearman 的任务队列中,最后通过
redis_worker.php,也就是 Gearman 的 worker 端来完成 redis 数据库的更新。
server1:安装包:
gearmand-1.1.8-2.el6.x86_64.rpm
gearman-mysql-udf-0.6.tar.gz
go1.8.linux-amd64.tar.gz
jemalloc-3.6.0-1.el6.x86_64.rpm
jemalloc-devel-3.6.0-1.el6.x86_64.rpm
libevent-1.4.13-4.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
libgearman-1.1.8-2.el6.x86_64.rpm
libgearman-devel-1.1.8-2.el6.x86_64.rpm
lib_mysqludf_json-master.zip
libyaml-0.1.3-4.el6_6.x86_64.rpm
[root@server1 redis]# yum install -y gearmand-1.1.8-2.el6.x86_64.rpm libgearman-* lib*
[root@server1 redis]# /etc/init.d/gearmand start 不用配置,直接启动
Starting gearmand: [ OK ]
[root@server1 redis]# netstat -antulpe #端口6379
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 0 29448 1707/redis-server 0
server3安装编译:
server3:
[root@server3 ~]# yum install -y unzip
[root@server3 ~]# unzip lib_mysqludf_json-master.zip
[root@server3 ~]# cd lib_mysqludf_json-master
[root@server3 lib_mysqludf_json-master]# ls
lib_mysqludf_json.c lib_mysqludf_json.so README.md
lib_mysqludf_json.html lib_mysqludf_json.sql
[root@server3 lib_mysqludf_json-master]# yum install -y gcc mysql-devel
[root@server3 lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
[root@server3 lib_mysqludf_json-master]# ls
lib_mysqludf_json.c lib_mysqludf_json.so README.md
lib_mysqludf_json.html lib_mysqludf_json.sql
[root@server3 plugin]# cd -
/root/lib_mysqludf_json-master
[root@server3 lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/ 拷贝 lib_mysqludf_json.so 模块:
lib_mysqludf_json.so模块安装完毕!数据库注册!
注册 UDF 函数:
mysql> CREATE FUNCTION json_object RETURNS STRING SONAME
-> 'lib_mysqludf_json.so';
这个插件是用来管理调用 Gearman 的分布式的队列。
[root@server3 ~]# tar zxf gearman-mysql-udf-0.6.tar.gz
[root@server3 ~]# yum install -y libgearman-* libevent-*
[root@server3 ~]# cd gearman-mysql-udf-0.6
[root@server3 gearman-mysql-udf-0.6]# ls
aclocal.m4 config configure libgearman_mysql_udf Makefile.in
AUTHORS config.h.in configure.ac m4 NEWS
ChangeLog config.log COPYING Makefile.am README
[root@server3 gearman-mysql-udf-0.6]# ./configure --with-mysql=/usr/bin/mysql_config --libdir=/usr/lib64/mysql/plugin/
[root@server3 gearman-mysql-udf-0.6]# make
[root@server3 gearman-mysql-udf-0.6]# make install
libgearman_mysql_udf.so安装完毕
数据库注册:注册 UDF 函数
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.30.1:4730');
+--------------------------------------+
| gman_servers_set('172.25.30.1:4730') |
+--------------------------------------+
| 172.25.30.1:4730 |
+--------------------------------------+
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 |
+-------------+--------+-------+----------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
[root@server3 ~]# 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@server3 ~]# mysql < test.sql
[root@server1 redis]# tar zxf gearman-1.1.2.tgz
[root@server1 redis]# cd gearman-1.1.2
[root@server1 gearman-1.1.2]# phpize
Configuring for:
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
[root@server1 gearman-1.1.2]# ./configure
[root@server1 gearman-1.1.2]# make && make install
Installing shared extensions: /usr/lib64/php/modules/
[root@server1 gearman-1.1.2]# cd /usr/lib64/php/modules/
[root@server1 modules]# ls
fileinfo.so json.so mysql.so pdo_sqlite.so sqlite3.so
gd.so mbstring.so pdo_mysql.so phar.so zip.so
[root@server1 modules]# cd /etc/php.d/
加入php模块
[root@server1 php.d]# cp redis.ini gearman.ini
[root@server1 php.d]# vim gearman.ini
extension=gearman.so
重新加载php
[root@server1 php.d]# /etc/init.d/php-fpm reload
[root@server1 php.d]# php -m | grep gearman
gearman
[root@server1 php.d]# cd
[root@server1 ~]# vim /usr/local/worker.php
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');
$redis = new Redis();
$redis->connect('172.25.30.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 ~]# php /usr/local/worker.php &
[1] 6599
[root@server1 ~]# nohup hup /usr/local/worker.php &
[2] 6600
全部配置完毕server3测试:
[root@server3 ~]# mysql < test.sql
mysql> update test.test set name='redhat';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 9 Changed: 0 Warnings: 0
mysql> select * from test.test;
+----+--------+
| id | name |
+----+--------+
| 1 | redhat |
| 2 | redhat |
| 3 | redhat |
| 4 | redhat |
| 5 | redhat |
| 6 | redhat |
| 7 | redhat |
| 8 | redhat |
| 9 | redhat |
+----+--------+