首页 > 后端开发 > 正文

php redis做mysql的缓存,怎么异步redis同步到mysql数据库

2025-02-14 14:14:11 | 我爱编程网

今天我爱编程网小编整理了php redis做mysql的缓存,怎么异步redis同步到mysql数据库相关信息,希望在这方面能够更好的大家。

本文目录一览:

php redis做mysql的缓存,怎么异步redis同步到mysql数据库

php redis做mysql的缓存,怎么异步redis同步到mysql数据库

对于变化频率非常快的数据来说,如果还选择传统的静态缓存方式(Memocached、File System等)展示数据 ,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的NoSQL数据库,就非常适合担任实时数据的容器。

但是往往又有数据可靠性的需求,采用MySQL作为数据存储,不会因为内存问题而引起数据丢失,同时也可以利用关系数据库的特性实现很多功能。

所以就会很自然的想到是否可以采用MySQL作为数据存储引擎,Redis则作为Cache。而这种需求目前还没有看到有特别成熟的解决方案或工具,因此采用Gearman+PHP+MySQL UDF的组合异步实现MySQL到Redis的数据复制。

MySQL到Redis数据复制方案

无论MySQL还是Redis,自身都带有数据同步的机制,比较常用的MySQL的Master/Slave模式,就是由Slave端分析Master的binlog来实现的,这样的数据复制其实还是一个异步过程,只不过当服务器都在同一内网时,异步的延迟几乎可以忽略。

那么理论上也可以用同样方式,分析MySQL的binlog文件并将数据插入Redis。但是这需要对binlog文件以及MySQL有非常深入的理解,同时由于binlog存在Statement/Row/Mixedlevel多种形式,分析binlog实现同步的工作量是非常大的。

因此这里选择了一种开发成本更加低廉的方式,借用已经比较成熟的MySQL UDF,将MySQL数据首先放入Gearman中,然后通过一个自己编写的PHP Gearman Worker,将数据同步到Redis。比分析binlog的方式增加了不少流程,但是实现成本更低,更容易操作。

Gearman的安装与使用

Gearman是一个支持分布式的任务分发框架。设计简洁,获得了非常广泛的支持。一个典型的Gearman应用包括以下这些部分:

Gearman Job Server:Gearman核心程序,需要编译安装并以守护进程形式运行在后台

Gearman Client:可以理解为任务的收件员,比如在后台执行一个发送邮件的任务,可以在程序中调用一个Gearman Client并传入邮件的信息,然后就可以将执行结果立即展示给用户,而任务本身会慢慢在后台运行。

Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行,Gearman Worker接收到Gearman Client传递的任务内容后,会按顺序处理。

以前曾经介绍过类似的后台任务处理项目Resque。两者的设计其实非常接近,简单可以类比为:

Gearman Job Server:对应Resque的Redis部分

Gearman Client:对应Resque的Queue操作

Gearman Worker:对应Resque的Worker和Job

这里之所以选择Gearman而不是Resque是因为Gearman提供了比较好用的MySQL UDF,工作量更小。

安装Gearman及PHP Gearman扩展

以下均以Ubuntu12.04为例。 我爱编程网

apt-get install gearman gearman-server libgearman-dev

检查Gearman的运行状况:

/etc/init.d/gearman-job-server status

* gearmand is running

说明Gearman已经安装成功。

PHP的Gearman扩展可以通过pecl直接安装

pecl install gearman

echo "extension=gearman.so">/etc/php5/conf.d/gearman.ini

service php5-fpm restart

但是实测发现ubuntu默认安装的gearman版本过低,直接运行pecl install gearman会报错

configure: error: libgearman version 1.1.0or later required

因此Gearman + PHP扩展建议通过编译方式安装,这里为了简单说明,选择安装旧版本扩展:

pecl install gearman-1.0.3

Gearman + PHP实例

为了更容易理解后文Gearman的运行流程,这里不妨从一个最简单的Gearman实例来说明,比如要进行一个文件处理的操作,首先编写一个Gearman Client并命名为client.php:

<?php

$client =newGearmanClient();

$client->addServer();

$client->doBackground('writeLog','Log content');

echo '文件已经在后台操作';

运行这个文件,相当于模拟用户请求一个Web页面后,将处理结束的信息返回用户:

php client.php

查看一下Gearman的状况:

(echo status ; sleep 0.1)| netcat127.0.0.14730

可以看到输出为

writeLog        100.

说明已经在Gearman中建立了一个名为writeLog的任务,并且有1个任务在队列等待中。

而上面的4列分别代表当前的Gearman的运行状态:

任务名称

在等待队列中的任务

正在运行的任务

正在运行的Worker进程

可以使用watch进行实时监控:

watch -n 1"(echo status; sleep 0.1) | nc 127.0.0.1 4730"

然后我们需要编写一个Gearman Worker命名为worker.php:

<?php

$worker =newGearmanWorker();

$worker->addServer();

$worker->addFunction('writeLog','writeLog');while($worker->work());function   writeLog($job){

$log = $job->workload();file_put_contents(__DIR__ .'/gearman.log', $log ."\n",   FILE_APPEND | LOCK_EX);}

Worker使用一个while死循环实现守护进程,运行

php worker.php

可以看到Gearman状态变为:

writeLog        001

同时查看同目录下gearman.log,内容应为从Client传入的值Log content。

通过MySQL UDF + Trigger同步数据到Gearman

MySQL要实现与外部程序互通的最好方式还是通过MySQL UDF(MySQL user defined functions)来实现。为了让MySQL能将数据传入Gearman,这里使用了lib_mysqludf_json和gearman-mysql-udf的组合。

安装lib_mysqludf_json

使用lib_mysqludf_json的原因是因为Gearman只接受字符串作为入口参数,可以通过lib_mysqludf_json将MySQL中的数据编码为JSON字符串

apt-get install libmysqlclient-dev

wget

unzip master.zip

cd lib_mysqludf_json-master/

rm lib_mysqludf_json.so

gcc $(mysql_config --cflags)-shared -fPIC -o lib_mysqludf_json.so   lib_mysqludf_json.c

可以看到重新编译生成了 lib_mysqludf_json.so 文件,此时需要查看MySQL的插件安装路径:

mysql -u root -pPASSWORD --execute="show variables like '%plugin%';"+---------------+------------------------+|Variable_name|Value|+---------------+------------------------+| plugin_dir    |/usr/lib/mysql/plugin/|+---------------+------------------------+

然后将 lib_mysqludf_json.so 文件复制到对应位置:

cp lib_mysqludf_json.so /usr/lib/mysql/plugin/

最后登入MySQL运行语句注册UDF函数:

CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';

安装gearman-mysql-udf

方法几乎一样:

apt-get install libgearman-dev

wget udf/trunk/0.6/+download/gearman-  mysql-udf-0.6.tar.gz

tar -xzf gearman-mysql-udf-0.6.tar.gz

cd gearman-mysql-udf-0.6./configure --with-mysql=/usr/bin/mysql_config

-libdir=/usr/lib/mysql/plugin/

make && make install

登入MySQL运行语句注册UDF函数:

CREATE FUNCTION gman_do_background RETURNS STRING SONAME   'libgearman_mysql_udf.so';

CREATE FUNCTION gman_servers_set RETURNS STRING SONAME   'libgearman_mysql_udf.so';

最后指定Gearman服务器的信息:

SELECT gman_servers_set('127.0.0.1:4730');

通过MySQL触发器实现数据同步

最终同步哪些数据,同步的条件,还是需要根据实际情况决定,比如将数据表data的数据在每次更新时同步,那么编写Trigger如下:

DELIMITER $$

CREATE TRIGGER datatoredis AFTER UPDATE ON data

FOR EACH ROW BEGIN

SET @ret=gman_do_background('syncToRedis', json_object(NEW.id as`id`,   NEW.volume as`volume`));END$$

DELIMITER ;

尝试在数据库中更新一条数据查看Gearman是否生效。

Gearman PHP Worker将MySQL数据异步复制到Redis

Redis作为时下当热的NoSQL缓存解决方案无需过多介绍,其安装及使用也非常简单:

apt-get install redis-server

pecl install redis

echo "extension=redis.so">/etc/php5/conf.d/redis.ini

然后编写一个Gearman Worker:redis_worker.php

#!/usr/bin/env php<?

$worker =newGearmanWorker();

$worker->addServer();

$worker->addFunction('syncToRedis','syncToRedis');

$redis =newRedis();

$redis->connect('127.0.0.1',6379);while($worker->work());function   syncToRedis($job){global $redis;

$workString = $job->workload();

$work = json_decode($workString);if(!isset($work->id)){returnfalse;}

$redis->set($work->id, $workString);}

最后需要将Worker在后台运行:

nohup php redis_worker.php &

通过这种方式将MySQL数据复制到Redis,经测试单Worker基本可以瞬时完成。

php redis做mysql的缓存,怎么异步redis同步到mysql数据库

php redis做mysql的缓存,怎么异步redis同步到mysql数据库

对于变化频率非常快的数据来说 ,如果还选择传统的静态缓存方式(Memocached、File System等)展示数据,可能在缓存的存取上会有很大的开销,并不能很好的满足需要,而Redis这样基于内存的NoSQL数据库,就非常适合担任实时数据的容器。

但是往往又有数据可靠性的需求,采用MySQL作为数据存储,不会因为内存问题而引起数据丢失,同时也可以利用关系数据库的特性实现很多功能。

所以就会很自然的想到是否可以采用MySQL作为数据存储引擎,Redis则作为Cache。而这种需求目前还没有看到有特别成熟的解决方案或工具,因此采用Gearman+PHP+MySQL UDF的组合异步实现MySQL到Redis的数据复制。

MySQL到Redis数据复制方案

无论MySQL还是Redis,自身都带有数据同步的机制,比较常用的MySQL的Master/Slave模式,就是由Slave端分析Master的binlog来实现的,这样的数据复制其实还是一个异步过程,只不过当服务器都在同一内网时,异步的延迟几乎可以忽略。

那么理论上也可以用同样方式,分析MySQL的binlog文件并将数据插入Redis。但是这需要对binlog文件以及MySQL有非常深入的理解,同时由于binlog存在Statement/Row/Mixedlevel多种形式,分析binlog实现同步的工作量是非常大的。

因此这里选择了一种开发成本更加低廉的方式,借用已经比较成熟的MySQL UDF,将MySQL数据首先放入Gearman中,然后通过一个自己编写的PHP Gearman Worker,将数据同步到Redis。比分析binlog的方式增加了不少流程,但是实现成本更低,更容易操作。

Gearman的安装与使用

Gearman是一个支持分布式的任务分发框架。设计简洁,获得了非常广泛的支持。一个典型的Gearman应用包括以下这些部分:

Gearman Job Server:Gearman核心程序,需要编译安装并以守护进程形式运行在后台

Gearman Client:可以理解为任务的收件员,比如在后台执行一个发送邮件的任务,可以在程序中调用一个Gearman Client并传入邮件的信息,然后就可以将执行结果立即展示给用户,而任务本身会慢慢在后台运行。

Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行,Gearman Worker接收到Gearman Client传递的任务内容后,会按顺序处理。

以前曾经介绍过类似的后台任务处理项目Resque。两者的设计其实非常接近,简单可以类比为:

Gearman Job Server:对应Resque的Redis部分

Gearman Client:对应Resque的Queue操作

Gearman Worker:对应Resque的Worker和Job

这里之所以选择Gearman而不是Resque是因为Gearman提供了比较好用的MySQL UDF,工作量更小。

安装Gearman及PHP Gearman扩展

以下均以Ubuntu12.04为例。

apt-get install gearman gearman-server libgearman-dev

检查Gearman的运行状况:

/etc/init.d/gearman-job-server status

* gearmand is running

说明Gearman已经安装成功。

PHP的Gearman扩展可以通过pecl直接安装

pecl install gearman

echo "extension=gearman.so">/etc/php5/conf.d/gearman.ini

service php5-fpm restart

但是实测发现ubuntu默认安装的gearman版本过低,直接运行pecl install gearman会报错

configure: error: libgearman version 1.1.0or later required

因此Gearman + PHP扩展建议通过编译方式安装,这里为了简单说明,选择安装旧版本扩展:

pecl install gearman-1.0.3

Gearman + PHP实例

为了更容易理解后文Gearman的运行流程,这里不妨从一个最简单的Gearman实例来说明,比如要进行一个文件处理的操作,首先编写一个Gearman Client并命名为client.php:

<?php

$client =newGearmanClient();

$client->addServer();

$client->doBackground('writeLog','Log content');

echo '文件已经在后台操作';

运行这个文件,相当于模拟用户请求一个Web页面后,将处理结束的信息返回用户:

php client.php

查看一下Gearman的状况:

(echo status ; sleep 0.1)| netcat127.0.0.14730

可以看到输出为

writeLog        100.

说明已经在Gearman中建立了一个名为writeLog的任务,并且有1个任务在队列等待中。

而上面的4列分别代表当前的Gearman的运行状态:

任务名称

在等待队列中的任务

正在运行的任务

正在运行的Worker进程

可以使用watch进行实时监控:

watch -n 1"(echo status; sleep 0.1) | nc 127.0.0.1 4730"

然后我们需要编写一个Gearman Worker命名为worker.php:

<?php

$worker =newGearmanWorker();

$worker->addServer();

$worker->addFunction('writeLog','writeLog');while($worker->work());function   writeLog($job){

$log = $job->workload();file_put_contents(__DIR__ .'/gearman.log', $log ."\n",   FILE_APPEND | LOCK_EX);}

Worker使用一个while死循环实现守护进程,运行

php worker.php

可以看到Gearman状态变为:

writeLog        001

同时查看同目录下gearman.log,内容应为从Client传入的值Log content。

通过MySQL UDF + Trigger同步数据到Gearman

MySQL要实现与外部程序互通的最好方式还是通过MySQL UDF(MySQL user defined functions)来实现。为了让MySQL能将数据传入Gearman,这里使用了lib_mysqludf_json和gearman-mysql-udf的组合。

安装lib_mysqludf_json

使用lib_mysqludf_json的原因是因为Gearman只接受字符串作为入口参数,可以通过lib_mysqludf_json将MySQL中的数据编码为JSON字符串

apt-get install libmysqlclient-dev

wget

unzip master.zip

cd lib_mysqludf_json-master/

rm lib_mysqludf_json.so

gcc $(mysql_config --cflags)-shared -fPIC -o lib_mysqludf_json.so   lib_mysqludf_json.c

可以看到重新编译生成了 lib_mysqludf_json.so 文件,此时需要查看MySQL的插件安装路径:

mysql -u root -pPASSWORD --execute="show variables like '%plugin%';"+---------------+------------------------+|Variable_name|Value|+---------------+------------------------+| plugin_dir    |/usr/lib/mysql/plugin/|+---------------+------------------------+

然后将 lib_mysqludf_json.so 文件复制到对应位置:

cp lib_mysqludf_json.so /usr/lib/mysql/plugin/

最后登入MySQL运行语句注册UDF函数:

CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so';

安装gearman-mysql-udf

方法几乎一样:

apt-get install libgearman-dev

wget udf/trunk/0.6/+download/gearman-  mysql-udf-0.6.tar.gz

tar -xzf gearman-mysql-udf-0.6.tar.gz

cd gearman-mysql-udf-0.6./configure --with-mysql=/usr/bin/mysql_config

-libdir=/usr/lib/mysql/plugin/

make && make install

登入MySQL运行语句注册UDF函数:

CREATE FUNCTION gman_do_background RETURNS STRING SONAME   'libgearman_mysql_udf.so';

CREATE FUNCTION gman_servers_set RETURNS STRING SONAME   'libgearman_mysql_udf.so';

最后指定Gearman服务器的信息:

SELECT gman_servers_set('127.0.0.1:4730');

通过MySQL触发器实现数据同步

最终同步哪些数据,同步的条件,还是需要根据实际情况决定,比如将数据表data的数据在每次更新时同步,那么编写Trigger如下:

DELIMITER $$

CREATE TRIGGER datatoredis AFTER UPDATE ON data

FOR EACH ROW BEGIN

SET @ret=gman_do_background('syncToRedis', json_object(NEW.id as`id`,   NEW.volume as`volume`));END$$

DELIMITER ;

尝试在数据库中更新一条数据查看Gearman是否生效。

Gearman PHP Worker将MySQL数据异步复制到Redis

Redis作为时下当热的NoSQL缓存解决方案无需过多介绍,其安装及使用也非常简单:

apt-get install redis-server

pecl install redis

echo "extension=redis.so">/etc/php5/conf.d/redis.ini

然后编写一个Gearman Worker:redis_worker.php

#!/usr/bin/env php<?

$worker =newGearmanWorker();

$worker->addServer();

$worker->addFunction('syncToRedis','syncToRedis');

$redis =newRedis();

$redis->connect('127.0.0.1',6379);while($worker->work());function   syncToRedis($job){global $redis;

$workString = $job->workload();

$work = json_decode($workString);if(!isset($work->id)){returnfalse;}

$redis->set($work->id, $workString);}

最后需要将Worker在后台运行:

nohup php redis_worker.php &

通过这种方式将MySQL数据复制到Redis,经测试单Worker基本可以瞬时完成。

php txt 文件续写

我爱编程网(https://www.52biancheng.com)小编还为大家带来php txt 文件续写的相关内容。

function writelog($str)
{

$open=fopen("log.txt","a" );
fwrite($open,$str);
fclose($open);
}

'a' 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
'a+' 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。

以上就是我爱编程网小编给大家带来的php redis做mysql的缓存,怎么异步redis同步到mysql数据库全部内容,希望对大家有所帮助!更多相关文章关注我爱编程网:www.52biancheng.com

免责声明:文章内容来自网络,如有侵权请及时联系删除。
与“php redis做mysql的缓存,怎么异步redis同步到mysql数据库”相关推荐
php redis 怎么清除数据库
php redis 怎么清除数据库

phpredis怎么清除数据库在PHP中使用Redis清除数据库,可以采用多种方法。首先,如果要删除单个键,可以使用del命令。例如,先设置一个键值对:$redis-&gt;set('myname','ikodota');通过get命令获取键值:echo$redis-&gt;get('myname').'';//返回:ikodota然后使用del命令删除该键:$

2024-12-05 21:54:34
thinkphp redis 怎么选择数据库
thinkphp redis 怎么选择数据库

PHP中MD5函数漏洞总结本文首发于个人博客:n0usec.top一、MD5算法MD5全名消息摘要算法(Message-DigestAlgorithm5),是一种密码散列函数,能将任意大小的数据转换为一个固定的128位(16字节)哈希值,确保信息传输的一致性和完整性。它的核心原理是将原始数据通过一系列计算过程,生成固定长度的哈希值。二、PHP中MD5函数的安全问题

2024-11-25 04:21:18
php下如何将json格式的数据直接存入mysql数据库
php下如何将json格式的数据直接存入mysql数据库

yaf框架中,PHPFatalerror:Calltoamemberfunctionprepare()onanon-object;是语法错误,是没有找到函数的错误,是没有加载PDO扩展造成的。PHP中查看phpinfo参数,是否加载并扩展了PDO,需要加载,否则解释错误更多问题到问题求助专区php下如何将json格式的数据直接存入mysql数据库在PHP中,json格式的数据

2025-02-09 00:31:45
java如何计算线程池中线程同步和异步运行时间
java如何计算线程池中线程同步和异步运行时间

java获取运行时间很多朋友都想知道java怎么获取运行时间?下面就一起来了解一下吧~第一种是以毫秒为单位计算的。//伪代码long startTime=System.currentTimeMillis(); //获取开始时间doSomeThing(); //测试的代码段long endTime=System.currentTimeMillis(); //获取结束时间System.

2024-06-15 21:37:05
PHP操作MySQL,删除一行数据库,怎么写?
PHP操作MySQL,删除一行数据库,怎么写?

php中一个html页面实现增删改查增加:insertinto表名(字段1,字段2,...)values('值1','值2',....)where条件;删除:delete表名修改:update表名set字段名='值'where条件;查询:select字段名from表名where条件;PHP操作MySQL,删除一行数据库,怎么写?删除一条记录简单方法,应该说是最简单的入门级的

2024-09-01 03:58:23
php如何连接mysql数据库
php如何连接mysql数据库

php如何连接mysql数据库1、首先在mysql数据库,创建一张data表,表内插入多条数据,用于测试。2、创建一个test.php文件,在文件内,使用header()方法将页面的编码格式设置为utf-8。3、然后在test.php文件内,连接mysql数据库,并使用mysqli_select_db选择要操作的数据库。4、在test.php文件内,创建一条查询data数

2024-10-30 02:55:09
抓取网页数据怎么保存到数据库 php
抓取网页数据怎么保存到数据库 php

抓取网页数据怎么保存到数据库php给一个例子你看看吧.if($pro_list_contents=@file_get_contents('-luxury.com/louis-vuitton-c-82.html')){preg_match_all("/&lt;tdwidth=\"50%\"valign=\"top\"&gt;(.*)&lt;tdwidth=\"10\"&gt;

2024-08-31 07:52:53
php函数怎么封装 PHP操作MySQL数据库的封装简单化php操作mysql封装
php函数怎么封装 PHP操作MySQL数据库的封装简单化php操作mysql封装

PHP实现下载与压缩文件的封装与整理一、PHP实现打包zip并下载功能通过PHP实现打包zip并下载功能,可以方便地将多个文件或文件夹压缩成一个zip文件,然后提供下载。以下是一个简单的实现方法:php&lt;?php$archiveName='archive.zip';$archive=newZipArchive();$archive-&gt;open($arc

2025-02-02 00:48:20