一 Cluster集群
Cluster 集群简介
Redis 的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的内容。
实验:本次实验在一个虚拟机server1上创建集群总共6个节点。实际生产情况下,每台机器作为一个集群节点。
实验前将server1上redis和mysql停掉。
使用redis源码包create-cluster脚本创建集群(脚本中默认创建6个节点,可更改),每个master节点分配16384个哈希槽,用来存储。redis集群是无中心化的,指定任一个节点ip都能访问整个集群。
查看30001状态为master,对应slave为30004 ,-c 指定集群 -p指定端口
添加key值
Redis cluster集群的故障迁移
停掉30002做测试:自动将30002的slave30005 切换成master,并接管其哈希槽,只要16384个哈希槽不出错集群就能正常运行。当重新取启动30002时,其自动作为30005的slave。如果master挂掉,其slave成为master接管哈希槽集群可以正常工作,但当master的slave全都挂掉时,没有节点接受此哈希槽,导致集群不可用
再添加两个节点,只需要更改集群创建的脚本文件节点个数NODES:
然后start开启实例,此时这两个实例不在集群中
将两个节点添加到集群:查看集群帮助
添加30007节点为master:
--cluster集群 add-node添加节点到集群 添加30007为master 30001指向要添加进的集群
添加30008为master30007的slave
下面代码参数:从127.0.0.1:30008开始依次表示:节点30008; 指向集群30001; slave状态; 对应master30007的ID
查看集群成功添加两节点
此时master30007上没有哈希槽,迁移哈希槽给30007:all就是均衡的从其他3个节点上移3000个哈希槽到30007上
查看集群状态成功迁移哈希槽
使用脚本停止集群:
二 Redis持久化
三 Redis作MySQL的缓存服务器
3.1 实验前准备:
server4作为mysql数据库,server3安装lnmp架构(包括编译redis模块),server2作为redis服务端(要能写数据,必须为master)
3.1.1 server2修改配置文件变为master:注释掉172.25.254.3此行,变为master
3.1.2 server4作为mysql数据库
安装mariadb-server
3.1.3 之前server1上lnmp架构php版本太高, server3上安装一个带有redis模块的lnmp架构
http占用了80端口,停止掉httpd,重新启动nginx
php-fpm 9000端口开启
更改后的/etc/local/nginx/html/test.php文件:
<?php
$redis = new Redis();
$redis->connect('172.25.254.2',6379) or die ("could net connect redis server");
# $query = "select * from test limit 9";
$query = "select * from test";
for ($key = 1; $key < 10; $key++)
{
if (!$redis->get($key))
{
$connect = mysql_connect('172.25.254.4','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>";
}
?>
3.1.4server4上:写文件test.sql,并导入数据库, test.sql中的内容:将1~9键值对,写入test数据库里的test表中。test表会自己创建。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');
#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 ;
3.2 开始实验:
浏览器上首次访问的是mysql数据库:
然后数据从mysql更新到redis,此后会直接从redis缓存拿数据,访问的是redis
3.3 存在问题,当server4上mysql数据库上更改了数据,redis不会同步。只要redis缓存不过期,网站访问的还是没有更改的redis缓存。
3.3.1 server4 mysql数据库端修改数据:
网站访问或者server2redis服务端访问还是原来的数据:
3.3.2 如果删除redis缓存中的数据,然后使用浏览器访问,由于此时redis没有数据,会从mysql数据库访问并更新数据到redis:
redis从数据库更新了数据,浏览器中访问到了新数据:
四 配置gearman实现Redis和MySQL数据同步
本实验以异步方式进行mysql和redis的数据同步。 分布式分发框架。
4.2 实验环境配置:
在server4上,解压lib_mysqludf_json-master.zip,并安装gcc
mariadb-devel依赖
安装lib_mysqludf_json,lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式。通常,数据库中的数据映射为 JSON 格式,是通过程序来转换的。查看 mysql 的模块目录:
将
lib_mysqludf_json-master/lib_mysqludf_json.so
模块拷贝到/usr/lib64/mysql/plugin/
插件目录下,注册udf函数,并查看函数。
安装 gearman-mysql-udf,这个插件是用来管理调用 Gearman 的分布式的队列。
安装此插件的依赖性
编译和安装
再次注册两个udf函数
在lnmp架构服务器server3上安装 gearman 软件包:
启动服务,gearmand 监听本机的4730端口:
server4 mysql数据库中指定 gearman 的服务信息,将数据给german 的worker端server3:
server4上编写 mysql 触发器(根据实际情况编写)
将原来的test删除,将添加了触发器的test.sql导入数据库
test表内容不变,只是比原来多了触发器
在server3 gearmand的worker端编辑一个worker.php,并且worker.php代码中还用到了gearmand模块,所以还要给php添加gearmand模块:
平滑加载php,php执行worker.php 并打入后台
worker.php 配置文件:
4.2 配置完成,开始测试:
server4 mysql数据库上更改数据
redis(server2中)中的数据同步更新,浏览器直接访问的redis缓存数据,变更成功。
直接在server2中redis中查看数据
浏览器访问的是redis缓存,数据已经更新