5

アプリケーション固有の json オブジェクトを使用して、ローカルの Couchbase インスタンスを読み込んでいます。

関連するコードは次のとおりです。

CouchbaseClient getCouchbaseClient()
{
    List<URI> uris = new LinkedList<URI>();
    uris.add(URI.create("http://localhost:8091/pools"));
    CouchbaseConnectionFactoryBuilder cfb = new CouchbaseConnectionFactoryBuilder();
    cfb.setFailureMode(FailureMode.Retry);
    cfb.setMaxReconnectDelay(1500); // to enqueue an operation
    cfb.setOpTimeout(10000); // wait up to 10 seconds for an operation to succeed
    cfb.setOpQueueMaxBlockTime(5000); // wait up to 5 seconds when trying to
                                      // enqueue an operation
    return new CouchbaseClient(cfb.buildCouchbaseConnection(uris, "my-app-bucket", ""));
}

エントリを保存する方法 ( Bulk Load および Exponential Backoffからの提案を使用しています):

  void continuosSet(CouchbaseClient cache, String key, int exp, Object value, int tries)
  {
    OperationFuture<Boolean> result = null;
    OperationStatus status = null;
    int backoffexp = 0;

    do
    {
      if (backoffexp > tries)
      {
        throw new RuntimeException(MessageFormat.format("Could not perform a set after {0} tries.", tries));
      }

      result = cache.set(key, exp, value);
      try
      {
        if (result.get())
        {
          break;
        }
        else
        {
          status = result.getStatus();
          LOG.warn(MessageFormat.format("Set failed with status \"{0}\" ... retrying.", status.getMessage()));
          if (backoffexp > 0)
          {
            double backoffMillis = Math.pow(2, backoffexp);
            backoffMillis = Math.min(1000, backoffMillis); // 1 sec max
            Thread.sleep((int) backoffMillis);
            LOG.warn("Backing off, tries so far: " + tries);
          }
          backoffexp++;
        }
      }
      catch (ExecutionException e)
      {
        LOG.error("ExecutionException while doing set: " + e.getMessage());
      }
      catch (InterruptedException e)
      {
        LOG.error("InterruptedException while doing set: " + e.getMessage());
      }
    }
    while (status != null && status.getMessage() != null && status.getMessage().indexOf("Temporary failure") > -1);
  }

continuosSet メソッドが大量のオブジェクトを格納するために呼び出された場合 (シングル スレッド) など

CouchbaseClient cache = getCouchbaseClient();
do
{
    SerializableData data = queue.poll();
    if (data != null)
    {
        final String key = data.getClass().getSimpleName() + data.getId();
        continuosSet(cache, key, 0, gson.toJson(data, data.getClass()), 100);
...

result.get() 操作の continuosSet メソッド内で CheckedOperationTimeoutException を生成します。

Caused by: net.spy.memcached.internal.CheckedOperationTimeoutException: Timed out waiting for operation - failing node: 127.0.0.1/127.0.0.1:11210
        at net.spy.memcached.internal.OperationFuture.get(OperationFuture.java:160) ~[spymemcached-2.8.12.jar:2.8.12]
        at net.spy.memcached.internal.OperationFuture.get(OperationFuture.java:133) ~[spymemcached-2.8.12.jar:2.8.12]

誰かがこの状況を克服して回復する方法に光を当てることができますか? Couchbase の Java クライアントで一括ロードする方法に関する適切なテクニック/回避策はありますか? 残念ながら、PHP Couchbase クライアント用のドキュメントPerforming a Bulk Setを既に調べました。

4

1 に答える 1

5

私の疑いでは、メモリがそれほど多くないコマンドラインから生成された JVM でこれを実行している可能性があります。その場合、GC の一時停止が長くなり、言及しているタイムアウトが発生する可能性があります。

いろいろ試してみるのが一番だと思います。最初に、JVM への -Xmx 引数を上げて、より多くのメモリを使用します。タイムアウトが後で発生するか、またはなくなるかを確認します。もしそうなら、記憶に関する私の疑いは正しいです。

それでもうまくいかない場合は、setOpTimeout() を発生させて、エラーが減少するか、またはなくなるかどうかを確認します。

また、最新のクライアントを使用していることを確認してください。

ちなみに、これは直接一括読み込みに関係しているとは思いません。一括読み込み中の大量のリソース消費が原因で発生する可能性がありますが、通常のバックオフが機能している必要があるか、ヒットしていないようです。

于 2014-02-08T18:04:03.050 に答える