Redis 作 mysql 缓存服务器
redis常本用来作为缓存服务器。缓存的好处是减少服务器的压力,数据查询速度快。解决数据响应慢的问题。
添加缓存:只用redis的Hash数据类型添加缓存.
- 1.首先需要在执行正常的业务逻辑之前(查询数据库之前),查询缓存,如果缓存中没有需要的数据,查询数据库
为了防止添加缓存出错,影响正常业务代码的执行,将添加缓存的代码放置到try-catch代码快中,让程序自动捕获。- 2.完成数据库的查询操作,查询完成之后需要将查询的数据添加到缓存中。
数据流向
webserver–>>(r/w)redis-server–>>钩子函数–>>input–>>mysql
数据更新
webserver–>>r(redis-server cache 降低mysql访问量)–>>w(mysql)–>>update mysql–>>trigger ->> redis-server
redis与mysql数据同步
mysql -> gearman(server) ->
job(mysql trigger)提交 mysql-gearman -->gearmand server --> worker(程序 php-gearmanserver获取任务,可以连接redis做set )
Gearman
Gearman提供了一个通用的应用程序框架,可以将工作分配给更适合工作的其他机器或进程。 它允许并行工作,负载均衡处理以及在语言之间调用函数。 它可用于各种应用程序,从高可用性网站到数据库复制事件的传输。 换句话说,它是分布式处理如何通信的神经系统。
Gearman驱动的应用程序由三部分组成:客户端,工作者和作业服务器。客户端负责创建要运行的作业并将其发送到作业服务器。作业服务器将找到一个合适的工作者,可以运行该作业并转发该作业。工作者执行客户端请求的工作,并通过作业服务器向客户端发送响应。 Gearman提供应用程序调用的客户端和工作者API,以与Gearman作业服务器(也称为gearmand)进行通信,因此您无需处理网络或作业映射。在内部,gearman客户端和worker API使用TCP套接字与作业服务器通信。
例如:下面的代码
client:
<?php
// Reverse Client Code
$client = new GearmanClient();
$client->addServer();
print $client->do("reverse", "Hello World!");
初始化客户端类,将其配置为使用带有add_server的作业服务器(没有参数意味着使用127.0.0.1和默认端口),然后告诉客户端API使用工作负载“Hello world!”运行反向函数。 就Gearman而言,函数名和参数完全是任意的,因此您可以发送适合您的应用程序的任何数据结构(文本或二进制)。 此时,Gearman客户端API会将作业打包成Gearman协议数据包并将其发送到作业服务器,以找到可以运行反向功能的相应工作程序。
worker:
<?php
// Reverse Worker Code
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction("reverse", function ($job) {
return strrev($job->workload());
});
while ($worker->work());
此代码定义了一个函数my_reverse_function,它接受一个字符串并返回该字符串的反向。 在设置连接到与客户端相同的本地作业服务器之后,工作对象使用它来注册名为reverse的函数。 当作业服务器收到要运行的作业时,它会查看已注册功能名称的工作人员列表,并将作业转发给其中一个免费工作人员。 然后,Gearman worker API接受此请求,运行my_reverse_function函数,并通过作业服务器将该函数的结果发送回客户端。
如您所见,客户端和工作者API(以及作业服务器)处理作业管理和网络通信,因此您可以专注于应用程序部分。 您可以通过几种不同的方式在Gearman中运行作业,包括异步处理和优先级作业的后台。
172.25.14.5 | webserver |
---|---|
172.25.14.6 | redis-server |
172.25.14.7 | mysql |
webserver:
- 1、安装lamp
$ yum install php php-mysql httpd pcre-devel autoconf automake
$ rpm -ivh php-devel-5.4.16-42.el7.x86_64.rpm
$ vim /var/www/html/test.php
<?php
$redis = new Redis();
$redis->connect('172.25.14.2',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.14.3','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>";
}
?>
- 2、redis-php模块
$ unzip phpredis-master.zip
$ cd phpredis-master/
$ phpize
$ ./configure --enable-redis
$ make
$ make install
$ vim /etc/php.ini 修改时区
$ systemctl restart htpd
$ cd /etc/php.d/
$ vim redis.ini
extension=redis.so
$ systemctl restart httpd
mariadb
- 1、 mysql < 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');
- 2、 授权:
MariaDB [(none)]> grant all on test.* to redis@'%' identified by 'westos';
- 3、测试:
web可以通过redis可以拿到数据,但是当后端数据库刷新数据后,web依然是拿到redis端的缓存数据,redis没有同步更新mysql的数据,redis只有清空缓存后才能重新获取新后的数据,web才能显示新的数据。
修改数据,然后清除redis缓存信息。
配置 gearman 实现数据同步
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 数据库的更新
- 1、webserver端 安装gearman
gearmand-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
libgearman-devel-1.1.12-18.el7.x86_64.rpm
systemctl start gearmand #启动服务
- 2、安装php的gearman扩展
[root@server1 ~]# tar zxf gearman-1.1.2.tgz
[root@server1 ~]# cd gearman-1.1.2/
[root@server1 gearman-1.1.2]# phpize
Configuring for:
PHP Api Version: 20100412
Zend Module Api No: 20100525
Zend Extension Api No: 220100525
[root@server1 gearman-1.1.2]# ./configure --with-gearman
[root@server1 gearman-1.1.2]# make && make install
[root@server1 php.d]# php -m | grep gearman
gearman
mariadb:
- 1、安装 lib_mysqludf_json
lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式。通常,数据库中的数据映射为 JSON 格式,是通过程序来转换的
[root@server3 lib_mysqludf_json-master]# unzip lib_mysqludf_json-master.zip
[root@server3 lib_mysqludf_json-master]# 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
- 2、查看mysql的模块目录
MariaDB [(none)]> show global variables like ‘plugin_dir’;
-
3、拷贝 lib_mysqludf_json.so 模块:
[root@server3 lib_mysqludf_json-master]# cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/ -
4、注册UDF函数
MariaDB [(none)]> CREATE FUNCTION json_object RETURNS STRING SONAME
-> 'lib_mysqludf_json.so';
- 5、安装 gearman-mysql-udf
# tar zxf gearman-mysql-udf-0.6.tar.gz
[root@server3 gearman-mysql-udf-0.6]# ./configure --with-mysql --libdir=/usr/lib64/mysql/plugin/
[root@server3 gearman-mysql-udf-0.6]# make && make install
- 6、注册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';
查看函数
指定gearman的服务信息
MariaDB [(none)]> select gman_servers_set('172.25.14.1:4730');
- 7、编写mysql触发器
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
查看触发器
- 8、编写gearman的worker端
[root@server1 ~]# vim /usr/local/worker.php
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');
$redis = new Redis();
$redis->connect('172.25.14.2', 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@server1 ~]# nohup php /usr/local/worker.php &
- 9、更新mysql数据信息
MariaDB [test]> update test set name='linux' where id=1;
redis同步获取更新数据
刷新网页,数据同步过来