目录
集群
Redis Cluster 工作原理
Redis cluster 基本架构
Redis cluster 主从架构
搭建集群
总结
集群
集群,即Redis Cluster,是Redis 3.0开始引入的分布式存储方案。
集群由多个节点(Node)组成,Redis的数据分布在这些节点中。集群中的节点分为主节点和从节点:只有主节点负责读写请求和集群信息的维护;从节点只进行主节点数据和状态信息的复制。
集群的作用,可以归纳为两点:
1、数据分区:数据分区(或称数据分片)是集群最核心的功能。集群将数据分散到多个节点,一方面突破了Redis单机内存大小的限制,存储容量大大增加;另一方面每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力。Redis单机内存大小受限问题,在介绍持久化和主从复制时都有提及:例如,如果单机内存太大,bgsave和bgrewriteaof 的:保存操作可能导致主进程阻塞,主从环境下主机切换时可能导致从节点长时间无法提供服务,全量复制阶段主节点的复制缓冲区可能溢出。
2、高可用:集群支持主从复制和主节点的自动故障转移〈与哨兵类似)﹔当任一节点发生故障时,集群仍然可以对外提供服务。
Redis集群的数据分片:
Redis集群引入了哈希槽的概念
Redis集群有16384个哈希槽(编号0-16383)集群的每个节点负责部分哈希槽
每个Key通过CRc16校验后对16384取余来决定放置哪个哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作
以3个节点组成的集群为例:
节点A包含0到5460号哈希槽
节点B包含5461到10922号哈希槽
节点C包含10923到16383号哈希槽
Redis集群的主从复制模型
集群中具有A、B、C三个节点,如果节点B失败了,整个集群就会因缺少5461-10922这个范围的槽而不可以用。
为每个节点添加一个从节点A1、B1、C1整个集群便有三个Master节点和三个slave 节点组成,在节点B失败后,集群选举:一位为主节点继续服务。当B和B1都失败后,集群将不可用。
Redis Cluster 工作原理
在哨兵sentinel机制中,可以解决redis高可用问题,即当master故障后可以自动将slave提升为master,从而可以保证redis服务的正常使用,但是无法解决redis单机写入的瓶颈问题,即单机redis写入性能受限于单机的内存大小、并发数量、网卡速率等因素。
Redis Cluster特点如下:
1、所有Redis节点使用(PING机制)互联,
2、集群中某个节点的是否失效,是由整个集群中超过半数的节点监测都失效,才能算真正的失效
3、客户端不需要proxy即可直接连接redis,应用程序中需要配置有全部的redis服务器IP
4、redis cluster把所有的redis node 平均映射到 0-16383个槽位(slot)上,读写需要到指定的redis node上进行操作,因此有多少个redis node相当于redis 并发扩展了多少倍,每个redis node 承担16384/N个槽位
5、Redis cluster预先分配16384个(slot)槽位,当需要在redis集群中写入一个key -value的时候,会使用CRC16(key)取余16384之后的值,决定将key写入哪一个槽位从而决定写入哪一个Redis节点上,从而有效解决单机瓶颈。
Redis cluster 基本架构
假如三个主节点分别是:A, B, C 三个节点,采用哈希槽 (hash slot)的方式来分配16384个slot 的话它们三个节点分别承担的slot 区间可以是
节点A覆盖 0-5460 节点B覆盖 5461-10922 节点C覆盖 10923-16383
Redis cluster 主从架构
Redis cluster的架构虽然解决了并发的问题,但是又引入了一个新的问题,每个Redis master的高可用
如何解决?
那就是对每个master 节点都实现主从复制,从而实现 redis 高可用性
多实例
搭建集群
多实例搭建集群,只需要在一台服务器上搭建即可
创建6个redis并配置端口号
[root@localhost ~]# cd /etc/redis/
[root@localhost /etc/redis]# mkdir -p redis-cluster/redis600{1..6}
[root@localhost /etc/redis]# ls
6379.conf redis-cluster
[root@localhost /etc/redis]# cd redis-cluster/
[root@localhost /etc/redis/redis-cluster]# ls
redis6001 redis6002 redis6003 redis6004 redis6005 redis6006
编写脚本
[root@localhost /opt/redis-5.0.7]# vim redis.sh
#/bin/bash
for i in {1..6}
do
cp redis.conf src/redis-cli src/redis-server /etc/redis/redis-cluster/redis600$i
done
运行并查看,6台redis就创建完毕了
[root@localhost /opt/redis-5.0.7]# tree /etc/redis/redis-cluster/
/etc/redis/redis-cluster/
├── redis6001
│ ├── redis-cli
│ ├── redis.conf
│ └── redis-server
├── redis6002
│ ├── redis-cli
│ ├── redis.conf
│ └── redis-server
├── redis6003
│ ├── redis-cli
│ ├── redis.conf
│ └── redis-server
├── redis6004
│ ├── redis-cli
│ ├── redis.conf
│ └── redis-server
├── redis6005
│ ├── redis-cli
│ ├── redis.conf
│ └── redis-server
└── redis6006
├── redis-cli
├── redis.conf
└── redis-server
6 directories, 18 files
修改配置文件
[root@localhost /etc/redis/redis-cluster]# ls
redis6001 redis6002 redis6003 redis6004 redis6005 redis6006
[root@localhost /etc/redis/redis-cluster]# cd redis6001
[root@localhost /etc/redis/redis-cluster/redis6001]# ls
redis-cli redis.conf redis-server
[root@localhost /etc/redis/redis-cluster/redis6001]# vim redis.conf
修改其余的端口号,记得要把每一个redis的配置文件要修改端口
[root@localhost /etc/redis/redis-cluster/redis6001]# \cp -f redis.conf ../redis6002
[root@localhost /etc/redis/redis-cluster/redis6001]# \cp -f redis.conf ../redis6003
[root@localhost /etc/redis/redis-cluster/redis6001]# \cp -f redis.conf ../redis6004
[root@localhost /etc/redis/redis-cluster/redis6001]# \cp -f redis.conf ../redis6005
[root@localhost /etc/redis/redis-cluster/redis6001]# \cp -f redis.conf ../redis6006
编写脚本
[root@localhost /etc/redis/redis-cluster/redis6001]# vim redis601.sh
#/bin/bash
for i in {1..6}
do
cd /etc/redis/redis-cluster/redis600$i
./redis-server redis.conf
done
~
查看是否启动
[root@localhost /etc/redis/redis-cluster/redis6001]# ps -elf |grep redis
5 S root 100113 1 0 80 0 - 38461 ep_pol 14:30 ? 00:01:27 redis-sentinel *:26379 [sentinel]
5 S root 100265 1 0 80 0 - 40125 ep_pol 14:44 ? 00:01:10 /usr/local/redis/bin/redis-server 0.0.0.0:6379
5 S root 102980 1 0 80 0 - 38462 ep_pol 19:09 ? 00:00:01 ./redis-server *:6001 [cluster]
5 S root 103173 1 0 80 0 - 38462 ep_pol 19:20 ? 00:00:00 ./redis-server *:6002 [cluster]
5 S root 103175 1 0 80 0 - 38462 ep_pol 19:20 ? 00:00:00 ./redis-server *:6003 [cluster]
5 S root 103180 1 0 80 0 - 38462 ep_pol 19:20 ? 00:00:00 ./redis-server *:6004 [cluster]
5 S root 103185 1 0 80 0 - 38462 ep_pol 19:20 ? 00:00:00 ./redis-server *:6005 [cluster]
5 S root 103190 1 0 80 0 - 38462 ep_pol 19:20 ? 00:00:00 ./redis-server *:6006 [cluster]
0 S root 103210 102333 0 80 0 - 28169 pipe_w 19:21 pts/0 00:00:00 grep --color=auto redis
启动群集
[root@localhost /etc/redis/redis-cluster/redis6001]# redis-cli --cluster create 127.0.0.1:6001 127.0.0.1:6002 127.0.0.1:6003 127.0.0.1:6004 127.0.0.1:6005 127.0.0.1:6006 --cluster-replicas 1###如果是6台机器,就把地址改成机器的IP地址即可
查看集群槽
[root@localhost /etc/redis/redis-cluster/redis6001]# redis-cli -p 6001 -c
#####-c 代表群集之间可以互相跳转
创建键值对
去别的另一个端口redis查看
[root@localhost /etc/redis/redis-cluster/redis6001]# redis-cli -p 6002 -c
127.0.0.1:6002> get x
-> Redirected to slot [16287] located at 127.0.0.1:6003
"bin"
127.0.0.1:6003>
总结
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如字符串(strings),散列(hashes),列表(lists),集合(sets),有序集合(sorted sets)与范围查询,
Redis 内置了复制(replication),LUA脚本(Lua scrpting),LRU驱动事件(LRU eviction),事务(transactions)和不同级别的 磁盘持久化(persistence), 并通过Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性(high availability)。