百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

手把手教你搭建Redis集群(redis5.0.8集群搭建)

mhr18 2024-11-04 12:45 25 浏览 0 评论

大家好,我是可乐,一个专注原创,乐于分享的程序猿。本系列教程持续更新,可以微信搜索「 IT可乐 」第一时间阅读。回复《电子书》有我为大家特别筛选的海量免费书籍资料

在上一篇博客我们介绍了------Redis哨兵(Sentinel)模式,哨兵模式主要是解决高可用问题,在master节点宕机时,slave节点能够自动切换成为master节点

本篇博客我们来介绍Redis的另外一种模式------集群模式.

PS:我这里搭建演示的版本是redis-5.0.5,这个版本对于集群搭建会有很大的简化,比如最常用的redis-trib.rb脚本功能已经集成到redis-cli工具中了,具体下面会详细介绍。

1、为什么需要集群?

①、并发量

通常来说,单台Redis能够执行10万/秒的命令,这个并发基本上能够满足我们所有需求了,但有时候比如做离线计算,为了更快的得出结果,有时候我们希望超过这个并发,那这个时候单机就不满足我们需求了,就需要集群了.

②、数据量

通常来说,单台服务器的内存大概在16G-256G之间,前面我们说Redis数据量都是存在内存中的,那如果实际业务要保存在Redis的数据量超过了单台机器的内存,这个时候最简单的方法是增加服务器内存,但是单台服务器内存不可能无限制的增加,纵向扩展不了了,便想到如何进行横向扩展.这时候我们就会想将这些业务数据分散存储在多台Redis服务器中,但是要保证多台Redis服务器能够无障碍的进行内存数据沟通,这也就是Redis集群.

2、数据分区方式

对于集群来说,如何将原来单台机器上的数据拆分,然后尽量均匀的分布到多台机器上,这是我们创建集群首先要考虑的一个问题,通常来说,有如下两种数据分区方式.

①、顺序分布

比如我们有100W条数据,有3台服务器,我们可以将100W/3的结果分别存储到三台服务器上,如下所示:

  特点:键值业务相关;数据分散,但是容易造成访问倾斜;支持顺序访问;支持批量操作

②、哈希分布

同样是100W条数据,有3台服务器,通过自定义一个哈希函数,比如节点取余的方法,余数为0的存在第一台服务器,余数为1的存在第二台服务器,余数为2的存储在第三台服务器.如下所示:

  特点:数据分散度高;键值分布与业务无关;不支持顺序访问;支持批量操作。

3、一致性哈希分布

问题:对于上面介绍的哈希分布,大家可以想一下,如果向集群中增加节点,或者集群中有节点宕机,这个时候应该怎么处理?

①、增加节点

  如上图所示,总共10个数据通过节点取余hash(key)%/3 的方式分布到3个节点,这时候由于访问量变大,要进行扩容,由 3 个节点变为 4 个节点。

我们发现,如图所示,数据除了标红的1 2 没有进行迁移,别的数据都要进行变动,达到了80%,如果这时候并发很高,80%的数据都要从下层节点(比如数据库)获取,会给下层节点造成很大的访问压力,这是不能接受的。

即使我们进行翻倍扩容,从3个节点增加到6个节点,其数据迁移也在50%左右。

②、删除节点

  上图其实不管是哪一个节点宕机,其数据迁移量都会超过50%。基本上也是我们所不能接受的。

那么如何使得集群中新增节点或者删除节点时,数据迁移量最少?——一致性哈希算法诞生。

PS:关于一致性哈希算法,我会另外写一篇博客进行详细介绍,这里只是大概介绍一下。

  假设有一个哈希环,从0到2的32次方,均匀的分成三份,中间存放三个节点,沿着顺时针旋转,从Node1到Node2之间的数据,存放在Node2节点上;从Node2到Node3之间的数据,存放在Node3节点上,依次类推。

假设Node1节点宕机,那么原来Node3到Node1之间的数据这时候改为存放到Node2节点上,Node2到Node3之间数据保持不变,原来Node1到Node2之间的数据还是存放在Node2上,也就是只影响三分之一的数据,节点越多,影响数据越少。

  同理,假设增加一个节点,影响的数据甚至更少。

  当然,实际业务中并不是你节点均匀分布,访问就会很平均,这时候容易造成访问倾斜的问题,这里就会引出虚拟节点的定义。我这里就不做详解了。

4、Redis Cluster虚拟槽分区

Redis集群数据分布没有使用一致性哈希分布,而是使用虚拟槽分区概念。

Redis内部内置了序号 0-16383 个槽位,每个槽位可以用来存储一个数据集合,将这些槽位按顺序分配到集群中的各个节点。每次新的数据到来,会通过哈希函数 CRC16(key) 算出将要存储的槽位下标,然后通过该下标找到前面分配的Redis节点,最后将数据存储到该节点中。

具体情况如下图:(以集群有3个节点为例)

  至于为什么Redis不使用一致性哈希分布,而是虚拟槽分区。因为虚拟槽分区虽然没有一致性哈希那么灵活,但是CRC16(key)%16384 已经分布很均匀了,并且对于后面节点增删(按照序号)操作起来也很方便。

5、原生搭建 Redis Cluster

集群以三主三从的模式来搭建。

①、服务器列表

②、配置各个节点参数

#配置端口
port ${port}
#以守护进程模式启动
daemonize yes
#pid的存放文件
pidfile /var/run/redis_${port}.pid
#日志文件名
logfile "redis_${port}.log"
#存放备份文件以及日志等文件的目录
dir "/opt/redis/data"  
#rdb备份文件名
dbfilename "dump_${port}.rdb"
#开启集群功能
cluster-enabled yes
#集群配置文件,节点自动维护
cluster-config-file nodes-${port}.conf
#集群能够运行不需要集群中所有节点都是成功的
cluster-require-full-coverage no

配置完成后,通过 redis-server redis.conf 命令启动这六个节点。

启动之后,进程后面会有 cluster 的字样:

③、建立各个节点通信   这里有 6 个节点,我们只需要拉通 1 个节点和另外 5 个节点之间通信,那么每两个节点就能够通信了。命令如下:

redis-cli -h -p {password} cluster meet {port2}

这里的 -a 参数表示该Redis节点有密码,如果没有可以不用加此参数。

实例中的 6 个节点,分别进行如下命令:

redis-cli -p 6379 -a 123 cluster meet 192.168.14.101 6382
redis-cli -p 6379 -a 123 cluster meet 192.168.14.102 6380
redis-cli -p 6379 -a 123 cluster meet 192.168.14.102 6383
redis-cli -p 6379 -a 123 cluster meet 192.168.14.103 6381
redis-cli -p 6379 -a 123 cluster meet 192.168.14.103 6384

执行完毕后,可以查看节点通信信息:

redis-cli -p 6379 -a 123 cluster nodes

结果如下:

 或者执行如下命令:

redis-cli -p 6379 -a 123 cluster info

结果如下:

④、分配槽位   由于我们是三主三从的架构,所以只需要对主服务器分配槽位即可。三个节点,分配序号为 0-16383 ,总共16384 个槽位。

Node1:0~5460
Node2:5461~10922
Node3:10923~16383

分配槽位的命令如下:

redis-cli -p {password} cluster addslots {{endSlot}}

比如,对于Node1主节点,我们执行命令如下:

redis-cli -p 6379 -a 123 cluster addslots {0..5462}

另外两个节点对于上面的命令更改一下槽位数,然后查看集群信息:

  查看Node1节点信息:

⑤、主从配置   命令如下:

redis-cli -p {nodeId}

前面的${port} 表示从节点的端口,这里的nodeId表示主节点的nodeId,如下:

  如果弄反了,会报如下错误:

(error) ERR To set a master the node must be empty and without assigned slots.

执行三条命令完毕后,查看节点信息:

  这时候,集群状态是成功了。

⑥、测试   经过如上几步操作,集群搭建成功,我们通过如下命令进入客户端:

redis-cli -c -p ${port} -a {password}

注意:必须要加 -c 参数,否则进行键值对操作时会报如下错误:

 正确进入后,可以正确存值和取值。

6、脚本搭建Redis Cluster

上面原生命令安装Redis Cluster 走下来其实挺费劲的,在实际生产环境中,如果集群数量比较大,操作还是容易出错的。

不过Redis官方提供了一个安装集群的脚本,在Redis安装目录的src目录下——redis-trib.rb,使用该脚本可以快速搭建Redis Cluster集群。

注意:redis版本在5之前的集群运行该脚本需要安装ruby环境,而redis5.0之后已经将redis-trib.rb 脚本的功能全部集成到redis-cli之中了,所以如果当前版本是Redis5,那么可以不用安装ruby环境。

下面我分别介绍这两种方法。

①、Redis5之前使用redis-trib.rb脚本搭建   redis-trib.rb脚本使用ruby语言编写,所以想要运行次脚本,我们必须安装Ruby环境。安装命令如下:

yum -y install centos-release-scl-rh
yum -y install rh-ruby23  
scl enable rh-ruby23 bash
gem install redis

安装完成后,我们可以使用 ruby -v 查看版本信息。

  Ruby环境安装完成后。运行如下命令:

redis-trib.rb create --replicas 1 192.168.14.101:6379 192.168.14.102:6380 192.168.14.103:6381 192.168.14.101:6382 192.168.14.102:6383 192.168.14.103:6384

关于这个命令的解释下面会一起介绍。

②、Redis5版本集群搭建    前面我们就说过,redis5.0之后已经将redis-trib.rb 脚本的功能全部集成到redis-cli中了,所以我们直接使用如下命令即可:

redis-cli -a ${password} --cluster create 192.168.14.101:6379 192.168.14.102:6380 192.168.14.103:6381 192.168.14.101:6382 192.168.14.102:6383 192.168.14.103:6384 --cluster-replicas 1

①、${password} 表示连接Redis的密码,通常整个集群我们要么不设置密码,要么设置成一样的。

②、后面的六个ip:port,按照顺序,前面三个是主节点,后面三个是从节点,顺序不能错。

③、最后数字 1 表示一个主节点只有一个从节点。和前面的配置相对应。

7、集群扩容

这里新增两个端口分别是 6390、6391的节点。其中6391节点是6390节点的从节点。

①、配置新增节点文件   比如,我们将6379节点的配置文件redis.conf 拷贝两份,然后将里面的配置文件里面的字符串 6379 分别替换成 6390 和 6391。

:%s/6379/6390/g,:%s/6379/6391/g

替换完成之后,分别启动这两个节点。

这时候这两个节点都不在集群当中,是两个孤儿节点。

②、将新增主节点加入到集群中   命令如下:

redis-cli -p existing_port -a ${password} --cluster add-node new_host:new_port existing_host:existing_port

我这里是将新增的主节点 6390 添加到原来的集群中。

redis-cli -p 6379 -a 123 --cluster add-node 192.168.14.101:6390 192.168.14.101:6379

添加完毕后,这时候查看集群状态

  6390节点已经存在集群中了,但是还没有分配槽位。

③、为新增主节点分配槽位   分配命令如下

redis-cli -p existing_port -a ${password} --cluster reshard existing_host:existing_port

后面的existing_host:existing_port表示原来集群中的任意一个节点,这个命令表示将源节点的一部分槽位分配个新增的节点。

在分配过程中,会出现如下几个提示:

#后面的2000表示分配2000个槽位给新增节点
How many slots do you want to move (from 1 to 16384)? 2000
#表示接受节点的NodeId,填新增节点6390的
What is the receiving node ID? 64a0779c7baef78c8fd0f2bb6e73f29375e00133d
#这里填槽的来源,要么填all,表示所有master节点都拿出一部分槽位分配给新增节点;
#要么填某个原有NodeId,表示这个节点拿出一部分槽位给新增节点
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: all

分配成功后,我们查看节点信息:

  我们发现已经给该节点分配了槽位。

④、将新增的从节点添加到集群中

redis-cli -p 6379 -a 123 --cluster add-node 192.168.14.101:6391 192.168.14.101:6379

⑤、建立新增节点的主从关系   命令如下:

redis-cli -p {nodeId}

前面的${port} 表示从节点的端口,这里的nodeId表示主节点的nodeId。

⑥、测试   查看节点信息,发现4主4从。

  在6379节点新增一个字符串 (k4,v4),然后到6390节点查看:

  自此,大功告成。

8、集群收缩

这里我们将上一步添加的主从节点6390和6391从集群中移除。

①、迁移待移除节点的槽位   移除之前的节点信息:

redis-cli -p existing_port -a {Redis登录密码} --cluster reshard --cluster-from {待移除的NodeId} --cluster-to {接受移除节点的NodeId} --cluster-slots {移除的槽位个数} existing_host:existing_port

比如,我这里要移除主节点 6390 的所有槽位,给6379节点。

redis-cli -p 6379 -a 123 --cluster reshard --cluster-from 4a0779c7baef78c8fd0f2bb6e73f29375e00133d --cluster-to 001a22b1edae6ea1699b753d193871824723f375 --cluster-slots 2000 192.168.14.101:6379

移除完后,查看节点信息,发现6379已经没有槽位了。

②、移除待删除主从节点   注意:要首先移除从节点,然后再移除主节点,因为如果你先移除主节点,会触发集群的故障转移。

所以,我们应该先移除 6391 从节点,然后在移除 6390 主节点。移除命令如下:

redis-cli -p existing_port -a {Redis登录密码} --cluster del-node host:port {待删除的NodeId}

删除 6391 从节点:

redis-cli -p 6379 -a 123 --cluster del-node 192.168.14.101:6379 3622ec34956b624358722e6f4a2b762574d35bf0

删除 6390 主节点:

redis-cli -p 6379 -a 123 --cluster del-node 192.168.14.101:6379 4a0779c7baef78c8fd0f2bb6e73f29375e00133d

本系列教程持续更新,可以微信搜索「 IT可乐 」第一时间阅读。回复《电子书》有我为大家特别筛选的书籍资料

相关推荐

【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...

Pure Storage推出统一数据管理云平台及新闪存阵列

PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...

对Java学习的10条建议(对java课程的建议)

不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...

SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!

官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...

JDK21有没有什么稳定、简单又强势的特性?

佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...

「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了

在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...

Java面试题及答案最全总结(2025版)

大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...

数据库日常运维工作内容(数据库日常运维 工作内容)

#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...

分布式之系统底层原理(上)(底层分布式技术)

作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...

oracle 死锁了怎么办?kill 进程 直接上干货

1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...

SpringBoot 各种分页查询方式详解(全网最全)

一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...

《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略

《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...

LoadRunner(loadrunner录制不到脚本)

一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...

Redis数据类型介绍(redis 数据类型)

介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...

RMAN备份监控及优化总结(rman备份原理)

今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...

取消回复欢迎 发表评论: