Redis的集群模式
集群
即使使用哨兵,此时的Redis集群的每个数据库依然存有集群中的所有数据,从而导致集群的总数据存储量受限于可用存储内存最小的数据库节点,形成木桶效应。由于Redis中的所有数据都是基于内存存储,这一问题就尤为突出了尤其是当使用Redis做持久化存储服务使用时。
对Redis进行水平扩容,在旧版Redis中通常使用客户端分片来解决这个问题,即启动多个Redis数据库节点,由客户端决定每个键交由哪个数据库节点存储,下次客户端读取该键时直接到该节点读取。这样可以实现将整个数据分布存储在N个数据库节点中,每个节点只存放总数据量的1/N。但对于需要扩容的场景来说,在客户端分片后,如果想增加更多的节点,就需要对数据进行手工迁移,同时在迁移的过程中为了保证数据的一致性,还需要将集群暂时下线,相对比较复杂。考虑到Redis实例非常轻量的特点,可以采用预分片技术(presharding)来在一定程度上避免此问题,具体来说是在节点部署初期,就提前考虑后的存储规模,建立足够多的实例(如128个节点),初期时数据很少,所以每个节点存储的数据也非常少,但由于节点轻量的特性,数据之外的内存幵销并不大,这使得只需要很少的服务器即可运行这些实例。曰后存储规模扩大后,所要做的不过是将某些实例迁移到其他服务器上,而不需要对所有数据进行重新分片并进行集群下线和数据迁移了。
无论如何,客户端分片终归是有非常多的缺点,比如维护成本高,增加、移除节点较繁琐等。Redis3.0版的一大特性就是支持集群(Cluster,广义的“集群”相区别)功能。集群的特点在于拥有和单机实例同样的性能,同时在网络分区后能够提供一定的可访问性以及对主数据库故障恢复的支持。另外集群支持几乎所有的单机实例支持的命令,对于涉及多键的命令(如MGET),如果每个键都位于同一个节点中,则可以正常支持,否则会提示错误。除此之外集群还有一个限制是只能使用默认的0号数据库,如果执行SELECT切换数据库则会提示错误。
哨兵与集群是两个独立的功能,但从特性来看哨兵可以视为集群的子集,当不需要数据分片或者已经在客户端进行分片的场景下哨兵就足够使用了,但如果需要进行水平扩容,则集群是一个非常好的选择
安装步骤
安装gcc
直接用yum install 安装
解压redis 包
make
如果出现 Jemalloc/jemalloc.h:没有那个文件
执行make distclean之后再make
注意 Redis Test(可以不用执行)
make install
执行完make后,跳过Redis test 继续执行make install
目录解析
查看默认安装目录:usr/local/bin
Redis-benchmark:性能测试工具,可以在自己本子运行,看看自己本子性能如何(服务启动起来后执行)
Redis-check-aof:修复有问题的AOF文件
Redis-check-dump:修复有问题的dump.rdb文件
Redis-sentinel:Redis集群使用
redis-server:Redis服务器启动命令
redis-cli:客户端,操作入口
为了演示方便下面我用配好的集群虚拟机
首先要解决一个环境问题 点击链接 即可获取 这里就不写了
创建redis-cluster
在 /opt 下执行 mkdir redis-cluster/
修改节点配置
注意要修改六个哦 当然也可以偷懒
开启daemonize yes
cluster-enabled yes
Pid文件名字
指定端口
Log文件名字
Dump.rdb名字
Appendonly 关掉或者换名字
star-all脚本
1 |
!/bin/bash |
shutdown-all 脚本
1 |
!/bin/bash |
启动节点
拼接集群
1 |
在redis 安装目录下 src下执行命令 |
查看节点情况
分析
一个集群至少要有三个主节点。选项—replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。分配原则尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上。
增加节点
redis-trib.rb是使用CLUSTERMEET命令来使每个节点认识集群中的其他节点的,可想而知如果想要向集群中加入新的节点,也需要使用CLUSTERMEET命令实现。加入新节点非常简单,只需要向新节点(以下记作A)发送如下命令即可:
CLUSTERMEETipport
ip和port是集群中任意一个节点的地址和端口号,A接收到客户端发来的命令后,会与该地址和端口号的节点B进行握手,使B将A认作当前集群中的一员。当B与A握手成功后,B会使用Gossip协议将节点A的信息通知给集群中的每一个节点。通过这一方式,即使集群中有多个节点,也只需要选择MEET其中任意一个节点,即可使新节点最终加入整个集群中。
插槽分配
1 |
[OK] All nodes agree about slots configuration. |
•一个Redis集群包含16384个插槽(hashslot),数据库中的每个键都属于这16384个插槽的其中一个,集群使用公式CRC16(key)%16384来计算键key属于哪个槽,其中CRC16(key)语句用于计算键key的CRC16校验和。
算法
代码如下
1 |
*Copyright 2001-2010 Georges Menie (www.menie.org) |