Home  >  Article  >  Database  >  How to install a six-node cluster in Redis

How to install a six-node cluster in Redis

WBOY
WBOYforward
2023-06-03 09:19:281182browse

Introduction

redis cluster is a native cluster solution. Currently, it has made great progress in terms of high availability and stability. According to statistics and observations, more and more companies and communities are adopting the redis cluster architecture, which has become a de facto standard. Its main feature is decentralization and no need for proxy agents. One of the main design goals is to achieve linear scalability.

Only relying on the redis cluster server itself cannot complete the officially promised functions. In a broad sense, redis cluster should include both redis servers and client implementations such as jedis, etc. They are a whole.

Distributed storage is nothing more than dealing with sharding and replicas. For redis cluster, the core concept is slot. If you understand it, you will basically understand the management method of the cluster.

Advantages and Disadvantages

After understanding these features, operation and maintenance is actually simpler. Let’s look at the more obvious advantages and disadvantages first.

Advantages

1. No additional Sentinel clusters are needed, providing users with a consistent solution and reducing learning costs.

2. Decentralized architecture, nodes are peer-to-peer, and the cluster can support thousands of nodes.

3. Abstract the concept of slot and perform operation and maintenance operations for slot.

4. The replica function can realize automatic failover, without manual intervention in most cases.

Disadvantages

1. The client needs to cache some data and implement the Cluster protocol, which is relatively complicated.

2. Data is copied asynchronously, and strong consistency of data cannot be guaranteed.

3. Resource isolation is difficult and traffic is often unbalanced, especially when multiple businesses share a cluster. We don’t know where the data is, and hot data cannot be achieved through Special Optimization.

4. The slave database is completely cold standby and cannot share read operations. It is really a waste. Additional work is required.

5, MultiOp and Pipeline have limited support. If you want to upgrade the architecture of old code, be careful.

6. Data migration is based on key rather than slot, and the process is slow.

Basic Principle

From slot to key, the positioning process is obviously a two-layer routing.

key's routing

redis cluster has nothing to do with the commonly used consistencyhash. It mainly uses the concept of hash slots. When a key needs to be accessed, the redis client will first use the crc16 algorithm to calculate a value for this key, and then Perform mod operations on this value.

crc16(key)mod 16384

So, each key will fall on one of the hash slots. 16384 is equivalent to 2^14 (16k). When the redis node sends a heartbeat packet, it needs to put all the slot information in this heartbeat packet, so we must do our best to optimize it. If you are interested, you can see why The default number of slots is 16384.

Simple principle of the server

As mentioned above, redis cluster defines a total of 16384 slots, and all cluster operations are encoded around this slot data. The server uses a simple array to store this information.

For the operation of determining whether there is any, it is the most space-saving to use bitmap to store. redis cluster uses an array called slot to save whether the current node holds this slot.

The length of the array is 16384/8=2048 Byte, then you can use 0 or 1 to identify whether this node owns a certain slot.

In fact, only the first piece of data ClusterState is needed to complete the operation, and the Slot array of another dimension is saved, which can facilitate encoding and storage. In addition to recording the slots it is responsible for processing in two places (slots and numslots of the clusterNode structure), a node will also send its own slots array to other nodes in the cluster through messages. To tell other nodes the slots they currently own.

When all 16384 slots in the database are processed by nodes, the cluster is in the online state (ok); conversely, if any slot in the database is not processed, the cluster is in the offline state (fail ).

When the client sends a related command to a node, the node receiving the command will calculate which slot the key to be processed by the command belongs to, and check whether this slot is assigned to itself. If it is not your own, it will direct the client to the correct node.

So, the client can complete the operation by connecting to any machine in the cluster.

Install a 6-node cluster

Preparation

Suppose we want to assemble a 3-shard cluster, each shard has a copy. Then the total number of node instances required is 3*2=6. redis can be started by specifying the configuration file. What we do is to modify the configuration file.

Copy 6 copies of the default configuration file.

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的速度特别的快。一般越快的东西,出问题的时候造成的后果越大。

Not long ago, I wrote a specification for redis: "Redis specification, this may be the most pertinent". The specifications are the same as the architecture. The one that suits your company environment is the best, but it will provide some basic ideas.

Things that are strictly prohibited are usually pitfalls of previous generations. In addition to the content of this specification, for redis-cluster, the following points are added.

1. redis cluster claims to be able to support 1k nodes, but you'd better not do this. When the number of nodes increases to 10, you can feel some jitter in the cluster. Such a large cluster proves that your business is already very good. Consider client sharding.

2. Be sure to avoid hot spots. If all traffic hits a certain node, the consequences will generally be serious.

3. Do not put redis in a large key, it will generate a large number of slow queries and affect normal queries.

4. If you are not using it as a storage, the cache must set an expiration time. The feeling of occupying the toilet and not taking a shit is very annoying.

5. For large traffic, do not enable aof, just enable rdb.

6, redis cluster operations, use less pipeline and less use multi-key, they will produce a lot of unpredictable results.

The above is the detailed content of How to install a six-node cluster in Redis. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete