redis集群原理

redis cluster在设计的时候,就考虑到了去中心化,去中间件,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。
每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。 Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。
redis cluster 默认分配了 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 。
所以我们在测试的时候看到set 和 get 的时候,直接跳转到了7001端口的节点。 Redis 集群会把数据存在一个 master 节点,然后在这个 master 和其对应的salve 之间进行数据同步。
当读取数据时,也根据一致性哈希算法到对应的 master 节点获取数据。只有当一个master 挂掉之后,才会启动一个对应的 salve 节点,充当 master 。

使用环境

解决单点固障,连接上集群中的任务一个节点都能取到数据.

安装环境

需要注意的是:reids集群从3.0开始支持的。必须要3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总节点数的一半时,整个集群就无法提供服务了
192.168.23.150 使用的docker
node1_redis 172.16.0.10
node2_redis 172.16.0.11 6个redis节点信息:
172.16.0.10:
172.16.0.10:
172.16.0.10:
172.16.0.11:
172.16.0.11:
172.16.0.11:

安装redis-3.2.8

分别在两个节点上安装redis
yum install -y gcc
tar -xf redis-3.2..tar.gz
cd redis-3.2.
make && make PREFIX=/opt/redis install
#centos7安装 make MALLOC=libc && make PREFIX=/opt/redis install
cd src 
cp redis-trib.rb /opt/redis/bin/
echo "export PATH=$PATH:/opt/redis/bin" >> /etc/profile.d/env.sh
source /etc/profile

创建redis节点

分别在两个节点上创建,别外一台是7004,,
创建目录
cd /opt/redis
mkdir -p {data,logs}/redis_cluster/{,,}
准备配置文件redis.conf
daemonize yes
  protected-mode no  #3.2 后的新特性,禁止公网访问redis cache,加强redis安全的
pidfile /opt/redis/data/redis_cluster//redis_7001.pid
port
timeout
loglevel debug
logfile /opt/redis/data/redis_cluster//redis_7001.log
databases
save
save
save
rdbcompression yes
dbfilename dump.rdb
dir /opt/redis/data/redis_cluster//
cluster-enabled yes #开启集群 把注释#去掉
cluster-config-file nodes_7001.conf #集群的配置 配置文件首次启动自动生成 ,,
cluster-node-timeout #请求超时 默认15秒,可自行设置 cp -a redis.conf /opt/redis/data/redis_cluster//
cp -a redis.conf /opt/redis/data/redis_cluster//
cp -a redis.conf /opt/redis/data/redis_cluster//
sed -i 's/7001/7001/g' /opt/redis/data/redis_cluster//redis.conf
sed -i 's/7001/7002/g' /opt/redis/data/redis_cluster//redis.conf
sed -i 's/7001/7003/g' /opt/redis/data/redis_cluster//redis.conf redis-server /opt/redis/data/redis_cluster//redis.conf
redis-server /opt/redis/data/redis_cluster//redis.conf
redis-server /opt/redis/data/redis_cluster//redis.conf

创建redis集群

安装依赖
yum -y install ruby ruby-devel rubygems rpm-build 安装ruby redis 接口
gem install redis #执行这步失败的话。可以说明的方式操作
. Fetching: redis-3.2..gem (%)
. Successfully installed redis-3.2.
. Parsing documentation for redis-3.2.
. Installing ri documentation for redis-3.2.
. Done installing documentation for redis after seconds
. gem installed
说明:由于ruby 官放提供的gem 源被GFW 干掉了,所以这里需要重新使用国内的源,方法如下:
移除自带的源:
gem sources -l
gem sources --remove https://rubygems.org/
添加国内淘宝源:
gem source --add https://ruby.taobao.org/
gem sources -l
gem install redis
 报错:redis requires Ruby version >= 2.2.2
    解决:
    方法1:采用rvm来更新ruby(不好用)
      gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
      curl -L get.rvm.io | bash -s stable
      source /usr/local/rvm/scripts/rvm
      rvm list known #查看rvm库中已知的ruby版本
rvm install 2.3.3
      rvm use 2.3.3
rvm use 2.3.3 --default #默认使用版本
rvm remove 2.0.0 #移除2.0.0版本
ruby --version #查看版本
      
      gem install redis
 方法2:编译安装(好用)
      (1)安装Ruby
      wget http://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.5.tar.gz
      tar zxvf  ruby-2.3.5.tar.gz
      cd ruby-2.3.5
      ./configure  --prefix=/opt/ruby
      make && make install
      ln -s /opt/ruby/bin/ruby /usr/bin/ruby
      ln -s /opt/ruby/bin/gem /usr/bin/gem
      ruby -v #查看版本
      (2)安装rubygem redis依赖
      wget http://rubygems.org/downloads/redis-3.3.0.gem
      gem install -l redis-3.3.0.gem
      redis-trib.rb   #出现帮助文档,说明成功了
      
创建集群
redis-trib.rb create --replicas 172.16.0.10: 172.16.0.10: 172.16.0.10: 172.16.0.11: 172.16.0.11: 172.16.0.11: #--replicas 就是这个集群节点都有一个副本

连接集群

连接方式为 redis-cli -h 172.16.0.10 -c -p   ,加参数 -c 可连接到集群,因为上面 redis.conf 将 bind 改为了ip地址,所以 -h 参数不可以省略。

集群验证

在第一台机器上连接集群的7002端口的节点,在另外一台连接7005节点,连接方式为 redis-cli -h 172.16.0.10 -c -p   
,加参数 -c 可连接到集群,因为上面 redis.conf 将 bind 改为了ip地址,所以 -h 参数不可以省略。 在7005节点执行命令:
set hello world
在7002节点执行:
get hello
在任何节点上能获取到hello的值,说明集群运作正常(注意:用keys *查看不到key.但是get hello 可以获取到值,另外可以在副本节点上面添加数据)

集群状态查看

随便登陆一个redis node节点执行命令:
redis-cli -h 172.16.0.10 -c -p #登陆
cluster nodes #查看节点信息

添加节点

添加启动个节点,步聚和上面一样
执行redis-trib.rb add-node 添加新节点:
/opt/src/redis-3.0./src/redis-trib.rb add-node 127.0.0.1: 127.0.0.1:
说明:添加新节点到群集中,需要指定群集中任意一个已存在的节点,实例中的第一个IP:PORT 为新的redis 节点的IP及端口,第二个IP:PORT 为redis 群集中已经存在的任意redis 节点。
添加完成,登陆群集,验证加入后的新节点变为主节点:
redis-cli -c -h 127.0.0.1:
. 127.0.0.1:> cluster nodes
. 1455e7fe08990793e9663ed14cf9c19778ef01a7 127.0.0.1: slave 5951f796ac2930f73b6988ccb633ab2ea10a873b connected
. 577be6355e37a54c7a076e27ab0927298abcae5f 127.0.0.1: slave 73bf492caa9ba02567581145b5d4f32f9f28e09d connected
. 30117592dc0d31b1c611ca47820f1d820565926e 127.0.0.1: slave 1e157ac10d8292661e80c6ee17f09d2dc94a4b2a connected
. 1e157ac10d8292661e80c6ee17f09d2dc94a4b2a 127.0.0.1: master - connected -
. 9868224efa99bca26a171f6e1c21dc11c4e2ab5c 127.0.0.1: master - connected
. 73bf492caa9ba02567581145b5d4f32f9f28e09d 127.0.0.1: myself,master - connected -
. 5951f796ac2930f73b6988ccb633ab2ea10a873b 127.0.0.1: master - connected -
.添加从节点:
/opt/src/redis-3.0./src/redis-trib.rb add-node --slave 127.0.0.1: 127.0.0.1:
redis-cli -c -p
. 127.0.0.1:> cluster nodes
. ef275d7c4c1f00ce236011f0c0cd7b4be7eb7772 127.0.0.1: slave 9868224efa99bca26a171f6e1c21dc11c4e2ab5c connected
. 1455e7fe08990793e9663ed14cf9c19778ef01a7 127.0.0.1: slave 5951f796ac2930f73b6988ccb633ab2ea10a873b connected
. 577be6355e37a54c7a076e27ab0927298abcae5f 127.0.0.1: slave 73bf492caa9ba02567581145b5d4f32f9f28e09d connected
. 30117592dc0d31b1c611ca47820f1d820565926e 127.0.0.1: slave 1e157ac10d8292661e80c6ee17f09d2dc94a4b2a connected
. 1e157ac10d8292661e80c6ee17f09d2dc94a4b2a 127.0.0.1: master - connected -
. 9868224efa99bca26a171f6e1c21dc11c4e2ab5c 127.0.0.1: master - connected
. 73bf492caa9ba02567581145b5d4f32f9f28e09d 127.0.0.1: myself,master - connected -
. 5951f796ac2930f73b6988ccb633ab2ea10a873b 127.0.0.1: master - connected -

数据分片转移

数据分片,也可称数据转移。由第二篇中添加的主节点可知,新的主节点没有数据,也不能参加主的选举,所以,为了该主恩能够正常被选举,我们可以将原有主节点的数据转移至该节点:
我们先来看下新主节点:

192.168.159.30:> cluster nodes
4a5799c7a7f53e8700e99be5a7a50d65c4204cac 192.168.159.30: myself,master - connected -
3d76e38836d78b0dc81ac7c0c306b57f2b6a389e 192.168.159.30: slave 4a5799c7a7f53e8700e99be5a7a50d65c4204cac connected
cc7833a44dd9f9a0157adec82e5afa959d20f29d 192.168.159.30: slave 6d377542e01a23fe5cfc7f8f25365e910480a11a connected
869458ad40bb9a2e4dcb870f3c2a4a2a2d3bc257 192.168.159.30: slave 73b5273bfa67693eeb01a5c99c855a333d6214e0 connected
9078070919bf726e213dfa634d86a5ae1f7a0ae8 127.0.0.1: slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e connected
6d377542e01a23fe5cfc7f8f25365e910480a11a 192.168.159.30: master - connected -
73b5273bfa67693eeb01a5c99c855a333d6214e0 192.168.159.30: master - connected -
456cbd75f4a74f818cb396b207b1ad6a3e4a242e 192.168.159.30: master - connected #新加节点没有数据

从上面的实例中可以很明显的看出,有三个从,四个主,当前登录的主为7003,且除了主节点7007没有数据外,其它三个主都有(7001:0-5460;7002:5461-10922;7003:10923-16383)

现在,我需要从三个节点抽取500个数据槽给新节点 7007,那么执行

redis-trib.rb reshard 127.0.0.1:

询问从1-16384 个插槽中要移动多少数据槽,我这里是500:

How many slots do you want to move (from  to )? 

询问接收数据槽节点的ID(根据上面的cluster nodes 可以得到 7007 的ID):

What is the receiving node ID? 9868224efa99bca26a171f6e1c21dc11c4e2ab5c

询问你是从所有主节点移除500 个数据槽还是单从某一个主节点中移出 500个数据槽?输入 all ,代表从所有主节点;如果要从某个节点逸出,那么只需要输入该主节点ID,回车即可:

Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #:all

输入完成,回车后开始移动数据槽

移动完成,再来看各主的数据

192.168.159.30:> cluster nodes
4a5799c7a7f53e8700e99be5a7a50d65c4204cac 192.168.159.30: myself,master - connected -
3d76e38836d78b0dc81ac7c0c306b57f2b6a389e 192.168.159.30: slave 4a5799c7a7f53e8700e99be5a7a50d65c4204cac connected
cc7833a44dd9f9a0157adec82e5afa959d20f29d 192.168.159.30: slave 6d377542e01a23fe5cfc7f8f25365e910480a11a connected
869458ad40bb9a2e4dcb870f3c2a4a2a2d3bc257 192.168.159.30: slave 73b5273bfa67693eeb01a5c99c855a333d6214e0 connected
9078070919bf726e213dfa634d86a5ae1f7a0ae8 127.0.0.1: slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e connected
6d377542e01a23fe5cfc7f8f25365e910480a11a 192.168.159.30: master - connected - -
73b5273bfa67693eeb01a5c99c855a333d6214e0 192.168.159.30: master - connected -
456cbd75f4a74f818cb396b207b1ad6a3e4a242e 192.168.159.30:7007 master - 0 1523530672367 9 connected 0-499 #很明显,主 7006 上已经被分配数据槽了!

上面是从所有主节点中平均抽取数据槽到新的主节点上。

==================对单一节点进行===========================

那么,我们也可以针对单一节点进行,比如,我想将7001 剩余的数据槽全部转移到 7007 上,那么如下:

执行:

redis-trib.rb reshard 127.0.0.1:

主节点 7001 上可以转移的数据槽:

How many slots do you want to move (from  to )? 

接收数据节点的ID:

What is the receiving node ID? 9868224efa99bca26a171f6e1c21dc11c4e2ab5c

转移数据主节点的ID(就是要把哪个节点的数据转移出去的节点ID)

Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #:73bf492caa9ba02567581145b5d4f32f9f28e09d

输完一个要转移数据的节点后,会继续要求输入第二个节点的ID。由于这里我只想转移主节点7000 上的所有数据,所以,第二个节点ID 我输入done,代表只需要转移第一个主节点:

Source node #:done

询问你是否确认要执行数据分片:

Do you want to proceed with the proposed reshard plan (yes/no)? yes

再次登录查看集群:

192.168.159.30:7003> cluster nodes
4a5799c7a7f53e8700e99be5a7a50d65c4204cac 192.168.159.30:7003 myself,master - 0 0 3 connected 11172-16383
3d76e38836d78b0dc81ac7c0c306b57f2b6a389e 192.168.159.30:7006 slave 4a5799c7a7f53e8700e99be5a7a50d65c4204cac 0 1523531456275 6 connected
cc7833a44dd9f9a0157adec82e5afa959d20f29d 192.168.159.30:7004 slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e 0 1523531457281 9 connected
869458ad40bb9a2e4dcb870f3c2a4a2a2d3bc257 192.168.159.30:7005 slave 73b5273bfa67693eeb01a5c99c855a333d6214e0 0 1523531454767 5 connected
9078070919bf726e213dfa634d86a5ae1f7a0ae8 127.0.0.1:7008 slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e 0 1523531454266 9 connected
6d377542e01a23fe5cfc7f8f25365e910480a11a 192.168.159.30:7001 master - 0 1523531453260 8 connected #可以看到7001没有数据了
73b5273bfa67693eeb01a5c99c855a333d6214e0 192.168.159.30:7002 master - 0 1523531455270 2 connected 5712-10922
456cbd75f4a74f818cb396b207b1ad6a3e4a242e 192.168.159.30:7007 master - 0 1523531452253 9 connected 0-5711 10923-11171

节点删除

redis 群集中,要删除节点,必须先将该节点的数据全部转移,否则是无法删除节点的(也就是,redis 群集中智能删除空节点):

查看集群信息:

redis-cli -h 192.168.159.30 -p  -c
192.168.159.30:> cluster nodes
3d76e38836d78b0dc81ac7c0c306b57f2b6a389e 192.168.159.30: slave 4a5799c7a7f53e8700e99be5a7a50d65c4204cac connected
9078070919bf726e213dfa634d86a5ae1f7a0ae8 127.0.0.1: slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e connected
456cbd75f4a74f818cb396b207b1ad6a3e4a242e 127.0.0.1: master - connected - -
869458ad40bb9a2e4dcb870f3c2a4a2a2d3bc257 192.168.159.30: slave 73b5273bfa67693eeb01a5c99c855a333d6214e0 connected
cc7833a44dd9f9a0157adec82e5afa959d20f29d 192.168.159.30: slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e connected
6d377542e01a23fe5cfc7f8f25365e910480a11a 127.0.0.1:7001 myself,master - 0 0 8 connected #7001没有数据
73b5273bfa67693eeb01a5c99c855a333d6214e0 192.168.159.30: master - connected -
4a5799c7a7f53e8700e99be5a7a50d65c4204cac 192.168.159.30: master - connected -

我们来尝试删除某个带有数据的主节点:

[root@docker1 ~]# redis-trib.rb del-node 127.0.0.1: '73b5273bfa67693eeb01a5c99c855a333d6214e0'
>>> Removing node 73b5273bfa67693eeb01a5c99c855a333d6214e0 from cluster 127.0.0.1:
[ERR] Node 127.0.0.1:7002 is not empty! Reshard data away and try again #7002是随便哪个能连上集群的端口,后面的是非空数据的节点ID. 可以看出非空的节点不能删除

再次删除空节点:

redis-trib.rb del-node 127.0.0.1: '6d377542e01a23fe5cfc7f8f25365e910480a11a'
>>> Removing node 6d377542e01a23fe5cfc7f8f25365e910480a11a from cluster 127.0.0.1:
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node. 注:在删除节点时,不允许使用 redis-trib.rb del-node 删除节点IP:PORT '删除节点的ID'.只能用其它节点IP:PORT '要删除节点的ID'

验证被删除:

[root@docker1 ~]# redis-cli -h 192.168.159.30 -p  -c
192.168.159.30:> cluster nodes
cc7833a44dd9f9a0157adec82e5afa959d20f29d 192.168.159.30: slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e connected
9078070919bf726e213dfa634d86a5ae1f7a0ae8 192.168.159.30: slave 456cbd75f4a74f818cb396b207b1ad6a3e4a242e connected
456cbd75f4a74f818cb396b207b1ad6a3e4a242e 192.168.159.30: master - connected - -
869458ad40bb9a2e4dcb870f3c2a4a2a2d3bc257 192.168.159.30: slave 73b5273bfa67693eeb01a5c99c855a333d6214e0 connected
73b5273bfa67693eeb01a5c99c855a333d6214e0 192.168.159.30: myself,master - connected -
4a5799c7a7f53e8700e99be5a7a50d65c4204cac 192.168.159.30: master - connected -
3d76e38836d78b0dc81ac7c0c306b57f2b6a389e 192.168.159.30: slave 4a5799c7a7f53e8700e99be5a7a50d65c4204cac connected 注#可以看出7001已经被删除了,上面删除的id就是7001的

redis集群-4的更多相关文章

  1. Redis集群案例与场景分析

    1.背景 Redis的出现确实大大地提高系统大并发能力支撑的可能性,转眼间Redis的最新版本已经是3.X版本了,但我们的系统依然继续跑着2.8,并很好地支撑着我们当前每天5亿访问量的应用系统.想当年 ...

  2. Java Spring mvc 操作 Redis 及 Redis 集群

    本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5941953.html 关于 Redis 集群搭建可以参考我的另一篇文章 Redis集群搭建与简单使用 R ...

  3. Redis集群搭建与简单使用

    介绍安装环境与版本 用两台虚拟机模拟6个节点,一台机器3个节点,创建出3 master.3 salve 环境. redis 采用 redis-3.2.4 版本. 两台虚拟机都是 CentOS ,一台 ...

  4. window下使用Redis Cluster部署Redis集群

    日常的项目很多时候都需要用到缓存.redis算是一个比较好的选择.一般情况下做一个主从就可以满足一些比较小的项目需要.在一些并发量比较大的项目可能就需要用到集群了,redis在Windows下做集群可 ...

  5. Redis集群~windows下搭建Sentinel环境及它对主从模式的实际意义

    回到目录 关于redis-sentinel出现的原因 Redis集群的主从模式有个最大的弊端,就是当主master挂了之前,它的slave从服务器无法提升为主,而在redis-sentinel出现之后 ...

  6. [个人翻译]Redis 集群教程(中)

    上一篇:http://www.cnblogs.com/li-peng/p/6143709.html 官方原文地址:https://redis.io/topics/cluster-tutorial  水 ...

  7. [个人翻译]Redis 集群教程(上)

    官方原文地址:https://redis.io/topics/cluster-tutorial  水平有限,如果您在阅读过程中发现有翻译的不合理的地方,请留言,我会尽快修改,谢谢.        这是 ...

  8. Redis集群(九):Redis Sharding集群Redis节点主从切换后客户端自动重新连接

    上文介绍了Redis Sharding集群的使用,点击阅读 本文介绍当某个Redis节点的Master节点发生问题,发生主从切换时,Jedis怎样自动重连新的Master节点 ​一.步骤如下: 1.配 ...

  9. Redis集群(八):Redis Sharding集群

    一.Redis目前的集群方案主要有两种:Redis Sharding和Redis Cluster 1.Redis Sharding:3.0以前基本上使用分片实现集群,目前主流方案,客户端实现 2.Re ...

  10. Redis-Sentinel(Redis集群监控管理)

    Redis的高可用方案的实现:主从切换以及虚拟IP或客户端 从Redis 2.8开始加入对Sentinel机制从而实现了服务器端的主从切换,但目前尚未发现实现虚拟IP或客户端切换方案 Redis-Se ...

随机推荐

  1. 【Java】时间戳与Date相互转换

    时间戳转Date public static void main(String[] args) { // 10位的秒级别的时间戳 long time1 = 1527767665; String res ...

  2. [CSP-S模拟测试]:Star Way To Heaven(最小生成树Prim)

    题目描述 小$w$伤心的走上了$Star\ way\ to\ heaven$. 到天堂的道路是一个笛卡尔坐标系上一个$n\times m$的长方形通道(顶点在$(0,0)$和$(n,m)$),小$w$ ...

  3. (选做)实现mypwd

    选做 实现mypwd 实验内容: 1.学习pwd命令. 2.研究pwd实现需要的系统调用(man -k; grep),写出伪代码. 3.实现mypwd. 4.测试mypwd. 实验步骤: 学习pwd命 ...

  4. ARM架构授权和IP核授权有什么不一样啊?

    比如,华为分别拿到这2个授权,能做的有什么区别啊? 匿名 | 浏览 2976 次 推荐于2016-06-09 02:43:35   最佳答案   一个公司若想使用ARM的内核来做自己的处理器,比如苹果 ...

  5. linux下不同服务器间数据传输(rcp,scp,rsync,ftp,sftp,lftp,wget,curl)

    因为工作原因,需要经常在不同的服务器见进行文件传输,特别是大文件的传输,因此对linux下不同服务器间数据传输命令和工具进行了研究和总结.主要是rcp,scp,rsync,ftp,sftp,lftp, ...

  6. Leaflet-Leafletv0.7使用leaflet-bing-layer

    digidem/leaflet-bing-layer: Bing Maps Layer for Leaflet v1.0.0:从标题就可以看出要Leaflet v1.0.0才能用.其实leaflet ...

  7. Xcode 10如何打包ipa包?

    参考: https://www.jianshu.com/p/0421b3fd2470 前置条件 首先导入证书和配置文件 具体操作步骤: product>>Archive 如图所示,选择Di ...

  8. mac 上查看python3的各种安装路径

    1.mac chromedriver的安装目录:/usr/local/bin 2.mac htmltestrunner的存放目录:命令行下 import sys sys.path/Library/Fr ...

  9. python面试题之简要描述Python的垃圾回收机制(garbage collection)

    这里能说的很多.你应该提到下面几个主要的点: Python在内存中存储了每个对象的引用计数(reference count).如果计数值变成0,那么相应的对象就会小时,分配给该对象的内存就会释放出来用 ...

  10. 空类的sizeof,有一个虚函数的类的sizeof

    今天面试,忽然被问到这个题目,查了一下果然有欸. #include <iostream> using namespace std; class A { }; class B { publi ...