redis cluster简介和配置(3)
前面我介绍了 redis sentinel,既然有了sentinel,为什么还要一个cluster呢?
因为随着业务量的增加,不可避免要对redis进行扩容,扩容方式一般由2种:1. 垂直扩容 2. 水平扩容
垂直扩容:增加内存方式来增加整个缓存系统容量。比如从2G增加到4G
水平扩容:通过增加节点的方式来增加整个缓存系统的容量。 这种方式一般需要应用程序支持。
垂直扩容比较方便,但是受制于机制内存的限制,一个机器不可能无限增大内存, 所以到了一定阶段肯定要进行水平扩容。
但是水平扩容,就会涉及到数据迁移。 而迁移过程中,一方面要保持业务可用,另一方面也要尽量保证数据不丢失。 但是 sentinel 在这方面
几乎没有作用。 针对这些问题,redis的作者就开发出了一个解决方案 redis cluster, 所以redis cluster就应运而生了。
一:Redis Cluster 集群简介
------------------------------------------------------------------------------------------------------------------------------
Redis Cluster是Redis官方出的一个分布式解决方案, 是在Redis3.0正式版推出的,有效解决了Redis在单机、并发、流量等方面的瓶颈。
Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation)。
Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的行为。
Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。
Redis 集群提供了以下两个好处:
- 将数据自动切分(split)到多个节点的能力。
- 当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力
Redis 集群节点之间相互关系:
二:Redis分布式集群数据解决方案
-------------------------------------------------------------------------------------------------------------------------------------
一般分布式集群首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集。
Redis集群使用数据分片(sharding)来提供数据分布的解决方案, 而不是 一致性哈希(consistency hashing)来实现的。
一个 Redis 集群包含 16384 个哈希槽(hash slot),范围是(0-16383), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和。
集群中的每个节点负责处理一部分哈希槽。
举个例子, 一个集群可以有三个哈希槽, 其中:
- 节点 A 负责处理 0 号至 5500 号哈希槽。
- 节点 B 负责处理 5501 号至 11000 号哈希槽。
- 节点 C 负责处理 11001 号至 16384 号哈希槽。
这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。 比如说:
如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。
与此类似, 如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。
因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会造成集群下线。
例子中的Redis 集群分区 和 槽范围示意图:
三:Redis集群中的主从复制
-----------------------------------------------------------------------------------------------------------------------------
为了使得集群在一部分节点下线或者无法与集群的大多数(majority)节点进行通讯的情况下, 仍然可以正常运作, Redis 集群对节点使用了主从复制功能: 集群中的每个节点都有 1 个至 N 个复制品(replica), 其中一个复制品为主节点(master), 而其余的 N-1 个复制品为从节点(slave)。
在之前列举的节点 A 、B 、C 的例子中, 如果节点 B 下线了, 那么集群将无法正常运行, 因为集群找不到节点来处理 5501 号至 11000 号的哈希槽。
另一方面, 假如在创建集群的时候(或者至少在节点 B 下线之前), 我们为主节点 B 添加了从节点 B1 , 那么当主节点 B 下线的时候, 集群就会将 B1 设置为新的主节点, 并让它代替下线的主节点 B , 继续处理 5501 号至 11000 号的哈希槽, 这样集群就不会因为主节点 B 的下线而无法正常运作了。
不过如果节点 B 和 B1 都下线的话, Redis 集群还是会停止运作。
四:Redis集群数据一致性保证
---------------------------------------------------------------------------------------------------------------------------------
Redis 集群不保证数据的强一致性(strong consistency): 在特定条件下, Redis 集群可能会丢失已经被执行过的写命令。
使用异步复制(asynchronous replication)是 Redis 集群可能会丢失写命令的其中一个原因。 考虑以下这个写命令的例子:
客户端向主节点 B 发送一条写命令。
主节点 B 执行写命令,并向客户端返回命令回复。
主节点 B 将刚刚执行的写命令复制给它的从节点 B1 、 B2 和 B3 。
如你所见, 主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。
Redis 集群另外一种可能会丢失命令的情况是, 集群出现网络分裂(network partition), 并且一个客户端与至少包括一个主节点在内的少数(minority)实例被孤立。
五:Redis集群配置
---------------------------------------------------------------------------------------------------------------------------
要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系如下(为了简单演示都在同一台机器上面)
1. 下载版本,创建相应目录
前面我下载了redis版本,并且安装在了/usr/local/redis/ 下, 为了创建Redis集群配置,我们在这个目录下创建一个目录,make ./data/cluster,
然后在里面创建6个目录, cd ./data/cluster, mkdir 7000 7001 7002 7003 7004 7005
2. 需要配置文件
cp redis/redis.conf /usr/local/redis/data/cluster/7000/
修改配置项目:vi /usr/local/redis/data/cluster/7000/redis.conf
port
daemonize yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout
appendonly yes
文件中的 cluster-enabled 选项用于开实例的集群模式, 而 cluster-conf-file 选项则设定了保存节点配置文件的路径, 默认值为nodes.conf 。其他参数相信童鞋们都知道。节点配置文件无须人为修改, 它由 Redis 集群在启动时创建, 并在有需要时自动进行更新。
修改完成后,把修改完成的redis.conf复制到7001-7005目录下,并且端口修改成和文件夹对应。
3. 分别启动6个实例
# cd ../
# /usr/local/redis/bin/redis-server redis.conf # cd ../
# /usr/local/redis/bin/redis-server redis.conf # cd ../
# /usr/local/redis/bin/redis-server redis.conf # cd ../
# /usr/local/redis/bin/redis-server redis.conf # cd ../
# /usr/local/redis/bin/redis-server redis.conf
查看进程是否存在
# ps aux|grep redis
root 0.0 0.4 ? Ssl : : /usr/local/redis/bin/redis-server 127.0.0.1: [cluster]
root 0.0 0.4 ? Ssl : : /usr/local/redis/bin/redis-server 127.0.0.1: [cluster]
root 0.0 0.4 ? Ssl : : /usr/local/redis/bin/redis-server 127.0.0.1: [cluster]
root 0.0 0.4 ? Ssl : : /usr/local/redis/bin/redis-server 127.0.0.1: [cluster]
root 0.1 0.4 ? Ssl : : /usr/local/redis/bin/redis-server 127.0.0.1: [cluster]
root 0.0 0.4 ? Ssl : : /usr/local/redis/bin/redis-server 127.0.0.1: [cluster]
4. 执行创建集群的命令
首先安装ruby的依赖:
yum install ruby rubygems -y
安装gem-redis:
下载地址:wget https://rubygems.org/gems/redis/versions/3.2.2
注意:上面下载下来就是一个 3.2.2 这样命名的文件
用命令安装gem redis:
# gem install redis -v 3.2.
Fetching: redis-3.2..gem (%)
Successfully installed redis-3.2.
Parsing documentation for redis-3.2.
Installing ri documentation for redis-3.2.
gem installed
5. 复制集群管理程序到/usr/local/bin
cp /redis-3.2.9/src/redis-trib.rb /usr/local/bin/redis-trib
6. 创建集群:
redis-trib 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
# redis-trib create --replicas 127.0.0.1: 127.0.0.1: 127.0.0.1: 127.0.0.1: 127.0.0.1: 127.0.0.1:
>>> Creating cluster
>>> Performing hash slots allocation on nodes...
Using masters:
127.0.0.1:
127.0.0.1:
127.0.0.1:
Adding replica 127.0.0.1: to 127.0.0.1:
Adding replica 127.0.0.1: to 127.0.0.1:
Adding replica 127.0.0.1: to 127.0.0.1:
M: 49b3e7a05b680484f959f91d3b7b7caa2c991908 127.0.0.1:
slots:- ( slots) master
M: 3d99267c015d1f38170b03ebec9718d2914ce484 127.0.0.1:
slots:- ( slots) master
M: 9d9c0a5993c5a36e04a77f2fc36a10e72f117d1d 127.0.0.1:
slots:- ( slots) master
S: c43ecfb119f0a47bc1f53acf7d7ec40001b5de35 127.0.0.1:
replicates 49b3e7a05b680484f959f91d3b7b7caa2c991908
S: 560206fd404c7fe81ef9a9a20c35c2dc09a588f8 127.0.0.1:
replicates 3d99267c015d1f38170b03ebec9718d2914ce484
S: 104d81494a1688296677c5bc9d4d10c81a523ede 127.0.0.1:
replicates 9d9c0a5993c5a36e04a77f2fc36a10e72f117d1d
Can I set the above configuration? (type 'yes' to accept):
输入 yes 后, 集群就会将配置应用到各个节点, 并连接起(join)各个节点 —— 也即是, 让各个节点开始互相通讯:
这个是接上面
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join..
>>> Performing Cluster Check (using node 127.0.0.1:)
M: 49b3e7a05b680484f959f91d3b7b7caa2c991908 127.0.0.1:
slots:- ( slots) master
additional replica(s)
M: 3d99267c015d1f38170b03ebec9718d2914ce484 127.0.0.1:
slots:- ( slots) master
additional replica(s)
S: 104d81494a1688296677c5bc9d4d10c81a523ede 127.0.0.1:
slots: ( slots) slave
replicates 9d9c0a5993c5a36e04a77f2fc36a10e72f117d1d
S: 560206fd404c7fe81ef9a9a20c35c2dc09a588f8 127.0.0.1:
slots: ( slots) slave
replicates 3d99267c015d1f38170b03ebec9718d2914ce484
M: 9d9c0a5993c5a36e04a77f2fc36a10e72f117d1d 127.0.0.1:
slots:- ( slots) master
additional replica(s)
S: c43ecfb119f0a47bc1f53acf7d7ec40001b5de35 127.0.0.1:
slots: ( slots) slave
replicates 49b3e7a05b680484f959f91d3b7b7caa2c991908
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All slots covered.
上面最后出现 2个 ok,正常安装完成
六:测试使用
---------------------------------------------------------------------------------------------------------------------------
我们用自带的 redis-cli 客户端来测试,在你的/redis/src/redis-cli
可以使用命令 redis-cli -c 来启动
增加一个值:
# redis-cli -c -p
127.0.0.1:> set name cluster-test
OK
127.0.0.1:> get name
"cluster-test"
127.0.0.1:> set hello world
-> Redirected to slot [] located at 127.0.0.1:
OK
127.0.0.1:> get hello
"world"
127.0.0.1:> set foo bar
-> Redirected to slot [] located at 127.0.0.1:
OK
127.0.0.1:> get foo
"bar"
查看集群node信息
# redis-cli -p cluster nodes
3d99267c015d1f38170b03ebec9718d2914ce484 127.0.0.1: master - connected -
104d81494a1688296677c5bc9d4d10c81a523ede 127.0.0.1: slave 9d9c0a5993c5a36e04a77f2fc36a10e72f117d1d connected
560206fd404c7fe81ef9a9a20c35c2dc09a588f8 127.0.0.1: slave 3d99267c015d1f38170b03ebec9718d2914ce484 connected
49b3e7a05b680484f959f91d3b7b7caa2c991908 127.0.0.1: myself,master - connected -
9d9c0a5993c5a36e04a77f2fc36a10e72f117d1d 127.0.0.1: master - connected -
c43ecfb119f0a47bc1f53acf7d7ec40001b5de35 127.0.0.1: slave 49b3e7a05b680484f959f91d3b7b7caa2c991908 connected
参考:
http://redisdoc.com/topic/cluster-tutorial.html#
http://www.cnblogs.com/gomysql/p/4395504.html
redis cluster简介和配置(3)的更多相关文章
- redis cluster最简配置
redis cluster最简配置 master配置如下:(默认6379端口) bind 127.0.0.1 port 6379 timeout 0 databases 16 Master的redis ...
- Redis Cluster 简单安装配置
1 新建目录 “/app/redis”,输入命令 mkdir -p /app/redis 2 先安装ruby-2.3.1.tar.gz 3 测试ruby是否安装成功,输入命令:gem,如果显示以下信息 ...
- Redis cluster集群配置教程
这里建议大家安装4.0.9版本的 1.打开Centos虚拟机,登陆. 2.通过WinSCP把Redis集群tar包上传到虚拟机里的目录里,我的目录是 /usr/local 这里我已经上传过了并解压了, ...
- Redis Cluster搭建方法简介22211111
Redis Cluster搭建方法简介 (2013-05-29 17:08:57) 转载▼ Redis Cluster即Redis的分布式版本,将是Redis继支持Lua脚本之后的又一重磅 ...
- 合理利用配置不同的机器资源做redis cluster的server
Redis cluster可以使用不同配置的机器学习因为我们可以手动调整不同的机器所承担的slot的个数,这样内存小CPU相对少的机器应该承担更少的slots
- 开源|如何开发一个高性能的redis cluster proxy?
文|曹佳俊 网易智慧企业资深服务端开发工程师 背 景 redis cluster简介 Redis cluster是redis官方提供集群方案,设计上采用非中心化的架构,节点之间通过gossip协 ...
- redis cluster介绍
讲解分布式数据存储的核心算法,数据分布的算法 hash算法 -> 一致性hash算法(memcached) -> redis cluster,hash slot算法 一.概述 1.我们的m ...
- 饿了么这样跳过Redis Cluster遇到的“坑”
内容来源:2017 年 8 月 12 日,饿了么高级Python工程师黄光星在“CRUG 2017北京活动”进行<Redis Cluster运维方案>演讲分享.IT 大咖说(微信id:it ...
- 在 K8S 中快速部署 Redis Cluster & Redisinsight
Redis Cluster 部署 使用 Bitnami helm chart 在 K8S redis 命名空间中一键部署 Redis cluster . helm repo add bitnami h ...
随机推荐
- 基于python的种子搜索网站-开发过程
本讲会对种子搜索网站的开发过程进行详细的讲解. 源码地址:https://github.com/geeeeeeeek/bt 项目开发过程 项目简介 该项目是基于python的web类库django开发 ...
- TextSwitcher 文本切换器的功能与用法
TextSwitcher集成了ViewSwitcher, 因此它具有与ViewSwitcher相同的特性:可以在切换View组件时使用动画效果.与ImageSwitcher相似的是,使用TextSwi ...
- 从0开始的Python学习015输入与输出
简介 在之前的编程中,我们的信息打印,数据的展示都是在控制台(命令行)直接输出的,信息都是一次性的没有办法复用和保存以便下次查看,今天我们将学习Python的输入输出,解决以上问题. 复习 得到输入用 ...
- C# Base64方式的编码与解码
编码与解码方法: ///编码 public static string EncodeBase64(string code_type, string code) { string encode = &q ...
- c++字节对齐编译器指令#pragma
第一种 #pragma pack(push, 1) // 先把当前对齐设置压栈,再设置为1字节对齐 struct S { char a; ]; }; #pragma pack(pop) // 恢复先前 ...
- windows 2008 开机启动 Docker Toolbox 并运行容器
新建 docker-startup.bat @echo off REM Set the name of the VM configuration where dockerd will be hoste ...
- python进阶之生成器
迭代器 什么叫迭代 可以被for循环的就说明他们是可迭代的,比如:字符串,列表,字典,元祖,们都可以for循环获取里面的数据 下面我们看一个代码: number = 12345 for i in nu ...
- Extjs renderer函数
昨天提到了改变grid中 行的背景颜色,其实还有一个更简单的方法,就是利用renderer:function(){}函数 renderer 函数是一个拦截者模式,用于改变渲染到单元格的值和样式. re ...
- DNS域名解析过程,域名的认识
DNS域名解析过程 参考知乎:https://www.zhihu.com/question/23042131 当你通过浏览器输入url访问资源时,会请求DNS解析域名成对应的IP地址,由IP地址在去与 ...
- 《Python神经网络编程》的读书笔记
文章提纲 全书总评 读书笔记 C01.神经网络如何工作? C02.使用Python进行DIY C03.开拓思维 附录A.微积分简介 附录B.树莓派 全书总评 书本印刷质量:4星.纸张是米黄色,可以保护 ...