lnmp架构--redis数据库(redis结合mysql,自动同步)

2023-11-11

1. redis结合mysql

由于目前互联网巨大的访问量,在生产环境中常常需要redis结合mysql来用,如下图例,
我们可以将redis当作mysql的缓存,应用(app)所有读的操作都负载到redis上,因为redis够快,如果直接从mysql上读会对它造成巨大的压力,之前的mysql主从复制同样也是为了解决这样的问题,如果redis中没有想要的内容再从mysql中读并把读到的内容缓存到redis中。但是现在存在一个问题:当应用执行update操作时,就是往mysql中添加内容时,这时候redis无法完成更新,并且mysql无法将更改传递到redis中,因为二者的数据结构不同并且没有专门的连接端口,这时候我们该如何解决呢?
第一种传统的方式:在mysql中事先定义好触发器,通过udf(用户自定义函数)将mysql数据做映射,比如说将其映射为json数据,json数据可以跨平台传输,因此可以将json文件传递给redis从而完成数据的同步。但是这种方式从根本上是对mysql做操作,相当于给数据库创建函数对象,这种操作对数据库的侵入度是比较高的
第二种方式是目前比较主流的,阿里开发的canal应用,它直接伪装成mysql slave的身份来对mysql进行复制,相当于mysql主从复制,然后通过事先准备好的javaclient将数据同步到redis,由于主从复制是mysql本身的功能,通过mysql主从复制协议实现的,因此侵入mysql数据库的程度更小
在这里插入图片描述

1.1 lamp架构搭建

[root@server12 ~]# cd rhel7/
[root@server12 rhel7]# yum install -y php-* libgearman-* libevent-*  ##server12上安装php-fpm
[root@server12 rhel7]# systemctl start php-fpm.service  ##启动php-fpm
[root@server12 rhel7]# netstat -antulp  ##查看是否开启相关端口
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      4121/php-fpm: maste 
[root@server11 local]# rsync -a nginx server12:/usr/local/ ##把server11上配置好的nginx复制到server12指定目录中

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

[root@server12 ~]# cd /usr/local/nginx/
[root@server12 nginx]# ls
client_body_temp  conf  fastcgi_temp  html  logs  proxy_temp  sbin  scgi_temp  uwsgi_temp
[root@server12 nginx]# cd conf/
[root@server12 conf]# cp nginx.conf.default nginx.conf
cp: overwrite ‘nginx.conf’? y
[root@server12 conf]# vim nginx.conf  ##打开php站点注释
[root@server12 ~]# vim .bash_profile  ##配置环境变量
[root@server12 ~]# source .bash_profile
[root@server12 ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@server12 ~]# nginx  ##开启nginx
[root@server12 ~]# php -m | grep mysql
mysql
mysqli
pdo_mysql
[root@server12 ~]# php -m | grep redis
redis
37

在这里插入图片描述

在这里插入图片描述
访问测试
在这里插入图片描述

1.2 server13上启动redis,server14安装mysql

server13上启动redis
[root@server13 ~]# systemctl start redis_server
[root@server13 ~]# redis-cli

server14安装mysql
[root@server14 local]# yum install -y mariadb-server
[root@server14 local]# systemctl start mariadb
[root@server14 local]# mysql

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.3 测试文件配置

[root@server12 ~]# cd rhel7
[root@server12 rhel7]# ll test.php 
-rw-r--r-- 1 root root 1369 Apr 16 10:34 test.php
[root@server12 rhel7]# cp test.php /usr/local/nginx/html/ ##复制测试文件到nginx默认发布目录
[root@server12 rhel7]# cd /usr/local/nginx/html/
[root@server12 html]# vim test.php 

在这里插入图片描述
在这里插入图片描述

[root@server14 local]# mysql
MariaDB [(none)]> show databases;
MariaDB [(none)]> grant all on test.* to redis@'%' identified by 'westos'; ##授权远程用户连接

[root@server12 rhel7]# scp test.sql server14:  ##将测试数据复制到mysql主机中 
[root@server14 ~]# cat test.sql   
[root@server14 ~]# mysql < test.sql ##测试数据导入数据库

在这里插入图片描述
在这里插入图片描述
测试文件内容
在这里插入图片描述

1.4 访问测试

[root@server14 ~]# mysql
MariaDB [(none)]> use test
MariaDB [test]> show tables;
MariaDB [test]> select * from test;  ##查看test库中生成的测试内容

[root@server13 ~]# redis-cli
127.0.0.1:6379> get 1
"test1"
127.0.0.1:6379> get 2
"test2"

在这里插入图片描述
第一次访问,redis中没有缓存,看不到数据库中相关内容
在这里插入图片描述
再次访问,已将mysql中相关内容缓存进redis中,可以访问到
在这里插入图片描述

在这里插入图片描述

server14
MariaDB [test]> update test set name='westos' where id=1;
server13
127.0.0.1:6379> DEL 1
(integer) 1

mysql中更新后,redis并没有同步。
在这里插入图片描述
删除redis中的缓存,nginx自动将新的内容缓存进redis中。
在这里插入图片描述

2. redis与mysql的自动同步

配置 gearman 实现数据同步:
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.2 安装lib_mysqludf_json

lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式。通常,数据库中的数据映射为 JSON 格式,是通过程序来转换的。
在mysql主机上(server14):
unzip lib_mysqludf_json-master.zip
cd lib_mysqludf_json-master/
yum install -y mysql-devel gcc
gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c  ##生成so文件

拷贝 lib_mysqludf_json.so 模块:
cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/


查看 mysql 的模块目录:
mysql> show global variables like 'plugin_dir';
+---------------+-------------------------+
| Variable_name | Value |
+---------------+-------------------------+
| plugin_dir | /usr/lib64/mysql/plugin |
+---------------+-------------------------+

注册 UDF 函数
mysql> CREATE FUNCTION json_object RETURNS STRING SONAME
'lib_mysqludf_json.so';

查看函数
mysql> select * from mysql.func;
+--------------------+-----+-------------------------+----------+
| name | ret | dl | type |
+--------------------+-----+-------------------------+----------+
| json_object | 0 | lib_mysqludf_json.so | function |
+--------------------+-----+-------------------------+----------+

在这里插入图片描述
在这里插入图片描述

2.3 安装 gearman-mysql-udf

gearman-mysql-udf用来管理调用 Gearman 的分布式的队列

server14上:
yum install -y libgearman-* libevent-devel-2.0.21-4.el7.x86_64.rpm
tar zxf gearman-mysql-udf-0.6.tar.gz
cd gearman-mysql-udf-0.6
./configure --libdir=/usr/lib64/mysql/plugin/
make
make install

注册 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';

查看函数
mysql> select * from mysql.func;
+--------------------+-----+-------------------------+----------+
| name | ret | dl | type |
+--------------------+-----+-------------------------+----------+
| json_object | 0 | lib_mysqludf_json.so | function |
| gman_do_background | 0 | libgearman_mysql_udf.so | function |
| gman_servers_set | 0 | libgearman_mysql_udf.so | function |
+--------------------+-----+-------------------------+----------+

指定 gearman 的服务信息
mysql> SELECT gman_servers_set('192.168.0.12:4730');       %指定gearman后台,负责接收mysql更改,但不负责处理,处理交给指定的worker

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.4 配置 gearman 的 worker 端

[root@server12 rhel7]# yum install -y gearmand-1.1.12-18.el7.x86_64.rpm
[root@server12 rhel7]# systemctl start gearmand.service
[root@server12 rhel7]# netstat -antlp | grep 4730
tcp        0      0 0.0.0.0:4730            0.0.0.0:*               LISTEN      19099/gearmand      
tcp6       0      0 :::4730                 :::*                    LISTEN      19099/gearmand      
[root@server12 rhel7]# vim worker.php  
[root@server12 rhel7]# php -m | grep redis
redis
[root@server12 rhel7]# nohup php worker.php & ##worker打入后台执行
[root@server12 rhel7]# ps ax

在这里插入图片描述
指定worker端
在这里插入图片描述
在这里插入图片描述

2.5 配置mysql 触发器

客户提交update任务,然后触发器启动,通过触发器中定义的函数将数据同步到redis。

[root@server14 ~]# vim test.sql 
use test;
ELIMITER $$
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 ;
[root@server14 ~]# mysql < test.sql
[root@server14 ~]# mysql
MariaDB [(none)]> SHOW TRIGGERS FROM test;
MariaDB [(none)]> use test
MariaDB [test]> update test set name='redhat' where id=1;
[root@server13 ~]# redis-cli
127.0.0.1:6379> get 1
"redhat"

在这里插入图片描述

2.6 访问测试

更新mysql,redis自动同步更新
在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

lnmp架构--redis数据库(redis结合mysql,自动同步) 的相关文章

  • matlab自动深复制(deep copy)

    matlab 程序中 多次重复实验 而每次重复中会对数据 X 加一些随机噪声 此处希望每次重复时深复制一次 X 使得本次的噪声不会影响原数据 matlab 似乎能自动决定要不要复制一份 测试如下 Code matlab R2018a 原数据
  • 深入剖析智能仓储管理(WMS)应用价值与应用场景

    中国企业都在思考和部署如何实现一种高度自动化 高度信息化 高度网络化的生产模式 从而实现基于大数据的用户全息深层分析 本文目的在于交流如何建设适合自己企业的智能仓储 文 供应链指南针 孙亚博 2013年德国提出第四次工业革命 工业4 0的兴
  • linux开机自启动脚本以及update-rc.d命令解析

    linux有很多种自启动方式 这里只是简单记录下update rc d的自启动方式 update rc d的介绍 update rc d命令用于安装或移除System V风格的初始化脚本连接 脚本是存放在 etc init d 目录下的 我
  • HashSet详解

    概述 HashSet也是一个使用频率非常高的一个集合容器 最大的特点是存储的元素是没有重复的 而且是无序的 那么对于HashSet是如何判断原始是否重复 底层又是怎么实现的 你了解吗 HashSet介绍 HashSet 基于 HashMap
  • git-常见问题解决方法(全)

    git使用过程中遇到的问题解决方法记录 问题 1 更新代码后显示 unable to unlink old xxx xxx xx invalid argument 问题原因 要提交或更新的文件被系统线程占用 解决方法 把相关服务暂停 重新p
  • PDF文件如何转成markdown格式

    百度上根据pdf转makrdown为关键字进行搜索 结果大多数是反过来的转换 即markdown文本转PDF格式 但是PDF转markdown的解决方案很少 正好我工作上有这个需求 所以自己实现了一个解决方案 下图是一个用PDF XChan
  • 微前端的出现的背景和意义

    目录 微前端是什么 大规模 Web 应用的困局 传统 Web 应用的利与弊 背景和意义总结 微前端是什么 微前端是一种类似于微服务的架构 是一种由独立交付的多个前端应用组成整体的架构风格 将前端应用分解成一些更小 更简单的能够独立开发 测试
  • mysql删除一行_MySql删除表中一行的实操方法

    MySql删除表中一行的实操方法 首先你要确定能够唯一确定你那一行数据的字段或字段组合是哪些 DELETE FROM 表名 WHERE 字段1 and 字段2 and 字段1 为能够唯一确定某一行数据的字段组合 中填写你要 删除的字段具体值
  • Unity-ScrollRect-循环播放图片(确实没有转载是真的)

    都在代码和代码注释里了 发表在这里我还是有私心想要问问题的 是因为自己在使用时发现 Unity会调用两次通过继承来的PictureScrollView的Start函数两次 我并不能想明白是怎么回事 还请有了解的指点一下 先谢谢能给我指点的各
  • 【好文分享】亲试可行!简单快捷!如何在Ubuntu上编译Linux0.11

    2023年9月10日 周日上午 昨天晚上按照博客园的这篇文章试了一下 很快就成功在Ubuntu上编译运行了Linux0 11 https www cnblogs com chaoguo1234 p 16883932 html
  • linux redhat6.5 64位 login登陆无限循环

    场景 公司VC上虚机要迁移 通过拷贝vmfs文件方式迁移 开机后 发现无法登陆 一开始怀疑密码有问题 后来排除 然后网上搜索要修改 etc pam d login里边的参数 64位系统将 lib security pam limits so
  • Eclipse 报错: “Workspace in use or cannot be created, chose a different one.”

    打开eclipse报错 Workspace in use or cannot be created chose a different one 意识是 正在使用或无法创建工作区 选择另一个 解决办法 找到你eclipse得工作区 打开 me
  • C++ typeid运算符:获取类型信息

    typeid 运算符用来获取一个表达式的类型信息 类型信息对于编程语言非常重要 它描述了数据的各种属性 对于基本类型 int float 等C 内置类型 的数据 类型信息所包含的内容比较简单 主要是指数据的类型 对于类类型的数据 也就是对象
  • vue2和vue3 父子组件传参及区别

    vue3 1 父组件传子组件 在父组件的子组件标签中定义一个属性 在子组件中用defineProps接收父组件传来的值 父组件
  • python读取excle表中的数据

    没什么可介绍的 直接看代码 import pandas as pd from pandas import DataFrame if name main 读取excle表中的数据 file path r D ex Concrete Data
  • 从零搭建一个vue项目

    为了几个姐妹的需求 本文详细图解怎么样从零搭建一个vue项目 供参考 第一步 了解工具 首先我们需要一些工具 比如npm nodejs vue cli 和一个编译器vscode 也可以用别的 这里用vscode作为开发工具演示 第二步 检查
  • VMware虚拟机首次安装centos7.15后配置网络和关闭防火墙

    听了朋友的意见打算学下linux 学习当然是从安装开始了 网上找了个最新版的边看教程边装 网上看了好几个不同的教程 安装的时候还不难 都比较详细 但配置网络时都说的不太清楚 毕竟我没什么基础 如果不说清楚的话 很多地方我也不太懂 看了很多个
  • 编译内核的相关知识

    1 在PC端搭建环境 ubantu 2 树莓派等芯片带操作系统的启动过程 C51 STM32 裸机 用C直接操控底层寄存器实现相关业务 业务流程型的裸机代码 3 带有操作系统的 X86 intel windows 启动过程 电源 gt bi
  • openGL之API学习(三十)深度缓冲区深度值为负值

    通过 glReadPixels 0 0 WINDOW WIDTH WINDOW HEIGHT GL DEPTH COMPONENT GL UNSIGNED BYTE tmpPixelsBuffer 从帧缓冲区中读取深度信息 深度值竟然是负值
  • 插入排序 Insertion Sort

    插入排序 Insertion Sort 基本概念 插入排序的实现 时间复杂度和空间复杂度 稳定性 基本概念 从 index 1开始 不断将元素插入右边已经排好序的数组 适用于少量元素 Example 9 2 1 4 3 Step 1 9 2

随机推荐