Redis3Cluster的学习笔记

redis3集群模式下的一些好处

这是官方给出的:RedisCluster提供了数据在多个redis实例中分片的方式,automatically sharded across multiple Redis nodes。Redis在数据分片上提供了一定的可用性,在某些节点宕机或者无法连接时候提供了支持。(除非大多数的主redis服务都不可用):

  1. 数据自动分片在多实例中
  2. 当少数实例宕机时候仍能继续运行

Rediscluster模式的一些注意点

Redis集群中的redis实例要求有两个tcp端口,一个用于接收客户端连接,例如6379,另外一个用于集群BUS,用于实例节点跟实例节点之间的二进制通信连接,主要用于宕机检测,配置更新,快速失效认证等。客户端连接的端口跟集群BUS的端口总是相差10000。
想要Redis集群正常工作,对于每个节点,你需要:

  1. 对于集群内的所有实例节点,客户端连接的端口必须是开放的
  2. 对于集群内的所有实例节点,BUS端口必须是开放的
    3.当前Redis集群不支持NAT环境或者IP(端口重新映射的环境)

Redis集群数据分片的形式

Redis集群不适用一致性hash,而是使用hash slot的方式将key分开来。这里有16384个hash桶在redis集群中,我们简单的使用key的CRC16值模上16384,每一个redis实例都负责redis集群中一些桶。
比如说你有三个实例节点:

  • A包含0-5500的hash桶
  • B包含5501-11000的hash桶
  • C包含11001-16384的桶

这使得添加和新增节点更加容易,如果我想要增加实例节点D,我需要把实例节点A,B,C的一些数据移动到D,如果我想要移除节点A,我只需要把节点A的数据迁移到B跟C,当A当中数据为0的时候我就可以移除节点A。
从一个几点移动hash桶到另外一个节点无需stop的操作,所以在移除新增节点,改变各个节点的百分比的时候故障时间。
Redis集群支持多key操作,即多个key在一个执行链中执行(一个事务或者一个lua脚本中),用户使用命令hash tags可以强制多key处以同一个hash桶中。Hash tags的要旨是如果在keys中有子串用大括号{},那么CRC16只会hash被大括号括住的子串。

Redis集群中的主从模式

在我们的例子中,A、B、C节点中B节点宕机,我们将会丧失5501-11000节点的数据。
假设我们给A、B、C节点加上从节点A1、B1、C1,当B节点宕机时候集群仍旧可以正常使用。B1复制B的数据,当B节点宕机时候,节点B1将会提升为主节点。更进一步,如果B1和B实例节点同时宕机,那么整个集群将无法继续操作。

Redis Cluster consistency guarantees

Redis不保证强一致性,Redis主从复制数据使用异步的方式,所以存在这种情况,你的client对B进行写,在B对B1、B2等从服务器进行复制之前B已经宕机,其中的从服务器B1或者B2成为主服务器,将会丢失你的client的写。
这也是为什么大部分redis的配置配置为每秒flush data到磁盘中,这是传统的关系型数据库跟nosql数据库区别。为了提升一致性,你可以强制要求在复制数据时候前要先flush数据到磁盘上面去,但是这么做同时也会降低性能,就降低到如同redis的同步复制数据的方式。Redis提供wait命令用于提供一致性,但是考虑到复杂的环境,我们并不推荐同步复制数据的方式。
Redis集群存在另一种明显丢失数据的场景,网络故障时候,一个client被分离为少数的至少包含一个主服务器的实例。
例如,存在三个主节点A、B、C,以及他们的从服务器节点A1、B1、C1,有一个client我们称之为Z1。
经过网络调整,被调整为A、C、A1、B1、C1,另一个是B、Z1,Z1仍旧可以往B进行写数据,Z1仍旧可以往B写数据,如果网络故障在短暂时间内恢复正常,redis将会继续正常工作;假若在B1上升为主实例节点时间内网络故障无法恢复,Z1到B的写入的数据将无法恢复。这里存一个客户端Z1往B进行写数据成功的最小窗口时间,在大部分redis的实例节点端把从节点实例上升为主节点实例后,少部分的节点将无法接受写命令的操作。
这里一个重要的redis集群配置的参数是 node timeout,node timeout时间经过后,一个主实例节点已经被认为是宕机了,该宕机的节点应该被他的从节点所代替。同样的,在nodetime out时间后,当一个主节点无法跟集群中大部分的主节点通信时候,该主节点将产生一个错误状态并停止写入操作。

Redis Cluster configuration parameters

redis集群部署相关的一些参数:

  • cluster-enabled(yes/no):启动形式,集群还是单例
  • cluster-config-file(filename):这不是用户可编辑的文件,是redis集群在集群变化时候主动保存的集群配置,用于在启动的时候重新加载。文件保存的是其他节点信息,以及节点状态,持久化的变量,这个文件在接收到信息时候会进行重写和保存。
  • cluster-node-time(毫秒):redis实例节点在超过cluster-node-time后将被认为宕机,一个主节点在cluster-node-time不可用后将会被他的从节点所代替,每一个节点在该时间内不能和主节点通信,将会停止接收查询.
  • cluster-slave-validity-factor(factor):如果设置为0,一个从服务器将总是尝试成为主服务器,而不管主从之间断开链接多少时间;如果设置为正数,最大的断开链接的时间将会是node time 乘以cluster-slave-validity-factor这个因子,如果该节点是从节点,在该因子乘积的时间经过后从节点才会尝试竞争成为主节点,当一个主服务器宕机后没有可用的从服务时候,该redis集群将不可用。
  • cluster-migration-barrier(count):一个主节点保持最小数量链接的从节点
  • cluster-require-full-coverage(yes/no):默认是yes,如果集群上面的key没有一定程度上分布到各个节点时候redis集群无法提供写服务,如果为no,不存在上述限制。

Creating and using a Redis Cluster

我们需要以集群模式启动各个redis实例,下面是redis集群模式启用的最小配置:

port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

从上面的配置文件可以看出,集群模式启用直接在cluster-enabled这个命令,默认集群运行过程中的信息是在nodes.conf文件中,该文件不允许认为修改,该文件在redis运行中是不断变化的。
最小集群模式需要3个主实例节点,如上所述,我们使用三主三从模式构建。

新建一个测试目录,我们将在该目录内进行测试。

mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005

把redis-server复制到cluster-test/700X各个目录中,依次启动

cd 7000
../redis-server ./redis.conf

启动后会输出

[82462] 26 Nov 11:56:55.329 * No cluster configuration found, I’m 97a3a64667477371c4479320d683e4c8db5858b1

因为各个redis的实例节点都不存nodes.conf文件,每个节点都会给自己生成一个新的ID。
该ID在本个集群中将会永远的运行下去,每一个节点通过ID来确认其他实例节点(而不是通过port跟ip,ip跟端口可能会改变,但是唯一的节点标示在整个节点的生命周期内将不会改变),这种ID我们称之为节点ID。

redis3安装

我们需要建立ruby执行环境,用于建立redis集群,检验,分片已存在的redis集群,使用redis提供的redis-trib集群命令工具将使我们很容易完成这项工作。
redis-trib工具是存放在src目录中,我们需要构建redis gem才能运行redis-trib。

yum install ruby
yum install rubygems
gem install redis

简单创建我们的集群模式

./redis-trib.rb create –replicas 1 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
127.0.0.1:7006 127.0.0.1:7007 127.0.0.1:7008 127.0.0.1:7009

上面例子中我们使用create这个命令,我们见创建一个新的集群,选项replicas 1代表我们为每一个主服务器创建一个从服务器,剩下的参数是一系列的cluster节点。
Redis-trib将会给你推荐配置,敲入yes表示接受,集群开始配置和加入,意味着集群中的节点与每一个节点开始通信,接收到如下信息就证明启动成功:

[OK] All 16384 slots covered

Playing with the cluster

Redis-cluster连接的客户端:redis-rb-cluster,redis-py-cluster,Jedis,thunk-redis(Node.js or IO.js),redis-go-cluster。
Redis自带的客户端redis-cli命令行工具在使用时候以选项-c启动。

$ redis-cli -c -p 7000
redis 127.0.0.1:7000> set foo bar
-> Redirected to slot [12182] located at 127.0.0.1:7002
OK
redis 127.0.0.1:7002> set hello world
-> Redirected to slot [866] located at 127.0.0.1:7000
OK
redis 127.0.0.1:7000> get foo
-> Redirected to slot [12182] located at 127.0.0.1:7002
“bar”
redis 127.0.0.1:7000> get hello
-> Redirected to slot [866] located at 127.0.0.1:7000
“world”

提示:如果使用脚本启动集群的话默认端口从30001开始。
Redis-cli的集群版支持客户端连接从一个实例节点跳转到另外一个实例节点,因为在各个实例节点缓存了slots到实例节点的映射。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值