0.学习准备:
参考资料
参考视频:慕课网教程《Redis从入门到高可用》
参考教程:http://www.redis.net.cn/tutorial/3501.html
Redis命令参考手册:http://redisdoc.com/
w3cschoolRedis教程:https://www.w3cschool.cn/redis/nma27f21.html
参考博客:
https://blog.csdn.net/sunhuiliang85/article/details/74800001?utm_source=gold_browser_extension记录一些动力节点的视频未涉及到的知识点。
包括:- 呼唤集群
- 数据分布
- 集群原生搭建
- 使用Ruby工具搭建
1.呼唤集群
- 为什么要呼唤集群:
- 并发量不足:默认是10万QPS(没有太多慢查询的情况下),如果超过10万就需要集群。
- 数据量不足:单台机器的存储容量不足。
- 网络流量的需求过大。
- 解决方案:
- 早期的解决方案,配置更强大的机器。(很贵)
- 正确的解决方案,分布式集群。简单解释就是加机器。
- Redis在3.0的时候提供了分布式的支持。
- 在集群中只有db0,没有db1到db15这些数据库。
2.数据分布
1)数据分区:
- 数据分区示意图:
但是如何去设计一个分区是非常重要的。 - 主要的分布方式:
顺序分布,哈希分布(使用哈希函数将数据打散但是均匀分布) - 两种数据分布方式的区别:
注意上图有误的一个地方,顺序分布是不支持批量操作的。 - 因为是Redis Cluster,所以主要介绍Hash分布,主要有三种分区方式:(前两种是客户端的分区)
- 节点取余分区
- 一致性哈希分区
- 虚拟槽分区(Redis Cluster的分区方式)
2)节点取余分区:
- hash(key)%nodes
nodes是节点数量,将数据放到余数对应的节点中。
如:
三个节点:hash(key)%3
四个节点:hash(key)%4 - 有一个问题,如果需要增加一个节点:
如从3个节点变成4个节点,那么几乎所有的数据都需要进行回写,数据迁移率达80%。
回写:访问某节点无数据,重新查询并写入缓存。 - 所以这种节点取余分区建议使用多倍扩容的方式:
使用翻倍扩容,如2个变为4个,3个变6个,则数据回写会降低为50%: - 迁移数据之后是无法从缓存中读取到的,所以会从数据库查询之后再进行缓存的回写,大量的回写是很不正常的。
- 总结:
- 客户端分片:哈希+取余
- 缺点:节点伸缩导致数据大量回写
- 最好使用翻倍扩容
- 是一些很早的分布式缓存的使用方式
3)一致性哈希分区:
- 在memcache中使用广泛。
- 示意图:
key进行哈希计算后落在某一个位置,然后进行顺时针查找节点并存入。 - 如果再添加一个节点,则示意图如下:
仍然有数据回写,但是影响范围非常小,只影响了node1和node2之间的部分数据。
尤其是在节点非常多的情况下,效果非常好。 - 这种方式也是一种数据回写的过程,原来在n2中的部分数据就变成垃圾了,客户端访问node5,没有数据,进行数据回写。不会将原有的数据迁移到新节点。
- 一致性哈希总结:
- 客户端分片:哈希+顺时针(优化取余)
- 节点伸缩:只影响临近节点,但还是有数据回写
- 翻倍伸缩:可以保证最小迁移数据和负载均衡
4)虚拟槽分区:
- Redis Cluster的方式
- 特点:
- 预设虚拟槽,每一个槽映射一个数据子集,一般比节点大
- 良好的哈希函数,如CRC16等
- 服务端管理节点,槽,数据
- 虚拟槽方式示意图:
说明:
如图将槽范围分为了5份分给5个节点,然后key进行CRC16哈希函数操作后算出一个值,然后按照该值去选择节点保存。
客户端查数据时key会访问一个节点,节点之间共享消息,如果选择节点不是对应节点,那个节点会返回对应的节点号。
Redis Cluster默认指定的槽的数量就是16384。 - 增加新节点时从现有的节点分配,并且将数据也一起分配
- 暂时不用了解那么清楚,因为后面Redis Cluster都是虚拟槽分区的运用
3.集群架构与安装架构
1)集群架构简介:
- 单机架构示意图:
- 分布式架构示意图:
每个节点之间是通过GOSSIP协议相互通信的。可以互相感知到对应节点所负责的槽,且每个节点都知道哪个槽是交给哪个节点负责的。而且客户端也需要知道。
2)Redis Cluster的安装架构:(不包括节点伸缩)
- 主要元素:
- 节点:nodes
- meet操作:节点间相互通信的基础
- 指派槽:优先访问该槽
- 复制:保证高可用(每个主节点都有一个备节点)
但是这种时候的内部监控不是依赖Sentinel,而是通过他们节点之间的交互。
- 主要元素的实现:
节点:通过配置cluster-enabled:yes
,来配置是否是集群的模式。
meet:AmeetB则AB可以进行通信,相当于PING
而如果AmeetB,BmeetC,AC也可以进行通信(gossip协议)
指派槽:对应可以访问过来时有数据返回数据,无数据返回对应的槽的节点 - RedisCluster的特定:
- 主从复制
- 高可用
- 安装方式:
- 原生命令安装:节点,meet,分配槽,搭配主从
- 官方工具安装:Ruby工具一键安装,只能实现简单配置
- 理解安装过程:
其实就是上述安装框架的四个步骤
4.Redis Cluster原生命令的安装方式
1)RedisCluster源生命令安装:简单过程
- 配置开启节点:配置模板(集群需要的最简配置)
最好配置六个,三对主从。port ${port} daemonize yes dir "/opt/redis/redis/data" //目录,可以随意指定 logfile "${port}.log" dbfilename "dump-${port}.rdb" //是否开启集群 cluster-enabled yes //节点配置文件 cluster-config-file nodes-${port}.conf
- Cluster节点的主要配置:
cluster-enabled yes cluster-node-timeout 15000 //很多作业,可以简单认为是故障转移时间 cluster-config-file "node.file" //节点配置文件(单机多部署则用端口号区分),用于记录集群信息 cluster-require-full-coverage no //一个节点坏掉则对外不提供服务,默认yes,一般配置为no
- 开启节点:
# redis-server redis-port.conf
- 使用meet使各个节点产生通信:
如有六个节点则最少要执行五次meet操作。cluster meet ip port
- 分配槽:
一共16384个节点,而有6个三组节点(7001~7006),所以这样分:cluster addslots slot[slot]
0~5461一组分配给7001节点,
5462~10922一组分配给7002节点,
10923~16383一组分配给7003节点。 - 判断集群是否设置成功,并可以对外提供服务。
- 设置主从关系:
node-id指的是节点的id,在节点启动时会自动分配。cluster replicate node-id
node-id和run-id是不同的,它不会因为节点重启而改变。 - 原生安装了解过程就可以,不必精通
2)配置节点:
- 配置redis-7000.conf:集群的最低配置
配置图:port 7000 daemonize yes dir "./" logfile "node7000.log" dbfilename "dump7000.rdb" cluster-enabled yes cluster-node-timeout 15000 cluster-config-file nodes-7000.conf cluster-require-full-coverage no //所有节点密码需要一致 masterauth 123456 requirepass 123456
- 快速生成其他5个节点的配置:
# sed 's/7000/7001/g' redis-7000.conf > redis-7001.conf
以此类推,生成7000~7005这六个节点 - 注意设置了密码的情况一定要设置
这两项,而且每个节点的密码也最好相同。可以像这样直接在配置文件中配置的。但是这样需要重启Redis服务,这里我还没启动所以这样配置。masterauth password requirepass password
如果要动态配置则可以在该端口客户端使用如下命令配置:
这样就可以不用重启进行配置了。config set masterauth passwd123 config set requirepass passwd123 config rewrite
- 启动这些节点的redis服务:
后面有个cluster说明是集群节点。 - 注意如果节点很多的话可以写个脚本来完成。
- 如果这时候使用客户端并执行某些操作(如get,set),会抛出一个错误:
这表明当前集群时下线的,不可用的。因为现在仅仅开启了Redis服务,集群还没有搭建好。(error)CLUSTERDOWN The cluster is down
- 可以在客户端下执行以下命令查看一些信息:
cluster nodes
:查看配置信息,交互节点信息cluster info
:查看集群信息(状态,是否分配槽等)
如下图:
3)配置meet节点交互(节点握手):
- 语法:在客户端下
ip就是想握手的节点的ip,port就是端口。cluster meet ip port
最好从单一节点的客户端出发,这样到其他节点只需要执行n-1次握手。 - 测试:
重复握手并不报错。 - 在客户端执行
cluster nodes
命令可以查看与该节点达成交互的节点:
说明整个集群已经达到了一种互通的效果。
还可以执行cluster info
命令查看一些其他信息。 - 但是此时,集群没有分配槽,依然不可以进行读写:
4)分配槽:
- 在需要分配槽的节点客户端下执行命令:
这样就可以将0这个槽分配给这个端口的节点。cluster addslots 0
但是如果要分配0~5461个槽分配到这个端口,就需要一个一个进行分配,这时就需要使用shell脚本了。 - 编写shell脚本addslots.sh如下:
# 起始终止slots start=$1 end=$2 # 端口 port=$3 for slot in `seq ${start} ${end}` do redis-cli -p ${port} -a "123456" cluster addslots ${slot} done
- 首先确定好主从关系再进行分配槽:
假设7000,7001,7002是主节点,
7003,7004,7005是对应的从节点。 - 根据确定的主从关系来执行上述shell脚本:
要执行好长好长好长时间(绝不夸张)。sh addslots.sh 0 5461 7000 sh addslots.sh 5462 10922 7001 sh addslots.sh 10923 16383 7002
仅了解这么做就行了,直到原理,实际生产过程中不会使用原生方式的,即容易出错,又耗费时间。 - 若仅分配完一部分槽,集群的状态依然是失败的。
只有当所有的槽都分配完毕了才算成功。 - 集群完毕后随便使用哪个客户端,使用
cluster info
以及cluster nodes
命令查看节点状态:
已经OK了,说明这时就可以使用读写命令了。 - 但是还需要一步:主从复制
- 补充:还可以使用
cluster slots
查看槽的分配信息及主从关系。
5)配置主从关系:
- 命令:在从节点下(7003,7004,7005)客户端执行
这个node-id可以使用cluster nodes看到,就是ip前的那一大串。cluster replicate node-id
也可以直接使用:
来执行客户端命令。redis-cli -p 从节点端口 -a "密码" cluster replicate nodeid
- 操作如下:
操作成功。 - 使用
cluster slots
及cluster info
查看槽及主从信息: - 这样子就大功告成啦。
6)如何使用:
- 客户端命令:
redis-cli -c -h ip -p port
在使用时会根据所在的槽口自动进行节点的跳转。
如果不加-c参数则跳转时会报错,如下:(error) MOVED 12182 172.0.0.1:7002
- 搭建好的集群,所有服务关闭后重启不需要重新搭建
- 测试:
- 注意一个很重要的问题:
一定要在第一次连接客户端时使用参数-a来输密码,而不是进去之后再输,否则就会出现这种情况:
卡了我一晚上。。。而且查遍全网也查不出问题。。。
5.在Linux下安装Ruby环境
1)查看是否安装Ruby
- 使用Ruby工具搭建Redis集群需要使用redis-trib.rb
- redis-trib.rb安装(针对Redis集群的)简单分为三步:
- 下载,编译,安装Ruby
- 安装rubygem redis(ruby对Redis的客户端)
- 安装redis-trib.rb
- 首先查看是否安装了Ruby:
或者直接rpm -qa | grep ruby yum list | grep ruby
man ruby
或者ruby -v
很幸运,我的安了,但是默认都是安装的Ruby2.0.0,想要安装更高版本。 - 下面介绍安装高版本Ruby的三种方式。
2)方式一:手动下载解压编译安装
- 下载并解压Ruby:
过程和Redis的非常相似
下载:
或者在Windows中下载后传过去。# wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.gz
如果没有用yum,则需要解压,编译(make),安装(make install)。
解压:# tar -zxvf ruby-2.5.1.tar.gz
- 移动到Ruby目录:
跳转到ruby2.5.1# cd ruby2.5.1
- 配置,编译,安装
源码安装一般有这三个步骤:配置(configure)、编译(make)、安装(make install)
配置:
编译:(时间可能有点长)# ./configure --prefix=/opt/ruby
安装:# make
这时Ruby就安装到了/opt/ruby目录下了。# make install
- 使用软连接或者cp复制将系统自带的Ruby相关命令覆盖:
为什么要覆盖呢:
跳转到/opt/ruby目录执行如下操作:
发现默认的ruby命令还是系统自带的。
(注意另个-f参数都是强制替换,如果不想替换掉原来的建议换名字)
可以使用软连接覆盖/usr/bin中的可执行文件:
也可以使用cp覆盖:# ln -sf /opt/ruby/bin/ruby /usr/bin/ruby # ln -sf /opt/ruby/bin/gem /usr/bin/gem
替换完毕再执行:ruby -v# cp -f /opt/ruby/bin/ruby /usr/bin/ruby # cp -f /opt/ruby/bin/gem /usr/bin/gem
3)方式二:切换yum安装源安装
- 使用yum安装的Ruby默认也是2.0.0版本的
- 具体安装步骤如下:
切换安装源:
安装并配置:# yum install centos-release-scl-rh //会在/etc/yum.repos.d/目录下多出一个CentOS-SCLo-scl-rh.repo源
# yum install rh-ruby23 -y # scl enable rh-ruby23 bash
- 这几步执行完毕就可以了。未测试。
4)方式三:RVM 安装(脚本安装)
- 先执行一条官方 https://rvm.io/ 复制来的长命令(…C0E3空格7D2B…):
# gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
- 然后执行命令(连接):
# \curl -sSL https://get.rvm.io | bash -s stable
- 进行安装:
按提示执行:
查看哪些可安装版本:# source /etc/profile.d/rvm.sh
安装某版本ruby,直接跟版本号即可:# rvm list known
# rvm install 2.5.1
- 使用
ruby-v
,gem-v
查看是否安装成功。 - 更加具体生动的(带图片的)过程可以访问大佬博客:
https://www.cnblogs.com/ding2016/p/7903147.html
6.使用Ruby工具搭建集群
1)安装redis-trib.rb:
- redis-trib.rb安装简单分为三步:(上面已经安装了Ruby环境了)
- 下载,编译,安装Ruby
- 安装rubygem redis(ruby对Redis的客户端)
- 安装redis-trib.rb
- 安装rubygem redis客户端
或者使用wget来下载安装:# gem install redis --version 4.0.0
如果gem install报错,可以查看Redis解决方案或者博客:# wget http://rubygems.org/downloads/redis-4.0.0.gem # gem install -l redis-4.0.0.gem
https://blog.csdn.net/feinifi/article/details/78251486
安装成功:
确认一下:
可以查看本机所安装的包:# gem list -- check redis gem
- 查看是否有redis-trib.rb:
- 查看是否能使用该命令:
create是搭建一个集群
reshard是集群扩展
rebalance是负载均衡 - 设置软连接到/usr/bin:
# ln -sf /usr/local/redis/src/redis-trib.rb /usr/local/bin/redis-trib.rb
- 使用redis-trib.rb看看是否成功
能弹出和上面一样的用法提示说明成功了 - 下面就可以使用该命令去自动化搭建集群了
2)第一步:配置开启几个Redis服务(8000-8005)
- 创建8000节点配置文件redis-8000.conf配置如下:
其余节点相同:port 8000 cluster-enabled yes cluster-config-file "nodes-8000.conf" cluster-node-timeout 15000 dir "./" appendonly yes appendfilename "appendonly-8000.aof" logfile "node-8000.log" daemonize yes pidfile "/var/run/redis-8000.pid" dbfilename "dump-8000.rdb" cluster-require-full-coverage no masterauth 123456 requirepass 123456
# sed 's/8000/8001-5/g' redis-7000.conf > redis-8001-5.conf
具体的创建过程就不截图了。 - 开启这些服务:
查看进程:# redis-server redis-8000.conf # redis-server redis-8001.conf # redis-server redis-8002.conf # redis-server redis-8003.conf # redis-server redis-8004.conf # redis-server redis-8005.conf
- 如果像我一样配置了密码,你还需要以下几步进行配置:
使用gem env
查看gem path:这是你的软件安装路径
可以看到我的路径(第一个)是/opt/开头的,那么久修改它:
修改password:# vim ${你的地址}/gems/redis-4.0.0/lib/redis/client.rb
3)第二步,一键搭建,完成了
- 一键搭建Redis集群:
–replicas后面的# redis-trib.rb create --replicas 1 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
1
代表每个主节点有一个从节点。
如果太多节点还是写个shell脚本吧。 - 中间可能需要输入一个yes确认:
创建完成: - 测试是否搭建成功:
牛逼,大功告成。 - 注意,如果节点非常多的话,这种方式也不是一个非常好的方式,最好搭建一个云平台,来对各种数据进行管理。我看《Redis运行与维护》那本书上有讲,有空买一本学习学习。
最后更新: 2018年04月27日 13:26
原始链接: https://zjxkenshine.github.io/2018/04/25/Redis学习笔记(八):Redis Cluster集群/