"Unlock Redis series 6" Redis Cluster Cluster

Feel good, do not forget to thumbs up! Search public micro-channel number] [Damocles pen for more resources, the end the two-dimensional code!

First, why use cluster

Before we mention redis can achieve master-slave replication, but the master-slave replication can not achieve high availability, capacity, or when the data requires a lot but even when QPS can not meet the demand. What is the difference also mentioned Redis Sentinel and Redis Cluster we showed at the end of the text.

1.1, concurrency

Redsi official data provided for the 10W / sec, we do not care about its accuracy, but actual use is entirely reach tens of thousands, we have to meet the needs of a large part, but some services may require a higher QPS, For example, one million of.

1.2, the amount of data

Redis is a memory-based database, the machine's memory generally between 16 ~ 256G, if the amount of data we have 500G, such as personalized recommendation system, the user-related data are stored in the Redis.

1.3 Solution

  1. Configure powerful machines, large memory, CPU and so on top, but the cost is very high, there is always a node limit.
  2. Distributed , add nodes.

Redis Redis Cluster launched after the 3.0 version to meet the needs of our distributed

Second, the data partition

Before we learn Redis cluster we look at the data partition concept, that is, how the rational allocation of all data to different nodes. Often there are ways of partitioning the order of partition and hash partitioning

2.1, the order of partition

The same data is stored within a range of the same Redis example, there is such a user table, we will of ID0-ID10000, ID-10001-ID20000, and so on, is stored in the same instance. So if we have some good data partitioning, for example, some random ID number, UUID, and so on, we can use hash partitioning

2.2, hash partitioning

Hash partitioning compared with the range of the partition is a significant advantage in any form suitable hash partitioning key, rather than as limitations order of the partitions, and partition method is very simple, a formula can be expressed: ID = the hash (Key )% nodes

Wherein the number representative of id Redis example, the formula is described first calculated according to a numeric key and a hash function (e.g., function crc32), then modulo the number of nodes on Redis object is calculated modulo data we want to deposit on the first few nodes!

2.2.1, the node takes over partition

When we have three nodes Redis, but the data rises, we will consider increasing node, this time we recommend the use of multiple expansion, such as three to four node expansion we then will switch 80% of data points, such as from 1 2 nodes to other phenomena, data migration change too much, if we Hee increased to six nodes that only 50% of the data will be migrated.

to sum up:

  1. Client fragmentation: Hash modulo +
  2. Telescopic node: node changes the relationship between data, resulting in data migration, because to be recalculated
  3. Migration and adding the number of nodes related to: double the recommended expansion
  4. This way is not recommended, it is a relatively old-fashioned way, because large amounts of data will cause migration when the new node, if your system is very dependent on the cache, the performance will be affected.

2.2.2, consistency hash partitioning

We take the top when it comes to migration hash over ways to increase if the node to the data caused by relatively large, consistent hashing is to solve this problem. We can Redis save data that is an annular, Hash values ​​are 32-bit, 0 to 2 ^ 32, the IP nodes + algorithm determines a unique hash value, after determining the position of the node in memory, when saving data, in accordance with hashing key, where the mount is determined clockwise station node. Figure ugly forgive me, ha ha ha ha ~ ~ ~ hic! ! !

If you need to add the cluster nodes, such as between node2 and add a node3 Node4, the data distribution becomes FIG.

我们会发现,数据依然有迁移,本来在node3上的数据一部分迁移到了node4上,但是node1和node2没有受到影响。如果我们集群有1000台,是由原本的取余分区方式会有80%的数据迁移,为了避免我们使用双倍扩容,也就是再添加1000台节点达到50%数据迁移的效果,很显然添加这么多的节点是不合适的!!!这种分区方式在memCache中使用。

2.3、Redis哈希槽

上边年我们介绍了顺序分区和hash分区,而Redis Cluster并没有使用其中的任何一种(坑爹呢,上边叨X叨半天),Redis而是引入了哈希槽的的概念,Redis内置了16384个槽,从0-16383。每一天界都都维护一个范围的哈希槽,当有新的key需要添加时,会使用CRC16算法并且对16384取余,公式:CRC16(key) & 16384。得到一个值,去找Redis集群中的节点,看看这个槽是哪个节点维护的,就将key存储到哪个节点上。

到这里我们知道有顺序分区哈希分区,哈希分区包含节点取余一致性哈希memCache分布式使用一致性哈希Redis集群中使用的是哈希槽的方式存储数据。 我们接下来说一下Redis集群的架构搭建方式

三、Redis集群架构

3.1、单体架构

单体架构如下图所示,只有一个Redis实例,多个客户端都在操作同一个Redis,数据存储量,访问量,数据备份上都是有问题的

3.2、Redis Cluster架构 

3.2.1、说明

下图是分布式架构(咋这么多箭头,我得了箭头眩晕症),蓝色圆圈是Redis实例,这里有五个,我们之前说Redis集群中存储数据通过槽的概念,会讲16384个槽平均到5台节点上,节点之间看到了有双向箭头指向,这代表他们之间是相互通信的,每个节点都知道对应的槽是哪个节点负责。下方的绿色客户端可以去操作Redis集群中可用的节点。如果客户端要找的数据在该节点上就会返回数据,如果不在会响应客户端新的节点地址,做一个转发操作,去新的节点上获取数据。当然这种方式效率不高,当节点多时,命中率不会很高,需要智能客户端,这个后边再说。

  1. 在分布式模式下节点之间会相互通信
  2. 每个节点都负责读写,每个节点负责数据的一部分

3.2.2、节点间通信

节点间使用meet命令进行通信,比如A向C发送meet命令,C会反馈给A一个PONG,A给B发送meet,B反馈给A一个PONG,这样B和C也能得知对方的存在。

节点更多时如下

3.2.3、指派槽

比如我们的Redis Cluster有三台节点,我们需要给三台节点分配槽,如下图,而客户端则需要使用公式计算结果将key存储在对应的节点上。

四、Redis集群配置和启动

Redis集群配置有原生配置、官方提供的ruby插件配置方式和redis5.0之后的快捷配置,我们这里三种方式我们说明第一种和第三种,原生配置比较麻烦,但是可以让你体验到Redis Cluster架构和整个流程,实际应用中使用快捷方式配置即可。

4.1、原生配置方式

4.1.1、步骤

  1.  配置开启Redis,这种情况每台节点都是独立的;

  2. 执行meet操作,让Redis集群之间感知到其他节点的存在;

  3. 分配槽;

  4. 设置主从关系,我们这里一共6台节点,3主3从。

4.1.2、Redis配置和启动

我们的配置文件从redis-7000.conf到redis-7005.conf,每个配置文件中端口日志文件名不一样,只贴出redis-7000.conf配置文件

port 7000
daemonize yes
logfile "7000.log"
dir "/usr/local/redis-5.0.5/data/"
protected-mode no
dbfilename dump-7000.rdb
# 开启集群
cluster-enabled yes
# 集群运行时文件
cluster-config-file nodes-7000.conf
# 是否集群所有的节点都正常集群才可使用,改为no
cluster-require-full-coverage no

 启动Redis6个节点,在查看进程,发现端口后边都有cluster标记

我们随便进入一个节点添加数据会发现,提示我们集群下线,没有提供哈希槽!请回头看我们的步骤。至此我们第一步和第二步就完成

接下来我们到data目录下发现有nodes开头的文件,这就是我们在redis配置文件中配置的,我们输出一下文件内容,绿色下划线的分别是该节点的ID和自己的状态为master。

 4.1.3、meet操作实现节点握手

命令:redis-cli -p port cluster meet 目标节点ip 目标节点port

[root@stt101 conf]# ./redis-cli -p 7000 cluster meet 127.0.0.1 7001
OK
[root@stt101 conf]# ./redis-cli -p 7000 cluster meet 127.0.0.1 7002
OK
[root@stt101 conf]# ./redis-cli -p 7000 cluster meet 127.0.0.1 7003
OK
[root@stt101 conf]# ./redis-cli -p 7000 cluster meet 127.0.0.1 7004
OK
[root@stt101 conf]# ./redis-cli -p 7000 cluster meet 127.0.0.1 7005

查看状态命令:redis-cli -p 7000 cluster info 发现节点个数为6个

那么这里给大家留个问题,至此我们可否向redis中存储数据呢? 

4.1.4、指派槽 

集群规划为7000,7001,7002是主节点,7003是7000从节点,7004是7001从节点,7005是7002从节点 

7000:0-5461

7001:5462-10922

7002:10923-16383

分配槽命令:redis-cli -p port cluster addslots slot

我们有16384个槽,一个一个分配是很慢的,所以我们编写一个脚本来分配!

分配槽脚本

start=$1
end=$2
port=$3
for slot in `seq ${start} ${end}`
do
  echo "slot:${slot}"
  redis-cli -p ${port} cluster addslots ${slot}
done

执行命令

addslots.sh 0 5461 7000 

addslots.sh 5462 10922 7001

addslots.sh 10923 16383 7002 

进入到7000端口实例执行cluster nodes命令看到槽已分配好,大家就可以向Redis中添加数据了 

 4.1.5、主从分配

根据指派槽哪里说得主从关系我们使用以下命令进行分配

命令

redis-cli -p 从节点port cluster replicate 主节点ID

主节点ID就是上图最前边的那一串字符

redis-cli -p 7003 cluster replicate cb436d72cee8f6547e0dc002c9342dd27087bdcc 
redis-cli -p 7004 cluster replicate 03717034bca9c03e40cf4c1a4041c94f79e209d8
redis-cli -p 7005 cluster replicate c0167209ceb9fa350704781a1a53432a61f92a8c 

在执行cluster nodes命令会发现已经变成3主3从,如下图 

 注意:如果启动集群模式的客户端需要使用redis-cli -c -p 7003命令加上了-c参数!

至此我们的原生方式已经搭建完成,很复杂,但是可以看到Redis Cluster的整个实现流程,对大家理解Redis Cluster更有帮助,希望大家可以自己动手跟着做一遍!有问题的可以下方留言! 

 4.2、快速配置

redis5.0集群创建方式改为了C编写的redis-cli创建,不用再安装麻烦的ruby了。ruby方式大家感兴趣可以到网上搜索,这里就不说了配置和之前一样就是将7000端口改为8000,以此类推为了区别,大家在配置的时候建议先将redis都停掉,还是3主3从的方式,下边只贴出8000的配置

4.2.1、配置文件

port 8000
daemonize yes
logfile "8000.log"
dir "/usr/local/redis-5.0.5/data/"
protected-mode no
dbfilename dump-8000.rdb
# 开启集群
cluster-enabled yes
# 集群运行时文件
cluster-config-file nodes-8000.conf
# 是否集群所有的节点都正常集群才可使用,改为no
cluster-require-full-coverage no
# 节点请求超时时间 
cluster-node-timeout 15000
# 关闭保护模式
protected-mode no

4.2.2、启动节点

分别启动6台节点,查看进程

 4.2.3、配置集群

直接使用以下命令即可,前边三台是主节点,后边三台是从节点

redis-cli --cluster create 127.0.0.1:8000 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 127.0.0.1:8004 127.0.0.1:8005 --cluster-replicas 1

下图为分配槽、配置主从的过程是可以看出来的

4.2.4、查看集群情况

 可以看出3主3从,操作和之前都一样

五、哨兵模式和集群有何区别

  1. 哨兵模式需要开启sentinel进程主要作用是监控Redis节点的运行状态,如果主数据库发生故障则切换到从数据库,sentinel发现master挂掉之后再重新选举出一个新的master,主要是监控,提醒和故障转移,实现Redis的高可用;
  2. 哨兵模式客户端不会记录具体的master节点的ip,而是记录sentinel节点,我们从sentinel节点获取redis的地址,上节我们用代码演示过;
  3. 哨兵模式存储数据都是全量存储,每个Redis存储的都是完整的数据,浪费内存而且存在木桶效应,为了最大化利用内存,我们可以使用分布式存储,采用集群。即每台节点存储不同的数据,共有16384个slot;
  4. 集群最少3主3从,且主从不用配置,集群会自己分配(参考我们的第二种搭建方式);
  5. 集群模式为了解决单机Redis容量有限的问题,将数据按照一定的规则分配到多台机器,提高并发。

未完待续... ...

写在最后:

各位的支持和认可(点赞)是我最大的动力,请不要轻轻的来,用力留下你的足迹!

本篇文章有任何错误希望不吝指出,不胜感激!我们下篇再见!

求知并无捷径,如果有,那就是放弃这个幼稚的想法,静下心来多读书、总结


 

发布了23 篇原创文章 · 获赞 49 · 访问量 1万+

Guess you like

Origin blog.csdn.net/qq_36386908/article/details/104291073