目录
简介
优缺点
优点
缺点
基本原理
key的路由
服务端简单原理
安装一个6节点集群
准备工作
启动&关闭
组合集群
几个高级原理
节点故障
主从切换
数据同步
数据丢失
复杂的运维
redis-cli —cluster
其他方案概览
主从模式
代理模式
使用限制和坑
首页 数据库 Redis Redis中怎么安装一个六节点集群

Redis中怎么安装一个六节点集群

Jun 03, 2023 am 09:19 AM
redis

简介

redis cluster是亲生的集群方案,目前,在高可用和稳定性方面,都有了很大的进步。据统计和观察,采用redis cluster架构的公司和社区越来越多,已经成为事实的标准。它的主要特点就是去中心化,无需proxy代理。其中一个主要设计目标就是达到线性可扩展性(linear scalability)。

仅仅靠redis cluster服务器本身,并不能完成官方承诺的功能。广义上的redis cluster应该既包含redis服务器,又包含客户端实现比如jedis等。它们是一个整体。

分布式存储无非就是处理分片和副本。redis cluster来说,核心概念就是槽(slot),了解了它,基本就了解了集群的管理方式。

优缺点

当了解这些特性以后,运维上其实是更简单了。我们先看下比较明显的优缺点。

优点

1、不再需要额外的Sentinel集群,为使用者提供了一致的方案,减少了学习成本。 

2、去中心架构,节点对等,集群可支持上千个节点。 

3、抽象出了slot概念,针对slot进行运维操作。 

4、副本功能能够实现自动故障转移,大部分情况下无需人工介入。

缺点

1、客户端要缓存部分数据,实现Cluster协议,相对复杂。 

2、数据是通过异步复制的,不能保证数据的强一致性。

3、资源隔离困难,经常流量不均衡,尤其是多个业务共用集群的时候。数据不知道在哪里,针对热点数据,也无法通过专项优化完成。 

4、从库是完全的冷备,无法分担读操作,真是太太浪费了。需要做额外工作。 

5、MultiOpPipeline支持有限,老代码要是进行架构升级,要小心了。 

6、数据迁移是基于key而不是基于slot的,过程较慢。

基本原理

从槽到key,定位过程明显就是一个双层的路由。

key的路由

redis cluster和常用的一致性hash没什么关系,它主要采用了哈希槽的概念。当需要在其中存取一个key时,redis客户端会首先对这个key采用crc16算法算出一个值,然后对这个值进行mod操作。

crc16(key)mod 16384
登录后复制

所以,每个key都会落在其中的一个hash槽上。16384 等同于 2^14(16k),redis节点发送心跳包时,需要把所有的槽信息放在这个心跳包里,所以要竭尽全力的优化,感兴趣的可以看下为什么默认的槽数量是 16384 。

服务端简单原理

上面谈到,redis cluster共定义了 16384 个槽,所有的集群操作都是围绕着这个槽数据进行编码。服务端使用一个简单的数组存储这些信息。

对于判断有无的操作,使用bitmap来存储是最节省空间的。redis cluster就是使用一个叫做slot的数组来保存当前节点是否持有了这个槽。

数组的长度为 16384/8=2048 Byte,那么就可以使用 0 或者 1 来标识本节点对某个槽是否拥有。

其实,只需要第一份数据ClusterState也能完成操作,保存另外一个维度的Slot数组,能够方便编码和存储。一个节点除了会将自己负责处理的槽记录在两个地方(clusterNode结构的slots和numslots),它还会将自己的slots数组通过消息发送给集群中的其他节点,以此来告诉其他节点自己目前拥有的槽。

当数据库中的 16384 个槽都有节点在处理时,集群处于上线状态(ok);相反地,如果数据库中有任何一个槽没有得到处理,那么集群处于下线状态(fail)。

当客户端向节点发送相关命令时,接收命令的节点会计算出命令要处理的key属于哪个槽,并检查这个槽是否指派给了自己。如果不是自己的,会指引客户端到正确的节点。

所以,客户端连接集群中的任意一台机器,都能够完成操作。

安装一个6节点集群

准备工作

假如我们要组装一个3分片的集群,每个分片有一个副本。那么总共需要的node实例就有 3*2=6 个。redis可以通过指定配置文件的方式启动,我们所做的工作就是修改配置文件。

复制6份默认的配置文件。

for i in {0..5}
do
cp redis.conf  redis-700$i.conf
done
登录后复制

修改其中的配置文件内容,拿redis-7000.conf来说,我们要启用它的cluster模式。

cluster-enabled yes
port 7000
cluster-config-file nodes-7000.conf
登录后复制

nodes-7000.conf会保存一些集群信息到当前节点,所以需要独立。

启动&关闭

同样的,我们使用脚本来启动它。

for i in {0..5}
do
nohup ./redis-server redis-700$i.conf &
done
登录后复制

为了演示,我们暴力把它关闭。

ps -ef| grep redis | awk '{print $2}' | xargs kill -9
登录后复制

组合集群

我们使用redis-cli进行集群的组合。redis将自动完成这个过程。这一系列的过程,是通过发送指令给每个节点进行组合的。

./redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1
登录后复制

几个高级原理

节点故障

集群中的每个节点都会定期地向集群中的其他节点发送ping消息,以此来检测对方是否在线,如果接收ping消息的节点没有在规定的时间内返回pong消息,那么发送ping消息的节点就会将接收ping消息的节点标记为疑似下线(PFAIL)。

如果在一个集群里面,半数以上节点都将某个主节点 x 报告为疑似下线,那么这个主节点x将被标记为已下线(FAIL),将x标记为FAIL的节点会向集群广播一条关于 x 的FAIL消息,所有收到这条FAIL消息的节点都会立即将 x 标记为FAIL

大家可以注意到这个过程,与 es 和 zk 的节点判断类似,都是半数以上才进行判断,所以主节点的数量一般都是奇数。由于没有最小组群配置,理论上会有脑裂(暂时并未遇到过)。

主从切换

当一个节点发现自己的主节点进入fail状态,将会从这个节点的从节点当中,选出一台,执行slaveof no one命令,变身为主节点。

新的节点完成自己的槽指派以后,会向集群广播一条pong消息,以便让其他节点立即知道自己的这些变化。它告诉别人:我已经是主节点了,我已经接管了有问题的节点,成为了它的替身。

redis内部对集群的这些管理,大量使用了已经定义好的这些指令。所以这些指令不仅仅供我们从命令行使用,redis自己内部也用。

数据同步

当一台从机连接到master之后,会发送一个sync指令。master在收到这个指令后,会在后台启动存盘进程。执行完毕后,master将整个数据库文件传输到slave,这样就完成了第一次全量同步。

接下来,master会把自己收到的变更指令,依次传送给slave,从而达到数据的最终同步。从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份。

数据丢失

redis cluster中节点之间使用异步复制,并没有类似kafka这种ack的概念。节点之间通过gossip协议交换状态信息,用投票机制完成SlaveMaster的角色提升,完成这个过程注定了需要时间。在发生故障的过程中就容易存在窗口,导致丢失写入的数据。比如以下两种情况。

一、命令已经到到master,此时数据并没有同步到slavemaster会对客户端回复ok。如果这个时候主节点宕机,那么这条数据将会丢失。redis这样做会避免很多问题,但对一个对数据可靠性要求较高的系统,是不可忍受的。

二、由于路由表是在客户端存放的,存在一个时效问题。如果分区导致一个节点不可达,提升了某个从节点,但原来的主节点在这个时候又可以用了(并未完成failover)。如果客户端的路由表没有及时更新,那么写入错误的节点可能导致数据丢失。

所以redis cluster在通常情况下运行的很好,在极端情况下某些值丢失问题,目前无解。

复杂的运维

redis cluster的运维非常的繁杂,虽然已经进行了抽象,但这个过程依然不简单。有些指令,必须在详细了解它的实现原理之后,才能真正放心的去用。

扩容会用到的一些命令。在实际使用的过程中,可能需要多次频繁地输入这些命令,且输入的过程中还要监视它的状态,所以基本上是不可能人工跑这些命令的。

运维的入口有两个。一个是使用redis-cli连接任意一台,然后发送cluster打头的命令,这部分命令大多数是对槽进行操作。 在开始组合集群时,就是反复调用这些命令进行的具体逻辑执行。

另外一个入口是使用redis-cli命令,加上--cluster参数和指令。这种形式主要是用来管控集群节点信息 ,比如增删节点等。所以推荐使用这种方式。

redis cluster提供了非常复杂的命令,难于操作和记忆。推荐使用类似CacheCloud的工具进行管理。

下面是几个例子。

通过向节点 A 发送 CLUSTER MEET 命令,客户端可以让接收命令的节点 A 将另一个节点 B 添加到节点 A 当前所在的集群里面:

CLUSTER MEET  127.0.0.1 7006
登录后复制

通过cluster addslots命令,可以将一个或者多个槽指派给某个节点负责。

127.0.0.1:7000> CLUSTER ADDSLOTS 0 1 2 3 4 . . . 5000
登录后复制

设置从节点。

CLUSTER REPLICATE <node_id>
登录后复制

redis-cli —cluster

redis-trib.rb是官方提供的Redis Cluster的管理工具,但最新版本已经推荐使用redis-cli进行操作。

向集群中添加新节点

redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7007 --cluster-replicas 1
登录后复制

从集群中删除节点

redis-cli --cluster del-node 127.0.0.1:7006 54abb85ea9874af495057b6f95e0af5776b35a52
登录后复制

迁移槽到新的节点

redis-cli --cluster reshard 127.0.0.1:7006 --cluster-from 54abb85ea9874af495057b6f95e0af5776b35a52 --cluster-to 895e1d1f589dfdac34f8bdf149360fe9ca8a24eb  --cluster-slots 108
登录后复制

类似的命令还有很多。

create:创建集群 check:检查集群 info:查看集群信息 fix:修复集群 reshard:在线迁移slot rebalance:平衡集群节点slot数量 add-node:添加新节点 del-node:删除节点 set-timeout:设置节点的超时时间 call:在集群所有节点上执行命令 import:将外部redis数据导入集群

其他方案概览

主从模式

redis最早支持的,就是M-S模式,也就是一主多从。redis单机qps可达到 10w+,但是在某些高访问量场景下,依然不太够用。一般通过读写分离来增加slave,减少主机的压力。

既然是主从架构,就面临着同步问题,redis主从模式的同步分为全同步和部分同步。当刚创建一个从机的时候,不可避免的要进行一次全量同步。等全量同步结束之后,进入增量同步阶段。这个和redis cluster是没什么区别的。

这种模式还是比较稳定的,但要额外做一些工作。用户需要自行开发主从切换的功能,也就是使用哨兵去探测每个实例的健康状况,然后通过指令进行集群状态的改变。

当集群规模增大,主从模式会很快遇到瓶颈。所以一般会采用客户端hash的方法进行扩展,包括类似于memcached的一致性哈希。

客户端hash的路由可能会很复杂,通常会通过发布jar包或者配置的方式维护这些meta信息,这也给线上环境增加了很多不确定性。

不过,通过加入类似ZK主动通知的功能,将配置维护在云端,可以显著降低风险。笔者曾经维护过的几千个redis节点,就是用这种方式进行管理的。

代理模式

代码模式在redis cluster出现之前,非常流行,比如codis。代理层通过把自己模拟成一个redis,接收来自客户端的请求,然后按照自定义的路由逻辑进行数据分片以及迁移,而业务方不需要改动任何代码。除了能够平滑的进行扩容,一些主从切换、FailOver的功能也在代理层完成,客户端甚至可以没有任何感知。这类程序又称为分布式中间件。

一个典型的实现如下图,背后的redis集群甚至可以是混合的。

但这种方式的缺点也是显而易见的。首先,它引入了一个新的代理层,在结构上、运维上都显复杂。需要进行大量的编码,比如failover、读写分离、数据迁移等。另外,proxy层的加入,对性能也有相应的损耗。

多个proxy一般使用lvs等前置进行负载均衡的设计,如果proxy层的机器很少而后端redis的流量很高,那么网卡会成为主要的瓶颈。

Nginx也可以作为redis的代理层,比较专业的说法叫做Smart Proxy。这种方式较为偏门,如果你对nginx比较熟悉,不失为一种优雅的做法。

使用限制和坑

redis的速度特别的快。一般越快的东西,出问题的时候造成的后果越大。

不久之前,写过一篇针对于redis的规范:《Redis规范,这可能是最中肯的了》。规范和架构一样,适合自己公司环境的,才是最好的,但会提供一些起码的思路。

严格禁止的东西,一般都是前人踩坑的地方。除了这篇规范的内容,对于redis-cluster,补充以下几点。

1、redis cluster号称能够支持1k个节点,但你最好不要这么做。当节点数量增加到10,就能够感受到集群的一些抖动。这么大的集群证明你的业务已经很牛x了,考虑一下客户端分片吧。

2、一定要避免产生热点,如果流量全部打到了某个节点,后果一般很严重。

3、大key不要放redis,它会产生大量的慢查询,影响正常的查询。

4、如果你不是作为存储,缓存一定要设置过期时间。占着茅坑不拉屎的感觉是非常讨厌的。

5、大流量,不要开aof,开rdb即可。

6、redis cluster的操作,少用pipeline,少用multi-key,它们会产生大量不可预料的结果。

以上是Redis中怎么安装一个六节点集群的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

redis集群模式怎么搭建 redis集群模式怎么搭建 Apr 10, 2025 pm 10:15 PM

Redis集群模式通过分片将Redis实例部署到多个服务器,提高可扩展性和可用性。搭建步骤如下:创建奇数个Redis实例,端口不同;创建3个sentinel实例,监控Redis实例并进行故障转移;配置sentinel配置文件,添加监控Redis实例信息和故障转移设置;配置Redis实例配置文件,启用集群模式并指定集群信息文件路径;创建nodes.conf文件,包含各Redis实例的信息;启动集群,执行create命令创建集群并指定副本数量;登录集群执行CLUSTER INFO命令验证集群状态;使

redis数据怎么清空 redis数据怎么清空 Apr 10, 2025 pm 10:06 PM

如何清空 Redis 数据:使用 FLUSHALL 命令清除所有键值。使用 FLUSHDB 命令清除当前选定数据库的键值。使用 SELECT 切换数据库,再使用 FLUSHDB 清除多个数据库。使用 DEL 命令删除特定键。使用 redis-cli 工具清空数据。

redis怎么读取队列 redis怎么读取队列 Apr 10, 2025 pm 10:12 PM

要从 Redis 读取队列,需要获取队列名称、使用 LPOP 命令读取元素,并处理空队列。具体步骤如下:获取队列名称:以 "queue:" 前缀命名,如 "queue:my-queue"。使用 LPOP 命令:从队列头部弹出元素并返回其值,如 LPOP queue:my-queue。处理空队列:如果队列为空,LPOP 返回 nil,可先检查队列是否存在再读取元素。

redis指令怎么用 redis指令怎么用 Apr 10, 2025 pm 08:45 PM

使用 Redis 指令需要以下步骤:打开 Redis 客户端。输入指令(动词 键 值)。提供所需参数(因指令而异)。按 Enter 执行指令。Redis 返回响应,指示操作结果(通常为 OK 或 -ERR)。

redis怎么使用锁 redis怎么使用锁 Apr 10, 2025 pm 08:39 PM

使用Redis进行锁操作需要通过SETNX命令获取锁,然后使用EXPIRE命令设置过期时间。具体步骤为:(1) 使用SETNX命令尝试设置一个键值对;(2) 使用EXPIRE命令为锁设置过期时间;(3) 当不再需要锁时,使用DEL命令删除该锁。

redis怎么读源码 redis怎么读源码 Apr 10, 2025 pm 08:27 PM

理解 Redis 源码的最佳方法是逐步进行:熟悉 Redis 基础知识。选择一个特定的模块或功能作为起点。从模块或功能的入口点开始,逐行查看代码。通过函数调用链查看代码。熟悉 Redis 使用的底层数据结构。识别 Redis 使用的算法。

redis命令行怎么用 redis命令行怎么用 Apr 10, 2025 pm 10:18 PM

使用 Redis 命令行工具 (redis-cli) 可通过以下步骤管理和操作 Redis:连接到服务器,指定地址和端口。使用命令名称和参数向服务器发送命令。使用 HELP 命令查看特定命令的帮助信息。使用 QUIT 命令退出命令行工具。

redis怎么解决数据丢失 redis怎么解决数据丢失 Apr 10, 2025 pm 08:24 PM

Redis 数据丢失的原因包括内存故障、停电、人为错误和硬件故障。解决方案为:1. 通过 RDB 或 AOF 持久化将数据存储到磁盘;2. 复制到多台服务器实现高可用性;3. 使用 Redis Sentinel 或 Redis Cluster 进行 HA;4. 创建快照以备份数据;5. 实施最佳实践,如持久化、复制、快照、监控和安全措施。

See all articles