redis和mysql的整合

  • 一、redis结合mysql
    • 1.redis和mysql的基础概念
    • 2.redis和mysql的区别总结
    • 3.为什么要作缓存
    • 4.redis作为缓存
  • 二、环境部署
  • 三、mysql+redis部署
  • 四、配置 gearman 实现redis和mysql的数据同步
    • 1.redis和mysql结合后出现的问题
    • 2.解决方案
    • 3.gearman同步效果测试

一、redis结合mysql

1.redis和mysql的基础概念

mysql:数据放在磁盘

是关系型数据库,主要用于存放持久化数据,

redis:数据放在内存 AOF:增量更新 RDB:覆盖

是NOSQL,非关系型数据库。

2.redis和mysql的区别总结

(1)类型上

从类型上来说,mysql是关系型数据库,redis是缓存数据库

(2)作用上

mysql用于持久化的存储数据到硬盘,功能强大,但是速度较慢

redis用于存储使用较为频繁的数据到缓存中,读取速度快

3.为什么要作缓存

当网站的处理和访问量非常大的时候,我们的数据库的压力就变大了,数据库的连接池,数据库同时处理数据的能力就会受到很大的挑战,一旦数据库承受了其最大承受能力,网站的数据处理效率就会大打折扣。此时就要使用高并发处理、负载均衡和分布式数据库,而这些技术既花费人力,又花费资金。

4.redis作为缓存

Redis其实就是说把表中经常访问的记录放在了Redis中,然后用户查询时先去查询Redis再去查询MySQL,确实实现了读写分离,也就是Redis只做读操作。由于缓存在内存中,所以查询会很快。

由上图可以看出, 用户端访问时,请求直接发送给redis,假如redis有数据就可以直接返给用户,假如redis没有,他就会调取数据库上的数据,用户写入的时候是直接写到了数据库上。

二、环境部署

我们主要解决的就是redis和mysql之间的数据同步的问题。

此时我们要模拟一个业务,读的时候从redis里面读,写的时候往mysql里面写,redis中没有的时候,我们要从数据库中进行加载。

step1将server2作为redis端

先检查2是不是master ,如果是就可以了,如果不是,按下面的步骤进行操作:

server2: vim /etc/redis/6379.conf

注销replicaof 172.25.73.1 6379

加入server2本来就是master,这部忽略

redis-cli

info查看server2是否为master


step2server4上进行操作,将server4作为数据库端

yum install -y mariadb-server.x86_64

systemctl start mariadb.service

step3: server3是作为lamp架构,在这里一定要注意选取一个干净的server节点去重新安装lamp架构,因为之前安装server1的lamp架构修改过好多参数,直接会影响实验结果

server3安装nginx:

yum install gcc pcre-devel openssl-devel -y 安装依赖性软件

[root@server3 nginx-1.20.2]# ./configure –with-http_ssl_module

[root@server3 nginx-1.20.2]# make && make install

安装好之后,创建软连接

ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/

vim /usr/local/nginx/conf/nginx.conf 如下图


yum install gcc pcre-devel openssl-devel -y 安装依赖性软件

vim /usr/local/nginx/conf/nginx.conf

server3安装php

yum install -y php-fpm-5.4.16-46.el7.x86_64.rpm

yum install -y php

yum install -y php-mysql

yum install -y php-pecl-redis-2.2.8-1.el7.x86_64.rpm php-pecl-igbinary-1.2.1-1.el7.x86_64.rpm

所有的软件安装结束后

php -m |grep mysql

php -m |grep redis 查看安装是否成功

systemctl start php-fpm 开启php

三、mysql+redis部署

server3上先安排一个默认发布目录

cp test.php /usr/local/nginx/html/
vim /usr/local/nginx/html/test.php


server4:

登陆数据库。先在数据库新建用户,授予远程登录权力并修改密码

grant all on test.* to redis@’%’ identified by ‘westos’;

导入数据库的备份文件

mysql < test.sql

server4登陆数据库查看导入效果

mysql

use test

show tables

select * from test;


此时由于是第一次读取,所以读取的是数据库的内容,刷新一次,redis中就有了缓存,此时由mysql变成了redis,这也就是为什么redis快的原因。

四、配置 gearman 实现redis和mysql的数据同步

1.redis和mysql结合后出现的问题

上面的实验做完我们会发现一个问题:
我们在配置文中可以看到,客户端访问的数据的时候,是先访问redis,如果在redis中访问不到,再去访问mysql。
那么,如果当数据库里的信息变更之后,redis中的数据没有和mysql保持同步,这个怎么办?


下图可以看出,在server4(mysql端)修改数据以后,redis上的数据还是原来的数据,并且网站页面上的数据也不会更新:


2.解决方案

解决方式:我们需要通过异步的方式来进行修改。
当然,你在redis中 把id=1的内容删掉,然后重新读取mysql中的内容就好了,但是在生产环境中不现实,并且也失去了redis的意义。

这个时候我们需要改动一下数据库的问题,安装点外部的函数,但是会对数据库造成侵入性,对其安全性造成问题。现在我们会选择一些侵入性较小的方案来进行设计,比如阿里的canal,它是直接把自己伪装成mysql一个slave,完全通过mysql的主从复制来同步数据,对我们的数据主库是没有任何侵入性的,这点非常不错,如下图红框所示。

但是刚刚说的canal只是完成了蓝框中的内容,他只是完成了把数据从mysql中拿过来,至于复制过来以后怎么办,是需要你自己解决。

我们采用的解决方式:把redis作为mysql的一种缓存的方式,这种方式比较成熟了,数据量适中的时候,效果还不错,

但当数据量过大时,在mysql和redis之间需要加一个分布式消息队列,就是mysql里面的数据更新后,不要直接由mysql的plugin往redis里面放,没有做解耦,很容易出问题,所以中间最好有一个分布式的分发框架来做解耦这个事情,

也就是说,不能直接就是redis同步mysql,缺乏解耦性也不行,万一中间的链路出现问题呢?这样就太不安全了。

具体操作如下:

1、数据库端的操作

step1首先要在server4上安装utf函数

server4:解压

yum install -y unzip

unzip lib_mysqludf_json-master.zip


step2安装软件
server4:安装gcc用于编译,安装maria插件

yum install -y gcc
yum install -y mariadb-devel


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

lib_mysqludf_json.c的意思是转换数据格式(因为mysql和redis 的数据结构不一样),将数据转换为json格式,这种格式的数据是可以跨平台的。

登陆mysql,

show global variables like ‘plugin_dir’; 查看一下数据库存放模块的目录,后边的命令需要

退出mysql。

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

直接把影射文件扔到数据目录下,这样数据库能读到

ls /usr/lib64/mysql/plugin/ 查看一下复制是否成功

step4
server4上,登陆数据库,注册udf函数:

CREATE FUNCTION json_object RETURNS STRING SONAME ‘lib_mysqludf_json.so’;

select * from mysql.func; 查看函数


step5

server4:安装gearman服务

得到三个rpm包:libgearman-devel-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

serve4:

先安装依赖性软件再configure

yum install -y libgearman-devel-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

step6

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

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

make && make install



安装完毕!

sep7:在server4上登陆数据库, 注册 UDF 函数

mysql> CREATE FUNCTION gman_do_background RETURNS STRING SONAME
‘libgearman_mysql_udf.so’; (用来指定发送给谁)
mysql> CREATE FUNCTION gman_servers_set RETURNS STRING SONAME
‘libgearman_mysql_udf.so’;(用来指定gearman server是谁)

select * from mysql.func; 查看函数


step8
接下来选择一个节点作为gearman的服务器,在这里选择server3

server3: 安装包均在rhel7目录下

yum install -y gearmand-1.1.12-18.el7.x86_64.rpm libgearman-1.1.12-18.el7.x86_64.rpm

systemctl start gearmand.service 安装成功后开启服务

netstat -antlp 查看端口,一会编辑配置文件要用到


step9
在server4上指定 gearman 的服务信息

SELECT gman_servers_set(‘172.25.73.3:4730’);


step10
server4:

创建触发器,通过触发器来调用之前创建的函数,在这里已经有了一个写好的test.sql,可以直接使用

vim test.sql 只留下原来加了注释那部分


step11
server4:

mysql < test.sql 导入触发器命令

mysql> SHOW TRIGGERS FROM test; 查看触发器

此时此刻,数据库端要做的事情就结束了。


2、gearman服务器端的操作
上面的步骤,我们创建了三个函数,创建了触发器,了解到了只要对数据库中的表做了修改,那么触发器就会生效,并将转换格式后的数据发送到【172.25.254.3:4730】,然后由这个gearmand的后台帮你调度,这个后台相当于一个分布式的分发框架,

那么数据到了server3上需要做什么呢?

server3相当于数据接收端,接收到数据以后,他要向下分发,分发给谁?

step1
把worker文件配置好

cp worker.php /usr/local/
vim /usr/local/worker.php

修改对应行的redis节点信息,redis安装在那个节点就写那个


step2
此时在server3上查询 php -m |grep gearman

发现依然没有,需要再安装一个插件。

yum install -y php-pecl-gearman-1.1.2-1.el7.x86_64.rpm

systemctl reload php-fpm.service 重新平滑加载服务


step3

nohup php /usr/local/worker.php & 后边按一下回车。打入后台 让他一直处于监听状态。当4730端口i接收到数据后,会分发给我们的消费端,消费端然后去redis做一个同步。
ps ax 查看

3.gearman同步效果测试

在mysql端修改数据,在resis端已经能看出数据已经做出变更:



所以,我们可以看出,业务首先访问的就是redis,redis相当于mysql的一个缓冲,当我们有数据变更,直接mysql中更新,更新后的数据通过UDF函数,配合触发器把数据发送给4730端口(server3上),由他再分发给我们的worker,