企业运维 --- LAMP架构( redis [2] 集群部署、redis与mysql的结合)

一、redis集群部署

  • Redis 集群是一个提供在多个Redis节点间共享数据的程序集,Redis集群并不支持处理多个keys的命令,因为需要移动数据,这样在高负载的情况下会发生不可预计的后果。
  • Redis 集群的优势:
    自动分割数据到不同的节点上。
    整个集群的部分节点失败或者不可达的情况下能够继续处理命令。

1.Redis Cluster(Redis集群)简介

  • redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;redis集群是没有统一的入口的,客户端(client)连接集群的时候连接集群中的任意节点(node)即可,集群内部的节点是相互通信的(PING-PONG机制),每个节点都是一个redis实例;
  • 为了实现集群的高可用,即判断节点是否健康(能否正常使用),redis-cluster有这么一个投票容错机制:如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否down掉的方法;
  • 判断集群down掉的方式:如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就down掉;
  • 那么为什么任意一个节点挂了(没有从节点)这个集群就挂了呢?, 因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点down了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。

查看create-cluster文件
请添加图片描述
可以看到里面指定了六个NODES(集群节点)
请添加图片描述
集群的使用:集群并不是由一些普通的Redis实例组成的,集群模式需要通过配置启用;
创建六个以端口号为名字的子目录, 在将每个目录中运行一个 Redis 实例,编辑文件redis.conf
请添加图片描述
cluster-enabled 选项用于开启实例的集群模式;
配置节点之间超时时间;
cluster-conf-file 选项设定了保存节点配置文件的路径,nodes.conf节点配置文件无须修改, Redis 集群在启动时创建, 并在有需要时自动进行更新。
开启Redis的AOF数据持久化存储,指定redis使用守护线程的方式启动;

编辑完成之后,启动第一个实例
请添加图片描述
查看进程
请添加图片描述
同样的,将7001目录下的redis.conf文件拷贝到其余5个目录,只需修改端口号即可
请添加图片描述
启动第二个实例
请添加图片描述
请添加图片描述
依次启动剩余实例
请添加图片描述
查看进程,可以看到6个redis节点都已经启动成功
请添加图片描述
可以看到生成的 appendonly.aof 日志文件
请添加图片描述
查看帮助文档
请添加图片描述

2.搭建集群

此时已经有6个正在运行中的 Redis 实例,我们需要使用这些实例来创建集群,replicas1 表示我们希望为集群中的每个主节点创建一个从节点;
可以看到,六个节点中, 三个为主节点, 其余三个则是各个主节点的从节点;
请添加图片描述
至此,Redi集群搭建成功,最后一段文字,显示了每个节点所分配的slots(哈希槽),这里总共6个节点,其中3个是从节点,所以3个主节点分别映射了0-5460、5461-10922、10933-16383solts。

集群分片模式
如果Redis只用复制功能做主从,那么当数据量巨大的情况下,单机情况下可能已经承受不下一份数据,更不用说是主从都要各自保存一份完整的数据。在这种情况下,数据分片(哈希分片)是一个非常好的解决办法。
Redis的Cluster正是用于解决该问题。它主要提供两个功能:
(1)自动对数据分片,落到各个节点上;
(2)即使集群部分节点失效或者连接不上,依然可以继续处理命令

输入yes
请添加图片描述
请添加图片描述
使用集群;
cluster info :查看集群状态
请添加图片描述
使用redis-cli来进行集群的交互;
使用客户端连接任意一个节点即可,使用-c 表示以集群的方式登录,-p 指定端口;
注意:一定要加上-c,不然节点之间是无法自动跳转的
请添加图片描述
可以看到主从信息
请添加图片描述
注意观察,它会自动切换到另一个redis去写或者读,可以看到在端口为7001的node上进行赋值操作,会重定向到在端口为7002的node上;
可以看到,端口为7006的节点虽然是端口为7001node节点的slave,但仍然能执行复制操作,说明redis集群无中心化的特点,任何节点都能进行读写操作
请添加图片描述
请添加图片描述
测试将端口号为7002的redis实例down掉
请添加图片描述
由于端口号为7002的redis实例是7004的master
请添加图片描述
因此,此时看不到7004redis实例的master
请添加图片描述
重新开启第二个redis实例
请添加图片描述
请添加图片描述
此时连接集群节点
请添加图片描述
可以看到相应的master
请添加图片描述
接下来演示节点加入redis集群的操作方式;
同样的继续建立两个以端口号为名字的子目录,在将每个目录中运行一个 Redis 实例,编辑文件redis.conf,修改端口号,启动相应实例
请添加图片描述
请添加图片描述
添加新的master节点(端口为7007的redis实例);
注意语法,一个新节点IP:端口 空格 一个旧节点IP:端口,注意点是:
1.不能多个新节点一次性添加;
2.新节点后是旧节点

这里是将节点加入了集群中,但是并没有分配slot(哈希槽),所以这个节点并没有真正的开始分担集群工作。
请添加图片描述
集群完整性检查:
集群完整性是指所有的槽都分配到存活的redis主节点上,只要16384个槽中有一个槽未被分配,则表示集群不完整
请添加图片描述
接下来为端口号为7007的redis实例分配相应的slave节点(端口号为7008的redis实例),后面要加上对应master的id(上图所示)
请添加图片描述
再次进行集群完整性检查,准备为加入集群的新的master(7007)分配哈希槽
请添加图片描述
请添加图片描述
分配slot需要使用以下参数
请添加图片描述
host:port :指定集群的任意一节点进行迁移slot,重新分slots
请添加图片描述
设定分配1000个,此时会自动从其余三个master节点为新的master节点分配一部分哈希槽,使得所有槽均匀分配
请添加图片描述
再次进行集群完整性检查,可以看到slot已经分配成功
请添加图片描述
测试将第一个redis实例down掉
请添加图片描述
请添加图片描述
再将第一个redis实例对应的slave节点的redis实例也down掉;
此时整个redis集群就已经down掉,无法正常工作
请添加图片描述
重新启动第二个和第六个redis实例
请添加图片描述
可以看到,此时第二个实例自动变为了原本是其slave的端口号为7004的redis节点的slave
请添加图片描述
请添加图片描述
输入info,可以看到指定redis服务的详细信息
请添加图片描述
请添加图片描述

2、redis与mysql的结合

  • redis:内存型数据库(数据放在内存 AOF:增量更新 RDB:覆盖),有持久化功能,具备分布式特性,可靠性高,适用于对读写效率要求都很高,数据处理业务复杂和对安全性要求较高的系统。
    mysql:数据放在磁盘,是关系型数据库,主要用于存放持久化数据
  • redis和mysql的区别总结
    类型上:从类型上来说,mysql是关系型数据库,redis是缓存数据库;
    作用上:mysql用于持久化的存储数据到硬盘,功能强大,但是速度较慢;redis用于存储使用较为频繁的数据到缓存中,读取速度快
  • 为什么要作缓存
    当网站的处理和访问量非常大的时候,我们的数据库的压力就变大了,数据库的连接池,数据库同时处理数据的能力就会受到很大的挑战,一旦数据库承受了其最大承受能力,网站的数据处理效率就会大打折扣。此时就要使用高并发处理、负载均衡和分布式数据库,而这些技术既花费人力,又花费资金。

缓存机制说明:所有的查询结果都放进了缓存,也就是把MySQL查询的结果放到了redis中去, 然后第二次发起该条查询时就可以从redis中去读取查询的结果,从而不与MySQL交互,也就实现了读写分离,也就是Redis只做读操作。由于缓存在内存中,所以查询会很快,从而达到优化的效果,redis的查询速度之于MySQL的查询速度相当于内存读写速度 /硬盘读写速度。

1.环境部署

实验环境:server1(安装httpd,php等) 、server2(作为redis服务器)、 server3(部署mysql数据库服务);
除了server2,停止其余主机的redis服务。

首先将server3上将之前添加的环境变量去掉,恢复初始设定即可
请添加图片描述
server3安装mariadb-server服务
请添加图片描述
编辑mysql配置文件
请添加图片描述
设定如下;
datadir = path:从给定目录读取数据库文件;
socket = filename:为MySQL客户程序与服务器之间的本地通信指定一个**套接字文件(**仅适用于UNIX/Linux系统;默认设置一般是/var/lib/mysql/mysql.sock文件)
请添加图片描述
启动数据库服务,测试进入数据库
请添加图片描述
真机将下载的sql数据传给server3
请添加图片描述
请添加图片描述
数据库名为test,表名也是test
请添加图片描述
将test.sql文件的内容输入重定向到mysql数据库;
进入数据库查看test表,可以看到数据信息
请添加图片描述
请添加图片描述
接下来去server2(部署redis服务器),编辑主配置文件
请添加图片描述
replicaof用于追随某个节点的redis,被追随的节点为主节点,追随的为从节点;
将replicaof注释掉,此时server2成为单独的master
请添加图片描述
请添加图片描述
请添加图片描述
查看Redis 服务器的信息
请添加图片描述
接下来对server1进行配置,安装pstree;

Psmisc软件包包含三个帮助管理/proc目录的程序:
fuser 显示使用指定文件或者文件系统的进程的PID;
killall 杀死某个名字的进程,它向运行指定命令的所有进程发出信号;
pstree 树型显示当前运行的进程。

请添加图片描述
使用killall指令将serve1之前开启的redis服务进程都杀掉
请添加图片描述
请添加图片描述
确保server1的环境变量也为初始设定
请添加图片描述
安装Apache, PHP,以及php连接mysql库组件
请添加图片描述
请添加图片描述
查看 php 扩展
请添加图片描述
查看当前的php版本
请添加图片描述
真机获取test.php 文件,传给server1的Apache默认发布目录下
请添加图片描述
编辑test.php文件,设定redis服务提供者为server2,mysql服务提供者为server3
请添加图片描述
接下来进入数据库,添加授权用户操作
请添加图片描述
可以看到,此时server1的php 扩展中没有redis模块,这样就无法将其联系起来
请添加图片描述
真机将指定目录传给server1
请添加图片描述
server1安装相应rpm包
请添加图片描述
启动httpd服务
请添加图片描述
接着客户端访问网页,可以看到此时还看不到数据,这是因为当用户访问该网页时,其实先去访问的是redis服务,如果有缓存直接获取,没有的话再去mysql数据库取数据,并且会向redis缓存一份
请添加图片描述
刷新后就可以看到数据了
请添加图片描述
server2连接Redis服务器;
Get 命令可以获取到指定 key 的值
请添加图片描述
进入数据库,使用UPDATE 命令来更新 MySQL 中的数据
请添加图片描述
更新成功
请添加图片描述
但是网页上仍然获取到的是之前的数据,并没有看到数据更新(mysql与redis不能实时同步数据)
请添加图片描述
除非在redis服务中,手动进行赋值操作
请添加图片描述
客户端才会看到同步后的数据
请添加图片描述

到这里,我们已经实现了 redis 作为 mysql 的缓存服务器,但是如果更新了 mysql,redis
中仍然会有对应的 KEY,数据就不会更新,此时就会出现 mysql 和 redis 数据不一致的情
。所以接下来就要通过 mysql 触发器将改变的数据同步到 redis 中。

2.配置 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 数据库的更新

真机将 lib_mysqludf_json 压缩包传给server3,server3需要编译数据库添加插件
请添加图片描述
安装unzip解压缩工具
请添加图片描述
解压缩,安装gcc编译工具;
lib_mysqludf_json UDF 库函数将关系数据映射为 JSON 格式。通常,数据库中的数据映
射为 JSON 格式,是通过程序来转换的。
请添加图片描述
安装 MariaDB-devel (包含开发首要的文件和一些静态库),编译数据库需要mariadb-devel和gcc
请添加图片描述
请添加图片描述
编译数据库
请添加图片描述
拷贝 lib_mysqludf_json.so 模块到 mysql 的插件目录
请添加图片描述
查看 mysql 的模块目录
请添加图片描述
注册 UDF 函数,查看函数
请添加图片描述
安装与配置 gearman:
在server1上安装 gearman 软件包
请添加图片描述
请添加图片描述
启动gearmand服务
请添加图片描述
真机将 gearman-mysql-udf 插件传给server3请添加图片描述
接下来 server3 安装 gearman-mysql-udf,这个插件是用来管理调用 Gearman 的分布式的队列
请添加图片描述
请添加图片描述
配置,此时会出现报错,因为需要安装依赖性软件
请添加图片描述
server1将libgearman、libgearman-devel、libevent-devel的rpm包传给server3
请添加图片描述
安装依赖性
请添加图片描述
重新配置
请添加图片描述
编译、安装
请添加图片描述
可以看到库函数已经被安装到了/usr/lib64/mysql/plugin目录下
请添加图片描述
请添加图片描述
以软连接的形式
请添加图片描述
进入数据库,继续注册 UDF 函数;
查看函数
请添加图片描述
指定 gearman 的服务信息
请添加图片描述
编写 mysql 触发器
请添加图片描述
将前面的内容注释,后面触发器部分打开
请添加图片描述
重新将test.sql文件输入重定向到mysql数据库;
查看触发器
请添加图片描述
请添加图片描述server1编写 gearman 的 worker 端
请添加图片描述

# vim worker.php
<?php
$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction('syncToRedis', 'syncToRedis');
$redis = new Redis();
$redis->connect('172.25.36.2', 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); #这条语句就是将 id 作 KEY 和 name 作 VALUE 分开存储,需要和前面写的 php 测试代码的存取一致。
}
?>

请添加图片描述
由于php 扩展没有gearman模块,因此需要安装相应rpm包
请添加图片描述
接下来后台运行 gearman 的 worker
请添加图片描述
请添加图片描述
此时更新 mysql 中的数据
请添加图片描述
刷新测试页面可以看到数据同步
请添加图片描述
查看 redis
请添加图片描述
再次更新 mysql 中的数据
请添加图片描述
查看 redis
请添加图片描述
数据仍然同步
请添加图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值