Redis做mysql缓存,gearman实现数据同步

本文介绍如何利用Redis作为MySQL的缓存服务器,通过Gearman框架实现数据更新时的缓存同步,确保缓存与数据库的一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.5webserver
172.25.14.6redis-server
172.25.14.7mysql
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同步获取更新数据
在这里插入图片描述

刷新网页,数据同步过来
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值