redis || 分片集群

集群介绍

集群由多个节点(Node)组成,Redis的数据分布在这些节点中。

集群中的节点分为主节点和从节点:只有主节点负责读写请求和集群信息的维护;从节点只进行主节点数据和状态信息的复制。

集群的作用

1、数据分区(集群最核心的功能)

集群将数据分散到多个节点,一方面突破了Redis单机内存大小的限制,存储容量大大增加;另一方面每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力。

Redis单机内存大小受限问题,如果单机内存太大,bgsave和bgrewriteaof的fork操作可能导致主进程阻塞,主从环境下主机切换时可能导致从节点长时间无法提供服务等。

2、高可用(集群支持主从复制和主节点的自动故障转移)

当任一节点发生故障时,集群仍然可以对外提供服务。

分片集群介绍

Redis 分片集群是一种将 Redis 数据库分散到多个节点上的方式,以提供更高的性能和可伸缩性。在分片集群中,数据被分为多个片段,每个片段存储在不同的节点上,这些节点可以是物理服务器或虚拟服务器。

Redis 分片集群的主要目的是将数据分布在多个节点上,以便可以通过并行处理来提高读写吞吐量。每个节点负责处理一部分数据,并且在需要时可以进行扩展以适应更多的负载。此外,分片集群还提供了故障容错和高可用性的功能,即使其中一个节点发生故障,其他节点仍然可以继续工作。

如何分片

Redis 通过一种称为哈希槽(hash slot)的机制来实现分片集群。哈希槽将整个数据集分成固定数量的槽,每个槽都有一个唯一的编号,通常是从 0 到 16383。

在 Redis 分片集群中,有多个节点(主节点和从节点),每个节点负责存储其中一部分的槽数据。节点之间通过集群间通信协议进行数据的交互和同步。

当一个客户端发送一个命令到 Redis 分片集群时,集群会根据命令涉及的键的哈希值将命令路由到正确的槽上。这个槽所在的节点负责处理这个命令并返回结果给客户端。

分片过程

1. 客户端发送命令到 Redis 分片集群中的任意一个节点。

2. 节点根据命令涉及的键的哈希值计算出对应的槽号。

3. 节点根据槽号确定该槽所在的节点,并将命令路由到该节点。

4. 该节点处理命令并返回结果给客户端。

当节点加入或离开集群时,Redis 分片集群会自动进行数据的重新分片和迁移,以保持数据的均衡和高可用性。

数据的重新分片和迁移

1、当一个新节点加入集群时,集群会将一部分槽从现有节点迁移到新节点上,以平衡数据负载。

2、当一个节点离开集群时,集群会将该节点负责的槽迁移到其他可用节点上,以保证数据的可用性。

通过哈希槽的机制,Redis 分片集群实现了数据的分片和自动迁移,以提供高可用性、扩展性和容错性。同时,节点间的通信和数据同步保证了集群的一致性和可用性。

分片集群结构

主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:

        海量数据存储问题

        高并发写的问题

使用分片集群可以解决上述问题

分片集群特征

1、集群中有多个master,每个master保存不同数据

2、每个master都可以有多个slave节点

3、master之间通过ping监测彼此健康状态

4、客户端请求可以访问集群任意节点,最终都会被转发到正确节点

搭建分片集群

1.集群架构

同一台虚拟机中开启6个redis实例,模拟分片集群

IPportrole
172.16.3.1527001master
172.16.3.1527002master
172.16.3.1527003master
172.16.3.1528001slave
172.16.3.1528002slave
172.16.3.1528003slave

2.准备实例和配置

# 进入/tmp目录
cd /tmp

# 删除旧的,避免配置干扰
rm -rf 7001 7002 7003

# 创建目录
mkdir  -p  7001 7002 7003 8001 8002 8003

[root@redis tmp]# mkdir -p 7001 7002 7003 8001 8002 8003
[root@redis tmp]# ll
总用量 432
drwxr-xr-x 2 root root      6 9月   5 20:14 7001
drwxr-xr-x 2 root root      6 9月   5 20:14 7002
drwxr-xr-x 2 root root      6 9月   5 20:14 7003
drwxr-xr-x 2 root root      6 9月   5 20:14 8001
drwxr-xr-x 2 root root      6 9月   5 20:14 8002
drwxr-xr-x 2 root root      6 9月   5 20:14 8003

在/tmp目录下编辑redis.conf文件

[root@redis tmp]# cat redis.conf 
# 指定端口号
port 6379
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称,不需要我们创建,由redis自己维护
cluster-config-file /tmp/6379/nodes.conf
# 节点心跳失败的超时时间
cluster-node-timeout 5000
# 持久化文件存放目录
dir /tmp/6379
# 绑定地址
bind 0.0.0.0
# 让redis后台运行
daemonize yes
# 注册的实例ip
replica-announce-ip 172.16.3.152
# 保护模式
protected-mode no
# 数据库数量
databases 1
# 日志
logfile /tmp/6379/run.log

将这个文件拷贝到每个目录下

[root@redis tmp]# echo 7001 7002 7003 8001 8002 8003 | xargs -t -n 1 cp redis.conf
cp redis.conf 7001 
cp redis.conf 7002 
cp redis.conf 7003 
cp redis.conf 8001 
cp redis.conf 8002 
cp redis.conf 8003 

修改每个目录下的redis.conf

[root@redis tmp]# printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t sed -i 's/6379/{}/g' {}/redis.conf
sed -i s/6379/7001/g 7001/redis.conf 
sed -i s/6379/7002/g 7002/redis.conf 
sed -i s/6379/7003/g 7003/redis.conf 
sed -i s/6379/8001/g 8001/redis.conf 
sed -i s/6379/8002/g 8002/redis.conf 
sed -i s/6379/8003/g 8003/redis.conf 

3.启动redis

一键启动所有服务

[root@redis tmp]# printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-server {}/redis.conf
redis-server 7001/redis.conf 
redis-server 7002/redis.conf 
redis-server 7003/redis.conf 
redis-server 8001/redis.conf 
redis-server 8002/redis.conf 
redis-server 8003/redis.conf 

查看进程和端口号

[root@redis tmp]# ps aux|grep redis
root      17414  0.1  0.4 153996  7692 ?        Ssl  20:37   0:00 redis-server 0.0.0.0:7001 [cluster]
root      17419  0.1  0.4 153996  7692 ?        Ssl  20:37   0:00 redis-server 0.0.0.0:7002 [cluster]
root      17421  0.1  0.4 153996  7692 ?        Ssl  20:37   0:00 redis-server 0.0.0.0:7003 [cluster]
root      17426  0.1  0.4 153996  7688 ?        Ssl  20:37   0:00 redis-server 0.0.0.0:8001 [cluster]
root      17431  0.1  0.4 153996  7692 ?        Ssl  20:37   0:00 redis-server 0.0.0.0:8002 [cluster]
root      17433  0.1  0.4 153996  7688 ?        Ssl  20:37   0:00 redis-server 0.0.0.0:8003 [cluster]
root      17446  0.0  0.0 112824   988 pts/1    S+   20:38   0:00 grep --color=auto redis

[root@redis tmp]# netstat -anplut|grep redis
tcp        0      0 0.0.0.0:17001           0.0.0.0:*               LISTEN      17414/redis-server  
tcp        0      0 0.0.0.0:17002           0.0.0.0:*               LISTEN      17419/redis-server  
tcp        0      0 0.0.0.0:17003           0.0.0.0:*               LISTEN      17421/redis-server  
tcp        0      0 0.0.0.0:18001           0.0.0.0:*               LISTEN      17426/redis-server  
tcp        0      0 0.0.0.0:18002           0.0.0.0:*               LISTEN      17431/redis-server  
tcp        0      0 0.0.0.0:18003           0.0.0.0:*               LISTEN      17433/redis-server  
tcp        0      0 0.0.0.0:7001            0.0.0.0:*               LISTEN      17414/redis-server  
tcp        0      0 0.0.0.0:7002            0.0.0.0:*               LISTEN      17419/redis-server  
tcp        0      0 0.0.0.0:7003            0.0.0.0:*               LISTEN      17421/redis-server  
tcp        0      0 0.0.0.0:8001            0.0.0.0:*               LISTEN      17426/redis-server  
tcp        0      0 0.0.0.0:8002            0.0.0.0:*               LISTEN      17431/redis-server  
tcp        0      0 0.0.0.0:8003            0.0.0.0:*               LISTEN      17433/redis-server 

关闭redis服务

printf '%s\n' 7001 7002 7003 8001 8002 8003 | xargs -I{} -t redis-cli -p {} shutdown
ps -aux | grep redis | awk '{print $2}' | xargs kill

4.创建集群

Redis5.0之前,集群命令都是用redis安装包下的src/redis-trib.rb来实现的。因为redis-trib.rb是有ruby语言编写的所以需要安装ruby环境。

 # 安装依赖
 yum -y install zlib ruby rubygems
 gem install redis

# 进入redis的src目录
cd /tmp/redis-5.0.14 /src

# 创建集群
./redis-trib.rb create --replicas 1 172.16.3.152:7001 172.16.3.152:7002 172.16.3.152:7003 172.16.3.152:8001 172.16.3.152:8002 172.16.3.152:8003

Redis5.0之后,集群管理以及集成到了redis-cli中

[root@redis tmp]# redis-cli --help
redis-cli 5.0.14

Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]]
  -h <hostname>      Server hostname (default: 127.0.0.1).
  -p <port>          Server port (default: 6379).
  -s <socket>        Server socket (overrides hostname and port).
  -a <password>      Password to use when connecting to the server.
                     You can also use the REDISCLI_AUTH environment
                     variable to pass this password more safely
                     (if both are used, this argument takes predecence).
  -u <uri>           Server URI.
  -r <repeat>        Execute specified command N times.
  -i <interval>      When -r is used, waits <interval> seconds per command.
                     It is possible to specify sub-second times like -i 0.1.
  -n <db>            Database number.
  -x                 Read last argument from STDIN.
  -d <delimiter>     Multi-bulk delimiter in for raw formatting (default: \n).
  -c                 Enable cluster mode (follow -ASK and -MOVED redirections).
  --raw              Use raw formatting for replies (default when STDOUT is
                     not a tty).
  --no-raw           Force formatted output even when STDOUT is not a tty.
  --csv              Output in CSV format.
  --stat             Print rolling stats about server: mem, clients, ...
  --latency          Enter a special mode continuously sampling latency.
                     If you use this mode in an interactive session it runs
                     forever displaying real-time stats. Otherwise if --raw or
                     --csv is specified, or if you redirect the output to a non
                     TTY, it samples the latency for 1 second (you can use
                     -i to change the interval), then produces a single output
                     and exits.
  --latency-history  Like --latency but tracking latency changes over time.
                     Default time interval is 15 sec. Change it using -i.
  --latency-dist     Shows latency as a spectrum, requires xterm 256 colors.
                     Default time interval is 1 sec. Change it using -i.
  --lru-test <keys>  Simulate a cache workload with an 80-20 distribution.
  --replica          Simulate a replica showing commands received from the master.
  --rdb <filename>   Transfer an RDB dump from remote server to local file.
  --pipe             Transfer raw Redis protocol from stdin to server.
  --pipe-timeout <n> In --pipe mode, abort with error if after sending all data.
                     no reply is received within <n> seconds.
                     Default timeout: 30. Use 0 to wait forever.
  --bigkeys          Sample Redis keys looking for keys with many elements (complexity).
  --memkeys          Sample Redis keys looking for keys consuming a lot of memory.
  --memkeys-samples <n> Sample Redis keys looking for keys consuming a lot of memory.
                     And define number of key elements to sample
  --hotkeys          Sample Redis keys looking for hot keys.
                     only works when maxmemory-policy is *lfu.
  --scan             List all keys using the SCAN command.
  --pattern <pat>    Useful with --scan to specify a SCAN pattern.
  --intrinsic-latency <sec> Run a test to measure intrinsic system latency.
                     The test will run for the specified amount of seconds.
  --eval <file>      Send an EVAL command using the Lua script at <file>.
  --ldb              Used with --eval enable the Redis Lua debugger.
  --ldb-sync-mode    Like --ldb but uses the synchronous Lua debugger, in
                     this mode the server is blocked and script changes are
                     not rolled back from the server memory.
  --cluster <command> [args...] [opts...]
                     Cluster Manager command and arguments (see below).
  --verbose          Verbose mode.
  --no-auth-warning  Don't show warning message when using password on command
                     line interface.
  --help             Output this help and exit.
  --version          Output version and exit.

Cluster Manager Commands:
  Use --cluster help to list all available cluster manager commands.

Examples:
  cat /etc/passwd | redis-cli -x set mypasswd
  redis-cli get mypasswd
  redis-cli -r 100 lpush mylist x
  redis-cli -r 100 -i 1 info | grep used_memory_human:
  redis-cli --eval myscript.lua key1 key2 , arg1 arg2 arg3
  redis-cli --scan --pattern '*:12345*'

  (Note: when using --eval the comma separates KEYS[] from ARGV[] items)

When no command is given, redis-cli starts in interactive mode.
Type "help" in interactive mode for information on available commands
and settings.

[root@redis tmp]# 

创建集群

redis-cli --cluster create --cluster-replicas 1 172.16.3.152:7001 172.16.3.152:7002 172.16.3.152:7003 172.16.3.152:8001 172.16.3.152:8002 172.16.3.152:8003

redis-cli --cluster         # 代表集群操作命令
create                      # 代表是创建集群
--cluster-replicas 1        # 指定集群中每个master的副本个数为1,此时节点总数 ÷ (replicas + 1) 得到的就是master的数量。因此节点列表中的前n个就是master,其它节点都是slave节点,随机分配到不同master。
[root@redis tmp]# redis-cli --cluster create --cluster-replicas 1 172.16.3.152:7001 172.16.3.152:7002 172.16.3.152:7003 172.16.3.152:8001 172.16.3.152:8002 172.16.3.152:8003
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.16.3.152:8002 to 172.16.3.152:7001
Adding replica 172.16.3.152:8003 to 172.16.3.152:7002
Adding replica 172.16.3.152:8001 to 172.16.3.152:7003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 924f2fa20bda219d317bb27b7cd2e29d0299a68f 172.16.3.152:7001
   slots:[0-5460] (5461 slots) master
M: d08715ade7f086a705ce581a3ff9d9b3dffb64aa 172.16.3.152:7002
   slots:[5461-10922] (5462 slots) master
M: 58bd479eff14eae43809aa26792295748938273d 172.16.3.152:7003
   slots:[10923-16383] (5461 slots) master
S: d50b7e4c4943cc03e2469bffe8184aa54a355fac 172.16.3.152:8001
   replicates 58bd479eff14eae43809aa26792295748938273d
S: 2b4e2e4443b6be6bed5c39d7ac7779d233b81d49 172.16.3.152:8002
   replicates 924f2fa20bda219d317bb27b7cd2e29d0299a68f
S: 99fd8e555d589fc2d07ddf10c4446c8631712bde 172.16.3.152:8003
   replicates d08715ade7f086a705ce581a3ff9d9b3dffb64aa
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
..
>>> Performing Cluster Check (using node 172.16.3.152:7001)
M: 924f2fa20bda219d317bb27b7cd2e29d0299a68f 172.16.3.152:7001
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 58bd479eff14eae43809aa26792295748938273d 172.16.3.152:7003
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 99fd8e555d589fc2d07ddf10c4446c8631712bde 172.16.3.152:8003
   slots: (0 slots) slave
   replicates d08715ade7f086a705ce581a3ff9d9b3dffb64aa
M: d08715ade7f086a705ce581a3ff9d9b3dffb64aa 172.16.3.152:7002
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: d50b7e4c4943cc03e2469bffe8184aa54a355fac 172.16.3.152:8001
   slots: (0 slots) slave
   replicates 58bd479eff14eae43809aa26792295748938273d
S: 2b4e2e4443b6be6bed5c39d7ac7779d233b81d49 172.16.3.152:8002
   slots: (0 slots) slave
   replicates 924f2fa20bda219d317bb27b7cd2e29d0299a68f
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

查看集群状态

[root@redis redis]# redis-cli -p 7001 cluster nodes
58bd479eff14eae43809aa26792295748938273d 172.16.3.152:7003@17003 master - 0 1693918397148 3 connected 10923-16383
99fd8e555d589fc2d07ddf10c4446c8631712bde 172.16.3.152:8003@18003 slave d08715ade7f086a705ce581a3ff9d9b3dffb64aa 0 1693918396132 6 connected
924f2fa20bda219d317bb27b7cd2e29d0299a68f 172.16.3.152:7001@17001 myself,master - 0 1693918395000 1 connected 0-5460
d08715ade7f086a705ce581a3ff9d9b3dffb64aa 172.16.3.152:7002@17002 master - 0 1693918396000 2 connected 5461-10922
d50b7e4c4943cc03e2469bffe8184aa54a355fac 172.16.3.152:8001@18001 slave 58bd479eff14eae43809aa26792295748938273d 0 1693918395000 4 connected
2b4e2e4443b6be6bed5c39d7ac7779d233b81d49 172.16.3.152:8002@18002 slave 924f2fa20bda219d317bb27b7cd2e29d0299a68f 0 1693918396638 5 connected

5.测试

连接7001节点,存储一个数据

[root@redis redis]# redis-cli -p 7001
127.0.0.1:7001> ping
PONG
127.0.0.1:7001> set num 123
OK
127.0.0.1:7001> get num
"123"
127.0.0.1:7001> set a 1
(error) MOVED 15495 172.16.3.152:7003
127.0.0.1:7001> 

集群操作时,需要给redis-cli加上选项 -c (启用群集模式(遵循 -ASK 和 -MOVE 重定向))

  -c                 Enable cluster mode (follow -ASK and -MOVED redirections).
[root@redis redis]# redis-cli -c -p 7001
127.0.0.1:7001> get num
"123"
127.0.0.1:7001> set a 1
-> Redirected to slot [15495] located at 172.16.3.152:7003
OK
172.16.3.152:7003> get a
"1"

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韩未零

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值