摘要: 豁达是正确乐观的面对失败的系统。不需要过多的担心,需要一种去说那又怎样的能力。因此架构的设计是如此的重要。许多优秀的系统没有进一步成长的能力,我们应该做的是使用其他的系统去共同分担工作。 Redis是 其中一 ...

豁达是正确乐观的面对失败的系统。不需要过多的担心,需要一种去说那又怎样的能力。因此架构的设计是如此的重要。许多优秀的系统没有进一步成长的能力,我们应该做的是使用其他的系统去共同分担工作。

Redis是 其中一个吸引我的系统,一个持久性的,键值对存储内存操作高性能的平台。它是一个优秀的键值对数据库。我已经在使用了。即使AWS最近宣布开始支持 ElasticCache的下级缓存。但是一个无主的redis集群仍然起着重要的作用。我们需要多系统去完成工作。同时,我们能够集合多种组件在一个容 错和无主的集群里共同工作么?在这片文章中我将介绍梦幻般的redis。

一致哈希

构建一个存储数据集群的关键是有一个有效的数据存储和复制机制。我希望通过一个行之有效的方法来说明建造一个数据集群,在这个过程中你可以随意添加或移除一个Redis节点,同时保证你的数据仍然存在,而不会消失。这个方法称为一致哈希。

由于它不是一个很明显的概念,我将用一点时间来解释一下。为了理解一致哈希,你可以想像有一个函数f(x),对于给定的x总是返回一个1到60(为什么是 60?你会知道的,但现在请等等)之间的结果,同样对于一个唯一的x,f(x)总是返回相同的结果。这些1到60的值按顺时针排成一个环。

现在集群中 的每个节点都需要一个唯一的名字。所以如果你将这个名字传递给f(''),它将返回一个1到60之间的数字(包括1和60),这个数字就是节点在环上的位 置。当然它只是节点的逻辑(记录的)位置。这样,你获得一个节点,将它传给哈希函数,获得结果并将它放到环上。是不是很简单?这样每个节点都在环上有了它 自己的位置。假设这里有5个Redis节点,名字分别为'a','b','c','d','e'。每个节点都传给哈希函数f(x)并且放到了环上。在这里 f('a') = 21, f('b') = 49, f('c') = 11, f('d') = 40, f('e') = 57。一定记得这里位置是逻辑位置。

那么,我们为什么要将节点放在一个环上呢?将节点放到环上的目的是确定拥有哪些哈希空间。图中的节点'd'拥有的哈希空间就是f('a')到f('d') (其值为40)之间的部分,包括f('d'),即(21, 40]。也就是说节点'd'将拥有键x,如果f(x)的属于区间(21, 40】。比如键‘apple’,其值f('apple') = 35,那么键'apple'将被存在'd'节点。类似的,每个存储在集群上的键都会通过哈希函数,在环上按顺时针方向被恰当地存到最近的节点。

虽然一致哈希讲完了,但应知道,在多数情况下,这种类型的系统是伴随着高可用性而构建。为了满足数据的高可用性,需要根据一些因子进行复制, 这些因子称为复制因子。假设我们集群的复制因子为2,那么属于'd'节点的数据将会被复制到按顺时针方向与之相隔最近的'b'和'e'节点上。这就保证了 如果从'd'节点获取数据失败,这些数据能够从'b'或'e'节点获取。

不仅仅是键使用一致哈希来存储,也很容易覆盖失败了的节点,并且复制因子依然完好有效。比如'd'节点失败了,'b'节点将获取'd'节点哈希空间的所有权,同时'd'节点的哈希空间能够很容易地复制到'c'节点。

坏事和好事

坏事就是目前这些讨论过的所有概念,复制(冗余),失效处理以及集群规模等,在Redis之外是不可行的。一致哈希仅仅描述了节点在哈希环上的映射以及那些哈希数据的所有权,尽管这样,它仍然是构建一个弹性可扩展系统的极好的开端。

好事就是,也有一些分立的其他工具在Redis集群上实现一致哈希,它们能提醒节点失效和新节点的加入。虽然这个功能不是一个工具的一部分,我们将看到如何用多个系统来使一个理想化的Redis集群运转起来。

Twemproxy aka Nutcracker

Twemproxy是一个开源工具,它是一个基于memcached和Redis协议的快速、轻量的代理。其本质就是,如果你有一些Redis服务器在运行,同时希望用这些服务器构建集群,你只需要将Twemproxy部署在这些服务器前端,并且让所有Redis流量都通过它。

Twemproxy除了能够代理Redis流量外,在它存储数据在Redis服务器时还能进行一致哈希。这就保证了数据被分布在基于一致哈希的多个不同Redis节点上。

但是Twemproxy并没有为Redis集群建立高可用性支持。最简单的办法是为集群中的每个节点都建立一个从(冗余)服务器,当主服务器失效时将从(冗余)服务器提升为主服务器。为Redis配置一个从服务器是非常简单的。

这种模型的缺点是非常明显的,它需要为Redis集群中的每个节点同时运行两个服务器。但是节点失效也是非常明显,并且更加危险,所以我们怎么知道这些问题并解决。

Gossip on Serf

Gossip是一个标准的机制,通过这个机制集群上的节点可以很清楚的了解成员的最新情况。这样子集群中的每个节点就很清楚集群中节点的变化,如节点的新增和节目的删除。

Serf通过实现Gossip机制提供这样的帮助。Serf是一个基于代理的机制,这个机制实现了Gossip的协议达到节点成员信息交换的目的。Serf是不断运行,除此之外,它还可以生成自定义的事件

现在拿我们的节点集群为例,如果每个节点上也有一个serf代理正在运行,那么节点与节点之间可以进行细节交换.因此,群集中的每个节点都能清楚知道其他节点的存在,也能清楚知道他们的状态。

这还并不够,为了高可靠性我们还需要让twemproxy知道何时一个节点已经失效,这样的话它就可以据此修改它的配置。像前面提到的Serf,就可以做 到这一点,它是基于一些gossip触发的事件,使用自定义动作实现的。因此只要集群中的一个Redis节点因为一些原因宕掉了,另一个节点就可以发送有 成员意外掉线的消息给任何给定的端点,这个端点在我们的案例中也就是twemproxy服务器。

这还不是全部

现在我们有了Redis集群,基于一致性哈希环,相应的是用twemproxy存储数据(一致性哈希),还有Serf,它用gossip协议来检测Redis集群成员失效,并且向twemproxy发送失效消息;但是我们还没有建立起理想化的Redis集群。

消息侦听器

虽然Serf可以给任何端点发送成员离线或者成员上线消息。然而twemproxy却没有侦听此类事件的机制。因此我们需要自定义一个侦听器,就像Redis-Twenproxy代理,它需要做以下这些事情。

  • 侦听Serf消息
  • 更新nutcraker.yml 以反映新的拓扑
  • 重启twemproxy

这个消息侦听器可以是一个小型的http服务器;它在收到一批POST数据的时候,为twemproxy做以上列表中的动作。需要记住的是,这种消息应该 是一个原子操作;因为当一个节点失效(或者意外离线)的时候,所有能发消息的活动节点都将发送这个失效事件消息给侦听器;但是侦听器应该只响应一次。

数据复制

在上面的“一致哈希”中,我提到了Redis集群中的复制因素。同样它也不是Twemproxy的固有特性;Twemproxy只关心使用一致哈希存储一 个拷贝。所以在我们追求理想化Redis集群的过程中,我们还需要给twemproxy或者redis自己创建这种复制的能力。

为了给Twenproxy创建复制能力,需要将复制因子作为一个配置项目,并且将数据保存在集群中相邻的redis节点(根据复制因子)。由于twemproxy知道节点的位置,所以这将给twemproxy增加一个很棒的功能。

由于twemproxy只不过是代理服务器,它的简单功能就是它强大的地方,为它创建复制管理功能将使它臃肿膨胀。

Redis 主从环

在思考这其中的工作机制的时候,我忽然想到,为什么不将每个节点设置成另一个节点的副本,或者说从节点,并由此而形成一个主从环呢?

这样的话如果一个节点失效了,失效节点的数据在这个环上相邻的节点上仍然可以获得。而那个具有该数据副本的节点,将作为该节点的从节点,并提供保存数据副 本的服务。这是一个既是主节点也是从节点的环。Serf仍像通常一样作为散布节点失效消息的代理。但是这一回,我们twenproxy上的的客户端,即侦 听器,将不仅仅只更新twenproxy上的失效信息,还要调整redis服务器群集来适应这个变化。

在这个环中有一个明显的,同样也是技术方面的缺陷。这个明显的缺陷是,这个环会坏掉,因为从节点的从节点无法判别哪一个是它的主节点的数据,哪一个是它的主节点的主节点的数据。这样的话就会循环的传送所有的数据。

同样技术性的问题是,一旦redis将主节点的数据同步给从节点,它就会将从节点的数据擦除干净;这样就将曾经写到从节点的所有数据删除了。这种主从环显 然不能实际应用,除非修改主从环的复制机制以适应我们的需求。这样的话每个从节点就不会将它的主节点的数据同步给它的从节点。要想实现这一点,必须的条件 是每个节点都可以区分出自己的密钥空间,以及它的主节点的密钥空间;这样的话它就不会将主节点的数据传送给它的从节点。

那么这样一来,当一个节点失效时,就需要执行四个动作。一,将失效节点的从节点作为它的密钥空间的所有者。二,将这些密钥散布给失效节点从节点的从节点,以便进行复制。三,将失效节点的从节点作为失效节点的主节点的从节点。最后,在新的拓扑上复位twemproxy。

如何理想化?

事实上并没有这样的Redis集群,它可以具有一致性的哈希,高可靠性以及分区容错性。因此最后一幅图片描绘了一种理想化的Redis集群;但这并不是不可能的。接下来将罗列一下需要哪些条件才能使之成为一个实实在在的产品。

透明的Twenproxy

有必要部署一个Twenproxy,这会使得Hash散列中Redis各节点的位置都是透明的。每个Redis节点都可以知道自己以及其相邻节点的位置, 这些信息对于节点的主从复制以及失败节点的修复是有必要的。自从Twenproxy开源之后,节点的位置信息可以被修改、以及扩展。

Redis的数据拥有权

这是比较困难的部分的,每个Redis节点都应该记录自身拥有的数据,以及哪些是主节点的数据。当前这样的隔离是不可能的。这也需要修改Redis的基础代码,这样节点才知道何时与从节点同步,什么时候不需要。

综上所述,我们的理想化的Redis集群变成现实需要修改这样的两个组件。一直以来,它们都是非常大的工业级别,使用在生产环境中。这已经值得任何人去实现这个集群了。

原文出处:http://megam.in/post/66659169136/utopian-redis-cluster

本文转载自:http://www.oschina.net/translate/utopian-redis-cluster

理想化的 Redis 集群相关推荐

  1. docker 实现redis集群搭建

    摘要:接触docker以来,似乎养成了一种习惯,安装什么应用软件都想往docker方向做,今天就想来尝试下使用docker搭建redis集群. 首先,我们需要理论知识:Redis Cluster是Re ...

  2. Redis 集群部署及踩过的坑

    本文目标 要在单台机器上搭建Redis集群,方式是通过不同的TCP端口启动多个实例,然后组成集群,同时记录在搭建过程中踩过的坑. 安装准备 centos版本:6.7 redis版本:3.2.3 安装方 ...

  3. windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error...

    windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error 学习了:https ...

  4. Redlock——Redis集群分布式锁

    欢迎关注方志朋的博客,回复"666"获面试宝典 前言 分布式锁是一种非常有用的技术手段.实现高效的分布式锁有三个属性需要考虑: 安全属性:互斥,不管什么时候,只有一个客户端持有锁 ...

  5. Redis数据库搭建集群(集群概念、redis集群、搭建集群(配置机器1、2、创建集群、数据操作验证)、Python与redis集群交互)

    1. 集群的概念 集群是一组相互独立的.通过高速网络互联的计算机,它们构成了一个组,并以单一系统的模式加以管理.一个客户与集群相互作用时,集群像是一个独立的服务器.集群配置是用于提高可用性和可缩放性. ...

  6. Redis 集群方案

    根据一些测试整理出来的一份方案: 1. Redis 性能 对于redis 的一些简单测试,仅供参考: 测试环境:Redhat6.2 , Xeon E5520(4核)*2/8G,1000M网卡 Redi ...

  7. 如何从0到1构建一个稳定、高性能的Redis集群?(附16张图解)

    阅读本文大约需要 13 分钟. 大家好,我是 Kaito. 这篇文章我想和你聊一聊 Redis 的架构演化之路. 现如今 Redis 变得越来越流行,几乎在很多项目中都要被用到,不知道你在使用 Red ...

  8. 天天用着Redis集群,主从同步该知道吧?集群工作原理是否需要了解下?

    作者:z小赵 ★ 一枚用心坚持写原创的"无趣"程序猿,在自身受益的同时也让朋友们在技术上有所提升. 前言 插播一个小插曲,本来文章已经写好准备发布了,手贱清理了缓存导致文本内容全部 ...

  9. 那些年用过的Redis集群架构(含面试解析)

    作者:孤独烟,平安银行资深后端工程师一枚! 引言 今天是2019年2月13号,也就是大年初九,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上R ...

最新文章

  1. 模板方法模式(Template Pattern)
  2. golang interface传结构体
  3. JAVA原生mvc实现用户信息的增删查改
  4. XCTF-高手进阶区:NewsCenter
  5. 大话数据结构18:最小生成树算法
  6. Linux 6安装kde桌面,CentOS 5/6 安装 GNOME 或 KDE 桌面
  7. 如何使柱状图左右展示_Excel多次层柱状图,让数据展示更清晰,简单五步就完成...
  8. jqery 实现滚动图片【三】
  9. mysql完成未完成_MYSQL SQL模式 (未完成)
  10. 收藏 | Transformer 论文详细解读
  11. 浅谈密码学中数论基础
  12. 【Unity】NGUI下载与导入
  13. 神经网络matlab仿真,MATLAB神经网络仿真与应用_IT教程网
  14. spec 文件 autopatch
  15. vue 用webpack打包文件名添加版本号
  16. 介绍几种 Windows10 自带的截图方式
  17. U盘、移动硬盘加密工具绿色版
  18. python绘制动漫人物图片女生可爱_绘画动漫人物图片女生唯美
  19. 鸿蒙文化博物馆,有趣、有味、有文化!“周末儿童博物馆”在成博欢乐启幕
  20. sql assistant mysql_SQL Assistant

热门文章

  1. 编译原理pl/0 c语言版 pl0.h文件
  2. day16 java的访问控制权限
  3. 02_使用jq实现进入和离开动画
  4. ES6_proxy_note
  5. 基于redis购物车java代码_基于redis实现购物车基本功能
  6. java 装饰器_装饰器模式(Java)
  7. linux批量文件编码转换,Linux系统批量转换文件编码脚本
  8. Python数据分析:pandas玩转Excel(一)
  9. VBA读取html表格内容,科学网—VBA读取word文档表格中table的cell的text文本 - 付安民的博文...
  10. linux桌面隐藏鼠标,如何隐藏鼠标光标