来自Redis 做者的见解 —— Twemproxy

 

虽然大量用户使用Redis节点的大型农场,但从项目自己来看,Redis主要是单实例业务。
 我有很大的计划与项目一块儿分发,在某种程度上我再也不评估Redis的任何线程版本:对我来讲,从Redis的角度看,核心就像一台计算机,所以能够扩展多核或者在一组计算机上的概念是相同的。多个实例是无共享架构。一切都有意义,由于咱们有一个*可信的方式*去碎片:-)

这就是为何Redis Cluster将成为2013年Redis的主要焦点,最后,如今Redis 2.6已经出现而且显示出很是稳定和成熟,如今是专一于Redis Cluster,Redis Sentinel和其余产品的合适时机。期待已久的复制领域的改进(部分从新同步)。
 但实际状况是,Redis Cluster还没有准备就绪,须要数月的工做。咱们的用户仍然须要对多个实例上的数据进行分片以分配负载,特别是为了使用许多计算机来为数据准备大量的RAM。
 到目前为止惟一的选择是客户端分片。客户端分片具备优点,由于客户端和节点之间没有中间层,也没有请求路由,所以它是一种很是可扩展的设置(基本上是线性可扩展的)。可是,要可靠地实现它须要一些调整,一种使客户端配置同步的方法,以及具备一致散列支持或其余分区算法的可靠客户端的可用性。
 显然,这方面有一个重大新闻,而且与Twitter有关,其中部署的最大的Redis农场之一刚好为用户提供服务时间表。所以,我在博客文章中谈到的项目来自Twitter开源部门并不奇怪。

Twemproxy
---

Twemproxy是一个支持Memcached ASCII协议的快速单线程代理,最近是Redis协议:

https://github.com/twitter/twemproxy

它彻底用C语言编写,并根据Apache 2.0许可证受权。
该项目适用于Linux,AFAIK没法在OSX上编译,由于它依赖于epoll API。

我使用个人Ubuntu 12.04桌面进行了测试。
 可是,我仍然没有说任何有用的东西。其实是什么twemproxy?(注意:我将专一于Redis部分,但项目也可以为memcached作一样的事情)。

1)它做为客户端和许多Redis实例之间的代理。
2)它可以在配置的Redis实例之间自动分片数据。
3)它支持具备不一样策略和散列函数的一致散列。
 Twemproxy的优势是它能够配置为在发生故障时禁用节点,并在一段时间后重试,或者坚持指定的键 - >服务器映射。这意味着当Redis用做数据存储(禁用节点弹出)时,以及当Redis用做缓存时,它既适用于分割Redis数据集,也适用于廉价的节点弹出(如简单,不如质量差)高可用性。
 这里的底线是:若是启用节点弹出,当节点出现故障时,数据可能会终止到其余节点,所以没法保证一致性。另外一方面,若是禁用节点弹出,则须要设置每一个实例的高可用性设置,例如使用Redis Sentinel自动故障转移。

安装
---
 在深刻了解项目功能以前,我有一个好消息,在Linux上构建它是微不足道的。好吧,不像Redis那么微不足道,可是......你只须要遵循这些简单的步骤:

apt-get install automake
apt-get install libtool
git clone git://github.com/twitter/twemproxy.git
cd twemproxy
autoreconf -fvi
./configure --enable-debug = log
使
src / nutcracker -h
 配置也很是简单,项目github页面中有足够的文档能够得到顺畅的初体验。例如,我使用了如下配置:

redis1:
  听:0.0.0.0:9999
  redis:是的
  hash:fnv1a_64
  分布:ketama
  auto_eject_hosts:true
  超时:400
  server_retry_timeout:2000
  server_failure_limit:1
  服务器:
   - 127.0.0.1:6379:1
   - 127.0.0.1:6380:1
   - 127.0.0.1:6381:1
   - 127.0.0.1:6382:1

redis2:
  听:0.0.0.0:10000
  redis:是的
  hash:fnv1a_64
  分布:ketama
  auto_eject_hosts:false
  超时:400
  服务器:
   - 127.0.0.1:6379:1
   - 127.0.0.1:6380:1
   - 127.0.0.1:6381:1
   - 127.0.0.1:6382:1

基本上,第一个集群配置了节点弹出,第二个集群配置为配置实例中的静态映射。
 最棒的是,您能够同时拥有多个可能涉及相同主机的设置。可是对于生产,我发现更适合使用多个实例来使用多个核心。

单点故障?
---

另外一个很是有趣的事实是,实际上,使用此设置并不意味着您只有一个故障点,由于您能够运行多个twemproxy实例并让您的客户端链接到第一个可用的实例。
 基本上你用twemproxy作的是将分片逻辑与你的客户端分开。此时,基本客户端将执行该操做,分片将由代理处理。

分区恕我直言是一种简单但安全的方法。
 目前,Redis群集不可用,我想说,对于今天想要一群Redis实例的大多数用户来讲,这是一种方法。可是要先阅读有关限制的内容,以避免太兴奋;)

限制
---
 我认为twemproxy作得对,不支持多个键命令和事务。目前,AFAIK比Redis Cluster更严格,若是全部命令都是相同的密钥,则容许使用MULTI / EXEC块。

但恕我直言,这是可行的方式,分发您能够有效分发的子集,并尽早将其做为设计挑战,而不是将大量资源投入到试图聚合来自多个实例的数据的“正常工做”实现中可是,一旦你开始出现严重负荷,因为太大的恒定时间来移动数据,这几乎不会足够快。
 可是,对具备多个键的命令有一些支持。MGET和DEL处理正确。有趣的是,MGET将在不一样服务器之间拆分请求,并将回复做为单个实体返回。即便我没有使用此功能得到正确的性能数字,这也很酷(见下文)。
 不管如何,不​​支持多键命令和事务这意味着twemproxy不适合全部人,就像Redis Cluster自己同样。特别是由于显然不支持EVAL(我认为它们应该支持它!它是微不足道的,EVAL被设计为在代理中工做,由于键名是明确的)。

能够改进的事情
---
 错误报告并不老是很好。发送不受支持的命令会关闭链接。一样,从redis-cli发送一个“GET”并不会报告有关参数数量错误的任何错误,但会永久挂起链接。

可是,服务器的其余错误会正确传递给客户端:

redis metal:10000>获取清单
(错误)WRONGTYPE对持有错误值的键的操做
 我但愿看到的另外一件事是支持自动故障转移。有不少选择:
 1)twemproxy已经可以监视实例错误,计算错误数量,并在检测到足够的错误时弹出节点。好吧,遗憾的是它没法将从属节点做为替代方案,而不是弹出节点在发送SLAVE OF NOONE命令后当即使用备用节点。这也将把它变成HA解决方案。

2)或者,若是可以与Redis Sentinel协同工做,我会很高兴,若是发生故障转移,请按期检查Sentinel配置以升级服务器表。

3)另外一种方法是提供一种热配置twemproxy的方法,以便在故障转移时Sentinel能够尽快切换代理的配置。

有不少选择,但基本上,对HA的一些支持可能很大。

表演
---
 这件事很快。真的很快,几乎与直接与Redis交谈同样快。我会说你最差的表现会减掉20%。

我惟一的表演问题是,当命令在实例之间分配时,恕我直言MGET可使用一些改进。
 毕竟,若是代理在它和全部Redis实例之间有类似的延迟(极可能),若是同时发送MGET,则回复可能会同时到达代理。所以,当我针对单个实例运行MGET时,我指望看到与MGET几乎相同的数字,但我每秒只得到50%的操做。也许如今是重建答复的时候了,我不肯定。

结论
---

这是一个很棒的项目,因为Redis Cluster还没有出现,我强烈建议Redis用户试一试。
 就我的而言,我要将它连接到Redis项目网站的某个可见位置。我认为这里的Twitter人员经过他们的项目为Redis自己提供了一些真正的价值,因此......

奖励!
相关文章
相关标签/搜索