完全理解Redis Cluster的机制[实例演示]
这篇文章是CAM Advent Calendar 2019的第16天的文章。
前一篇文章是由@tosaka07先生撰写的,标题为从优化角度看Swift的 / 2 和 * 0.5 – 在Qiita上。
首先
在业务中使用Redis,不仅要了解如何使用,还希望能够理解它的工作原理!因此,我整理了关于Redis集群的内容!我还打算亲自搭建一个集群,应该会非常容易理解!
群集是什么?
クラスター(Cluster)は「房」「集団」「群れ」の意味。ネットワークに接続した複数のコンピューターを連携して1つのコンピューターシステムに統合し、処理や運用を効率化するシステムのこと
Redis Clusterとは
-
- redisインスタンスをクラスタリングすることができる機能
-
- クラスター全体であるデータがどのノード(後述)に保存されるかを把握している
ノード間でリダイレクトすることによって、どのノードから接続しても指定するデータにたどり着ける
マルチマスター構成を採用していて、データは複数のRedisサーバに自動的に分散される(シャーディング)
マスターがタヒんでも自動的にスレーブがマスターに昇格する(自動フェイルオーバー)
用語解説
今回出てくる用語を解説していきます。
redisに関わらずデータベースのレプリケーション全般に共通する単語なので、ぜひ覚えましょう!
节点
Redis实例本身
主节点
有两种类型的节点,可以进行读写操作的节点被称为主节点,一个主节点可以拥有零个或多个从节点,从节点与数据进行共享。
奴隶节点
在这两种节点中,只有读取节点是与主节点共享数据的。当主节点出现故障时,将自动进行故障切换。
碎片
在一个分片中有多个节点存在,这些节点将数据同步(复制)在分片内部。
構成的例子
实际上尝试构建集群配置.
我们将在假设已经安装了Redis的前提下继续进行。
我们使用的验证版本是5.0.5。
我们将使用与所示示例相同的配置来组建集群。由于在本地建立,因此所有IP地址都是127.0.0.1。
准备目录
$ mkdir ~/sample-redis-cluster
$ cd ~/sample-redis-cluster
$ mkdir 700{0,1,2,3,4,5}
为每个创建的目录准备配置文件。
$ cd 7000
$ vim redis.conf
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
$ cd ../7001
$ vim redis.conf
port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
在每个目录中准备配置文件,只需要更改端口而其他保持不变。
启动服务器
在7000〜7005的每个目录中,使用命令行工具进行屏幕分割启动服务器。启动后将生成一个名为nodes.conf的文件。
请在终端中运行以下命令以启动Redis服务器:
$ redis-server redis.conf
・
・
・
注意:
如果不进入各个目录,而是以$ redis-server 7000/redis.conf的方式启动,将会在sample-redis-cluster目录下生成nodes.conf文件。第一台服务器可以正常启动,但是尝试启动第二台服务器时会出现以下错误。
Sorry, the cluster configuration file nodes.conf is already used by a different Redis Cluster node. Please make sure that different nodes use different cluster configuration files.
请在每个目录内建立服务器,因为nodes.conf已经被使用了。
构建聚类
请使用另一个命令行继续构建。
请执行以下命令。
$ 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
–cluster-replicas 1 是一个选项,用于将至少多少个副本分配给每个节点。本次将分配一个副本。
当你敲击它时
Can I set the above configuration? (type 'yes' to accept):
当被问到时,我选了“yes”,这样集群就构建完成了。
试着触摸
让我们进入集群实例并尝试输入命令CLUSTER NODES。
$ redis-cli -p 7000 -c
127.0.0.1:7000> cluster nodes
1ce9bfaffd38e89209fc946d3c184d4e89c5d358 127.0.0.1:7005@17005 slave 765030e4d8c4ad2a90aef5a18c09bd10d8a634b3 0 1575817912219 6 connected
b67a6e13e4aefad72d18a2d40476d6eb14783ec0 127.0.0.1:7001@17001 master - 0 1575817910171 2 connected 5461-10922
743c3c84ce696199da0419880eefda902b4fe509 127.0.0.1:7003@17003 slave b67a6e13e4aefad72d18a2d40476d6eb14783ec0 0 1575817911597 4 connected
24f6a74a5cbe2f754f5453f73f88899c0ae0fc16 127.0.0.1:7004@17004 slave 3538af0b31d0275ee617963863356c0cdbab5e82 0 1575817912000 5 connected
3538af0b31d0275ee617963863356c0cdbab5e82 127.0.0.1:7002@17002 master - 0 1575817911189 3 connected 10923-16383
765030e4d8c4ad2a90aef5a18c09bd10d8a634b3 127.0.0.1:7000@17000 myself,master - 0 1575817911000 1 connected 0-5460
使用这个命令,可以确认集群的配置是怎样的。
可以确认7000, 7001, 7002是master节点,而7003, 7004, 7005是slave节点。
在slave节点旁边有写着一个id,表示它是属于哪个master节点的slave节点。
在这个例子中,可以知道7005是7000的slave节点。
槽位
让我们再次查看通过CLUSTER NODES命令输出的结果。
$ redis-cli -p 7000 -c
127.0.0.1:7000> cluster nodes
1ce9bfaffd38e89209fc946d3c184d4e89c5d358 127.0.0.1:7005@17005 slave 765030e4d8c4ad2a90aef5a18c09bd10d8a634b3 0 1575817912219 6 connected
b67a6e13e4aefad72d18a2d40476d6eb14783ec0 127.0.0.1:7001@17001 master - 0 1575817910171 2 connected 5461-10922
743c3c84ce696199da0419880eefda902b4fe509 127.0.0.1:7003@17003 slave b67a6e13e4aefad72d18a2d40476d6eb14783ec0 0 1575817911597 4 connected
24f6a74a5cbe2f754f5453f73f88899c0ae0fc16 127.0.0.1:7004@17004 slave 3538af0b31d0275ee617963863356c0cdbab5e82 0 1575817912000 5 connected
3538af0b31d0275ee617963863356c0cdbab5e82 127.0.0.1:7002@17002 master - 0 1575817911189 3 connected 10923-16383
765030e4d8c4ad2a90aef5a18c09bd10d8a634b3 127.0.0.1:7000@17000 myself,master - 0 1575817911000 1 connected 0-5460
请查看主节点的信息。
您可以确认最右边有类似于0-5460或5461-10922的数字。
这表示分配给每个分片的槽位。
slot是什么意思?
redis clusterにはslot(スロット)という概念があります。
スロットは0番~16383番まであり、
redis clusterで値を格納するとき、格納するデータを0~16383の番号を返すアルゴリズムにかけます。
その返ってきた番号のスロットがあるノードにデータが格納されます。
このようにしてredis clusterは水平分割(シャーディング)をしているのです!
クラスターを組む時、特に指定しなければ 16384/マスターノードの数個のスロットが各マスターノードに割り振られます。
上記では7000番ポートのノードには0~5460番、7001番ポートのノードには5461~10922番、7002番ポートのノードには10923~16383番のスロットが割り振られているということになります。
可以将被储存的值乘以的算法
我会简单介绍一下。
HASH SLOT = CRC16(key) mod 16384
试着写入数据。
现在我们来实际添加数据并体验一下slot吧!
$ redis-cli -p 7000 -c
127.0.0.1:7000> set hoge 'hoge'
OK
127.0.0.1:7000>
好的,我用”hoge”这个键设置了一个”hoge”的字符串。
没有什么特别的变化,我感觉不出来正在体验slot。
那么接下来让我们试着运行下面的内容吧。
$ redis-cli -p 7000 -c
127.0.0.1:7000> set fuga 'fuga'
-> Redirected to slot [9097] located at 127.0.0.1:7001
OK
127.0.0.1:7001>
我在fuga键中设置了一个fuga字符串。
先前没有输出的消息”Redirected to slot [9097] located at 127.0.0.1:7001″被输出了。
以下的内容按顺序执行:
-
- 7000番ポートのノードでset fuga ‘fuga’が実行される
-
- redis clusterは fugaをアルゴリズムにかける
-
- 結果として9097がでる
-
- 9097番スロットは7000番ポートのノードでは対応していないので、redis clusterがクライアントの向き先を7000番ポートのノードから7001番ポートのノードに変える
-
- 値をセットする
- セットできたらクライアントにOKと返す
顺便说一下,如果不在redis-cli命令中使用-c选项,是无法在7000端口上注册fuga的。
$ redis-cli -p 7000
127.0.0.1:7000> set fuga 'fuga'
(error) MOVED 9097 127.0.0.1:7001
127.0.0.1:7000>
结束
这次我们讲解了关于Redis集群的内容。实际上,Redis的冗余配置有三种,而集群只是其中之一。除此之外,还有复制(Replication)和哨兵(Sentinel)这两种配置方式,下次我们可以介绍它们!
指引
使用Redis 5.0进行集群建设和验证 – shirobrak的博客
Redis集群建设 – Qiita
Redis
集群 | IT词典 | 大塚商会