如何使⽤redis缓存mysql数据_使⽤redis做为MySQL的缓存介绍
在实际项⽬中,MySQL数据库服务器有时会位于另外⼀台主机,需要通过⽹络来访问数据库;即使应⽤程序与MySQL数据库在同⼀个主机中,访问MySQL也涉及到磁盘IO操作(MySQL也有⼀些数据预读技术,能够减少磁盘IO读写,此部分后续继续研究),总之,直接从MySQL中读取数据不如直接从内存中读取数据来的效率⾼。为了提⾼数据库访问效率,⼈们采⽤了各种各样的⽅法,其中⽅法之⼀就是使⽤⼀个给予内存的缓存系统放置在数据库和应⽤程序之间。在查数据的时候,⾸先从内存中查,如果到则使⽤,如果没有到,那么再真正访问数据库。这种⽅法在⼀些场景下(例如:频繁查相同数据)能够提⾼系统的整体效率。
本⽂的主要⽬的即介绍上⽂说的这样⼀种⽅法,采⽤redis nosql数据库作为Mysql数据库的缓存,在查的时候,⾸先查redis缓存,如果到则返回结果;如果在redis中没有到,那么查Mysql数据库,到的花则返回结果并且更新redis;如果没有到则返回空。对于写⼊的情况,直接写⼊mysql数据库,mysql数据库通过触发器及UDF机制⾃动把变更的内容更新到redis中。
框图
读取步骤:
1. client读取redis,如果命中返回结果,如果没有命中转到
2.
2. client读取数据库,在数据库中没有查到,返回空;在数据库中查到了,返回查到的结果并更新Redis。
写⼊步骤:
1. client修改/删除或者新增数据到MySQL。
2. MySQL的触发器调⽤⽤户⾃定义的UDF。
3. UDF把修改/删除或者新增的数据更新到redis中。
代码实现
软件需求
redis server与client安装,redis编程相关的c库。
mysql server安装,mysql-devel包的安装,此包包含操作mysql数据库的C语⾔API包。
-
实现步骤
1. 安装并验证redis
127.0.0.1:6379> hgetall w3ckey
(empty list or set) #最开始在reids中没有w3ckey的K-V对。
127.0.0.1:6379>
2. 安装MySQL数据库服务器
2.1 创建MySQL数据库的脚本如下
drop database if exists mysqlRedis;
create database mysqlRedis;
use mysqlRedis;
create table test1(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(64),
age INT,
description VARCHAR(1000),
primary key(id));
2.2 创建UDF使⽤的动态库
#include
#include
#include
#include
#include
int gxupdate(UDF_INIT * initid, UDF_ARGS * args, char * is_null, char * error) { redisContext * c = redisConnect("127.0.0.1", 6379);
if(c->err) {
redisFree(c);
return 1;
}
/*
//如果设有密码为ubuntu
redisReply *reply;
char strReply[] = "AUTH ubuntu";
reply = (redisReply*)redisCommand(c, strReply);
freeReplyObject(reply);
reply = NULL;
*/
const char * command1 = "HMSET w3ckey id %d name %s age %d description %s"; redisReply * r = (redisReply *)redisCommand(c, command1,
*(int*)args->args[0], args->args[1], *(int *)args->args[2], args->args[3]);
if (r == NULL) {
return 1;
}
if (!((r->type == REDIS_REPLY_STATUS) && (strcasecmp(r->str, "OK") == 0))) { freeReplyObject(r);
redisFree(c);
return 1;
}
freeReplyObject(r);
return 0;
}
my_bool gxupdate_init(UDF_INIT * initid, UDF_ARGS * args, char * message) {
return 0;
}
redis是nosql数据库吗编译为动态库:
gcc -shared -fPIC -I /usr/include/mysql -o udfredis.so mysqlUDFdemo.c /usr/local/lib/libhiredis.a 编译完成之后拷贝动态库udfgx.so到 /usr/lib/mysql/plugin/⽂件夹中,并修改成⽤户对应权限。
2.3 配置udf与trigger。
use mysqlRedis;
drop function if exists gxupdate;
create function gxupdate returns INTEGER soname "udfredis.so";
drop trigger if exists insert_redis;
drop trigger if exists update_redis;
drop trigger if exists delete_redis;
delimiter |
create trigger insert_redis
after insert on test1
for each row
begin
declare ret int;
select gxupdate(NEW.id, NEW.name, NEW.age, NEW.description) into @ret;
#必须加into @ret,否则返回错误ERROR 1415 (0A000)
#at line 6: Not allowed to return a result set from a trigger
#insert只有NEW变量。
#update有NEW和OLD变量。
#delete只有OLD变量。
end|
create trigger update_redis
after update on test1
for each row
begin
declare ret int;
select gxupdate(NEW.id, NEW.name, NEW.age, NEW.description) into @ret;
end|
create trigger delete_redis
after delete on test1
for each row
begin
declare ret int;
select gxupdate(OLD.id, OLD.name, OLD.age, OLD.description) into @ret;
end|
delimiter ;
注意,在MySQL中创建UDF的时候,insert, update和delete不能写成⼀个触发器,只能分别定义成三个触发器。测试
查看redis
[root@VM_24_16_centos mysql_redis]# redis-cli
127.0.0.1:6379> hgetall w3ckey
(empty list or set)
127.0.0.1:6379>
redis中⽆key w3ckey 对应的value。
insert MySQL
mysql>insert into test1 (name, age, description) values ("ggglwlop", 23, "ddddgdg");
Query OK, 1 row affected (0.02 sec)
mysql>
插⼊mysql。
查看redis
127.0.0.1:6379> hgetall w3ckey
1) "name"
2) "ggglwlop"
3) "description"
4) "ddddgdg"
5) "likes"
6) "27"
7) "visitors"
8) "23"
127.0.0.1:6379>
MySQL中有了对应的数据,说明mysql通过triger+udf的⽅式把改动更新到了redis中。有⽤的链接

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。