Redis 3.0中文官方文档翻译计划(19)
——集群(上)
这篇文档是对Redis集群的介绍,没有使用复杂难懂的东西来理解分布式系统的概念。本文提供了如何建立,测试和操作一个集群的相关指导,但没有涉及在Redis集群规范(参考本系列其他文章,译者注)中的诸多细节,只是从用户的视角来描述系统是如何运作的。
注意,如果你打算来一次认真的Redis集群的部署,更正式的规范文档(关注本系列文章,译者注)强烈建议你好好读一读。
Redis集群当前处于alpha阶段,如果你发现任何问题,请联系Redis邮件列表,或者在Redis的Github仓库中开启一个问题(issue)。
Redis集群(Redis Cluster)
Redis集群提供一种运行Redis的方式,数据被自动的分片到多个Redis节点。
集群不支持处理多个键的命令,因为这需要在Redis节点间移动数据,使得Redis集群不能提供像Redis单点那样的性能,在高负载下会表现得不可预知。
Redis集群也提供在网络分割(partitions)期间的一定程度的可用性,这就是在现实中当一些节点失败或者不能通信时能继续进行运转的能力。
所以,在实践中,你可以从Redis集群中得到什么呢?
- 在多个节点间自动拆分你的数据集的能力。
- 当部分节点正在经历失败或者不能与集群其他节点通信时继续运转的能力。
Redis集群的TCP端口(Redis Cluster TCP ports)
每个Redis集群节点需要两个TCP连接打开。正常的TCP端口用来服务客户端,例如6379,加10000的端口用作数据端口,在上面的例子中就是16379。
第二个大一些的端口用于集群总线(bus),也就是使用二进制协议的点到点通信通道。集群总线被节点用于错误检测,配置更新,故障转移授权等等。客户端不应该尝试连接集群总线端口,而应一直与正常的Redis命令端口通信,但是要确保在防火墙中打开了这两个端口,否则Redis集群的节点不能相互通信。
命令端口和集群总线端口的偏移量一直固定为10000。
注意,为了让Redis集群工作正常,对每个节点:
- 用于与客户端通信的正常的客户端通信端口(通常为6379)需要开放给所有需要连接集群的客户端以及其他集群节点(使用客户端端口来进行键迁移)。
- 集群总线端口(客户端端口加10000)必须从所有的其他集群节点可达。
如果你不打开这两个TCP端口,你的集群就不会像你期待的那样去工作。
Redis集群的数据分片(Redis Cluster data sharding)
Redis集群没有使用一致性哈希,而是另外一种不同的分片形式,每个键概念上是被我们称为哈希槽(hash slot)的东西的一部分。
Redis集群有16384个哈希槽,我们只是使用键的CRC16编码对16384取模来计算一个指定键所属的哈希槽。
每一个Redis集群中的节点都承担一个哈希槽的子集,例如,你可能有一个3个节点的集群,其中:
- 节点A包含从0到5500的哈希槽。
- 节点B包含从5501到11000的哈希槽。
- 节点C包含从11001到16384的哈希槽。
这可以让在集群中添加和移除节点非常容易。例如,如果我想添加一个新节点D,我需要从节点A,B,C移动一些哈希槽到节点D。同样地,如果我想从集群中移除节点A,我只需要移动A的哈希槽到B和C。当节点A变成空的以后,我就可以从集群中彻底删除它。
因为从一个节点向另一个节点移动哈希槽并不需要停止操作,所以添加和移除节点,或者改变节点持有的哈希槽百分比,都不需要任何停机时间(downtime)。
Redis集群的主从模型(Redis Cluster master-slave model)
为了当部分节点失效时,或者无法与大多数节点通信时仍能保持可用,Redis集群采用每个节点拥有1(主服务自身)到N个副本(N-1个附加的从服务器)的主从模型。
在我们的例子中,集群拥有A,B,C三个节点,如果节点B失效集群将不能继续服务,因为我们不再有办法来服务在5501-11000范围内的哈希槽。
但是,如果当我们创建集群后(或者稍后),我们为每一个主服务器添加一个从服务器,这样最终的集群就由主服务器A,B,C和从服务器A1,B1,C1组成,如果B节点失效系统仍能继续服务。
B1节点复制B节点,于是集群会选举B1节点作为新的主服务器,并继续正确的运转。
Redis集群的一致性保证(Redis Cluster consistency guarantees)
Redis集群不保证强一致性。实践中,这意味着在特定的条件下,Redis集群可能会丢掉一些被系统收到的写入请求命令。
Redis集群为什么会丢失写请求的第一个原因,是因为采用了异步复制。这意味着在写期间下面的事情发生了:
- 你的客户端向主服务器B写入。
- 主服务器B回复OK给你的客户端。
- 主服务器B传播写入操作到其从服务器B1,B2和B3。
你可以看到,B在回复客户端之前没有等待从B1,B2,B3的确认,因为这是一个过高的延迟代价,所以如果你的客户端写入什么东西,B确认了这个写操作,但是在发送写操作到其从服务器前崩溃了,其中一个从服务器被提升为主服务器,永久性的丢失了这个写操作。
这非常类似于在大多数被配置为每秒刷新数据到磁盘的数据库发生的事情一样,这是一个可以根据以往不包括分布式系统的传统数据库系统的经验来推理的场景。同样的,你可以通过在回复客户端之前强制数据库刷新数据到磁盘来改进一致性,但这通常会极大的降低性能。
基本上,有一个性能和一致性之间的权衡。
注意:未来,Redis集群在必要时可能或允许用户执行同步写操作。
Redis集群丢失写操作还有另一个场景,发生在网络分割时,客户端与至少包含一个主服务器的少数实例被孤立起来了。
举个例子,我们的集群由A,B,C,A1,B1,C1共6个节点组成,3个主服务器,3个从服务器。还有一个客户端,我们称为Z1。
分割发生以后,有可能分割的一侧是A,C,A1,B1,C1,分割的另一侧是B和Z1。
Z1仍然可以写入到可接受写请求的B。如果分割在很短的时间内恢复,集群会正常的继续。但是,如果分割持续了足够的时间,B1在分割的大多数这一侧被提升为主服务器,Z1发送给B的写请求会丢失。
注意,Z1发送给B的写操作数量有一个最大窗口:如果分割的大多数侧选举一个从服务器为主服务器后过了足够多的时间,少数侧的每一个主服务器节点将停止接受写请求。
这个时间量是Redis集群一个非常重要的配置指令,称为节点超时(node timeout)。
节点超时时间过后,主服务器节点被认为失效,可以用其一个副本来取代。同样地,节点超时时间过后,主服务器节点还不能感知其它主服务器节点的大多数,则进入错误状态,并停止接受写请求。
创建和使用Redis集群(Creating and using a Redis Cluster)
要创建一个集群,我们要做的第一件事情就是要有若干运行在集群模式下的Redis实例。这基本上意味着,集群不是使用正常的Redis实例创建的,而是需要配置一种特殊的模式Redis实例才会开启集群特定的特性和命令。
下面是最小的Redis集群配置文件:
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
正如你所看到的,简单的cluster-enabled指令开启了集群模式。每个实例包含一个保存这个节点配置的文件的路径,默认是nodes.conf。这个文件不会被用户接触到,启动时由Redis集群实例生成,每次在需要时被更新。
注意,可以正常运转的最小集群需要包含至少3个主服务器节点。在你的第一次尝试中,强烈建议开始一个6个节点的集群,3个主服务器,3个从服务器。
要这么做,先进入一个新的目录,创建下面这些以端口号来命名的目录,我们后面会在每个目录中运行实例。
像这样:
mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005
在从7000到7005的每个目录内创建一个redis.conf文件。作为你的配置文件的模板,只使用上面的小例子,但是要确保根据目录名来使用正确的端口号来替换端口号7000。
现在,复制你从Github的不稳定分支的最新的源代码编译出来的redis-server可执行文件到cluster-test目录中,最后在你喜爱的终端应用程序中打开6个终端标签。
像这样在每个标签中启动实例:
cd 7000
../redis-server ./redis.conf
你可以从每个实例的日志中看到,因为nodes.conf文件不存在,每个节点都为自己赋予了一个新ID。
[82462] 26 Nov 11:56:55.329 * No cluster configuration found, I'm 97a3a64667477371c4479320d683e4c8db5858b1
这个ID会一直被这个实例使用,这样实例就有一个在集群上下文中唯一的名字。每个节点使用这个ID来记录每个其它节点,而不是靠IP和端口。IP地址和端口可能会变化,但是唯一的节点标识符在节点的整个生命周期中都不会改变。我们称这个标识符为节点ID(Node ID)。
创建集群(Creating the cluster)
现在,我们已经有了一些运行中的实例,我们需要创建我们的集群,写一些有意义的配置到节点中。
这很容易完成,因为我们有称为redis-trib 的Redis集群命令行工具来帮忙,这是一个Ruby程序,可以在实例上执行特殊的命令来创建一个新的集群,检查或重分片一个已存在的集群,等等。
redis-trib工具在Redis源代码分发版本的src目录中。要创建你的集群,简单输入:
./redis-trib.rb 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
这里使用的命令是create,因为我们想创建一个新的集群。--replicas 1选项意思是我们希望每个创建的主服务器有一个从服务器。其他参数是我想用来创建新集群的实例地址列表。
显然,我们要求的唯一布局就是创建一个拥有3个主服务器和3个从服务器的集群。
Redis-trib会建议你一个配置。输入yes接受。集群会被配置和连接在一起,也就是说,实例会被引导为互相之间对话。最后,如果一切顺利你会看到一个类似这样的消息:
[OK] All 16384 slots covered
这表示,16384个槽中的每一个至少有一个主服务器在处理。
与集群共舞(Playing with the cluste)
在当前阶段,Redis集群的一个问题是缺少客户端库的实现。
据我所知有以下实现:
- redis-rb-cluster是我(@antirez)写的Ruby实现,作为其他语言的参考。这个是对原先的redis-rb进行了简单的封装,实现了与集群高效对话的最小语义。
- redis-py-cluster看起来就是redis-rb-cluster的Python版本。最新没有更新(最后一次提交是6个月之前)但是这是一个起点。
- 流行的Predis有对Redis集群的支持,支持最近有更新,并处于活跃开发状态。
- 最多使用的Java客户端Jedis最近增加了对Redis集群的支持,请查看项目README中的Jedis集群部分。
- StackExchange.Redis提供对C#的支持(应该与大多数.NET语言工作正常:VB,F#等)。
- Github上Redis仓库的不稳定分支上的redis-cli工具实现了一个基本的集群支持,使用-c启动时切换。
测试Redis集群的简单办法就是尝试上面这些客户端,或者只是使用redis-cli命令行工具。下面的交互例子使用的是后者:
$ redis-cli -c -p 7000
redis 127.0.0.1:7000> set foo bar
-> Redirected to slot [12182] located at 127.0.0.1:7002
OK
redis 127.0.0.1:7002> set hello world
-> Redirected to slot [866] located at 127.0.0.1:7000
OK
redis 127.0.0.1:7000> get foo
-> Redirected to slot [12182] located at 127.0.0.1:7002
"bar"
redis 127.0.0.1:7000> get hello
-> Redirected to slot [866] located at 127.0.0.1:7000
"world"
redis-cli的集群支持非常基本,所以总是依赖Redis集群节点重定向客户端到正确的节点。一个真正的客户端可以做得更好,缓存哈希槽和节点地址之间的映射,直接使用到正确节点的正确连接。映射只在集群的配置发生某些变化时才重新刷新,例如,故障转移以后,或者系统管理员通过添加或移除节点改变了集群的布局以后。
===============================================================================
大家好,我是阮威。华中科技大学,计算机软件专业硕士。毕业后加入腾讯,先后在腾讯电子商务部和无线游戏产品部工作,现供职于欢聚时代基础产品部。IT男,至今。欢迎大家收听我的公众账号。
分享到:
相关推荐
Redis 3.0在原有的基础上进行了升级,新增了丰富的功能,其中包括支持Lua脚本、可插拔模块化、多主复制、集群等,使得Redis 3.0在性能、可扩展性、安全性等方面有着显著的提升。 2、Redis 3.0新特性: (1)支持Lua...
本文档将详细介绍如何在CentOS 6.5环境下搭建Redis 3.0集群,并通过具体的步骤指导用户完成整个部署过程。 #### 二、环境准备与要求 **系统环境**: CentOS 6.5 **硬件要求**: 至少3台主机或虚拟机(为了简化示例...
Redis 3.0 集群环境安装手册 Redis 3.0 集群环境安装手册是指在 Linux 操作系统中安装和配置 Redis 3.0 集群的步骤指南。Redis 是一个开源、基于内存的数据结构存储系统,可以用作数据库、消息队列、缓存层等。 ...
Redis 3.0版本是其发展历程中的一个重要里程碑,它带来了许多改进和新特性,旨在提升性能、稳定性和功能多样性。 在Redis 3.0中,主要关注以下几个方面的更新: 1. **多线程I/O**: 以往的Redis版本是单线程模型,...
虽然Redis 3.0不支持集群功能,但在更高版本中,Redis引入了集群方案,允许在多台服务器之间分散数据,提高可用性和容量。若需要扩展,可以考虑升级到更高版本或使用哨兵(Sentinel)系统实现高可用性。 综上所述,...
### Redis 3.0 集群指南 ...综上所述,Redis 3.0 的集群部署不仅涉及安装配置、主从复制等基础概念,还涵盖了更为高级的故障转移机制——哨兵。通过合理规划和配置,可以有效提升 Redis 集群的可用性和性能。
某播客Redis3.0新特性、主从复制、集群视频教程 某播客Redis3.0新特性、主从复制、集群视频教程 某播客Redis3.0新特性、主从复制、集群视频教程
1. 下载Redis安装包:根据提供的链接或通过官方渠道获取Redis 3.0.503的Windows版本。通常,这会是一个名为“3.0.503”的压缩包文件。 2. 解压安装包:将下载的压缩包解压到你选择的任意目录,例如"C:\Program ...
本资源“redis3.0-window免安装”是专门为Windows操作系统设计的Redis 3.0版本,旨在简化在Windows平台上的部署和使用流程。 Redis 3.0是一个重要的版本,它引入了多项新特性和改进,包括但不限于: 1. **多线程...
在Redis 3.0版本中,它已经具备了丰富的特性和功能,使其成为开发者们青睐的NoSQL数据库之一。以下是关于Redis 3.0的一些关键知识点: 1. **数据类型**:Redis支持五种基本数据类型,包括字符串(String)、哈希(Hash...
这个"redis3.0-windows"压缩包文件显然包含了Redis 3.0版本的Windows兼容版本,允许用户在Windows操作系统上运行和管理Redis实例。 Redis的核心特性包括: 1. **键值存储**:Redis的基础是键值对存储,它允许存储...
在Windows环境下编译Redis3.0,可以让你在本地系统上测试和开发基于Redis的应用,尤其是利用其新特性——Cluster。 **Redis3.0的新特性:** 1. **Cluster支持**:Redis 3.0引入了Cluster功能,这是一个分布式解决...
redis3.0 widows集群 spring整合jedis redis搭建window集群代码和文档rubygems-2.5.1和rubyinstaller-2.2.3-x64软件下载
3. **Redis Cluster**:在3.0版本中,官方正式支持了Redis Cluster,这是一个分布式解决方案,可以将数据分片到多个节点,实现自动故障转移和扩展性。 4. **Streams**:虽然这个特性在后来的版本中才引入,但了解...
这个版本是Redis 3.0.504的64位版本,适合在Windows操作系统上运行。它是一个绿色免安装版本,意味着你无需经过传统安装过程,只需将压缩包解压到任意目录,然后执行`startup.bat`脚本就可以启动Redis服务器。 1. *...
Redis 3.0.504 是一个稳定版本的开源键值存储系统,以其高性能、丰富的数据结构和灵活的数据操作而被广泛应用于缓存、数据库和消息中间件等多个场景。这个版本是为32位操作系统设计的,确保了在资源有限的环境下也能...
1. 下载:首先,你需要从官方或者可靠的第三方源下载Redis 3.0.504 for Windows的压缩包。压缩包名称为"Redis-windows"。 2. 解压:下载完成后,解压缩到你希望安装的目录,例如"C:\Program Files\Redis"。 3. ...
redis3.0windows版,解压后可直接使用