一、为什么要弄redis集群
集群技能是构建高性能网站架构的紧张本领,试想在网站遭受高并发访问压力的同时,还必要从海量数据中查询出满意条件的数据,并快速相应,我们肯定想到的是将数据举行切片,把数据根据某种规则放入多个差别的服务器节点,来低落单节点服务器的压力。上篇redis_主从我们讲到了Redis的主从复制技能,当实现了多节点的master-slave后,我们也可以把它叫做集群,但我们本日要讲的集群重要是利用切片技能来组建的集群。我们末了盼望到达的是雷同下图:
二、实现战略
由于从3.0开始以后官方已经支持了rediscluster,https://redis.io/topics/cluster-tutorial
集群要实现的目标是要将差别的key分散放置到差别的redis节点,这里我们必要一个规则大概算法,通常的做法是获取key的哈希值,然后根据节点数来求模,但这种做法有其显着的弊端,当我们必要增长或镌汰一个节点时,会造成大量的key无法掷中,这种比例是相称高的,以是就有人提出了同等性哈希的概念。
由于官方版本是基于哈希槽(hashslot)的概念来实现的,我们还是从其官方先容中翻译表明一下:
Redis集群中内置了16384个哈希槽,当必要在Redis集群中放置一个key-value时,redis先对key利用crc16算法算出一个结果,然后把结果对16384求余数,如许每个key都会对应一个编号在0-16383之间的哈希槽,redis会根据节点数量大抵均等的将哈希槽映射到差别的节点。
利用哈希槽的长处就在于可以方便的添加或移除节点:
当必要增长节点时,只必要把其他节点的某些哈希槽挪到新节点就可以了;
当必要移除节点时,只必要把移除节点上的哈希槽挪到其他节点就行了;
三、集群实现
对于我们来说,在新增或移除节点的能做到无缝(即不必要重启集群),这点它做到了。还是来看看具体的实现吧:
新建redis_cluster文件夹下面新建6000、6100、6200三个文件夹。
把src目次下面的redis-server、redis.conf这两个文件分别拷贝到这三个目次内里,拷贝完之后就像如许子了:
[mysql@localhost6000]$ll-rw-rw-r--.1mysqlmysql116Aug2105:37redis.conf-rwxrwxr-x.1mysqlmysql7820101Aug2105:29redis-server
修改每个目次下面的redis.conf文件由于我们启动的端口是不一样的,viredis.conf删除内里的全部添加如下的:
daemonizeyes//指定以保卫进程启动port6000//启动端口cluster-enabledyescluster-config-filenodes.confcluster-node-timeout5000appendonlyyes
依次启动每一个实例文件夹下面的./redis-server./redis.conf,如许的话3个实例就启动了,但是怎样将3个实例维护成一个集群呢,在src目次下面实行:
./redis-trib.rbcreate--replicas0127.0.0.1:6000127.0.0.1:6100127.0.0.1:6200
实行以后是不是会发现实行失败提示没有redis-trib.rb文件,好吧我们还忘了装一个,由于我们实行的是ruby下令,以是还必要安装ruby:
https://rubygems.org/gems/redis下载,然后离线安装。sudogeminstallredis-3.3.1.gem--local
安装完成以后再src目次下面就有了redis-trib.rb文件。
实行上面的集群下令控制台输出如下:
来试试集群的结果吧:
在6000端口实例上测试[mysql@localhostsrc]$./redis-cli-c-p6000127.0.0.1:6000getname-Redirectedtoslot[5798]locatedat127.0.0.1:6100//发现当没有指定的key的时间会重定向到集群的别的呆板去找127.0.0.1:6100setaaa111OK127.0.0.1:6100getaaa"111"//如上索性在6100实例的呆板上面setaaa的值,然后在6200的呆板上面去查[mysql@localhostsrc]$./redis-cli-c-p6200127.0.0.1:6200getaaa-Redirectedtoslot[10439]locatedat127.0.0.1:6100//发现重定向去6100的端口的实例上找到了结果"111"//在6200的呆板上面直接重置aaa为1234127.0.0.1:6200setaaa1234-Redirectedtoslot[10439]locatedat127.0.0.1:6100//还是重定向去6100的端口的实例上更新结果OK
从上面的结果可以看出,集群中的节点是会举行通讯的,从而能找到差别的key在差别实例上,在呆板固定的环境下,key唯一时后续对其的全部更新以及查询都会映射到这一台呆板上面。
固然我们的集群的节点是不会一成稳固的,我们随时有大概扩容、缩容那该怎么来实现呢?下面来讲讲集群节点的变革吧。
四、集群变动
我们先在上面的底子上试试添加端口为6300的实例,重复操纵如上:
[mysql@localhostredis_cluster]$mkdir6300[mysql@localhostredis_cluster]$lltotal16drwxrwxr-x.2mysqlmysql4096Aug2105:406000drwxrwxr-x.2mysqlmysql4096Aug2105:406100drwxrwxr-x.2mysqlmysql4096Aug2105:406200drwxrwxr-x.2mysqlmysql4096Aug2106:276300[mysql@localhostredis_cluster]$cp../redis/redis-3.2.3/src/redis-server../redis/redis-3.2.3/redis.conf6300/
不要忘了修改redis.conf,具体设置如上文提到的。
[mysql@localhost6300]$./redis-server./redis.conf[mysql@localhost6300]$netstat-an|grep6300tcp000.0.0.0:163000.0.0.0:*LISTENtcp000.0.0.0:63000.0.0.0:*LISTENtcp00:::16300:::*LISTENtcp00:::6300:::*LISTEN
新的redis实例已经启动好了,然后必要把它加到已有的集群啦:
./redis-trib.rbadd-node127.0.0.1:6300127.0.0.1:6000
如上已经能查察到新的实例啦,为什么6300这个新的实例的connected背面没有分配hash槽呢,别慌我们还没有reshard,实行如下下令:
./redis-trib.rbreshard127.0.0.1:6300
我们想从6000节点中分配1000个hash槽位出来:
如许有hash槽了,当crc16(key)/16384的结果在该节点的地点区间时,数据就放在该节点上。
redis采取的crc16算法详见:
https://blog.csdn.net/guodongxiaren/article/details/44706613
五、如作甚每一个主节点增长从节点呢?
好吧,先创建6400端口实例看看,具体新建文件夹以及设置和重启实例我就不再讲了,上面以及有了。实行如下下令:
./redis-trib.rbadd-node--slave127.0.0.1:6400127.0.0.1:6000
我们也可以试试在从节点6400上面做set操纵:
127.0.0.1:6400setda87(error)ERRwrongnumberofargumentsfor'set'command127.0.0.1:6400setda(error)ERRwrongnumberofargumentsfor'set'command
很不幸,确实不能做set操纵会报错,从节点只能用于做读工作。
六、我们怎样来删除一个节点呢?[mysql@localhostsrc]$./redis-trib.rbdel-node127.0.0.1:6000'eb868ce2c102b897ee0a48cd8893288c36bacf5c'Removingnodeeb868ce2c102b897ee0a48cd8893288c36bacf5cfromcluster127.0.0.1:6000[ERR]Node127.0.0.1:6000isnotempty!Resharddataawayandtryagain.[mysql@localhostsrc]$
我们发现删除6000端口的实例失败了,应该是上面尚有一些数据假如直接删除就有数据丢失,我们应该把数据移到别的节点去:
./redis-trib.rbreshard127.0.0.1:6000//移除6000实例的数据然后输出了很多信息,很多数值和ID都可以从这段信息中找到。Howmanyslotsdoyouwanttomove(from1to16384)?5461会问你要移动多少个哈希槽,我们把6000上的全部哈希槽都移走,5461这个数字可以从终端上看到,大概你的实际环境不是这个数字。WhatisthereceivingnodeID?d4467ece7cca245345b71cc1f639508f4f7831c4//选定移动到6300端口的实例上面,实例IDPleaseenterallthesourcenodeIDs.Type'all'touseallthenodesassourcenodesforthehashslots.Type'done'onceyouenteredallthesourcenodesIDs.Sourcenode#1:eb868ce2c102b897ee0a48cd8893288c36bacf5c//选定移撤除6000端口的实例上面,实例IDSourcenode#2:done之后,redis列出了重新分片筹划,末了问你Doyouwanttoproceedwiththeproposedreshardplan(yes/no)?yes
中心有一些重新分配的刷屏信息省略。
[mysql@localhostsrc]$./redis-cli-p6300127.0.0.1:6300keys*1)"aaa"127.0.0.1:6300
数据移到6300实例上面啦,我们再来试试删除6000端口实例吧:
[mysql@localhostsrc]$./redis-trib.rbdel-node127.0.0.1:6000'eb868ce2c102b897ee0a48cd8893288c36bacf5c'Removingnodeeb868ce2c102b897ee0a48cd8893288c36bacf5cfromcluster127.0.0.1:6000SendingCLUSTERFORGETmessagestothecluster...SHUTDOWNthenode.[mysql@localhostsrc]$./redis-cli-c-p6000CouldnotconnecttoRedisat127.0.0.1:6000:ConnectionrefusedCouldnotconnecttoRedisat127.0.0.1:6000:Connectionrefused
终极我们还是删除乐成啦!维护一个redis集群就是这么简单。
号外号外:
如今我们公众号推出参加奖和互动奖,凡是通过微信与我们参加讨论互动最多的朋侪,将得到我们送出的秘密礼品,尚有机遇得到Ansible中文官网立刻将出书的新书哦!我们将不定期的推出嘉奖筹划!嘉奖多多,小搭档们,一起来吧!
以上是本日为各人带来的内容,假如有任何题目,各人也可以添加以下QQ群参加题目的讨论。
Ansible中文权势巨子群:372011984(已满)
AWKSED企业实战:260039357
docker企业架构实践:491533668
Jumpserver交换群:399218702
Ansible中文权势巨子-2号群:486022616
关于我们:
我要评论