Dse\Exception\RuntimeException: все соединения во всех потоках ввода-вывода заняты

В нашем веб-приложении есть возможность удалять большие объемы данных. Мы делаем это, просматривая все записи, найденные против u_id.

Имеющиеся у нас ключи предназначены для других запросов, которые есть в нашем приложении. В идеале было бы здорово иметь первичный ключ для u_id, но это нарушит работу всех наших других запросов.

Приведенный ниже метод работает хорошо в большинстве случаев, однако после удаления примерно 6-8 миллионов записей мы получаем:

Dse\Exception\RuntimeException: все соединения во всех потоках ввода-вывода заняты

Мы также иногда получаем немного другое сообщение об ошибке:

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);

Мы запускаем сервер с 8 ГБ оперативной памяти.

Версия драйвера DSE — 6.0.1.

Заранее спасибо!


person deano23    schedule 25.06.2018    source источник


Ответы (1)


Вам нужно контролировать, сколько запросов «в полете» у вас есть в один и тот же момент времени. Существует ограничение на количество запросов на одно соединение и количество соединений. Они управляются соответствующими функциями класса Cluster (не могу найти достаточно быстро в документах PHP, но это должно быть похоже на Функции кластера в драйвере C++, поскольку PHP построен поверх драйвера C++).

person Alex Ott    schedule 25.06.2018
comment
Спасибо за помощь @Alex. Я изо всех сил пытаюсь найти эквивалент в документации по PHP (docs.datastax.com/en/developer/php-driver-dse/1.1/api/Dse/), возможно, я ищу не в том месте? Мы также посмотрели в cassandra.yaml, и они, кажется, установлены по умолчанию, что является «неограниченным». Наконец, после моего первоначального сообщения мы также попытались просмотреть netstat, используя netstat -tapn | grep php | grep 9042 | wc -l, который показывает количество подключений 22, а в другом тесте - 23. - person deano23; 26.06.2018
comment
Это не параметр Cassandra, а драйверы - person Alex Ott; 26.06.2018
comment
вам нужно искать функции withConnectionsPerHost вместе с withIOThreads... - person Alex Ott; 26.06.2018
comment
Спасибо @alex - я отследил это вчера, и похоже, что наша проблема решена. Я провел много больших тестов, чтобы подтвердить. Спасибо за вашу помощь - person deano23; 27.06.2018