安装了带有Twemproxy的Redis集群,我真的很困惑为什么一些SET命令被移动了



我已经用Redis Server 3.0.5版本(Ubuntu 14.04)安装了一个Redis集群

为了简单起见,我们将忽略复制。我有三个redis实例在本地主机上运行,分别是端口7001、7002和7003。他们都通过这个命令成为集群的主人

redis-trib.rb create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003

我喜欢使用twemproxy 的想法

twemproxy-config.yml

twem-1:
  listen: 127.0.0.1:22121
  hash: fnv1a_64
  distribution: ketama
  redis: true
  preconnect: true
  servers:
  - 127.0.0.1:7001:1
  - 127.0.0.1:7002:1
  - 127.0.0.1:7003:1

我用nutcracker -c twemproxy-config.yml -d初始化twemproxy,然后我可以用redis-cli -h 127.0.0.1 -p 22121 访问twempoxy

请看一下这个输入和输出

127.0.0.1:22121> set hello 4542342342424
OK
127.0.0.1:22121> set goodbye 345353535545
(error) MOVED 9354 159.203.136.204:7002
127.0.0.1:22121> get hello
"4542342342424"
127.0.0.1:22121> get goodbye
(error) MOVED 9354 159.203.136.204:7002

我担心这可能无法正常工作。如果我绕过twemproxy并使用redis-cli -c -h 127.0.0.1 -p 7001连接,我可以看到自动转发正在发生。就像这样;

127.0.0.1:7001> get hello
"4542342342424"
127.0.0.1:7001> get goodbye
-> Redirected to slot [9354] located at 127.0.0.1:7002
(nil)
127.0.0.1:7002> set goodbye 3240923842094840
OK
127.0.0.1:7002> get goodbye
"3240923842094840"

参考

Redis集群规范

在code.hootsuite.com上有趣地阅读了关于twemproxy的使用(大约在页面的一半)

最终目标

我的最终目标是使用redis集群在负载均衡器后面的多个Web服务器上存储PHP会话数据。在php.ini中,我将有session.save_handler = redissession.save_path = tcp://127.0.0.1:22121(twemproxy实例将在每个web服务器上运行)。PHP会话配置位尚未设置。

我希望我说得有道理。我使用的哈希代码正确吗?我真的很想看到twemproxy回馈OK,而不是MOVED

谢谢!

更新

感谢@real bill的回答,我在两个节点上设置了redis,标准redis运行端口6380,sentinel运行端口16380,一个是主节点,另一个是从节点。看着原木,一切看起来都很好。

我看过predis和phpredis

这是我仍然有点不确定的一点,我相信如果有更多的时间,我会解决的。查询只能写入到主服务器,查询只能从从属服务器读取。我们让Sentinel根据可用性来推广其中一个或另一个——会话处理程序如何知道它可以写入哪个?我当然需要提供两个IP地址。。

Redis集群是一个客户端感知模式。在Redis集群中,客户端总是连接到给定密钥的"正确"节点。MOVED回复告诉客户端哪个节点为该密钥提供服务。最初,客户端需要在连接时拉取当前拓扑,然后在收到MOVED时进行更新。这是性能最高的模式,因为不涉及代理。

然而,这意味着您不能在Redis Cluster设置之前使用任何现有的代理。正如您所看到的,Twemproxy只是代理某些命令,并拒绝其他命令。为了让Twemproxy处理这个问题,它需要实现集群API并完成客户端所做的一切。这是不可能的,你也不应该期望它这么快就会发生。任何其他代理,如nginx或HAProxy,都需要做同样的事情(假设有了openresty或自定义模块,可以在nginx中比其他模块更容易地做到这一点)。

此外,上次我检查了PHP客户端不支持Redis Cluster。

然而,对于您的用例,我怀疑您是否真的需要Redis集群。使用Sentinel在Pod中配置Redis(主+从)以管理故障切换,再加上客户端的Sentinel支持,很可能会很好地满足您的需求。我相信PRedis有支持,但我确信phpredis没有。

如果你一心想运行共享集群的复杂性,那么在Twemproxy后面使用常规的Redis+Stinel,并让Twemproxx通过你告诉它使用的共享算法进行连接。这是尝试使用Twepoxy的另一个问题——它做Redis Cluster所做的事情,但作为一个代理。因此,实际上您将尝试对数据集进行两次分片。我相信你可以想象这是灾难性的

如果您无法获得适当的支持,或者不希望Twemproxy为您管理共享,您的最终选择(除了自己添加客户端支持之外)是设置一个由sentinel配置的代理。例如,您可以使用配置为指向主服务器的HAProxy。在故障转移上,Sentinel可以为您执行脚本。

然后,这个脚本可以更新您的HAProxy配置并为您重新启动它,从而确保正确的重新连接行为。有很多方法可以做到这一点,谷歌搜索它,再加上Redis Sentinel文档,并将它们应用到您的环境中,就会为您显示路径。

您不能同时使用Redis集群twemproxy。在Redis集群模式下,应该是客户端将请求发送到正确的主机。当您向错误的主控器请求密钥时,它总是会发回MOVE回复,将您重定向到正确的主控。

最新更新