1、集群的概念
1.1、集群的两大能力
负载均衡:负载均衡把任务比较均匀的分布到集群环境下的计算和网络资源,以提高数据吞吐量。
错误恢复(高可用):如果集群中的某一台服务器由于故障或者维护需要无法使用,资源和应用程序将转移到可用的集群节点上。这种由于某个节点的资源不能工作,另一个可用节点中的资源能够透明的接管并继续完成任务的过程,叫做错误恢复。
负载均衡和错误恢复要求各服务实体中有执行同一任务的资源存在,而且对于同一任务的各个资源来说,执行任务所需的信息视图必须是相同的。
1.2、集群的特点
可扩展性:集群的性能不限制于单一的服务实体,新的服务实体可以动态的添加到集群,从而增强集群的性能。
高可用性:集群当其中一个节点发生故障时,这台节点上面所运行的应用程序将在另一台节点被自动接管,消除单点故障对于增强数据可用性、可达性和可靠性是非常重要的。
1.3、集群与分布式的区别
相同点:
分布式和集群都是需要有很多节点服务器通过网络协同工作完成整体的任务目标。
不同点:
分布式是指将业务系统进行拆分,即分布式的每一个节点都是实现不同的功能。而集群每个节点做的是同一件事情。
2、搭建zookeeper集群
因为集群需要leader的存在,集群的数量最好为奇数,故集群的最少操作数量是3台,下面都将以最少数量作为示例。
2.1、准备工作
(1)安装JDK 【此步骤省略】。
(2)Zookeeper压缩包上传到服务器
(3)将Zookeeper解压 ,创建data目录 ,并将 conf目录下的zoo_sample.cfg 文件改名为 zoo.cfg
(4)建立/usr/local/zookeeper-cluster目录,将解压后的Zookeeper复制到以下三个目录
cp -r zookeeper /usr/local/zookeeper-cluster/zookeeper-1
cp -r zookeeper /usr/local/zookeeper-cluster/zookeeper-2
cp -r zookeeper /usr/local/zookeeper-cluster/zookeeper-3
(5)修改每一个conf下的zoo.cfg文件
将每个dataDir属性改为当前data目录的路径
如果是在同一台服务器上搭建zookeeper集群则还需要将clientPort属性分别分配不同的端口号,分别为2181 2182 2183
2.2、配置集群
(1)在每个zookeeper的 data 目录下创建一个 myid 文件,并给予不同的内容,如:1、2、3 。这个文件就是记录每个服务器的ID。
使用echo命令写入,使用cat命令查看写入文件内容
(2)在每一个zookeeper 的 conf目录下zoo.cfg配置客户端访问端口(clientPort)和集群服务器IP列表。
server.1=192.168.25.140:2881:3881 server.2=192.168.25.140:2882:3882 server.3=192.168.25.140:2883:3883 |
解释:server.服务器ID=服务器IP地址:服务器之间通信端口:服务器之间投票选举端口
注意:此处为服务器通信端口,不可与client对外服务端口重复
2.3、启动集群
Mode为follower表示是跟随者(从)
Mod 为leader表示是领导者(主)
2.4、Dubbox连接zookeeper集群
<dubbo:registry protocol="zookeeper" address="192.168.25.140:2181,192.168.25.140:2182,192.168.25.140:2183"> </dubbo:registry>
3、redis主从
3.1、准备工作
如果redis使用过,需要先将持久化文件dump.rdb删掉,清空数据 rm rf *.rdb
3.2、创建主从目录,并将redis复制到该目录下
实现如下架构
3.3、配置redis的conf文件
3.3.1、修改redis.conf文件的port
3.3.2、修改两个从redis中redis.conf文件的slaveof
如:slaveof 192.168.25.129 6379
解释:slaveof 主redisIP 主redis端口
3.4、启动redis集群
可以看到即使连接的是第三个redis,IP端口号也显示的是主redis
3.5、主从关系
当主redis挂掉后,从redis只能读取不能写入
3.6、关闭主从redis
[root@jd redis03]# ./redis-cli -p 6379 shutdown [root@jd redis03]# ./redis-cli -p 6380 shutdown [root@jd redis03]# ./redis-cli -p 6381 shutdown [root@jd redis03]# cd .. [root@jd redis-master-slave]# cd redis01 [root@jd redis01]# ./redis-cli Could not connect to Redis at 127.0.0.1:6379: Connection refused not connected> exit
4、redis集群
任意一个redis都可以进行读写操作,redis3.0以后才支持redis集群。即多主多从关系。
4.1、redis的哈希槽
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。
例如三个节点:槽分布的值如下:
SERVER1: 0-5460
SERVER2: 5461-10922
SERVER3: 10923-16383
4.2、redis集群的准备工作
安装gcc和ruby,并上传redis-3.0.0.gem文件
yum install gcc-c++
yum install ruby
yum install rubygems
创建目录,将redis-3.0.0.gem文件放入
mkdir redis-cluster
4.3、将redis/bin复制到创建的目录中,并修改redis.conf文件
修改运行端口为7001 (7002 7003 .....)
将cluster-enabled yes 前的注释去掉(632行)
4.4、使用脚本搭建redis主从配置
进入解压的redis源码目录中的src目录 执行下面的命令
上传redis-3.0.0.gem ,安装 ruby用于搭建redis集群的脚本
[root@localhost ~]# gem install redis-3.0.0.gem Successfully installed redis-3.0.0 1 gem installed Installing ri documentation for redis-3.0.0... Installing RDoc documentation for redis-3.0.0...
先启动所有的redis 进入redis源码目录中的src目录 执行下面的命令即可
./redis-trib.rb create --replicas 1 192.168.25.140:7001 192.168.25.140:7002 192.168.25.140:7003192.168.25.140:7004 192.168.25.140:7005 192.168.25.140:7006
4.5、测试
redis01/redis-cli -p 7002 -c
集群下的主从节点都可以进行读写操作,但根据槽点最终仍是存在主节点上,实质是由从节点转发到主节点上。
4.6、SpringDataRedis连接Redis集群
添加配置文件applicationContext-redis-cluster.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 加载配置属性文件 --> <context:property-placeholder ignore-unresolvable="true" location="classpath:properties/redis-cluster-config.properties" /> <bean id="redis-clusterConfiguration" class="org.springframework.data.redis.connection.redis-clusterConfiguration"> <property name="maxRedirects" value="${redis.maxRedirects}"></property> <property name="clusterNodes"> <set> <bean class="org.springframework.data.redis.connection.redis-clusterNode"> <constructor-arg name="host" value="${redis.host1}"></constructor-arg> <constructor-arg name="port" value="${redis.port1}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.redis-clusterNode"> <constructor-arg name="host" value="${redis.host2}"></constructor-arg> <constructor-arg name="port" value="${redis.port2}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.redis-clusterNode"> <constructor-arg name="host" value="${redis.host3}"></constructor-arg> <constructor-arg name="port" value="${redis.port3}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.redis-clusterNode"> <constructor-arg name="host" value="${redis.host4}"></constructor-arg> <constructor-arg name="port" value="${redis.port4}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.redis-clusterNode"> <constructor-arg name="host" value="${redis.host5}"></constructor-arg> <constructor-arg name="port" value="${redis.port5}"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.redis-clusterNode"> <constructor-arg name="host" value="${redis.host6}"></constructor-arg> <constructor-arg name="port" value="${redis.port6}"></constructor-arg> </bean> </set> </property> </bean> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxTotal" value="${redis.maxTotal}" /> </bean> <bean id="jeidsConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" > <constructor-arg ref="redis-clusterConfiguration" /> <constructor-arg ref="jedisPoolConfig" /> </bean> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jeidsConnectionFactory" /> </bean> </beans>
添加属性文件redis-cluster-config.properties
redis.host1=192.168.25.140 redis.port1=7001 redis.host2=192.168.25.140 redis.port2=7002 redis.host3=192.168.25.140 redis.port3=7003 redis.host4=192.168.25.140 redis.port4=7004 redis.host5=192.168.25.140 redis.port5=7005 redis.host6=192.168.25.140 redis.port6=7006 redis.maxRedirects=3 redis.maxIdle=100 redis.maxTotal=600