欢迎来到冰点文库! | 帮助中心 分享价值,成长自我!
冰点文库
全部分类
  • 临时分类>
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • ImageVerifierCode 换一换
    首页 冰点文库 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    redis集群学习笔记.docx

    • 资源ID:18076761       资源大小:26.79KB        全文页数:19页
    • 资源格式: DOCX        下载积分:6金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要6金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    redis集群学习笔记.docx

    1、redis集群学习笔记Redis集群Redis集群介绍Redis集群是一个提供在多个Redis间节点间共享数据的程序集.Redis集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误.Redis集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令.Redis集群的优势: 自动分割数据到不同的节点上. 整个集群的部分节点失败或者不可达的情况下能够继续处理命令.Redis集群的数据分片Redis集群没有使用一致性hash, 而是引入了哈希槽的概念.Redis集群有16

    2、384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么: 节点 A 包含 0 到 5500号哈希槽. 节点 B 包含5501 到 11000 号哈希槽. 节点 C 包含11001 到 16384号哈希槽.这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我像移除节点A,需要将A中得槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可.由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈

    3、希槽的数量都不会造成集群不可用的状态.Redis集群的主从复制模型为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品.在我们例子中具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用.然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了不过当B和B1 都

    4、失败后,集群人爱是不可用的.Redis一致性保证Redis并不能保证数据的强一致性. 这意味这在实际中集群在特定的条件下可能会丢失写操作.第一个原因是因为集群是用了异步复制. 写操作过程: 客户端向主节点B写入一条命令. 主节点B向客户端回复命令状态. 主节点将写操作复制给他得从节点 B1, B2 和 B3.主节点对命令的复制工作发生在返回命令回复之后,因为如果每次处理命令请求都需要等待复制操作完成的话,那么主节点处理命令请求的速度将极大地降低 我们必须在性能和一致性之间做出权衡。注意:Redis集群可能会在将来提供同步写的方法。Redis集群另外一种可能会丢失命令的情况是集群出现了网络分区,

    5、并且一个客户端与至少包括一个主节点在内的少数实例被孤立。.举个例子假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点,其中 A 、B 、C 为主节点, A1 、B1 、C1 为A,B,C的从节点,还有一个客户端 Z1假设集群中发生网络分区,那么集群可能会分为两方,大部分的一方包含节点 A 、C 、A1 、B1 和 C1 ,小部分的一方则包含节点 B 和客户端 Z1 .Z1仍然能够向主节点B中写入, 如果网络分区发生时间较短,那么集群将会继续正常运作,如果分区的时间足够让大部分的一方将B1选举为新的master,那么Z1写入B中得数据便丢失了.注意,在网络分裂出现期间,客户

    6、端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的,这一时间限制称为节点超时时间(node timeout),是Redis集群的一个重要的配置选项:搭建并使用Redis集群搭建集群的第一件事情我们需要一些运行在集群模式的Redis实例. 这意味这集群并不是由一些普通的Redis实例组成的,集群模式需要通过配置启用,开启集群模式后的Redis实例便可以使用集群特有的命令和特性了.下面是一个最少选项的集群的配置文件:port 7000cluster-enabled yescluster-config-filenodes.confcluster-node-timeout 5000append

    7、only yes文件中的 cluster-enabled 选项用于开实例的集群模式,而 cluster-conf-file 选项则设定了保存节点配置文件的路径,默认值为nodes.conf.节点配置文件无须人为修改,它由Redis集群在启动时创建,并在有需要时自动进行更新。要让集群正常运作至少需要三个主节点,不过在刚开始试用集群功能时,强烈建议使用六个节点:其中三个为主节点,而其余三个则是各个主节点的从节点。首先,让我们进入一个新目录,并创建六个以端口号为名字的子目录,稍后我们在将每个目录中运行一个Redis实例:命令如下:mkdir cluster-testcd cluster-testmk

    8、dir 7000 7001 7002 7003 7004 7005在文件夹 7000 至 7005 中,各创建一个redis.conf文件,文件的内容可以使用上面的示例配置文件,但记得将配置中的端口号从 7000 改为与文件夹名字相同的号码。从RedisGithub页面的 unstable 分支中取出最新的Redis源码,编译出可执行文件redis-server ,并将文件复制到 cluster-test 文件夹,然后使用类似以下命令,在每个标签页中打开一个实例:cd 7000./redis-server ./redis.conf实例打印的日志显示,因为nodes.conf文件不存在,所以每个

    9、节点都为它自身指定了一个新的 ID :82462 26 Nov 11:56:55.329 * No cluster configuration found, Im 97a3a64667477371c4479320d683e4c8db5858b1实例会一直使用同一个 ID ,从而在集群中保持一个独一无二(unique)的名字。搭建集群现在我们已经有了六个正在运行中的Redis实例,接下来我们需要使用这些实例来创建集群,并为每个节点编写配置文件。通过使用Redis集群命令行工具redis-trib,编写节点配置文件的工作可以非常容易地完成:redis-trib位于Redis源码的src文件夹中,它

    10、是一个 Ruby 程序,这个程序通过向实例发送特殊命令来完成创建新集群,检查集群,或者对集群进行重新分片(reshared)等工作。./redis-trib.rbcreate -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这个命令在这里用于创建一个新的集群, 选项-replicas 1表示我们希望为集群中的每个主节点创建一个从节点。之后跟着的其他参数则是这个集群实例的地址列表,3个master3个slaveredis-trib会打印出一份预

    11、想中的配置给你看,如果你觉得没问题的话,就可以输入 yes ,redis-trib就会将这份配置应用到集群当中,让各个节点开始互相通讯,最后可以得到如下信息:OK All 16384 slots covered这表示集群中的 16384 个槽都有至少一个主节点在处理,集群运作正常。使用集群Redis集群现阶段的一个问题是客户端实现很少。以下是一些我知道的实现: redis-rb-cluster是我(antirez)编写的 Ruby 实现,用于作为其他实现的参考。该实现是对redis-rb的一个简单包装,高效地实现了与集群进行通讯所需的最少语义(semantic). redis-py-clust

    12、erredis-py-cluster 看上去是redis-rb-cluster 的一个 Python 版本,这个项目有一段时间没有更新了(最后一次提交是在六个月之前),不过可以将这个项目用作学习集群的起点。 流行的Predis曾经对早期的Redis集群有过一定的支持,但我不确定它对集群的支持是否完整,也不清楚它是否和最新版本的Redis集群兼容(因为新版的Redis集群将槽的数量从 4k 改为 16k 了). 使用最多的时java客户端,Jedis最近添加了对集群的支持, 详细请查看项目README中Jedis Cluster部分. Redis unstable 分支中的redis-cli程序

    13、实现了非常基本的集群支持,可以使用命令redis-cli -c来启动。测试Redis集群比较简单的办法就是使用redis-rb-cluster或者redis-cli,接下来我们将使用redis-cli为例来进行演示:$ redis-cli -c -p 7000redis 127.0.0.1:7000 set foo bar- Redirected to slot 12182 located at 127.0.0.1:7002OKredis 127.0.0.1:7002 set hello world- Redirected to slot 866 located at 127.0.0.1:70

    14、00OKredis 127.0.0.1:7000 get foo- Redirected to slot 12182 located at 127.0.0.1:7002barredis 127.0.0.1:7000 get hello- Redirected to slot 866 located at 127.0.0.1:7000worldredis-cli 对集群的支持是非常基本的,所以它总是依靠Redis集群节点来将它转向(redirect)至正确的节点。一个真正的(serious)集群客户端应该做得比这更好:它应该用缓存记录起哈希槽与节点地址之间的映射(map),从而直接将命令发送到正

    15、确的节点上面。这种映射只会在集群的配置出现某些修改时变化,比如说,在一次故障转移(failover)之后,或者系统管理员通过添加节点或移除节点来修改了集群的布局(layout)之后,诸如此类。使用redis-rb-cluster写一个例子在展示如何使用集群进行故障转移、重新分片等操作之前,我们需要创建一个示例应用,了解一些与Redis集群客户端进行交互的基本方法。在运行示例应用的过程中,我们会尝试让节点进入失效状态,又或者开始一次重新分片,以此来观察Redis集群在真实世界运行时的表现,并且为了让这个示例尽可能地有用,我们会让这个应用向集群进行写操作。本节将通过两个示例应用来展示redis-r

    16、b-cluster 的基本用法,以下是本节的第一个示例应用,它是一个名为example.rb的文件,包含在redis-rb-cluster 项目里面1 require ./cluster 23 startup_nodes = 4 :host = 127.0.0.1, :port = 7000, 5 :host = 127.0.0.1, :port = 70016 7 rc = RedisCluster.new(startup_nodes,32,:timeout = 0.1) 89 last = false 1011 while not last 12 begin 13 last = rc.ge

    17、t(_last_) 14 last = 0 if !last15 rescue = e 16 puts error #e.to_s 17 sleep 1 18 end19 end 2021 (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.130 这个应用所做的工作非常简单:它不断地以 foo为键, number 为值,使用 SET

    18、命令向数据库设置键值对: SET foo0 0 SET foo1 1 SET foo2 2 And so forth.代码中的每个集群操作都使用一个 begin 和 rescue 代码块(block)包裹着,因为我们希望在代码出错时,将错误打印到终端上面,而不希望应用因为异常(exception)而退出。代码的第七行是代码中第一个有趣的地方,它创建了一个Redis集群对象,其中创建对象所使用的参数及其意义如下:第一个参数是记录了启动节点的startup_nodes列表,列表中包含了两个集群节点的地址。第二个参数指定了对于集群中的各个不同的节点,Redis集群对象可以获得的最大连接数,第三个参数

    19、 timeout 指定了一个命令在执行多久之后,才会被看作是执行失败。启动列表中并不需要包含所有集群节点的地址,但这些地址中至少要有一个是有效的:一旦redis-rb-cluster 成功连接上集群中的某个节点时,集群节点列表就会被自动更新,任何真正的的集群客户端都应该这样做。现在,程序创建的Redis集群对象实例被保存到rc变量里面,我们可以将这个对象当作普通Redis对象实例来使用。在十一至十九行,我们先尝试阅读计数器中的值,如果计数器不存在的话,我们才将计数器初始化为 0 :通过将计数值保存到Redis的计数器里面,我们可以在示例重启之后,仍然继续之前的执行过程,而不必每次重启之后都从

    20、foo0 开始重新设置键值对。为了让程序在集群下线的情况下,仍然不断地尝试读取计数器的值,我们将读取操作包含在了一个 while 循环里面,一般的应用程序并不需要如此小心。二十一至三十行是程序的主循环,这个循环负责设置键值对,并在设置出错时打印错误信息。程序在主循环的末尾添加了一个 sleep 调用,让写操作的执行速度变慢,帮助执行示例的人更容易看清程序的输出。执行example.rb程序将产生以下输出:ruby ./example.rb123456789C (I stopped the program here)这个程序并不是十分有趣,稍后我们就会看到一个更有趣的集群应用示例,不过在此之前,

    21、让我们先使用这个示例来演示集群的重新分片操作。集群重新分片现在,让我们来试试对集群进行重新分片操作。在执行重新分片的过程中,请让你的example.rb程序处于运行状态,这样你就会看到,重新分片并不会对正在运行的集群程序产生任何影响,你也可以考虑将example.rb中的 sleep 调用删掉,从而让重新分片操作在近乎真实的写负载下执行重新分片操作基本上就是将某些节点上的哈希槽移动到另外一些节点上面,和创建集群一样,重新分片也可以使用redis-trib程序来执行执行以下命令可以开始一次重新分片操作:./redis-trib.rbreshard 127.0.0.1:7000你只需要指定集群中其

    22、中一个节点的地址,redis-trib就会自动找到集群中的其他节点。目前redis-trib只能在管理员的协助下完成重新分片的工作,要让redis-trib自动将哈希槽从一个节点移动到另一个节点,目前来说还做不到你像移动多少个槽( 从1 到 16384)?我们尝试从将100个槽重新分片,如果example.rb程序一直运行着的话,现在 1000 个槽里面应该有不少键了。除了移动的哈希槽数量之外,redis-trib还需要知道重新分片的目标,也即是,负责接收这 1000 个哈希槽的节点。$ redis-cli -p 7000 cluster nodes | grep myself97a3a646

    23、67477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5460我得目标节点是 97a3a64667477371c4479320d683e4c8db5858b1.现在需要指定从哪写节点来移动keys到目标借调我输入的是all,这样就会从其他每个master上取一些哈希槽。最后确认后你将会看到每个redis-trib移动的槽的信息,每个key的移动的信息也会打印出来在重新分片的过程中,你得例子程序是不会受到影响的,你可以停止或者重新启动多次。在重新分片结束后你可以通过如下命令检查集群状态:一个更有趣的程序我们在前

    24、面使用的示例程序example.rb并不是十分有趣,因为它只是不断地对集群进行写入,但并不检查写入结果是否正确。比如说,集群可能会错误地将example.rb发送的所有 SET 命令都改成了 SET foo 42 ,但因为example.rb并不检查写入后的值,所以它不会意识到集群实际上写入的值是错误的因为这个原因,redis-rb-cluster 项目包含了一个名为 consistency-test.rb的示例应用,这个应用比起example.rb有趣得多:它创建了多个计数器(默认为 1000 个),并通过发送 INCR 命令来增加这些计数器的值。在增加计数器值的同时, consistenc

    25、y-test.rb还执行以下操作: 每次使用 INCR 命令更新一个计数器时,应用会记录下计数器执行 INCR 命令之后应该有的值。举个例子,如果计数器的起始值为 0 ,而这次是程序第 50 次向它发送 INCR 命令,那么计数器的值应该是 50 。 在每次发送 INCR 命令之前,程序会随机从集群中读取一个计数器的值,并将它与自己记录的值进行对比,看两个值是否相同。换句话说,这个程序是一个一致性检查器(consistency checker):如果集群在执行 INCR 命令的过程中,丢失了某条 INCR 命令,又或者多执行了某条客户端没有确认到的 INCR 命令,那么检查器将察觉到这一点 在

    26、前一种情况中, consistency-test.rb记录的计数器值将比集群记录的计数器值要大;而在后一种情况中, consistency-test.rb记录的计数器值将比集群记录的计数器值要小。运行 consistency-test 程序将产生类似以下的输出:$ ruby consistency-test.rb925 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

    27、err) | 17780 W (0 err) |22025 R (0 err) | 22025 W (0 err) |25818 R (0 err) | 25818 W (0 err) |结果展示了执行的读和写,和错误(由于系统不可用而没有接受的查询发生的错误)的数量.如果程序察觉了不一致的情况出现,它将在输出行的末尾显式不一致的详细情况。比如说,如果我们在 consistency-test.rb运行的过程中,手动修改某个计数器的值:$ redis 127.0.0.1:7000 set key_217 0OK(in the other tab I see.)94774 R (0 err) |

    28、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 |在我们修改计数器值的时候,计数器的正确值是 114 (执行了 114 次 INCR 命令),因为我们将计数器的值设成了 0 ,所以 consistency-test.rb会向我们报告说丢失了 114 个 INCR 命令。这个程序作为测试程序很有意思,所以我们用这个程序来测试故障恢复.测试故障转移在执行本

    29、节操作的过程中,请一直运行 consistency-test 程序。要触发一次故障转移,最简单的办法就是令集群中的某个主节点进入下线状态。首先用以下命令列出集群中的所有主节点:$ redis-cli -p 7000 cluster nodes | grep master3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 127.0.0.1:7001 master - 0 138*82 0 connected 5960-109212938205e12de373867bf38f1ca29d31d0ddb3e46 127.0.0.1:7002 master - 0 13

    30、8*82 0 connected 11423-1638397a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5959 10922-11422通过命令输出得知端口号为 7000 、 7001 和 7002 的节点都是主节点,然后我们可以通过向端口号为7002 的主节点发送 DEBUG SEGFAULT 命令,让这个主节点崩溃:$ redis-cli -p 7002 debug segfaultError: Server closed the connection现在,切换到运行着 consis

    31、tency-test 的标签页,可以看到, consistency-test 在 7002 下线之后的一段时间里将产生大量的错误警告信息: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) |从 consistency-test 的这段输出可以看到,集群在执行故障转移期间,总共丢失了 578 个读命令和 577 个写命令,但是并没


    注意事项

    本文(redis集群学习笔记.docx)为本站会员主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2023 冰点文库 网站版权所有

    经营许可证编号:鄂ICP备19020893号-2


    收起
    展开