Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类keyvalue存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。

在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。Redis只会缓存所有的key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = age*log(sizeinmemory)”计算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以 保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap操作的。同时由于Redis将内存 中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操作的子线程会共享这部分内存,所以如果更新需要swap的数据,Redis将阻塞这 操作,直到子线程完成swap操作后才可以进行修改。

从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,然后再返回给请求方。 这里就存在一个I/O线程池的问题。在默认的情况下,Redis会出现阻塞,即完成所有的swap文件加载后才会相应。这种策略在客户端的数量较小,进行批量操作的时候比较合适。但是如果将Redis应用在一个大型的网站应用程序中,这显然是无法满足大并发的情况的。所以Redis运行我们设置I/O线程 池的大小,对需要从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。

所有Redis的操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。Redis是一个多实用的工具,可以在一些像缓存,消息,队列用例中使用(Redis原生支持发布/订阅),在应用程序,如Web应用程序的会话,网络页面点击数短期数据等等。

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

在用Redis作为Mysql的缓存时我们可以用gearman来进行数据的同步。

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

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

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

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

Gearman实现redis缓存mysql的大致流程:

首先利用mysql UDF(通过了libmysqludfjson和gearman-mysql-udf的组合实现)在mysql中的数据发生改变时触动触发器将数据传入Gearman中,这时的mysql相当于Gearman的clinet。然后运行自己编写的php程序作为worker,将Gearman中的数据传到Redis中去,这时的Redis相当于是Gearman的consumer。

下面redis缓存mysql的配置过程了(实验环境rhel6.5):

Redis的安装:

tar zxf redis-3.0.2.tar.gz

yum install gcc -y

cd redis-3.0.2

make

make install

配置并启动服务

cd utils/

./install_server.sh #安装服务启动程序,同一台服务器可以有多个启动程序

#redis的运行端口为6379

配置Redis做mysql的缓存服务器

安装所需的软件包:

yum install  mysql-server nginx-1.8.0-1.el6.ngx.x86_64.rpm php-5.3.3-38.el6.x86_64.rpm php-cli-5.3.3-38.el6.x86_64.rpm php-common-5.3.3-38.el6.x86_64.rpm php-devel-5.3.3-38.el6.x86_64.rpm php-fpm-5.3.3-38.el6.x86_64.rpm php-gd-5.3.3-38.el6.x86_64.rpm php-mbstring-5.3.3-38.el6.x86_64.rpm php-mysql-5.3.3-38.el6.x86_64.rpm php-pdo-5.3.3-38.el6.x86_64.rpm -y

配置php:

vim /etc/php.ini

date.timezone =Asia/Shanghai

vim /etc/php-fpm.d/www.conf

user = nginx

group = nginx

unzip phpredis-master.zip

cd phpredis-master

phpize

./configure

make

make install

vim /etc/php.d/redis.ini

extension=redis.so

/etc/init.d/php-fpm start

配置nginx:

vim /etc/nginx/conf.d/default.conf

server {

listen       80;

server_name  localhost;

location / {

root   /usr/share/nginx/html;

index  index.php index.html index.htm;

}

location ~ \.php$ {

root           html;

fastcgi_pass   127.0.0.1:9000;

fastcgi_index  index.php;

fastcgi_param  SCRIPT_FILENAME  /usr/share/nginx/html$fastcgi_script_name;

include        fastcgi_params;

}

/etc/init.d/nginx start

配置mysql

/etc/init.d/mysqld start

mysql

cat 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');

mysql> grant all on test.* to [email protected] identified by 'westos'; #创建用于缓存mysql数据的redis用户

mysql -uredis -pwestos #测试这个用户

创建测试用的php页面:

cat /usr/share/nginx/html/index.php

$redis = new Redis();

$redis->connect('127.0.0.1',6379) or die ("could net connect redis server");

# $query = "select * from test limit 9";

$query = "select * from test";

for ($key = 1; $key

{

if (!$redis->get($key))

{

$connect = mysql_connect('127.0.0.1','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 "
";

for ($key = 1; $key

{

echo "number is $key";

echo "
";

echo "name is $data[$key]";

echo "
";

}

?>

测试结果

Redis对mysql的缓存已经完成,但是当更新了mysql,Redis不会跟着更新,就会出现mysql与redis数据不一致的情况,接下来我们来处理这种情况:

配置gearman实现数据同步

安装gearman

yum install gearmand-1.1.8-2.el6.x86_64.rpm libgearman-1.1.8-2.el6.x86_64.rpm -y

/etc/init.d/gearmand start#开启gearman它的端口是4730

安装php的gearman模块:

tar zxf gearman-1.1.2.tgz

cd gearman-1.1.2

phpize

yum install -y libgearman-devel-1.1.8-2.el6.x86_64.rpm libevent-doc-1.4.13-4.el6.noarch.rpm libevent-devel-1.4.13-4.el6.x86_64.rpm libevent-headers-1.4.13-4.el6.noarch.rpm #解决依赖性

./configure

make

make install

vim /etc/php.d/gearman.ini

extension=gearman.so

/etc/init.d/php-fpm reload

安装lib_mysqludef_json将mysql数据转换为Redis能用的JSON格式

yum install mysql-devel -y

unzip lib_mysqludf_json-master.zip

cd lib_mysqludf_json-master

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

将lib_mysqludf_json.so模块拷贝到mysql的插件目录

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

注册UDF函数(只用于mysql5.7以前的版本,5.7以后mysql自带JSON格式)

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

mysql> select * from mysql.func;#查看函数

安装 gearman-mysql-udf来调用Gearman的分布式队列

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

cd gearman-mysql-udf-0.6

yum install gcc-c++ -y

./configure --libdir=/usr/lib64/mysql/plugin/

make

make install

注册UDF函数:

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

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

mysql> select * from mysql.func;#查看函数

mysql> SELECT gman_servers_set('127.0.0.1:4730');#指定gearman的服务信息,如果是远程就填写远程IP

编写mysql触发器:

mysql

cat 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 ;

最后配置gearman的worker端并使它一直运行在后端

cat /usr/local/bin/worker.php

$worker = new GearmanWorker();

$worker->addServer();

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

$redis = new Redis();

$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)){

return false;

}

$redis->set($work->id, $work->name);

}

?>

nohup php worker.php &

测试:更新mysql数据库可以看到redisye跟着更新了

mysql> use test

mysql> update test set name='hello' where id=1;

[[email protected] bin]# redis-cli

127.0.0.1:6379> get 1

"hello"

刷新页面数据也跟着更新了

mysql大数据更新缓存_redis缓存mysql相关推荐

  1. redis 查询缓存_Redis缓存总结:淘汰机制、缓存雪崩、数据不一致....

    在实际的工作项目中, 缓存成为高并发.高性能架构的关键组件 ,那么Redis为什么可以作为缓存使用呢?首先可以作为缓存的两个主要特征: 在分层系统中处于内存/CPU具有访问性能良好, 缓存数据饱和,有 ...

  2. redis配置mysql缓存_Redis做mysql的缓存服务器

    一redis简介:redis 是一个高性能的 key-value 数据库. redis 的出现,很大程度补偿了memcached 这类 keyvalue 存储的不足,在部分场合可以对关系数据库起到很好 ...

  3. linux mysql 大页_Linux HugePages及MySQL 大页配置

    ㈠ HugePages简介 HugePages是kernel 2.6引入以便适应越来越大的物理内存 在Linux下.page size默认是4K.如果使用HugePages.默认是2M 再看2个术语: ...

  4. java cache缓存_Redis缓存失效策略思考

    1 删除过期数据 我们设置Redis元素时可以指定过期时间,那么Redis如何删除这些超时元素?Redis采用了两种策略:定期删除和惰性删除. (1) 定期删除 Redis每隔一段时间就检查哪些KEY ...

  5. tp5 mysql大数据_Tp5入门——数据库(MySQL)操作

    MySQL 是最流行的关系型数据库管理系统,在WEB应用方面 MySQL 是最好的RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之 ...

  6. mysql视图数据更新_怎么更新Mysql数据表视图中数据

    本篇文章主要给大家介绍mysql数据表中视图中数据的更新操作. 相关mysql视频教程推荐:<mysql教程> mysql数据表视图的定义及相关操作,如查询.修改.删除.添加等操作介绍,在 ...

  7. redis mysql 雪崩_Redis缓存雪崩、缓存穿透、并发等5大难题,你有没有解决方案

    缓存雪崩 数据未加载到高速缓存中,或者高速缓存同时在较大区域中失效,这将导致所有请求都去查找数据库,从而导致数据库CPU和内存负载过高,甚至会出现宕机. 比如雪崩的一个简单过程: 1.redis集群大 ...

  8. mysql缓存淘汰机制_Redis缓存总结:淘汰机制、缓存雪崩、数据不一致....

    在实际的工作项目中, 缓存成为高并发.高性能架构的关键组件 ,那么Redis为什么可以作为缓存使用呢?首先可以作为缓存的两个主要特征: 在分层系统中处于内存/CPU具有访问性能良好, 缓存数据饱和,有 ...

  9. 分布式缓存redis 方案_Redis缓存和MySQL数据一致性方案详解

    在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到Redis,而不是直接访问MySQL等数据库. 这个业务场景,主要是解决读数 ...

最新文章

  1. CF498C Array and Operations(数论 + 最大流)
  2. 如何成为简历界的“老司机”?这些简历技能你get到了吗?
  3. python绘制动态模拟图-用python生成地球运动的动态模拟动态图
  4. mysql bypass_Bypass MySQL Safedog
  5. NTP时间服务相关基础及配置文件详解
  6. 以MATLAB的方式实现微积分问题的计算机求解问题及解决方案集锦(二)
  7. Oracle 用户管理
  8. 判断能被N整除的字符串
  9. 学习Spring Boot:(二十一)使用 EhCache 实现数据缓存
  10. 3-1:HTTP协议之应用层协议了解
  11. (33)Verilog HDL缩减运算
  12. OpenCV学习(7.10)
  13. 想学 AI,先搞懂这件小事!
  14. 北航的计算机与技术专业如何,计算机科学与技术考研北航的这个专业怎么样
  15. html中超链接使用_html超链接有哪些类型 html中,超链接用的是什么标签
  16. 【ARM基础概念:ARMv7架构,ARM(ARM7、ARM9)、Cortex-M4、M7等内核、MCU、MPU、SOC,STM32的一些概念】
  17. 关于电脑安装新硬盘,出现无法是识别设备,03F0问题解答。
  18. 计算机视觉的应用,计算机视觉新手指南
  19. 配色那么差,还不‘哥屋恩’去看电影!
  20. 【知识图谱】通俗易懂的知识图谱技术

热门文章

  1. android 开关数据连接电脑,Android网络数据开关用法简单示例
  2. sqli-labs less11 POST注入-字符型
  3. java mifare_如何正确写入MifareUltralight NFC标签?
  4. wxpython 下拉框只能选择不能输入_用wxPython创建GUI应用程序展示NASA图片(第三部分)...
  5. 结束oracle import,Oracle 结束 imp/exp 和 expdp/impdp 进程的正确方法
  6. Windows 10+Ubuntu 16.04在MBR分区上安装双系统之后没有Windows 10的启动菜单解决方法...
  7. 在数据仓储的情况下进一步封装数据库基础操作,此版本为异步版本
  8. jsp页面点击显示影藏div的一个方法
  9. MySQL查询不到中文的问题
  10. Hibernate的Session会话中get()和load()方法的区别