Heim >Datenbank >Redis >So installieren Sie einen Cluster mit sechs Knoten in Redis

So installieren Sie einen Cluster mit sechs Knoten in Redis

WBOY
WBOYnach vorne
2023-06-03 09:19:281192Durchsuche

Einführung

redis-cluster ist eine native Clusterlösung, die derzeit große Fortschritte in Bezug auf hohe Verfügbarkeit und Stabilität gemacht hat. Statistiken und Beobachtungen zufolge übernehmen immer mehr Unternehmen und Communities die redis-Cluster-Architektur, die zum De-facto-Standard geworden ist. Sein Hauptmerkmal ist, dass es dezentralisiert ist und keinen proxy-Proxy benötigt. Eines der Hauptdesignziele besteht darin, lineare Skalierbarkeit zu erreichen. 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

Der redis-Cluster-Server allein kann die offiziell versprochenen Funktionen nicht erfüllen. Im weitesten Sinne sollte redis sowohl redis-Server als auch Client-Implementierungen wie jedis usw. umfassen. Sie sind ein Ganzes.

Verteilter Speicher ist nichts anderes als der Umgang mit Sharding und Replikaten. Für redis-cluster ist das Kernkonzept Slot. Wenn Sie es verstehen, werden Sie im Grunde auch die Verwaltungsmethode des Clusters verstehen. 🎜🎜Vor- und Nachteile🎜🎜Nachdem Sie diese Funktionen verstanden haben, werden Bedienung und Wartung tatsächlich einfacher. Schauen wir uns zunächst die offensichtlicheren Vor- und Nachteile an. 🎜

Vorteile

🎜1. Es ist kein zusätzlicher Sentinel-Cluster erforderlich, was den Benutzern eine konsistente Lösung bietet und die Lernkosten senkt. 🎜🎜2. Dezentrale Architektur, Knoten sind Peer-to-Peer und der Cluster kann Tausende von Knoten unterstützen. 🎜🎜3. Das Konzept von slot wird abstrahiert und Betriebs- und Wartungsvorgänge werden auf slot durchgeführt. 🎜🎜4. Die Replikatfunktion kann in den meisten Fällen ein automatisches Failover realisieren, ohne dass ein manueller Eingriff erforderlich ist. 🎜

Nachteile

🎜1. Der Client muss einige Daten zwischenspeichern und das Cluster-Protokoll implementieren, was relativ kompliziert ist. 🎜🎜2. Daten werden asynchron kopiert und eine starke Datenkonsistenz kann nicht garantiert werden. 🎜🎜3. Die Isolierung von Ressourcen ist schwierig und der Datenverkehr ist oft unausgeglichen, insbesondere wenn sich mehrere Unternehmen einen Cluster teilen. Wir wissen nicht, wo sich die Daten befinden, und heiße Daten können nicht durch spezielle Optimierung erreicht werden. 🎜🎜4. Die Slave-Datenbank ist vollständig kalt und kann keine Lesevorgänge teilen. Das ist wirklich eine Verschwendung. Es sind zusätzliche Arbeiten erforderlich. 🎜🎜5. MultiOp und Pipeline werden nur eingeschränkt unterstützt. Wenn Sie die Architektur von altem Code aktualisieren möchten, seien Sie vorsichtig. 🎜🎜6. Die Datenmigration basiert auf key statt auf slot und der Prozess ist langsamer. 🎜🎜Grundprinzip🎜🎜Vom Steckplatz bis zum Schlüssel ist der Positionierungsprozess offensichtlich ein zweischichtiges Routing. 🎜

Schlüsselrouting

🎜redis-cluster hat nichts mit der häufig verwendeten Konsistenz hash zu tun. Es verwendet hauptsächlich das Konzept von Hash-Slots. Wenn auf einen Schlüssel zugegriffen werden muss, verwendet der redis-Client zunächst den crc16-Algorithmus, um den Schlüssel A zu berechnen Wert, und führen Sie dann eine mod-Operation für diesen Wert aus. 🎜
for i in {0..5}
do
cp redis.conf  redis-700$i.conf
done
🎜Also, jeder Schlüssel fällt auf einen der Hash-Slots. 16384 entspricht 2^14 (16k). Wenn der redis-Knoten ein Heartbeat-Paket sendet, muss er alle Slot-Informationen in dieses Heartbeat-Paket einfügen, daher müssen wir unser Bestes tun, um es zu optimieren. Wenn Sie interessiert sind, können Sie lesen, warum die Standardanzahl der Slots 16384 beträgt. 🎜

Einfaches Prinzip der Serverseite

🎜Wie oben erwähnt, definiert redis Cluster insgesamt 16384 Slots, und alle Cluster-Vorgänge sind um diese Slot-Daten herum codiert. Der Server verwendet ein einfaches Array zum Speichern dieser Informationen. 🎜🎜Um festzustellen, ob welche vorhanden sind, ist es am platzsparendsten, bitmap zum Speichern zu verwenden. redis-cluster verwendet ein Array namens slot, um zu speichern, ob der aktuelle Knoten diesen Slot enthält. 🎜🎜Die Länge des Arrays beträgt 16384/8=2048 Byte, dann können Sie 0 oder 1 verwenden, um zu identifizieren, ob dieser Knoten einen bestimmten Slot besitzt. 🎜🎜Tatsächlich ist nur das erste Datenelement ClusterState erforderlich, um den Vorgang abzuschließen, und das Slot-Array einer anderen Dimension wird gespeichert, was die Codierung und Speicherung erleichtern kann. Zusätzlich zur Aufzeichnung der Slots, für deren Verarbeitung er an zwei Stellen verantwortlich ist (Slots und Numslots der ClusterNode-Struktur), sendet ein Knoten auch sein eigenes slots-Array über Nachrichten an andere Knoten im Cluster teilt anderen Knoten die Slots mit, die sie derzeit besitzen. 🎜🎜Wenn alle 16384 Slots in der Datenbank von Knoten verarbeitet werden, befindet sich der Cluster im Online-Status (OK); wenn umgekehrt ein Slot in der Datenbank nicht verarbeitet wird, befindet sich der Cluster im Offline-Status (Fehler). 🎜🎜Wenn der Client einen entsprechenden Befehl an einen Knoten sendet, berechnet der Knoten, der den Befehl empfängt, zu welchem ​​Steckplatz der vom Befehl zu verarbeitende Schlüssel gehört, und prüft, ob dieser Steckplatz ihm selbst zugewiesen ist. Wenn es sich nicht um Ihren eigenen Knoten handelt, wird der Client zum richtigen Knoten weitergeleitet. 🎜🎜So kann der Client den Vorgang abschließen, indem er eine Verbindung zu einer beliebigen Maschine im Cluster herstellt. 🎜🎜Installieren eines 6-Knoten-Clusters🎜

Vorbereitung

🎜Angenommen, wir möchten einen 3-Shard-Cluster mit einem Replikat für jeden Shard zusammenstellen. Dann beträgt die Gesamtzahl der erforderlichen node-Instanzen 3*2=6. redis kann durch Angabe einer Konfigurationsdatei gestartet werden. Wir ändern die Konfigurationsdatei. 🎜🎜Kopieren Sie 6 Standardkonfigurationsdateien. 🎜
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的速度特别的快。一般越快的东西,出问题的时候造成的后果越大。

Vor nicht allzu langer Zeit habe ich einen Artikel über die Spezifikation für redis geschrieben: „Redis-Spezifikation, das ist vielleicht die relevanteste.“ Die Spezifikationen sind dieselben wie die Architektur, die am besten zu Ihrer Unternehmensumgebung passt, es werden jedoch einige grundlegende Ideen bereitgestellt. redis的规范:《Redis规范,这可能是最中肯的了》。规范和架构一样,适合自己公司环境的,才是最好的,但会提供一些起码的思路。

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

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

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

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

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

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

6、redis cluster的操作,少用pipeline,少用multi-key

Strikt verbotene Dinge sind meist Fallstricke früherer Generationen. Zusätzlich zum Inhalt dieser Spezifikation werden für redis-cluster die folgenden Punkte hinzugefügt. #🎜🎜##🎜🎜#1. redis-cluster behauptet, 1.000 Knoten unterstützen zu können, aber Sie sollten dies besser nicht tun. Wenn die Anzahl der Knoten auf 10 steigt, ist im Cluster ein gewisser Jitter zu spüren. Ein solch großer Cluster beweist, dass Ihr Unternehmen bereits sehr gut ist. Denken Sie über Client-Sharding nach. #🎜🎜##🎜🎜#2. Vermeiden Sie unbedingt Hotspots. Wenn der gesamte Datenverkehr auf einen bestimmten Knoten trifft, sind die Folgen im Allgemeinen schwerwiegend. #🎜🎜##🎜🎜#3. Geben Sie redis nicht in einen großen key ein. Dies führt zu einer großen Anzahl langsamer Abfragen und wirkt sich auf normale Abfragen aus. #🎜🎜##🎜🎜#4. Wenn Sie es nicht als Speicher verwenden, muss der Cache eine Ablaufzeit festlegen. Das Gefühl, auf der Toilette zu sitzen und nicht zu kacken, ist sehr nervig. #🎜🎜##🎜🎜#5. Aktivieren Sie bei großem Datenverkehr nicht aof, sondern nur rdb. #🎜🎜##🎜🎜#6. Für Operationen von redis-cluster verwenden Sie weniger pipeline und weniger multi-key große Anzahl unvorhersehbarer Ergebnisse. #🎜🎜#

Das obige ist der detaillierte Inhalt vonSo installieren Sie einen Cluster mit sechs Knoten in Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen