使用CouchbaseClient的最佳实践

时间:2014-02-05 13:50:55

标签: c# .net nosql memcached couchbase

我们正在与couchbase合作超过一年,并希望通过他们的.Net sdk改进我们的工作。

在他们的网站上,我找不到建议使用get / set的最佳方式。

我知道当我尝试使用时:CouchbaseClient.Get(key)它可能会失败, 而且我们应该等待X时间再试一次。

我想了解在进行获取/设置过程时等待时间的最佳做法是什么。

任何遇到此问题的人都能告诉我这件事吗?

3 个答案:

答案 0 :(得分:2)

我没有使用.net客户端,因为我只使用Java和Ruby与Couchbase,但高级概念将是相同的。

你说get操作可能会失败,你发现它失败很多吗?当智能客户端无法及时与群集通信或队列太满而无法接受新请求时,您必须处理多个异常,操作超时(非常罕见)。

你应该包装你的调用(获取/设置/添加)并捕获特定的异常,然后这一切都取决于系统的要求。如果您到达完整队列,多次重试请求将使情况变得更糟。如果没有异常,您可以在异常的情况下返回吗?

在我们的应用程序(REST API)中,如果我们捕获超时问题,那么我们抛出一个自定义异常,我们将返回给用户,通知他们将来重试。

如果我们有业务需求,我们必须重试,那么我们需要捕获超时并将请求放到队列或调用特定的重试策略。

如果您捕获任何一个异常,那么它可能表示您的系统正在或即将发生故障,因此请仔细监控。我认为Couchbase文档中的这个页面很好地涵盖了这些问题。

https://www.couchbase.com/docs/couchbase-devguide-2.0/about-client-timeouts.html

关于C#特定sdk http://www.couchbase.com/docs/couchbase-sdk-net-1.2/couchbase-sdk-net-configuration.html

的文档

我希望这会有所帮助,如果没有随意扩展原始问题的更多细节。

答案 1 :(得分:2)

一般情况下,我建议你使用ExecuteXXX,其中XXX是一种操作方法,而不是常规/遗留的Get或Set方法。原因是这些方法返回有关操作的其他信息,此信息可用于定制重试策略。

有关详细信息,请阅读文档的这一部分:http://docs.couchbase.com/couchbase-sdk-net-1.3/#working-with-operation-results-and-error-codes

答案 2 :(得分:0)

感谢您的回答。

通过我在这个论坛中发现的那些答案和好帖子: Retry process

我写了一些代码,以下是其中一个方法的示例:

            public static TResult Do<T,TResult>(Func<T,TResult> action, T param, TimeSpan retryInterval, int retryCount = 3)
            {
                for (int retry = 0; retry < retryCount; retry++)
                {
                    try
                    {
                        return action(param);
                    }
                    catch (RetryOperationException)
                    {
                        Log.SaveFormat("Retry:{0} for action:{1}", "RetryProcessLog",retry, action.Method.Name);
                        Thread.Sleep(retryInterval);
                    }
                    catch (Exception ex)
                    {
                        Log.SaveFormat("Exception when retry:{0} error:{1}","RetryProcessLog",action.Method.Name,ex.Message);
                        return default(TResult);
                    }
                }

                return default(TResult);
            }

        public static T ExecuteGet<T>(string key)
        {
            var defaultReturnValue = default(T);

            cacheHit("ExecuteGet", key);

            var result = CacheClient.ExecuteGet<T>(CachePrefix + key);

            if (result.Success)
            {
                return result.Value;
            }
            else if (result.StatusCode ==
                     CouchbaseStatusCode.StatusCodeExtension.ToInt(CouchbaseStatusCode.StatusCode.Busy)
                     ||
                     result.StatusCode ==
                     CouchbaseStatusCode.StatusCodeExtension.ToInt(CouchbaseStatusCode.StatusCode.TemporaryFailure)
                     ||
                     result.StatusCode ==
                     CouchbaseStatusCode.StatusCodeExtension.ToInt(CouchbaseStatusCode.StatusCode.SocketPoolTimeout)
                     ||
                     result.StatusCode ==
                     CouchbaseStatusCode.StatusCodeExtension.ToInt(CouchbaseStatusCode.StatusCode.UnableToLocateNode)
                     ||
                     result.StatusCode ==
                     CouchbaseStatusCode.StatusCodeExtension.ToInt(CouchbaseStatusCode.StatusCode.NodeShutdown)
                     ||
                     result.StatusCode ==
                     CouchbaseStatusCode.StatusCodeExtension.ToInt(CouchbaseStatusCode.StatusCode.OperationTimeout))
            {
                Log.SaveFormat("Error:{0}:{2} in ExecuteGet for key:{1}. Going to throw RetryOperationException",
                               "CacheManager", result.StatusCode, key,result.Message);
                throw new RetryOperationException();
            }

            Log.SaveFormat("Error:{0}:{2} in ExecuteGet for key:{1}", "CacheManager", result.StatusCode, key,result.Message);
            return defaultReturnValue;
        }

这只是一个示例,您可以添加更多方法重载,这些方法重载可以获得多个param或其他没有返回值的方法。 第二种方法在不同的类中,并使用ExecuteGet。

以下是一个使用示例:

var result = RetryProcess.Do(CacheManager.ExecuteGet<long>, keyOfValue, TimeSpan.FromMilliseconds(10));

希望它有所帮助。