1. redis+mysql缓存服务器实现读写分离
Redis其实就是说把表中经常访问的记录放在了Redis中,然后用户查询时先去查询Redis再去查询MySQL,确实实现了读写分离,也就是Redis只做读操作。
1.1实验环境
主机 | 环境 |
---|
server1 | lnmp环境 | server2 | redis | server3 | mysql |
1.1.1server1搭建lnmp环境
安装nginx
tar zxf nginx-1.20.2.tar.gz
cd nginx-1.18.0.tar.gz
yum install -y pcre-devel zlib-devel
./configure --prefix=/usr/local/nginx
make && make install
配置nginx ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/ //软连接 vim /etc/nginx.conf nginx //启动nginx
安装php及插件 yum install -y *.rpm php -m |grep mysql
php -m |grep redis 查看安装是否成功
systemctl start php-fpm 开启php
1.1.2server2安装redis
/etc/init.d/redis_6379 start
1.1.3server3安装mysql
yum install -y mariadb-server systemctl start mariadb.service
登陆并授权 mysql grant all on test.* to redis@‘%’ identified by ‘westos’;
导入数据库的备份文件
mysql < test.sql
1.2 准备测试页
vim /usr/local/nginx/html/test.php chmod +r test.php
<?php
$redis = new Redis();
$redis->connect('172.25.1.12',6379) or die ("could net connect redis server");
$query = "select * from test";
for ($key = 1; $key < 10; $key++)
{
if (!$redis->get($key))
{
$connect = mysql_connect('172.25.1.13','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 "<br>";
for ($key = 1; $key < 10; $key++)
{
echo "number is <b><font color=#FF0000>$key</font></b>";
echo "<br>";
echo "name is <b><font color=#FF0000>$data[$key]</font></b>";
echo "<br>";
}
?>
1.3 准备数据库中的数据
使用备份直接导入
mysql < test.sql
1.4 测试访问172.25.1.11/test.php
第二次访问结果如图,缓存成功
2.gearman实现mysql和redis同步
2.1什么是Gearman
Gearman是一个支持分布式的任务分发框架:
- Gearman Job Server:Gearman核心程序,需要编译安装并以守护进程形式运行在后台。
- Gearman Client:可以理解为任务的请求者。
- Gearman Worker:任务的真正执行者,一般需要自己编写具体逻辑并通过守护进程方式运行,Gearman Worker接收到Gearman Client传递的任务内容后,会按顺序处理。
我们在最开始安装php插件时已经安装了gearman
下面要编写的mysql触发器,就相当于Gearman的客户端。
修改表,插入表就相当于直接下发任务。
通过lib_mysqludf_json UDF库函数将关系数据映射为JSON格式
再通过gearman-mysql-udf插件将任务加入到Gearman的任务队列中
最后通过redis_worker.php,也就是Gearman的worker端来完成redis数据库的更新。
2.2 部署gearman
2.2.1 安装lib_mysqludf_json
yum install -y unzip
unzip lib_mysqludf_json-master.zip
cd lib_mysqludf_json-master/
yum install -y gcc
gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/ 直接把影射文件扔到数据目录下,这样数据库能读到,
这里编译报错是因为没有安装mysql的开发包yum -y install mysql-devel 进入数据库,查看mysql 的模块目录,注册 UDF 函数,查看函数
MariaDB [(none)]> CREATE FUNCTION json_object RETURNS STRING SONAME 'lib_mysqludf_json.so'; 注册 UDF 函数
MariaDB [(none)]> select * from mysql.func; 查看函数
2.2.2 server3下载解压gearman,并解决依赖性进行编译
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
tar zxf gearman-mysql-udf-0.6.tar.gz
cd gearman-mysql-udf-0.6/
./configure --libdir=/usr/lib64/mysql/plugin/
make && make install
cd /usr/lib64/mysql/plugin/
出现以下插件表示安装成功
2.2.3注册UDF函数,并查看
mysql 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;
SELECT gman_servers_set(‘172.25.1.11:4730’); 指定gearman的服务信息
可以打开server1的gearman,验证下端口
2.2.4编辑mysql触发器,重新导入数据库
vim test.sql 创建触发器
mysql < test.sql 导入触发器命令
mysql
SHOW TRIGGERS FROM test;
2.2.5在server1中启动服务及worker任务
yum install -y php-pecl-gearman-1.1.2-1.el7.x86_64.rpm php -m | grep gearman php -m | grep redis
vim /usr/local/worker.php
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');
$redis = new Redis();
$redis->connect('127.25.1.12', 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);
}
?>
写 gearman 的 worker 端,修改对应行的redis节点信息,redis安装在那个节点就写那个
cd /usr/local
nohup php worker.php &
ps ax
2.2.6在server3更新 mysql 中的数据
###server3
use test update test set name=‘hhhh’ where id=1; ##更新 mysql 中的数据
2.2.7查看 redis,数据更新成功
###server2 redis-cli ##查看 redis 访问redis,查看数据,已经更新为新数据
get 1 ##hello
|