我在两个Amazon EC2实例(版本1.8.0)和大约5个应用程序服务器上有一个实时Couchbase集群,每个服务器运行PHP,并在其上运行moxi客户端。偶尔,Moxi将在尝试访问数据时返回SERVER_ERROR
。这种情况平均每隔几分钟发生一次。集群每秒处理大约500次操作。
在检查moxi日志(启用了-vvv)后,在我得到SERVER_ERROR
时我注意到以下内容:
2013-07-16 03:07:22: (cproxy.c.2680) downstream_timeout
2013-07-16 03:07:22: (cproxy.c.1911) 56: could not forward upstream to downstream
2013-07-16 03:07:22: (cproxy.c.2004) 56: upstream_error: SERVER_ERROR proxy downstream timeout^M
我尝试将moxi configs中的下游超时从5000增加到25000,但这根本没有帮助。错误仍然经常发生。
有人可以建议我发现问题的原因吗?或者,如果有可能是罪魁祸首?
答案 0 :(得分:2)
SERVER_ERROR代理下游超时
在此错误响应中,moxi在等待a时达到超时 下游服务器响应请求。也就是说,莫西没有看到 任何明显的错误,例如连接断开,但响应 只是花了太长时间。下游连接也将关闭 通过moxi而不是将下游连接放回到 连接池。默认的downstream_timeout配置为5000 (毫秒)。
非常直接的错误,但它可能是由一些可能的事情引起的。
尝试获取" stats proxy"的输出来自莫西:
echo stats proxy | nc HOST 11211
显然你已经发现你关注这些设置:
STAT 11211:default:pstd_stats:tot_downstream_timeout xxxx
STAT 11211:default:pstd_stats:tot_wait_queue_timeout nnnnn
您的downstream_timeout正如您所说的应该显示为5000
但也请查看:
STAT 11211:default:pstd_stats:tot_downstream_conn_queue_timeout 0
来自网址:
http://www.couchbase.com/docs/moxi-manual-1.8/moxi-dataflow.html
非常完美地了解了moxi的运作方式。
了解moxi中的一些可配置命令行标志 (并发,downstream_max,downstream_conn_max,downstream_timeout, wait_queue_timeout等),跟随请求会很有帮助 通过moxi ...
moxi的正常数据流如下:
客户端连接
客户端创建与moxi的连接(上游连接)。 moxi的-c命令行参数最终控制了限制 最大连接数。
在这个-c参数中,moxi继承了与memcached相同的行为, 并将停止接受()客户端连接,直到 现有连接已关闭。当计数存在 连接低于-c定义的级别,moxi将接受()更多 客户关系。
客户端发出请求,该请求进入等待队列
接下来,客户端发出请求 - 例如简单的单键 命令(如set,add,append或单键get)。
此时,moxi将上游conn置于等待的尾部 队列。 moxi的wait_queue_timeout参数控制一个多长时间 上游conn应该在moxi超时之前保持等待队列 并使用SERVER_ERROR响应响应客户端。
并发参数
接下来,对于有多少个上游连接,可配置的最大限制 请求moxi将同时处理等待的头部 队列。此可配置限制称为并发。 (以前这个 以前,也许是混淆,知道为downstream_max。对于 向后兼容性,并发性和downstream_max配置 标志被视为同义词。)
并发配置是每线程和每桶。那 是的,moxi进程级并发实际上是并发X. num-worker-threads X num-buckets。
默认并发配置值为1024.这意味着moxi 将同时处理1024个上游连接请求 等待队列的头部。 (然而,莫西有更多的队列, 在moxi实际转发请求之前。这将在稍后讨论 段。)
以并发值1024为例,如果你有4 工作线程(默认情况下,由moxi' s -t参数控制)和1 桶(大多数人开始使用的,例如"默认"桶), 您将同时处理1024 x 4 x 1或4096的限制 客户在单一moxi过程中的请求。
对于moxi来说,并发性的基本原理增加到1024 配置(它曾经低得多)是由于不断发展的设计 莫西最初,moxi只有等待队列作为其唯一的内部 队列。在moxi的历史中,更多的后期队列被添加了, 我们发现从等待队列中获取请求的时间越早越好 后期队列是一种更好的方法。我们将讨论这些问题 下面的后期队列。
接下来,让我们讨论客户端请求如何与下游连接匹配。
键哈希
同时处理的客户端请求(取自头部 等待队列)现在需要与下游连接匹配 到Couchbase服务器。如果客户的请求带有密钥 (如SET,DELETE,ADD,INCR,单键GET),请求的关键是 哈希找到合适的下游服务器" host:port:bucket"信息。 例如,像" memcache1:11211:默认"。如果 客户端的请求是广播式命令(如FLUSH_ALL,或者 多键GET),moxi知道它需要的下游连接 获得。
下游conn池
接下来,使用那些host:port:bucket identifier into进行查找 下游conn池,以获取或保留 适当的下游conns。每个下游的conn池都有 线。每个下游conn池只是一个键入的hashmap host:port:bucket,其哈希值为可用的链表 下游的conns。任何下游conn链表的最大长度是 由moxi的downstream_conn_max配置参数控制。
downstream_conn_max参数
默认情况下,downstream_conn_max值为4.值为0表示没有限制。
因此,如果您将downstream_conn_max设置为4,则有4个工作线程, 并且有1个桶,你应该看到moxi创造了最多4个 X 4 X 1或16个连接到任何Couchbase服务器。
连接到下游服务器
如果没有可用的下游conn,那么 未达到downstream_conn_max,moxi创建下游conn as 需要时根据需要执行connect()和SASL身份验证。
connect_timeout和auth_timeout参数
connect()和SASL auth具有自己的可配置超时 参数,称为connect_timeout和auth_timeout,以及这些参数 以毫秒为单位。 connect_timeout的默认值为400 毫秒,auth_timeout默认值为100毫秒。
下游连接队列
如果达到downstream_conn_max,则请求必须等到a 下游conn变得可用;因此请求是 放置在每个线程,每个主机:端口:桶队列,称为a 下游连队队列。随着下游的conns被释放回来 下游conn池,它们将被分配给任何请求 等待下游conn队列。
downstream_conn_queue_timeout参数
还有另一个可配置的超时,来自pm_conn_queue_timeout, 定义请求应该多长时间 在超时之前以毫秒为单位保持在下游连接队列中。 默认情况下,downstream_conn_queue_timeout为200毫秒。一个 值为0表示没有超时。
保留下游连接
最后,在这一点上,下游的conn匹配了 客户的要求。如果您已配置moxi来跟踪时序直方图 统计数据,moxi现在将获得请求的正式开始时间。 moxi现在开始异步发送请求消息字节到 下游conn和异步等待响应。
要打开时序直方图统计信息,请使用" time_stats = 1" 配置标志。默认情况下,time_stats为0或关闭。
downstream_timeout参数
接下来,如果您已配置了downstream_timeout,则moxi启动计时器 对于moxi可以限制花费时间的请求 此时处理请求。如果计时器开火,moxi会 返回" SERVER_ERROR代理下游超时"回到客户端。
downstream_timeout默认值为5000毫秒。如果莫西看到了 这个时间过去了,它将关闭任何下游连接 被分配到请求。由于这种简单的关闭行为 超时时的下游连接,非常短 不建议使用downstream_timeout。这有助于避免重复 连接创建,超时,关闭和重新连接。在一个 重载群集,您可能希望增加downstream_timeout 莫西并不总是试图下游 已经过载的群集上的连接,或者通过创建更多 服务器已在尝试处理请求时的新连接 旧的,封闭的连接。如果你看到你的服务器大大增加,那么你 应该考虑进行这种调整。
收到回复
当从下游服务器收到请求的所有响应时(或者 下游conn有一个错误),moxi是异步的 将这些响应发送到客户端的上游连接。如果你有 配置moxi跟踪时序直方图统计,moxi现在跟踪 请求的正式结束时间。下游的康恩现在 释放回每个线程的下游conn池,另一个 等待客户端请求(如果有)从下游conn队列中取出 并指定使用该下游连接。
退避/黑名单
在步骤6,可能会出现connect()尝试失败的情况。没戏 可以配置为计算a的connect()失败次数 下游服务器,并且还将跟踪上次失败的时间 connect()尝试。
使用connect()失败计数,moxi可以配置为 如果看到太多connect()失败,则将服务器列入黑名单 由connect_max_errors配置参数定义。当更多 比connect_max_errors看到的连接数()失败,moxi 可以配置为暂时停止connect()尝试 该服务器(或退避)已配置的时间量。退避 time是通过connect_retry_interval配置定义的 毫秒。
connect_max_errors的默认值为5,connect_retry_interval 是30000毫秒,即30秒。
如果使用connect_max_errors参数,则应将其设置为大于 downstream_conn_max配置参数。