Redis分布式集群搭建
Redis集群架构图
上图蓝色为redis集群的节点。
节点之间通过ping命令来测试连接是否正常,节点之间没有主区分,连接到任何一个节点进行操作时,都可能会转发到其他节点。
1、Redis的容错机制
节点之间会定时的互相发送ping命令,测试节点的健康状态,当节点接受到ping命令后,会返回一个pong字符串。
投票机制:如果一个节点A给节点B发送ping没有得到pong返回,会通知其他节点再次给B发送ping,如果集群中有超过一半的节点收不B节点的pong。那么就认为B节点挂了。一般会为每个节点提供一个备份节点,如果挂掉会切换到备份节点。
2、Redis集群存储原理
Redis对于每个存放的key会进行hash操作,生成一个[0-16384]的hash值(先进行
crc 算法再对16384取余)。
集群的情况下,就是把[0-16384]的区间进行拆分,放到不同的redis中。
3、Redis的持久化
Snapshotting:定时的将Redis内存中的数据保存到硬盘中
AOF:将所有的command操作保存到aof中,AOP的同步频率很高,数据即使丢失,粒度也很小,但会在性能上造成影响。
二、Redis集群准备工作
Redis安装
源码下载
下载地址https://pan.baidu.com/s/1bCcLv4 密码i5k6
解压源码
tar -zxvf redis-3.0.0.tar.gz
进入解压后的目录进行编译
cd /usr/local/redis-3.0.0
make
安装到指定目录,如 /usr/local/redis
cd /usr/local/redis-3.0.0
make PREFIX=/usr/local/redis install
nredis.conf
redis.conf是redis的配置文件,redis.conf在redis源码目录。
注意修改port作为redis进程的端口,port默认6379。
拷贝配置文件到安装目录下
进入源码目录,里面有一份配置文件 redis.conf,然后将其拷贝到安装路径下
cd /usr/local/redis
mkdir conf
cp /usr/local/redis-3.0.0/redis.conf /usr/local/redis/bin
运行:bin/redis-server 将出现下图画面:
Redis默认是前台运行的,可以修改redis.conf的daemonize yes ,将其变成后台运行。
集群环境搭建
redis集群管理工具redis-trib.rb依赖ruby环境,首先需要安装ruby环境
安装ruby
yum install ruby
yum install rubygems
安装ruby和redis的接口程序
拷贝redis-3.0.0.gem至/usr/local下
执行:
gem install /usr/local/redis-3.0.0.gem
三、创建Redis集群
在一台服务器上,可以用不同端口号来表示不同redis服务器。
Redis集群最少需要三台服务器,而每台服务器有需要备用服务器,所以最少需要6台服务器。端口规划如下:
主服务器:192.168.100.66 :7001 :7002 :7003
从服务器:192.168.100.66 :7004 :7005 :7006
在/usr/local 创建文件夹用来存放服务器程序
mkdir 7001 7002 7003 7004 7005 7006
如果想让redis支持集群需要修改redis.config配置文件的cluster-enabled yes
本例中我们以端口来区别不同的redis服务,所以还需要修改redis.config的port为对应端口
修改完配置文件,将redis安装目录的bin复制到上面每个目录中。
分别进入7001/bin/ 7002/bin .....
启动服务./redis-server ./redis.conf
查看redis进程:ps -aux|grep redis 如下图则说明启动成功
创建集群:
将之前解压的文件夹的redis-3.0.0/src/redis-trib.rb复制到redis-cluster目录
运行
./redis-trib.rb create --replicas 1 192.168.100.66:7001 192.168.100.66:7002 192.168.100.66:7003 192.168.100.66:7004 192.168.100.66:7005 192.168.100.66:7006
如果执行时报如下错误:
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
解决方法是删除生成的配置文件nodes.conf,如果不行则说明现在创建的结点包括了旧集群的结点信息,需要删除redis的持久化文件后再重启redis,比如:appendonly.aof、dump.rdb
如果成功最终输入如下:
查询集群信息:
说明:
./redis-cli -c -h 192.168.101.3 -p 7001 ,其中-c表示以集群方式连接redis,-h指定ip地址,-p指定端口号
cluster nodes 查询集群结点信息
cluster info 查询集群状态信息
hash槽重新分配
第一步:连接上集群
./redis-trib.rb reshard 192.168.101.3:7001(连接集群中任意一个可用结点都行)
第二步:输入要分配的槽数量
输入 500表示要分配500个槽
第三步:输入接收槽的结点id
这里准备给7007分配槽,通过cluster nodes查看7007结点id为15b809eadae88955e36bcdbb8144f61bbbaf38fb
输入:15b809eadae88955e36bcdbb8144f61bbbaf38fb
第四步:输入源结点id
这里输入all
第五步:输入yes开始移动槽到目标结点id
添加从节点
集群创建成功后可以向集群中添加节点,下面是添加一个slave从节点。
添加7008从结点,将7008作为7007的从结点。
./redis-trib.rb add-node --slave --master-id 主节点id 添加节点的ip和端口 集群中已存在节点ip和端口
执行如下命令:
./redis-trib.rb add-node --slave --master-id cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 192.168.101.3:7008 192.168.101.3:7001
cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 是7007结点的id,可通过cluster nodes查看。
注意:如果原来该结点在集群中的配置信息已经生成cluster-config-file指定的配置文件中(如果cluster-config-file没有指定则默认为nodes.conf),这时可能会报错:
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
解决方法是删除生成的配置文件nodes.conf,删除后再执行./redis-trib.rb add-node指令
查看集群中的结点,刚添加的7008为7007的从节点:
1.1. 删除结点:
./redis-trib.rb del-node 127.0.0.1:7005 4b45eb75c8b428fbd77ab979b85080146a9bc017
删除已经占有hash槽的结点会失败,报错如下:
[ERR] Node 127.0.0.1:7005 is not empty! Reshard data away and try again.
需要将该结点占用的hash槽分配出去(参考hash槽重新分配章节)。
测试:
Maven:
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.10.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
普通测试:
@Test
public void redisClusterTest1(){
JedisPoolConfig config=new JedisPoolConfig();
config.setMaxTotal(30);
config.setMaxIdle(2);
Set<HostAndPort> jedisNode=new HashSet<HostAndPort>();
jedisNode.add(new HostAndPort("192.168.100.66",7001));
jedisNode.add(new HostAndPort("192.168.100.66",7002));
jedisNode.add(new HostAndPort("192.168.100.66",7003));
jedisNode.add(new HostAndPort("192.168.100.66",7004));
jedisNode.add(new HostAndPort("192.168.100.66",7005));
jedisNode.add(new HostAndPort("192.168.100.66",7006));
JedisCluster jc=new JedisCluster(jedisNode,config);
jc.set("name","老王");
String value=jc.get("name");
System.out.println(value);
}
Spring测试:
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 连接池配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大连接数 -->
<property name="maxTotal" value="30" />
<!-- 最大空闲连接数 -->
<property name="maxIdle" value="10" />
<!-- 每次释放连接的最大数目 -->
<property name="numTestsPerEvictionRun" value="1024" />
<!-- 释放连接的扫描间隔(毫秒) -->
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<!-- 连接最小空闲时间 -->
<property name="minEvictableIdleTimeMillis" value="1800000" />
<!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
<property name="softMinEvictableIdleTimeMillis" value="10000" />
<!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
<property name="maxWaitMillis" value="1500" />
<!-- 在获取连接的时候检查有效性, 默认false -->
<property name="testOnBorrow" value="true" />
<!-- 在空闲时检查有效性, 默认false -->
<property name="testWhileIdle" value="true" />
<!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
<property name="blockWhenExhausted" value="false" />
</bean>
<!-- redis集群 -->
<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg index="0">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.100.66"></constructor-arg>
<constructor-arg index="1" value="7001"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.100.66"></constructor-arg>
<constructor-arg index="1" value="7002"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.100.66"></constructor-arg>
<constructor-arg index="1" value="7003"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.100.66"></constructor-arg>
<constructor-arg index="1" value="7004"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.100.66"></constructor-arg>
<constructor-arg index="1" value="7005"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg index="0" value="192.168.100.66"></constructor-arg>
<constructor-arg index="1" value="7006"></constructor-arg>
</bean>
</set>
</constructor-arg>
<constructor-arg index="1" ref="jedisPoolConfig"></constructor-arg>
</bean>
</beans>
测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring-config.xml"})
public class RedisClusterTest {
@Autowired
private JedisCluster jedisCluster;
@Test
public void redisClusterTest2(){
jedisCluster.set("username","小明啦啦");
String name=jedisCluster.get("username");
System.out.println(name);
}
}
转载于:https://www.cnblogs.com/chenkeyu/p/8047811.html
Redis分布式集群搭建相关推荐
- Linux 系列(三)——Redis 分布式集群搭建
在Redis的安装和部署(Linux)一文中详细介绍了在Linux环境中搭建Redis服务,本文将介绍关于Redis分布式 集群搭建细节. 一.Redis集群架构 1.Redis集群架构图 蓝色 ...
- Redis 分布式集群搭建2022版本+密码(linux环境)
Linux环境 安装 Redis-6.2.6 配置运行_01 https://gblfy.blog.csdn.net/article/details/105583077 文章目录 一.节点分布总览 二 ...
- redis分布式集群环境搭建
redis 分布式集群可分为主从集群.哨兵集群.分片集群,本片文章我们就来分别介绍这三种集群环境的搭建. 本次搭建环境为 Linux 虚拟机系统. 在搭建 redis集群之前,需要先在 linux 系 ...
- 大数据调度平台Airflow(八):Airflow分布式集群搭建及测试
目录 Airflow分布式集群搭建及测试 一.节点规划 二.airflow集群搭建步骤 1.在所有节点安装python3.7 2.在所有节点上安装airflow 三.初始化Airflow 1.每台节点 ...
- 大数据分布式集群搭建(1)
在学习了几天的hadoop分布式集群搭建之后想写写文章记录一下一路以来遇到的困难和解决方案. 闲话不多说,进入正题. 一.环境及准备 因为只有一台电脑,所以需要用虚拟机来模拟环境. 本地机器用到软件: ...
- down redis集群_硬核干货!Redis 分布式集群部署实战
原理: Redis集群采用一致性哈希槽的方式将集群中每个主节点都分配一定的哈希槽,对写入的数据进行哈希后分配到某个主节点进行存储. 集群使用公式(CRC16 key)& 16384计算键key ...
- redis 槽点重新分配 集群_5000+字硬核干货!Redis 分布式集群部署实战
原理: Redis集群采用一致性哈希槽的方式将集群中每个主节点都分配一定的哈希槽,对写入的数据进行哈希后分配到某个主节点进行存储. 集群使用公式(CRC16 key)& 16384计算键key ...
- redis分片_5000+字硬核干货!Redis 分布式集群部署实战
原理: Redis集群采用一致性哈希槽的方式将集群中每个主节点都分配一定的哈希槽,对写入的数据进行哈希后分配到某个主节点进行存储. 集群使用公式(CRC16 key)& 16384计算键key ...
- SpringBoot2.x整合Redis 分布式集群_01
文章目录 一.节点分布总览 二.软件配置初始化 三.集群配置修改 3.1. redis-7002.conf 3.2. redis-7003.conf 3.3. redis-8001.conf 3.4. ...
- 硬核干货!Redis 分布式集群部署实战
原理: Redis集群采用一致性哈希槽的方式将集群中每个主节点都分配一定的哈希槽,对写入的数据进行哈希后分配到某个主节点进行存储. 集群使用公式(CRC16 key)& 16384计算键key ...
最新文章
- [推荐]最强最全的电脑硬件知识
- 后台开发经典书籍--linux性能优化
- viterbi算法_HMM模型和Viterbi算法如何应用于分词
- 淘宝拼多多之争,从宏观的角度看拼多多是如何实现商业逆袭的?
- There is no getter for property named ‘col‘ in ‘class String‘,不是说一个参数不需要@Param注解吗?#{}和${}的区别
- 使用 SCons 代替 Makefile 快速构建应用程序
- JavaScript中的arguments,callee,caller
- 国产机器人销售增涨 安防市场有待挖掘
- python和jupyter安装
- nginx ---- nginx.conf核心配置文件
- FireEye动态:SolarWinds Orion 新 0day用于安装SUPERNOVA
- linux下安装gcc及设置多版本gcc多版本共存(如果enable静态库,会报错,不知道为什么,忽略静态库就没问题了)...
- 存储过程适用于你吗?
- 电脑桌面图标突然不见了
- windows putty Bitvise 登陆linux 服务器
- 一次Linux遭入侵,挖矿进程被隐藏案例分析
- 手把手教你架构3D引擎高级篇系列一
- vue中用canvas 画一个六边形 类似蜂窝形的功能导航主菜单
- 深度学习进阶课程16---用ReL解决Vanishing Gradient问题
- Unity3D占用内存太大怎么解决呢? -尾
热门文章
- Linux中的cp命令老九门
- Maven入门实战笔记-11节[7-11]
- oracle 偶尔登录超时,OracleClient,间歇性连接问题:应用程序挂起在OracleConnection.Open()上,没有超时,没有引发异常...
- Android 多媒体开发学习之加载大图片
- layui 自定义request_layuiAdmin pro v1.x 【单页版】开发者文档
- CentOS 7下编译FreeSWITCH 1.6
- tcpdump -w xxxxx.pcap 提示 Permission denied
- 2015年第六届(C/C++)B组蓝桥国赛题
- linux所有内存监控,流量监控?负载监控?内存监控?IO监控?check_linux_stats全部替你搞定!...
- C++小游戏——打方块