一、集群与分布式概述
1.什么是集群?
集群就是 很多服务器组成的一个网络。指的是将多台服务器集中在一起,实现同一业务。
2.为什么要集群?
一台服务器不能满足开发需要的时候,需要多台服务器来支持。这个时候就需要做集群,但是集群往往伴随着分布式;
3.什么是分布式?
分布式是指将不同的业务分布在不同的地方. web应用和数据库服务分开.
4.集群的优化
5.集群的两大关键特性及两大能力
集群提供了以下两个关键特性:
1、可扩展性--集群的性能不限于单一的服务实体,新的服务实体可以动态地加入到集群,从而增强集群的性能。动态添加服务器
2、高可用性--集群通过服务实体冗余使客户端免于轻易遇到out of service的警告。在集群中,同样的服务可以由多个服务实体提供。如果一个服务实体失败了,另一个服务实体会接管失败的服务实体。集群提供的从一个出错的服务实体恢复到另一个服务实体的功能增强了应用的可用性
当访问的服务器挂了时,集群要有能力找可以正常使用额服务器继续提供服务器。
两大能力:
1、负载均衡--负载均衡能把任务比较均衡地分布到集群环境下的计算和网络资源。
2、错误恢复--由于某种原因,执行某个任务的资源出现故障,另一服务实体中执行同一任务的资源接着完成任务。这种由于一个实体中的资源不能工作,另一个实体中的资源透明的继续完成任务的过程叫错误恢复。
当访问的服务器挂了时,集群要有能力找可以正常使用额服务器继续提供服务器。
6.分布式和集群的相同点和不同点
面试题:
相同点:都是处理高并发,而且都需要多台服务器协同.一般在一个系统中同时存在分布式和集群.
不同点:分布式中不同服务器处理是不同业务.而集群处理时同一业务.
二、redis集群方案
1.为什么redis要做集群?
防止单点故障、处理高并发-太多请求一台服务器搞不定、处理大量数据-太多内存数据一台服务器搞不定
2.方案一:主从复制
优点:支持主从复制,主机会自动将数据同步到从机,可以进行读写分离
缺点:Redis不具备自动容错和恢复功能,Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。只解决高并发
3.方案三:哨兵模式
功能:
(1)监控主服务器和从服务器是否正常运行。
(2)主服务器出现故障时自动将从服务器转换为主服务器。
优点:哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。
主从可以自动切换,系统更健壮,可用
4.Redis-Cluster集群
4.1.什么是Redis-Cluster?
从redis 3.0之后版本支持redis-cluster集群,它是Redis官方提出的解决方案,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。
客户端与 redis 节点直连,不需要中间 proxy 层.客户端不需要连接集群所有节点连接集群中任何一个可用节点即可。
所有的 redis 节点彼此互联(PING-PONG 机制),内部使用二进制协议优化传输速度和带宽.
4.2.分布存储机制-槽
4.3.容错机制-投票(选举)
5.集群环境搭建
5.1.所需软件
5.2.搭建
第一步,安装并拷贝6台服务器
第二步,进行配置
打开每个Redis目录下的文件 redis.windows.conf,修改里面的端口号分别对应相对应的文件夹名:6379、6380、6381、6382、6383、6384。
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
appendonly yes
第三步,编写启动脚本start.bat
title redis-6379
redis-server.exe redis.windows.conf
title命名规则 redis-相对应的端口。
第四步,安装ruby
第五步,安装Redis的Ruby驱动redis-xxxx.gem
下载地址 https://rubygems.org/pages/download
解压后执行命令:ruby setup.rb
再执行命令:gem install redis
第六步,启动每个节点并且执行集群构建脚本
点击每个节点start.bat进行启动
拷贝redis-trib.rb到6379的redis节点
执行命令
redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384
6、集群环境测试
6.1.命令测试redis-cli
redis-cli –c –h ”地址” –p “端口号”
6.2.查看集群信息:cluster info
6.3.代码测试
@Test
public void testCluster() throws IOException, InterruptedException {
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("127.0.0.1", 6379));
nodes.add(new HostAndPort("127.0.0.1", 6380));
nodes.add(new HostAndPort("127.0.0.1", 6381));
nodes.add(new HostAndPort("127.0.0.1", 6382));
nodes.add(new HostAndPort("127.0.0.1", 6383));
nodes.add(new HostAndPort("127.0.0.1", 6384));
JedisCluster cluster = new JedisCluster(nodes);
try {
String res = cluster.get("name");
System.out.println(res);
// cluster.quit();
} catch (Exception e) {
e.printStackTrace();
// cluster.quit();
}
}