·redis集群
Redis集群是一个提供在多个redis节点间共享数据的程序集。
Redis Cluster模式是Redis3.0之后推荐的一种解决方案,其是由多个主节点群组成的分布式服务器群,它具有复制、高可用和分片的特性。另外,Redis Cluster集群不需要哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置为集群模式,这种集群模式没有中心节点,可水平扩展,且集群配置非常简单。
Cluster集群模式工作特点:
Cluster集群模式工作原理:
Redis Cluster有固定的16384个hash slot(槽),对每个key计算CRC16值,然后对16384取模,可以获取key对应的hash slot。每个master都会持有部分slot,比如有3个master,那么可能每个master持有5000多个hash slot,在redis cluster写入数据的时候。
其实是你可以将请求发送到任意一个master上去执行。但是,每个master都会计算这个key对应的CRC16值,然后对16384个hashslot取模,找到key对应的hashslot,找到hashslot对应的master。
主观下线(pfail):集群中的每个节点都会定期向其他节点发送ping消息,如果在一段时间内一直通信失败,则发送节点方认为接收节点存在故障,把接收节点标为主观下线(pfail)状态。
客观下线(fail):当某个节点判断另一个节点主观下线后,相应的节点状态就会在集群中进行传播,如果集群中所有节点都将它标为主观下线,那么该节点为客观下线,并通知该节点的Slave进行故障转移操作。
故障转移:在某个节点客观下线后,该节点的从节点开始故障转移流程,首先进行资格检查,每个从节点检查与主节点的断开时间,超过一定时间的取消选举资格,然后同样在所有从节点中寻找复制偏移量最大的节点先开始进行选举,只有持有槽的主节点才有投票权,当从节点收集到过半的票数时,即晋升为Master,随即通知Slave当前Master变为自己。
一、Redis Cluster(Redis集群)简介
redis是一个开源的key value存储系统,受到了广大互联网公司的青睐。redis3.0版本之前只支持单例模式,在3.0版本及以后才支持集群,我这里用的是redis3.0.0版本;
redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;
redis集群是没有统一的入口的,客户端(client)连接集群的时候连接集群中的任意节点(node)即可,集群内部的节点是相互通信的(PING-PONG机制),每个节点都是一个redis实例;
为了实现集群的高可用,即判断节点是否健康(能否正常使用),redis-cluster有这么一个投票容错机制:如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否挂了的方法;
那么如何判断集群是否挂了呢? -> 如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就挂了。这是判断集群是否挂了的方法;
那么为什么任意一个节点挂了(没有从节点)这个集群就挂了呢? -> 因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。
redis使用中遇到的瓶颈
我们日常在对于redis的使用中,经常会遇到一些问题
1、高可用问题,如何保证redis的持续高可用性。
2、容量问题,单实例redis内存无法无限扩充,达到32G后就进入了64位世界,性能下降。
3、并发性能问题,redis号称单实例10万并发,但也是有尽头的。
redis-cluster的优势
1、官方推荐,毋庸置疑。
2、去中心化,集群最大可增加1000个节点,性能随节点增加而线性扩展。
3、管理方便,后续可自行增加或摘除节点,移动分槽等等。
4、简单,易上手。
redis-cluster名词介绍
1、master 主节点、
2、slave 从节点
3、slot 槽,一共有16384数据分槽,分布在集群的所有主节点中。
16379端口为集群总线端口
集群内部划分为16384个数据分槽,分布在三个主redis中。
从redis中没有分槽,不会参与集群投票,也不会帮忙加快读取数据,仅仅作为主机的备份。
三个主节点中平均分布着16384数据分槽的三分之一,每个节点中不会存有有重复数据,仅仅有自己的从机帮忙冗余。
三台服务器搭建redis集群(6个实例)
主机名 |
IP |
服务 |
端口 |
Redis1 |
192.168.1.10 |
Redis-3.0.7 |
7000/7001 |
Redis2 |
192.168.1.11 |
Redis-3.0.7 |
7002/7003 |
Redis3 |
192.168.1.12 |
Redis-3.0.7 |
7004/7005 |
Systemctl stop firewalld
[root@localhost ~]# tar xf redis-3.0.7.tar.gz [root@localhost ~]# cd redis-3.0.7 [root@localhost ~]# mv redis-3.0.7 /usr/local/redis [root@localhost ~]# cd /usr/local/redis [root@localhost redis]# make [root@localhost redis]# make install 创建目录创建实例 [root@localhost redis]# mkdir cluster [root@localhost redis]# cd cluster [root@localhost cluster]# mkdir 7000 [root@localhost cluster]# mkdir 7001 [root@localhost cluster]# cd 7000 实例中的配置文件 [root@localhost 7000]# vim redis.conf
port 7000 bind 192.68.1.10 daemonize yes pidfile /var/run/redis_7000.pid cluster-enabled yes cluster-config-file nodes_7000.conf cluster-node-timeout 15000 appendonly yes [root@localhost cluster]# cd 7001 [root@localhost 7001]# vim redis.conf port 7000 bind 192.68.1.10 daemonize yes pidfile /var/run/redis_7000.pid cluster-enabled yes cluster-config-file nodes_7000.conf cluster-node-timeout 15000 appendonly yes
启动redis实例 [root@localhost 7005]# redis-server /usr/local/redis/cluster/7004/redis.conf [root@localhost 7005]# redis-server /usr/local/redis/cluster/7005/redis.conf [root@localhost 7005]# netstat -antup |grep redis
安装rubygem redis依赖 [root@localhost 7005]# wget http://rubygems.org/downloads/redis-3.3.0.gem [root@localhost ~]# yum -y install gem [root@localhost ~]# gem install -l redis-3.3.0.gem Successfully installed redis-3.3.0 Parsing documentation for redis-3.3.0 Installing ri documentation for redis-3.3.0 1 gem installed [root@localhost redis]# cd /usr/local/redis/src/
启动实例使用 redis-trib.rb create 命令完成节点握手和槽分配过程 ./redis-trib.rb create --replicas 1 192.168.1.10:7000 192.168.1.10:7001 192.168.1.11:7002 192.168.1.11:7003 192.168.1.12:7004 192.168.1.12:7005
>>> Creating cluster >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 192.168.1.10:7000 192.168.1.11:7002 192.168.1.12:7004 Adding replica 192.168.1.11:7003 to 192.168.1.10:7000 Adding replica 192.168.1.10:7001 to 192.168.1.11:7002 Adding replica 192.168.1.12:7005 to 192.168.1.12:7004 M: 5de425752b3146c4013da9f2fc068512bae15a6d 192.168.1.10:7000 slots:0-5460 (5461 slots) master S: b45f923b82d7d6684ac97006f5470b081f5d1246 192.168.1.10:7001 replicates 02005dfdffbd18db93af7f0d66e2e4b82fbbdea4 M: 02005dfdffbd18db93af7f0d66e2e4b82fbbdea4 192.168.1.11:7002 slots:5461-10922 (5462 slots) master S: c8c8d4266610fefdb637d786b6320f2b1f96cf96 192.168.1.11:7003 replicates 5de425752b3146c4013da9f2fc068512bae15a6d M: 5753ea85bfdf8ca52e46161ef1038c1c1b3f04f3 192.168.1.12:7004 slots:10923-16383 (5461 slots) master S: a5f65754933a9b70e5b11149facf6b0c4e71c104 192.168.1.12:7005 replicates 5753ea85bfdf8ca52e46161ef1038c1c1b3f04f3 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 192.168.1.10:7000) M: 5de425752b3146c4013da9f2fc068512bae15a6d 192.168.1.10:7000 slots:0-5460 (5461 slots) master M: b45f923b82d7d6684ac97006f5470b081f5d1246 192.168.1.10:7001 slots: (0 slots) master replicates 02005dfdffbd18db93af7f0d66e2e4b82fbbdea4 M: 02005dfdffbd18db93af7f0d66e2e4b82fbbdea4 192.168.1.11:7002 slots:5461-10922 (5462 slots) master M: c8c8d4266610fefdb637d786b6320f2b1f96cf96 192.168.1.11:7003 slots: (0 slots) master replicates 5de425752b3146c4013da9f2fc068512bae15a6d M: 5753ea85bfdf8ca52e46161ef1038c1c1b3f04f3 192.168.1.12:7004 slots:10923-16383 (5461 slots) master M: a5f65754933a9b70e5b11149facf6b0c4e71c104 192.168.1.12:7005 slots: (0 slots) master replicates 5753ea85bfdf8ca52e46161ef1038c1c1b3f04f3 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered
登录到redis集群 [root@localhost src]# ./redis-cli -c -h 192.168.1.10 -p 7000 192.168.1.10:7000>
|
测试
192.168.1.10:7000> set key aaa -> Redirected to slot [12539] located at 192.168.1.12:7004 OK 192.168.1.12:7004> get key "aaa" 192.168.1.12:7004> set key1 111 -> Redirected to slot [9189] located at 192.168.1.11:7002 OK 192.168.1.11:7002> get key1 "111" 192.168.1.11:7002> get key1 "111" 192.168.1.11:7002> get key -> Redirected to slot [12539] located at 192.168.1.12:7004 "aaa |