来自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本身提供了一些真正的价值,所以......

奖励!
posted @ 2018-10-10 14:07  寻找普拉多  阅读(433)  评论(0编辑  收藏  举报