`
powersoft
  • 浏览: 199237 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
53a63413-d61c-321e-8dc6-5008e88923c6
Redis官方文档翻译和源...
浏览量:191971
社区版块
存档分类
最新评论

Redis 3.0中文官方文档翻译计划(20) ——集群(中)

阅读更多
Redis 3.0中文官方文档翻译计划(20)
——集群(中)


    使用redis-rb-cluster写一个示例应用
    在后面介绍如何操作Redis集群之前,像故障转移或者重新分片这样的事情,我们需要创建一个示例应用,或者至少要了解简单的Redis集群客户端的交互语义。
    我们采用运行一个示例,同时尝试使节点失效,或者开始重新分片这样的方式,来看看在真实世界条件下Redis集群如何表现。如果没有人往集群写的话,观察集群发生了什么也没有什么实际用处。
    这一小节通过两个例子来解释redis-rb-cluster的基本用法。第一个例子在redis-rb-cluster发行版本的exemple.rb文件中,如下:
     1  require './cluster'
     2
     3  startup_nodes = [
     4      {:host => "127.0.0.1", :port => 7000},
     5      {:host => "127.0.0.1", :port => 7001}
     6  ]
     7  rc = RedisCluster.new(startup_nodes,32,:timeout => 0.1)
     8
     9  last = false
    10
    11  while not last
    12      begin
    13          last = rc.get("__last__")
    14          last = 0 if !last
    15      rescue => e
    16          puts "error #{e.to_s}"
    17          sleep 1
    18      end
    19  end
    20
    21  ((last.to_i+1)..1000000000).each{|x|
    22      begin
    23          rc.set("foo#{x}",x)
    24          puts rc.get("foo#{x}")
    25          rc.set("__last__",x)
    26      rescue => e
    27          puts "error #{e.to_s}"
    28      end
    29      sleep 0.1
    30  }

    这个程序做了一件很简单的事情,一个一个地设置形式为foo<number>的键的值为一个数字。所以如果你运行这个程序,结果就是下面的命令流:
SET foo0 0
SET foo1 1
SET foo2 2
And so forth...

    这个程序看起来要比通常看起来更复杂,因为这个是设计用来在屏幕上展示错误,而不是由于异常退出,所以每一个对集群执行的操作都被begin rescue代码块包围起来。
    第7行是程序中第一个有意思的地方。创建了Redis集群对象,使用启动节点(startup nodes)的列表,对象允许的最大连接数,以及指定操作被认为失效的超时时间作为参数。
启动节点不需要是全部的集群节点。重要的是至少有一个节点可达。也要注意,redis-rb-cluster一旦连接上了第一个节点就会更新启动节点的列表。你可以从任何真实的客户端中看到这样的行为。
    现在,我们将Redis集群对象实例保存在rc变量中,我们准备像一个正常的Redis对象实例一样来使用这个对象。
    第11至19行说的是:当我们重启示例的时候,我们不想又从foo0开始,所以我们保存计数到Redis里面。上面的代码被设计为读取这个计数值,或者,如果这个计数器不存在,就赋值为0。
    但是,注意这里为什么是个while循环,因为我们想即使集群下线并返回错误也要不断地重试。一般的程序不必这么小心谨慎。
    第21到30行开始了主循环,键被设置赋值或者展示错误。
    注意循环最后sleep调用。在你的测试中,如果你想尽可能快地往集群写入,你可以移除这个sleep(相对来说,这是一个繁忙的循环而不是真实的并发,所以在最好的条件下通常可以得到每秒10k次操作)。
    正常情况下,写被放慢了速度,让人可以更容易地跟踪程序的输出。
    运行程序产生了如下输出:
ruby ./example.rb
1
2
3
4
5
6
7
8
9
^C (I stopped the program here)

    这不是一个很有趣的程序,稍后我们会使用一个更有意思的例子,看看在程序运行时进行重新分片会发生什么事情。

    重新分片集群(Resharding the cluster)
    现在,我们准备尝试集群重分片。要做这个请保持example.rb程序在运行中,这样你可以看到是否对运行中的程序有一些影响。你也可能想注释掉sleep调用,这样在重分片期间就有一些真实的写负载。
    重分片基本上就是从部分节点移动哈希槽到另外一部分节点上去,像创建集群一样也是通过使用redis-trib工具来完成。
    开启重分片只需要输入:
./redis-trib.rb reshard 127.0.0.1:7000

    你只需要指定单个节点,redis-trib会自动找到其它节点。
    当前redis-trib只能在管理员的支持下进行重分片,你不能只是说从这个节点移动5%的哈希槽到另一个节点(但是这也很容易实现)。那么问题就随之而来了。第一个问题就是你想要重分片多少:
    你想移动多少哈希槽(从1到16384)?
    我们尝试重新分片1000个哈希槽,如果没有sleep调用的那个例子程序还在运行的话,这些槽里面应该已经包含了不少的键了。
    然后,redis-trib需要知道重分片的目标了,也就是将接收这些哈希槽的节点。我将使用第一个主服务器节点,也就是127.0.0.1:7000,但是我得指定这个实例的节点ID。这已经被redis-trib打印在一个列表中了,但是我总是可以在需要时使用下面的命令找到节点的ID:
$ redis-cli -p 7000 cluster nodes | grep myself
97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5460

    好了,我的目标节点是97a3a64667477371c4479320d683e4c8db5858b1。
    现在,你会被询问想从哪些节点获取这些键。我会输入all,这样就会从所有其它的主服务器节点获取一些哈希槽。
    在最后的确认后,你会看到每一个被redis-trib准备从一个节点移动到另一个节点的槽的消息,并且会为每一个被从一侧移动到另一侧的真实的键打印一个圆点。
    在重分片进行的过程中,你应该能够看到你的示例程序运行没有受到影响。如果你愿意的话,你可以在重分片期间多次停止和重启它。
    在重分片的最后,你可以使用下面的命令来测试一下集群的健康情况:
./redis-trib.rb check 127.0.0.1:7000

    像平时一样,所有的槽都会被覆盖到,但是这次在127.0.0.1:7000的主服务器会拥有更多的哈希槽,大约6461个左右。

    一个更有意思的示例程序
    到目前为止一切挺好,但是我们使用的示例程序却不够好。不顾后果地(acritically)往集群里面写,而不检查写入的东西是否是正确的。
    从我们的观点看,接收写请求的集群可能一直将每个操作都作为设置键foo值为42,我们却根本没有察觉到。
    所以在redis-rb-cluster仓库中,有一个叫做consistency-test.rb的更有趣的程序。这个程序有意思得多,因为它使用一组计数器,默认1000个,发送INCR命令来增加这些计数器。
但是,除了写入,程序还做另外两件事情:
  • 当计数器使用INCR被更新后,程序记住了写操作。
  • 在每次写之前读取一个随机计数器,检查这个值是否是期待的值,与其在内存中的值比较。

    这个的意思就是,这个程序就是一个一致性检查器,可以告诉你集群是否丢失了一些写操作,或者是否接受了一个我们没有收到确认(acknowledgement)的写操作。在第一种情况下,我们会看到计数器的值小于我们记录的值,而在第二种情况下,这个值会大于。
    运行consistency-test程序每秒钟产生一行输出:
$ ruby consistency-test.rb
925 R (0 err) | 925 W (0 err) |
5030 R (0 err) | 5030 W (0 err) |
9261 R (0 err) | 9261 W (0 err) |
13517 R (0 err) | 13517 W (0 err) |
17780 R (0 err) | 17780 W (0 err) |
22025 R (0 err) | 22025 W (0 err) |
25818 R (0 err) | 25818 W (0 err) |

    每一行展示了执行的读操作和写操作的次数,以及错误数(错误导致的未被接受的查询是因为系统不可用)。
    如果发现了不一致性,输出将增加一些新行。例如,当我在程序运行期间手工重置计数器,就会发生:
$ redis 127.0.0.1:7000> set key_217 0
OK

(in the other tab I see...)

94774 R (0 err) | 94774 W (0 err) |
98821 R (0 err) | 98821 W (0 err) |
102886 R (0 err) | 102886 W (0 err) | 114 lost |
107046 R (0 err) | 107046 W (0 err) | 114 lost |

    当我把计数器设置为0时,真实值是144,所以程序报告了144个写操作丢失(集群没有记住的INCR命令执行的次数)。
    这个程序作为测试用例很有意思,所以我们会使用它来测试Redis集群的故障转移。

    测试故障转移(Testing the failover)
    注意:在测试期间,你应该打开一个标签窗口,一致性检查的程序在其中运行。
    为了触发故障转移,我们可以做的最简单的事情(这也是能发生在分布式系统中语义上最简单的失败)就是让一个进程崩溃,在我们的例子中就是一个主服务器。
    我们可以使用下面的命令来识别一个集群并让其崩溃:
$ redis-cli -p 7000 cluster nodes | grep master
3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 127.0.0.1:7001 master - 0 1385482984082 0 connected 5960-10921
2938205e12de373867bf38f1ca29d31d0ddb3e46 127.0.0.1:7002 master - 0 1385482983582 0 connected 11423-16383
97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5959 10922-11422

    好了,7000,7001,7002都是主服务器。我们使用DEBUG SEGFAULT命令来使节点7002崩溃:
$ redis-cli -p 7002 debug segfault
Error: Server closed the connection

    现在,我们可以看看一致性测试的输出报告了些什么内容。
18849 R (0 err) | 18849 W (0 err) |
23151 R (0 err) | 23151 W (0 err) |
27302 R (0 err) | 27302 W (0 err) |

... many error warnings here ...

29659 R (578 err) | 29660 W (577 err) |
33749 R (578 err) | 33750 W (577 err) |
37918 R (578 err) | 37919 W (577 err) |
42077 R (578 err) | 42078 W (577 err) |

    你可以看到,在故障转移期间,系统不能接受578个读请求和577个写请求,但是数据库中没有产生不一致性。这听起来好像和我们在这篇教程的第一部分中陈述的不一样,我们说道,Redis集群在故障转移期间会丢失写操作,因为它使用异步复制。但是我们没有说过的是,这并不是经常发生,因为Redis发送回复给客户端,和发送复制命令给从服务器差不多是同时,所以只有一个很小的丢失数据窗口。但是,很难触发并不意味着不可能发生,所以这并没有改变Redis集群提供的一致性保证(即非强一致性,译者注)。
    我们现在可以看看故障转移后的集群布局(注意,与此同时,我重启了崩溃的实例,所以它以从服务器的身份重新加入了集群):
$ redis-cli -p 7000 cluster nodes
3fc783611028b1707fd65345e763befb36454d73 127.0.0.1:7004 slave 3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 0 1385503418521 0 connected
a211e242fc6b22a9427fed61285e85892fa04e08 127.0.0.1:7003 slave 97a3a64667477371c4479320d683e4c8db5858b1 0 1385503419023 0 connected
97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5959 10922-11422
3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7005 master - 0 1385503419023 3 connected 11423-16383
3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 127.0.0.1:7001 master - 0 1385503417005 0 connected 5960-10921
2938205e12de373867bf38f1ca29d31d0ddb3e46 127.0.0.1:7002 slave 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 0 1385503418016 3 connect

    现在,主服务器运行在7000,7001和7005端口。之前运行在7002端口的主服务器现在是7005的从服务器了。
    CLUSTER NODES命令的输出看起来挺可怕的,但是实际上相当的简单,由以下部分组成:
  • 节点ID
  • ip:port
  • flags: master, slave, myself, fail, ...
  • 如果是从服务器的话,就是其主服务器的节点ID
  • 最近一次发送PING后等待回复的时间
  • 最近一次发送PONG的时间
  • 节点的配置纪元(请看集群规范).
  • 节点的连接状态
  • 服务的哈希槽

===============================================================================
    大家好,我是阮威。华中科技大学,计算机软件专业硕士。毕业后加入腾讯,先后在腾讯电子商务部和无线游戏产品部工作,现供职于欢聚时代基础产品部。IT男,至今。欢迎大家收听我的公众账号。

分享到:
评论

相关推荐

    redis3.0安装包 window 64位

    (1)支持Lua脚本:Redis 3.0支持Lua脚本,可以在Redis中执行脚本,大大提高了Redis的灵活性和可扩展性; (2)可插拔模块化:Redis 3.0提供了可插拔的模块化功能,可以根据用户的需求,自定义模块,实现不同的功能...

    redis3.0-集群部署文档

    本文档将详细介绍如何在CentOS 6.5环境下搭建Redis 3.0集群,并通过具体的步骤指导用户完成整个部署过程。 #### 二、环境准备与要求 **系统环境**: CentOS 6.5 **硬件要求**: 至少3台主机或虚拟机(为了简化示例...

    redis3.0.集群环境安装手册

    Redis 3.0 集群环境安装手册是指在 Linux 操作系统中安装和配置 Redis 3.0 集群的步骤指南。Redis 是一个开源、基于内存的数据结构存储系统,可以用作数据库、消息队列、缓存层等。 安装环境准备: 在安装 Redis ...

    redis最新3.0版本

    Redis 3.0版本是其发展历程中的一个重要里程碑,它带来了许多改进和新特性,旨在提升性能、稳定性和功能多样性。 在Redis 3.0中,主要关注以下几个方面的更新: 1. **多线程I/O**: 以往的Redis版本是单线程模型,...

    redis 3.0 集群指南

    ### Redis 3.0 集群指南 ...综上所述,Redis 3.0 的集群部署不仅涉及安装配置、主从复制等基础概念,还涵盖了更为高级的故障转移机制——哨兵。通过合理规划和配置,可以有效提升 Redis 集群的可用性和性能。

    redis 3.0 win7 32位x86

    虽然Redis 3.0不支持集群功能,但在更高版本中,Redis引入了集群方案,允许在多台服务器之间分散数据,提高可用性和容量。若需要扩展,可以考虑升级到更高版本或使用哨兵(Sentinel)系统实现高可用性。 综上所述,...

    某播客Redis3.0新特性、主从复制、集群视频教程

    某播客Redis3.0新特性、主从复制、集群视频教程 某播客Redis3.0新特性、主从复制、集群视频教程 某播客Redis3.0新特性、主从复制、集群视频教程

    redis3.0-window免安装

    3. **Stream数据结构**:虽然Redis 3.0并没有正式引入Stream数据结构,但3.2版本中引入的Stream是Redis的重要扩展,它提供了一种时间序列数据存储和管理的方式,适用于日志记录、时间序列分析等场景。 4. **Redis ...

    redis windows安装包 3.0.503

    1. 下载Redis安装包:根据提供的链接或通过官方渠道获取Redis 3.0.503的Windows版本。通常,这会是一个名为“3.0.503”的压缩包文件。 2. 解压安装包:将下载的压缩包解压到你选择的任意目录,例如"C:\Program ...

    Redis 3.0 中文版,纯文字版

    在Redis 3.0版本中,它已经具备了丰富的特性和功能,使其成为开发者们青睐的NoSQL数据库之一。以下是关于Redis 3.0的一些关键知识点: 1. **数据类型**:Redis支持五种基本数据类型,包括字符串(String)、哈希(Hash...

    Windows下Redis3.0 编译过后的exe

    在Windows环境下编译Redis3.0,可以让你在本地系统上测试和开发基于Redis的应用,尤其是利用其新特性——Cluster。 **Redis3.0的新特性:** 1. **Cluster支持**:Redis 3.0引入了Cluster功能,这是一个分布式解决...

    redis3.0-windows

    1. **下载**:首先从官方或者可靠的源获取redis3.0的Windows二进制文件,这通常是一个.zip压缩包。 2. **解压**:解压缩文件到你选择的目录,通常包含`redis-server.exe`和`redis-cli.exe`等可执行文件。 3. **配置*...

    redis3.0widows集群+spring整合jedis

    redis3.0 widows集群 spring整合jedis redis搭建window集群代码和文档rubygems-2.5.1和rubyinstaller-2.2.3-x64软件下载

    redis3.0 windows64位

    3. **Redis Cluster**:在3.0版本中,官方正式支持了Redis Cluster,这是一个分布式解决方案,可以将数据分片到多个节点,实现自动故障转移和扩展性。 4. **Streams**:虽然这个特性在后来的版本中才引入,但了解...

    Redis 3.0.504 64位

    这个版本是Redis 3.0.504的64位版本,适合在Windows操作系统上运行。它是一个绿色免安装版本,意味着你无需经过传统安装过程,只需将压缩包解压到任意目录,然后执行`startup.bat`脚本就可以启动Redis服务器。 1. *...

    redis-3.0.504 for windows

    1. 下载:首先,你需要从官方或者可靠的第三方源下载Redis 3.0.504 for Windows的压缩包。压缩包名称为"Redis-windows"。 2. 解压:下载完成后,解压缩到你希望安装的目录,例如"C:\Program Files\Redis"。 3. ...

    Redis3.0.504

    Redis 3.0.504 是一个稳定版本的开源键值存储系统,以其高性能、丰富的数据结构和灵活的数据操作而被广泛应用于缓存、数据库和消息中间件等多个场景。这个版本是为32位操作系统设计的,确保了在资源有限的环境下也能...

    Redis 3.0 window版

    redis3.0windows版,解压后可直接使用

Global site tag (gtag.js) - Google Analytics