无法在couchbase服务器社区版3.0.1上更新6m +文档

时间:2015-06-29 08:01:23

标签: java couchbase

我正在尝试更新couchbase服务器社区版3.0.1服务器群集中的600万个文档。我正在使用最新的java sdk并尝试了各种方法,我可以从View中读取一批文档,更新它们并将它们替换回桶中。

在我看来,随着流程的进展,吞吐量变得太慢,甚至不会达到300 op / s。我尝试使用许多方法使用批量操作方法(使用Observable)来加速它但是徒劳无功。我甚至让这个过程运行了几个小时才能看到Timeout异常。

我尝试的最后一个选项是从View中将所有文档ID读入临时文件,以便我可以读回文件并更新记录。但是,在3小时后,从View中读取的只有1.7米ID(仅约157项/秒!),数据库会给出超时异常。

请注意,couchbase群集包含3个服务器(Ubuntu 14.04),其中包含8个内核,24GB RAM和每个1TB SSD和运行更新数据的java代码在同一网络中,具有4个内核,16GB RAM和1TB SSD。并且此群集上没有其他负载正在运行。

看来,从服务器视图中读取所有ID都是不可能的。我检查了网络吞吐量,数据库服务器提供的数据几乎不到1mbps。

以下是用于从视图中读取所有文档ID的示例代码:

final Bucket statsBucket = db.getStatsBucket();
int skipCount = 0;
int limitCount = 10000;

System.out.println("reading stats ids ...");

try (DataOutputStream out = new DataOutputStream(new FileOutputStream("rowIds.tmp")))
{
    while (true)
    {
        ViewResult result = statsBucket.query(ViewQuery.from("Stats", "AllLogs").skip(skipCount).limit(limitCount).stale(Stale.TRUE));

        Iterator<ViewRow> rows = result.iterator();

        if (!rows.hasNext())
        {
            break;
        }

        while (rows.hasNext())
        {
            out.writeUTF(rows.next().id());
        }

        skipCount += limitCount;
        System.out.println(skipCount);
    }
}

即使使用批量操作(Observable)方法,我也尝试过这种方法,但没有成功。也尝试将限制计数更改为1000(不限制java应用程序在一段时间后变得疯狂,甚至SSH停止响应。

有办法做到这一点吗?

1 个答案:

答案 0 :(得分:1)

我找到了解决方案。 ViewQuery.skip()方法实际上并不是跳过的,不应该用于分页。 skip()方法只会从视图的开头读取所有数据,并且只在读取记录数后才开始提供输出,就像链表一样。

解决方案是使用startKey()和startKeyDocId()。进入这些方法的ID是您读过的最后一项ID。从这里得到这个解决方案:http://tugdualgrall.blogspot.in/2013/10/pagination-with-couchbase.html

因此,阅读视图中所有项目的最终代码是:

final Bucket statsBucket = db.getStatsBucket();
int limitCount = 10000;
int skipCount = 0;

System.out.println("reading stats ids ...");

try (DataOutputStream out = new DataOutputStream(new FileOutputStream("rowIds.tmp")))
{
    String lastKeyDocId = null;

    while (true)
    {
        ViewResult result;

        if (lastKeyDocId == null)
        {
            result = statsBucket.query(ViewQuery.from("Stats", "AllLogs").limit(limitCount).stale(Stale.FALSE));
        }
        else
        {
            result = statsBucket.query(ViewQuery.from("Stats", "AllLogs").limit(limitCount).stale(Stale.TRUE).startKey(lastKeyDocId).skip(1));
        }

        Iterator<ViewRow> rows = result.iterator();

        if (!rows.hasNext())
        {
            break;
        }

        while (rows.hasNext())
        {
            lastKeyDocId = rows.next().id();
            out.writeUTF(lastKeyDocId);
        }

        skipCount += limitCount;
        System.out.println(skipCount);
    }
}