redis作为mysql的缓存服务器(读写分离) (转)
一、redis简介
Redis是一个key-value存储系统。和Memcached类似,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。在部分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++(hiredis),C#,PHP,JavaScript,Perl,Object-C,Python,Ruby等客户端,使用很方便。
二、架构图
<ignore_js_op>
大致结构就是读写分离,将mysql中的数据通过触发器同步到redis中
三、安装LNMP环境(这里为了省事,就是用yum来安装)
1、修改yum源
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[iyunv@redis ~]# vim /etc/yum.repos.d/epel.repo #添加这个文件 [epel] name=Extra Packages for Enterprise Linux 6 - $basearch baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch failovermethod=priority enabled=1 gpgcheck=0 [nginx] |
2、yum安装
1 | [iyunv@redis ~]# yum -y install nginx php php-fpm php-cli php-common php-gd php-mbstring php-mysql php-pdo php-devel php-xmlrpc php-xml php-bcmath php-dba php-enchant mysql mysql-server |
3、简单配置一下nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[iyunv@redis ~]# vim /etc/nginx/nginx.conf server { listen 80; #定义使用www.xx.com访问 server_name www.xx.com; #设定本虚拟主机的访问日志 #默认请求 |
4、启动服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
[iyunv@redis ~]# sed -i 's/apache/nginx/g' /etc/php-fpm.d/www.conf [iyunv@redis ~]# /etc/init.d/php-fpm start 正在启动 php-fpm: [确定] [iyunv@redis ~]# /etc/init.d/mysqld start [iyunv@redis ~]# mkdir /{logs,www} [iyunv@redis www]# service iptables stop [iyunv@redis redis]# netstat -tnlp #查看监听 |
5、给mysql授权
1 2 3 4 |
[iyunv@redis ~]# mysql mysql> grant all privileges on *.* to root@localhost identified by '123456'; mysql> flush privileges; |
6、测试
1 2 3 4 |
[iyunv@redis ~]# vim /www/index.php <?php phpinfo(); ?> |
然后访问页面看到php的相关信息,基础环境就算搭建完成了。
四、安装redis
1、安装redis
1 2 3 4 5 6 7 8 9 10 11 12 |
[iyunv@redis ~]# wget -c -t 0 http://download.redis.io/releases/redis-2.8.19.tar.gz
[iyunv@redis ~]# mkdir /usr/local/redis [iyunv@redis ~]# tar xvf redis-2.8.19.tar.gz #编译完成后,将src中的可执行文件拷贝到刚刚创建的目录中 |
Redis-benchmark 压力测试工具
Redis-check-aof 检查redis持久化命令文件的完整性
Redis-check-dump 检查redis持久化数据文件的完整性
Redis-cli redis在linux上的客户端
Redis-sentinel redis-sentinel是集群管理工具,主要负责主从切换。
Redis-server Redis服务器的daemon启动程序
2、安装php的redis扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[iyunv@redis ~]# wget -c -t 0 https://github.com/owlient/phpredis/archive/master.zip [iyunv@redis ~]# unzip master.zip [iyunv@redis ~]# cd phpredis-master/ #修改php的配置文件,如果没有“extension=redis.so”,就加上这一行 [iyunv@redis ~]# /etc/init.d/php-fpm restart |
3、是否安装成功
还是访问phpinfo的那个界面
<ignore_js_op>
看到这个就是安装完成了。
五、读写分离
这里只是简单的做了一下读,没有写操作的相关代码,过一会测试,直接到数据库里执行update来模拟写操作。
1、在mysql中插入一些测试数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[iyunv@redis ~]# mysql -u root -p123456 mysql> create database mytest; mysql> CREATE TABLE `test` (`id` int(7) NOT NULL AUTO_INCREMENT, `name` char(8) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; mysql> INSERT INTO `test` VALUES (1,'sven'),(2,'jim'),(3,'zhu'),(4,'wang'),(5,'ftd'),(6,'test'),(7,'test01'),(8,'test02'),(9,'test03'); mysql> select * from mytest.test; +----+--------+ | id | name | +----+--------+ | 1 | sven | | 2 | jim | | 3 | zhu | | 4 | wang | | 5 | ftd | | 6 | test | | 7 | test01 | | 8 | test02 | | 9 | test03 | +----+--------+ |
2、编写php的测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?php $redis = new Redis(); $redis->connect('127.0.0.1',6379) or die ("could net connect redis server"); $query = "select * from test limit 8"; //为了简单一点,这里就读取了8条数据 for ($key = 1; $key < 9; $key++) { if (!$redis->get($key)) { $connect = mysql_connect('127.0.0.1','root','123456'); mysql_select_db(mytest); $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>"; echo "name is <b><font color=#FF0000>$data[$key]</font></b>"; echo "<br>"; |
第一次访问,redis中没有对应的KEY时
<ignore_js_op>
再次访问,此时redis中已有相关数据
<ignore_js_op>
到这里,我们已经实现了redis作为mysql的缓存服务器,但是如果更新了mysql,redis中仍然会有对应的KEY,数据就不会更新,此时就会出现mysql和redis数据不一致的情况。所以接下来就要通过mysql触发器将改变的数据同步到redis中。
六、通过gearman实现同步
1、介绍
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数据库的更新。
2、安装启动
1 2 3 4 5 |
[iyunv@redis ~]# yum -y install gearmand libgearman-devel [iyunv@redis ~]# /etc/init.d/gearmand start 正在启动 gearmand: [确定] [iyunv@redis ~]# /etc/init.d/gearmand status gearmand (pid 7702) 正在运行... |
3、安装php的gearman扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[iyunv@redis ~]# wget -c -t 0 https://pecl.php.net/get/gearman-1.1.1.tgz
[iyunv@redis ~]# tar xvf gearman-1.1.1.tgz #如果php的配置文件中没有extension = gearman.so,就加上此行 |
<ignore_js_op>
这样就是安装成功了
4、安装lib_mysqludf_json
lib_mysqludf_json UDF库函数将关系数据映射为JSON格式。通常,数据库中的数据映射为JSON格式,是通过程序来转换的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
[iyunv@redis ~]# wget -c -t 0 https://github.com/mysqludf/lib_mysqludf_json/archive/master.zip [iyunv@redis ~]# unzip master.zip [iyunv@redis ~]# cd lib_mysqludf_json-master/ [iyunv@redis lib_mysqludf_json-master]# gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c lib_mysqludf_json.c:40:23: 错误:my_global.h:没有那个文件或目录 lib_mysqludf_json.c:41:20: 错误:my_sys.h:没有那个文件或目录 lib_mysqludf_json.c:43:19: 错误:mysql.h:没有那个文件或目录 lib_mysqludf_json.c:44:21: 错误:m_ctype.h:没有那个文件或目录 lib_mysqludf_json.c:45:22: 错误:m_string.h:没有那个文件或目录 #这里编译报错是因为没有安装mysql的开发包,如果是源码安装的mysql,需要在/etc/ld.so.conf.d/ mysql> show global variables like 'plugin_dir'; #将模块拷贝到插件目录下 #注册UDF函数 |
5、安装gearman-mysql-udf
这个插件是用来管理调用 Gearman 的分布式的队列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[iyunv@redis ~]# wget -c -t 0 https://launchpad.net/gearman-my ... ysql-udf-0.6.tar.gz [iyunv@redis ~]# tar xvf gearman-mysql-udf-0.6.tar.gz [iyunv@redis ~]# cd gearman-mysql-udf-0.6 #注册UDF函数 #查看函数 #指定gearman的服务信息 |
6、编写mysql触发器(根据实际情况编写)
1 2 3 4 5 |
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 ; |
7、编写gearman的worker端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[iyunv@redis ~]# vim /www/redis_worker.php <?php $worker = new GearmanWorker(); $worker->addServer(); $worker->addFunction('syncToRedis', 'syncToRedis'); $redis = new Redis(); while($worker->work()); #后台运行 |
"$redis->set($work->id, $work->name);"这条语句就是将id作KEY和name作VALUE分开存储,需要和前面写的php测试代码的存取一致。
8、更新mysql中的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
mysql> set @RECV = 1; mysql> select @RECV; +------+ | @RECV| +------+ | 1 | +------+ mysql> update test set name = 'ssss' where id = 1; mysql> select @RECV; +------+ | @RECV| +------+ | NULL | +------+ |
从返回值可以看到,触发器是触发成功的(这里的@RECV是上面mysql TIGGER的返回值)。我们在redis中查看数据:
1 2 3 |
[iyunv@redis redis]# ./redis-cli 127.0.0.1:6379> get 1 "sven" |
这里的数据居然没有变化,这是我们就要排错了。
1 2 3 4 5 6 7 8 9 10 11 |
[iyunv@redis ~]# vim /var/log/audit/audit.log type=AVC msg=audit(1427807674.425:107): avc: denied { name_connect } for pid=12453 comm="mysqld" dest=4730 scontext=unconfined_u:system_r:mysqld_t:s0 tcontext=system_u:o bject_r:port_t:s0 tclass=tcp_socket #看到这样一条日志,就知道是selinux阻止了同步 #现在将selinux的模式调成Permissive |
设置完成以后,再次执行update,进入redis进行查看
1 2 |
127.0.0.1:6379> get 1 "ssss" |
刷新一下刚刚的php界面
<ignore_js_op>
到这里就基本算是大功告成了,只要application将数据写到mysql中,mysql触发器检测到更新,就会通过Gearman将数据同步到redis中。然后读取的话,就直接从redis中进行读取。当然这只是个实验环境,实际上还有很多细节要调整。
参考文章:http://avnpc.com/pages/mysql-replication-to-redis-by-gearman
http://www.cnblogs.com/hellowzd/p/5163782.html
redis作为mysql的缓存服务器(读写分离) (转)的更多相关文章
- redis 作为 mysql的缓存服务器(读写分离)
redis 作为 mysql的缓存服务器(读写分离) 一.redis简介 Redis是一个key-value存储系统.和Memcached类似,为了保证效率,数据都是缓存在内存中.区别的是redis会 ...
- redis作为mysql的缓存服务器(读写分离,通过mysql触发器实现数据同步)
一.redis简介Redis是一个key-value存储系统.和Memcached类似,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录 ...
- redis作为mysql的缓存服务器(读写分离)
转自:https://www.iyunv.com/thread-52670-1-1.html 一.redis简介Redis是一个key-value存储系统.和Memcached类似,为了保证效率,数据 ...
- 一个适合变化的产品部署集成包(nginx+jdk+tomcat+nodejs+mysql+redis+mongo+MYSQL主主(读写分离)集群建立+代码包+持续上线+备份)
一.前言 最近公司做了一套新产品,需要发布到不确定的硬件环境中(不同使用单位规模,使用人数,服务器提供的资源不同)若每次进行人工部署耗时费力,周期过长. 二.分析 具体的部署流程如下: 由上图流程进行 ...
- MySQL主从同步、读写分离配置步骤、问题解决笔记
MySQL主从同步.读写分离配置步骤.问题解决笔记 根据要求配置MySQL主从备份.读写分离,结合网上的文档,对搭建的步骤和出现的问题以及解决的过程做了如下笔记: 现在使用的两台服务器已经 ...
- MySql的主从复制以及读写分离详解
MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践 Mysql作为目前世界上使用最广泛的免费数据库,相信所有从事系统运维的工程师都一定接触过.但在实际的生产环境中, ...
- mysql数据库主从同步读写分离(一)主从同步
1.mysql数据库主从同步读写分离 1.1.主要解决的生产问题 1.2.原理 a.为什么需要读写分离? 一台服务器满足不了访问需要.数据的访问基本都是2-8原则. b.怎么做? 不往从服务器去写了 ...
- 基于Mysql-Proxy实现Mysql的主从复制以及读写分离(下)
基于Mysql-Proxy实现Mysql的主从复制以及读写分离(下) 昨天谈到了Mysql实现主从复制,但由于时间原因并未讲有关读写分离的实现,之所以有读写分离,是为了使数据库拥有双机热备功能,至于双 ...
- 基于Mysql-Proxy实现Mysql的主从复制以及读写分离(上)
基于Mysql-Proxy实现Mysql的主从复制以及读写分离(上) 上周BOSS给分配任务让实现一下Mysql数据库的主从复制以及读写分离,然后花了一盏茶的功夫进行了调研,发现主从复制数据库进行一番 ...
随机推荐
- MySQL生成-单据号不重复
需求生成一个单据编号 单据编号结构: “单据类型” + “日期” + “流水号” 例子 : GD201605230000007 代码: DELIMITER $$ CREATE PROCEDURE `y ...
- 基于visual Studio2013解决面试题之0701寻找丑数
题目
- Java面试宝典2014版
一. Java基础部分......................................................................................... ...
- Swift - 多线程实现方式(2) - NSOperation和NSOperationQueue
1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术: (1)NSThread (2)Cocoa NSOperation(NSOperation和NSOperationQueu ...
- Boost Thread学习笔记四
barrierbarrier类的接口定义如下: 1 class barrier : private boost::noncopyable // Exposition only 2 { 3 pub ...
- 无比奇怪的问题,Runtime报错,程序仍可运行(有可能是线程崩溃,但主程序不崩溃,线程崩溃可能是因为锁使用不当引起的)
但主界面仍可操作. 我估计是,线程运行崩溃,不影响主界面的运行(如果你不去点击那个确认错误的对话框的话). 仔细分析,我估计是使用锁不当引起的.有2种情况下必崩溃: 1. 对没有上锁的锁进行解锁 2. ...
- VC++ WIN32 sdk实现按钮自绘详解 之二.
网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片: 首先建立一个标准的Win32 Application 工程.选择a simple Wi ...
- iphone关于单倍图和二倍图(导航 背景 变高)
同学们and朋友们大家好!今天我想说一下关于@2x二倍图的知识,以我所知所见所闻来讲述我的理解! 别看关于这么点小知识,有很多初学者在这个上面常会犯错误,以下是我的理解: 用二倍图是为了适配iphon ...
- GCC编译优化指南【作者:金步国】
GCC编译优化指南[作者:金步国] GCC编译优化指南 作者:金步国 版权声明 本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布.任何人都可以自由使用.转载.复制和再分 ...
- 使用git微命令深入理解git工作机制
首先.这篇不是真正意义上的翻译,所以大家在看的时候不要找相应的英文文章相应着看.这篇文章之所以归类为翻译.是由于最開始有一篇英文文章让我对git内部机制有了清楚的认识,它能够说是我git的启蒙老师吧. ...