【问题标题】:Dse\Exception\RuntimeException: All connections on all I/O threads are busyDse\Exception\RuntimeException:所有 I/O 线程上的所有连接都忙
【发布时间】:2018-12-03 18:56:08
【问题描述】:

我们的网络应用程序中有一个工具可以删除大量数据。我们通过分页查看针对u_id 找到的所有记录来做到这一点。

我们拥有的键是为我们在应用程序中的其他查询而设计的——理想情况下,拥有u_id 的主键会很棒,但这会破坏我们所有的其他查询。

下面的方法在大多数情况下效果很好,但是,在删除大约 6-8 百万条记录后,我们得到:

Dse\Exception\RuntimeException: 所有 I/O 线程上的所有连接都忙

我们有时也会收到稍有不同的错误消息:

Dse\Exception\ReadTimeoutException: 操作超时 - 仅收到 0 个响应

您会在下面的代码usleep(2500000) 中注意到它暂停了脚本。这是我们的解决方法,但最好能解决这个问题,因为 Cassandra 应该能够处理这么多的删除。

$cluster        = \Dse::cluster()
                    ->withDefaultTimeout(3600)
                      ->withContactPoints(env('CA_HOST'))
                        ->build();

$session        = $cluster->connect(env('CONNECT'));
$options        = array('page_size' => 50);
$results        = $session->execute("SELECT * FROM datastore WHERE u_id = $u_id;", $options);
$future_deletes = array();

while (true) {

    foreach ($results as $result) {

      $future_deletes[] = $session->executeAsync("DELETE FROM datastore WHERE record_id = '" . $result['record_id'] . "' AND record_version = " . $result['record_version'] . " AND user_id = " . $result['user_id']);
      $future_deletes[] = $session->executeAsync("UPDATE data_count set u_count = u_count - 1 WHERE u_id = " . $u_id);

    }

    if( !empty($future_deletes) ){
      foreach ($future_deletes as $future_delete) {
          // we will not wait for each result for more than 5 seconds
          $future_delete->get(5);
      }
      //usleep(2500000); //2.5 seconds
    }

    $future_deletes = array();

    if ($results->isLastPage()) {
        break;
    }

    $results = $results->nextPage();

}

//Disconnect
$session = NULL;

以下是我们的表格供您参考:

CREATE TABLE datastore (id uuid,
    record_id varchar,
    record_version int,
    user_id int,
    u_id int,
    column_1 varchar,
    column_2 varchar,
    column_3 varchar,
    column_4 varchar,
    column_5 varchar,
PRIMARY KEY((record_id), record_version, user_id)
);
CREATE INDEX u_id ON datastore (u_id);

CREATE TABLE data_count (u_id int PRIMARY KEY, u_count counter);

我们正在运行一个具有 8GB RAM 的服务器。

DSE驱动的版本是6.0.1。

提前谢谢你!

【问题讨论】:

    标签: cassandra datastax-enterprise datastax-startup datastax-php-driver


    【解决方案1】:

    您需要控制在同一时间点有多少“进行中”请求。每个连接的查询数和连接数都有限制。它们由 Cluster 类的相应函数控制(在 PHP 文档中找不到足够快,但应该类似于 Cluster functions in the C++ driver,因为 PHP 是建立在 C++ 驱动程序之上的)。

    【讨论】:

    • 感谢您的帮助@Alex。我正在努力在 PHP 文档 (docs.datastax.com/en/developer/php-driver-dse/1.1/api/Dse/…) 中找到等价物,也许我找错地方了?我们还查看了cassandra.yaml,这些似乎被设置为默认值,即“无限制”。最后,自从我的原始消息以来,我们还尝试使用netstat -tapn | grep php | grep 9042 | wc -l 查看 netstat,它显示连接数为 22,而另一个测试为 23。
    • 不是 Cassandra 参数而是驱动程序
    • 你需要查看函数withConnectionsPerHost函数,以及withIOThreads...
    • 谢谢@alex - 我昨天找到了它,它似乎已经解决了我们的问题。我一直在运行许多大型测试来确认。感谢您的帮助
    猜你喜欢
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多