当前位置: 首页 > news >正文

redis 集群

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

复制的问题

由于复制中,每个数据库都是拥有完整的数据,因此复制的总数据存储量,受限于

内存最小的数据库节点,如果数据量过大,复制就无能为力了。

一,分片

分片(Partitioning)就是将你的数据拆分到多个Redis实例的过程,这样每个

Redis实例将只包含完整数据的一部分。常见的分片方式:

1:按照范围分片

2:哈希分片,比如一致性哈希

二, 常见的分片实现:

1:在客户端进行分片

2:通过代理来进行分片,比如:Twemproxy

3:查询路由:就是发送查询到一个随机实例,这个实例会保证转发你的查询到正确的节点,

Redis集群在客户端的帮助下,实现了查询路由的一种混合形式,请求不是直接从Redis实

例转发到另一个,而是客户端收到重定向到正确的节点

4:在服务器端进行分片, Redis采用哈希槽(hash slot)的方式在服务器端进行分片:

Redis集群有16384个哈希槽,使用键的CRC16编码对16384取模来计算一个键所属的哈希槽

三,Redis分片的缺点

1:不支持涉及多键的操作,如mget,如果所操作的键都在同一个节点,就正常执行,否则会提示错误

2:分片的粒度是键,因此每个键对应的值不要太大

3:数据备份会比较麻烦,备份数据时你需要聚合多个实例和主机的持久化文件

4:扩容的处理比较麻烦

5:故障恢复的处理会比较麻烦,可能需要重新梳理Master和Slave的关系,并调整每个复制集里面的数据

四, 集群

由于数据量过大,单个复制集难以承担,因此需要对多个复制集进行集群,形成水平扩展,每个

复制集只负责存储整个数据集的一部分,这就是Redis的集群。

1:在以前版本中,Redis的集群是依靠客户端分片来完成,但是这会有很多缺点,比如维护成本高,需要客

户端编码解决;增加、移出节点都比较繁琐等

2:Redis3.0新增的一大特性就是支持集群,在不降低性能的情况下,还提供了网络分区后的可访问性和支

持对主数据库故障的恢复。

3:使用集群后,都只能使用默认的0号数据库

4:每个Redis集群节点需要两个TCP连接打开,正常的TCP端口用来服务客户端,例如6379,加10000的端口

用作数据端口,必须保证防火墙打开这两个端口

5:Redis集群不保证强一致性,这意味着在特定的条件下,Redis集群可能会丢掉一些被系统收到的写入请

求命令。

五,集群架构

195635_dSpa_2540936.jpg

1:所有的Redis节点彼此互联,内部使用二进制协议优化传输速度和带宽

2:节点的fail是通过集群中超过半数的节点检测失效时才生效

3:客户端与Redis节点直连,不需要中间proxy层。客户端不需要连接集群所有节点,连接集

群中任何一个可用节点即可

4:集群把所有的物理节点映射到[0-16383]插槽上,集群负责维护:节点-插槽-值的关系

六,集群操作基本命令

1:CLUSTER INFO:获取集群的信息

2:CLUSTER NODES:获取集群当前已知的所有节点,以及这些节点的相关信息

3:CLUSTER MEET <ip> <port>:将ip和port所指定的节点添加到集群当中

4:CLUSTER FORGET <node_id>:从集群中移除node_id 指定的节点

5:CLUSTER REPLICATE <node_id>:将当前节点设置为node_id 指定的节点的从节点

6:CLUSTER SAVECONFIG:将节点的配置文件保存到硬盘里面

7:CLUSTER ADDSLOTS <slot> [slot ...]:将一个或多个槽分配给当前节点

8:CLUSTER DELSLOTS <slot> [slot ...]:从当前节点移除一个或多个槽

9:CLUSTER FLUSHSLOTS:移除分配给当前节点的所有槽

10:CLUSTER SETSLOT <slot> NODE <node_id>:将槽分配给node_id 指定的节点,如果槽已经分配给另一

个节点,那么先让另一个节点删除该槽>,然后再进行分配

11:CLUSTER SETSLOT <slot> MIGRATING <node_id>:将本节点的槽迁移到指定的节点中

12:CLUSTER SETSLOT <slot> IMPORTING <node_id>:从指定节点导入槽到本节点

13:CLUSTER SETSLOT <slot> STABLE:取消对槽的导入(import)或迁移(migrate)

14:CLUSTER KEYSLOT <key>:计算键key 应该被放置在哪个槽

15:CLUSTER COUNTKEYSINSLOT <slot>:返回槽目前包含的键值对数量

16:CLUSTER GETKEYSINSLOT <slot> <count>:返回count 个槽中的键

17:migrate 目的节点ip 目的节点port 键名数据库号码超时时间[copy] [replace]:迁移某个键值对

七,手工创建集群

1:首先进行集群配置

只需要将每个数据库的cluster-enabled配置选项打开,然后再修改如下内

容:pidfile、port、logfile、dbfilename、cluster-config-file

2:分别启动这些Redis数据库,可以用info cluster查看信息

3:连接节点,使用cluster meet,把所有的数据库都放到一个集群中来

4:可以通过cluster info ,或者cluster nodes 查看信息

5:设置部分数据库为slave,使用cluster replicate

6:然后就该来分配插槽了,使用cluster addSlots,这个命令目前只能一个一个

加,如果要加区间的话,就得客户端编写代码来循环添加。

有个实用的技巧:把所有的Redis停下来,然后直接修改node的配置文件,

只需要配置master的数据库就可以,然后再重启数据库。

分配完插槽,可以使用cluster slots查看信息。

7:通过cluster info查看集群信息,如果显示ok,那就可以使用了

八,(1),什么是插槽

插槽是Redis对Key进行分片的单元。在Redis的集群实现中,内置了数据自动分片机

制,集群内部会将所有的key映射到16384个插槽中,集群中的每个数据库实例负责其中部

分的插槽的读写。

(2),键与插槽的关系

Redis会将key的有效部分,使用CRC16算法计算出散列值,然后对16384取余数,从

而把key分配到插槽中。键名的有效部分规则是:

1:如果键名包含{},那么有效部分就是{}中的值

2:否则就是取整个键名

n 移动已分配的插槽

(3),这个稍微麻烦点,尤其是有了数据过后,假设要迁移123号插槽从A到B,大致步骤如下:

1:在B上执行cluster setslot 123 importing A

2:在A上执行cluster setslot 123 migrating B

3:在A上执行cluster getkeysinslot 123 要返回的数量

4:对上一步获取的每个键执行migrate命令,将其从A迁移到B

5:在集群中每个服务器上执行cluster setslot 123 node B

避免在移动已分配插槽过程中,键的临时丢失

上面迁移方案中的前两步就是用来避免在移动已分配插槽过程中,键的临

九,(1)时丢失问题的,大致思路如下:

1:当前两步执行完成后,如果客户端向A请求插槽123中的键时,如果键还未被转

移,A将处理请求

2:如果键已经转移,则返回,把新的地址告诉客户端,客户端将发起新的请求以获

取数据

(2)获取插槽对应的节点

当客户端向某个数据库发起请求时,如果键不在这个数据库里面,将会返

回一个move重定向的请求,里面包含新的地址,客户端收到这个信息后,需要重

新发起请求到新的地址去获取数据。

当然,大部分的Redis客户端都会自动去重定向,也就是这个过程对开发人

员是透明的。

redis-cli也支持自动重定向,只需要在启动时加入-c 的参数。

十,故障判定

1:集群中每个节点都会定期向其他节点发出ping命令,如果没有收到回复,就认为

该节点为疑似下线,然后在集群中传播该信息

2:当集群中的某个节点,收到半数以上认为某节点已下线的信息,就会真的标记该

节点为已下线,并在集群中传播该信息

3:如果已下线的节点是master节点,那就意味着一部分插槽无法写入了

4:如果集群任意master挂掉,且当前master没有slave,集群进入fail状态

5:如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态

6:当集群不可用时,所有对集群的操作做都不可用,收到CLUSTERDOWN The

cluster is down错误信息

十一,(1)故障恢复

发现某个master下线后,集群会进行故障恢复操作,来将一个slave变成master,基

于Raft算法,大致步骤如下:

1:某个slave向集群中每个节点发送请求,要求选举自己为master

2:如果收到请求的节点没有选举过其他slave,会同意

3:当集群中有超过节点数一半的节点同意该slave的请求,则该Slave选举成功

4:如果有多个slave同时参选,可能会出现没有任何slave当选的情况,将会等待一个随机时

间,再次发出选举请求

5:选举成功后,slave会通过slaveof no one命令把自己变成master

如果故障后还想集群继续工作,可设置cluster-require-full-coverage为no,默认yes

(2)对于集群故障恢复的说明

1:master挂掉了,重启还可以加入集群,但挂掉的slave重启,如果对应的master变化了,是

不能加入集群的,除非修改它们的配置文件,将其master指向新master

2:只要主从关系建立,就会触发主和该从采用save方式持久化数据,不论你是否禁止save

3:在集群中,如果默认主从关系的主挂了并立即重启,如果主没有做持久化,数据会完全丢

失,从而从的数据也被清空

十三,(1),使用redis-trib.rb来操作集群

redis-trib.rb是Redis源码中提供的一个辅助工具,可以非常方便的来操作集群,它是用

ruby写的,因此需要在服务器上安装相应环境

1:安装Ruby

(1)下载ruby安装包,地址https://www.ruby-lang.org/en/downloads/

(2)然后分别configure、make、make install

(3)安装后通过ruby -v 查看一下版本,看是否正常

2:还需要安装rubygems

(1)下载包,地址https://rubygems.org/pages/download

(2)解压后进入解压文件夹,运行ruby setup.rb

(3)安装后通过gem –v查看一下版本,看是否正常

3:还需要安装redis的ruby library

(1)由于连接国外源不太稳定,请先删除,如gem sources --remove

https://rubygems.org/ ,然后添加gem sources -a https://ruby.taobao.org/

(2)可以通过gem sources -l 查看源

(3)运行gem install redis

4:使用redis-trib.rb来初始化集群,形如:

ruby redis-trib.rb create --replicas 1 127.0.0.1:6381

127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385

127.0.0.1:6386

create表示要初始化集群,--replicas 1表示每个驻数据库拥有的从数据

库为1个

5:使用redis-trib.rb来迁移插槽,如下:

(1)执行ruby redis-trib.rb reshard ip:port ,这就告诉Redis要重新分片,

ip:port可以是集群中任何一个节点

(2)然后按照提示去做就可以了

(3)这种方式不能指定要迁移的插槽号


转载于:https://my.oschina.net/u/2540936/blog/666054

相关文章:

  • 项目的简单描述加实例代码
  • 远程协助解决重建索引的危机问题
  • 解析、理解 cookie
  • 04-Windows频繁打开和关闭端口可能引发的问题 | 07.杂项
  • ajax的简单了解,适合刚进门 的,注释相对比较详细
  • Android——shape和selector和layer-list的(详细说明 转)
  • ajax的兼容问题
  • 对象管理器(defineProperty)学习笔记
  • ajax的登录页面,发送post方式
  • AHK 中 = 和 == 等比较运算符的用法
  • nodejs的简单分析理解
  • NPM的操作步骤
  • Zabbix监控Windows主机
  • promise解决回调地狱的方法之一
  • HTML5的兼容性测试
  • 【347天】每日项目总结系列085(2018.01.18)
  • 2018一半小结一波
  • 4个实用的微服务测试策略
  • Android单元测试 - 几个重要问题
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • Hibernate最全面试题
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • JavaScript-Array类型
  • Laravel 中的一个后期静态绑定
  • REST架构的思考
  • supervisor 永不挂掉的进程 安装以及使用
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • 爬虫模拟登陆 SegmentFault
  • 前端代码风格自动化系列(二)之Commitlint
  • 前端路由实现-history
  • 试着探索高并发下的系统架构面貌
  • 主流的CSS水平和垂直居中技术大全
  • No resource identifier found for attribute,RxJava之zip操作符
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​如何在iOS手机上查看应用日志
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (12)Hive调优——count distinct去重优化
  • (2.2w字)前端单元测试之Jest详解篇
  • (SpringBoot)第二章:Spring创建和使用
  • (南京观海微电子)——I3C协议介绍
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转)Unity3DUnity3D在android下调试
  • (转载)Linux 多线程条件变量同步
  • .aanva
  • .dwp和.webpart的区别
  • .net framework 4.0中如何 输出 form 的name属性。
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .net分布式压力测试工具(Beetle.DT)
  • .net下简单快捷的数值高低位切换
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复