Пакетная вставка в Кассандре с использованием C # - PullRequest
1 голос
/ 04 мая 2019

Я новичок в Кассандре. Я должен вставить 50000 строк за один раз в Кассандре, используя C #. Я использую Cassandra C # драйвер. я использую следующий код для вставки данные в кассандре. Пожалуйста, помогите мне

string tableName = "" + ConfigurationManager.AppSettings["tableName"];
            string keySpace = "test";// "" + ConfigurationManager.AppSettings["Keyspace"];
            //string query = "INSERT INTO " + tableName + " (emp_name, emp_position,emp_firstname,uniqueid) VALUES (?, ?,?,?)"; //; "SELECT * FROM "+ tableName + " limit 2 ";
            string query = string.Empty;
            query =
"BEGIN BATCH " +
"INSERT INTO " + tableName + " (emp_name, emp_position,emp_firstname,uniqueid) VALUES (?, ?,?,?);" +
"INSERT INTO " + tableName + " (emp_name, emp_position,emp_firstname,uniqueid) VALUES (?, ?,?,?);" +
"INSERT INTO " + tableName + " (emp_name, emp_position,emp_firstname,uniqueid) VALUES (?, ?,?,?);" +
" APPLY BATCH";

BatchStatement(keySpace, query,
                    Convert.ToString("ashish" + i), 2, Convert.ToString("Mohan" + i), System.Guid.NewGuid(),
                    Convert.ToString("ashish" + i), 2, Convert.ToString("Mohan" + i), System.Guid.NewGuid(),
                    Convert.ToString("ashish" + i), 2, Convert.ToString("Mohan" + i), System.Guid.NewGuid()
public void BatchStatement(string keySpace, string query, params object[] parameter)
    {
        try
        {
            BatchStatement objBatchStatement = new BatchStatement();
            PreparedStatement statement = PrepareQueryStatement(keySpace, query);
            objBatchStatement.Add(statement.Bind(parameter));
            var session = cluster.Connect(keySpace);
            //objBatchStatement.ConsistencyLevel
            // Execute the batch
            //RowSet row = session.Execute(query);
            RowSet row = session.Execute(objBatchStatement);

        }
        catch (Exception ex)
            {
            Console.WriteLine("Excpetion occured during batch operation method Name BatchStatement error : " + ex.ToString());
        }

    }

Я получаю сообщение об ошибке: неверный оператор в пакете: разрешены только операторы UPDATE, INSERT и DELETE.

Ответы [ 2 ]

3 голосов
/ 04 мая 2019

Я не очень хорошо понимаю ваш пример кода, поэтому не знаю, используете ли вы SELECT запросы в пакете, что, похоже, является проблемой. В любом случае, вы можете неправильно использовать Batch, потому что партии в Cassandra используются для атомарности, а не для производительности (большую часть времени).

Если вы хотите вставить эти 50000 строк как можно быстрее, то быстрее (и рекомендуется) выполнить 50000 вставок асинхронно с session.ExecuteAsync. Попробуйте что-то вроде этого:

var tasks = new List<Task>();

foreach (BoundStatement query in queries) 
{
    tasks.Add(session.ExecuteAsync(query));
}

await Task.WhenAll(tasks).ConfigureAwait(false);

Для более сложных сценариев использования с большим количеством строк для вставки может потребоваться контролировать, сколько запросов выполняется одновременно, но стандартная библиотека параллельных задач уже делает это за вас.

Единственный случай, когда Batch быстрее, чем асинхронное выполнение всех этих запросов по отдельности, - это когда вы можете создавать микропакеты с инструкциями, которые принадлежат одному и тому же разделу, но это гораздо труднее сделать, и, вероятно, вы выиграли ' Это увеличение производительности не требуется.

UPDATE

После того, как вы отредактировали свой вопрос, я могу понять пример кода. Если вы все еще хотите использовать Batch вместо подхода, который я предложил выше, то вы должны сделать следующее:

var batch = new BatchStatement();
foreach (BoundStatement query in queries) 
{
    batch.Add(query); // you can also add SimpleStatements instead of BoundStatements
}

await session.ExecuteAsync(batch).ConfigureAwait(false);
1 голос
/ 06 мая 2019

Чтобы ответить на конкретный вопрос ...

Недопустимый оператор в пакете: разрешены только операторы UPDATE, INSERT и DELETE.

"BEGIN BATCH " +
...
" APPLY BATCH";

BEGIN BATCH и APPLY BATCH являютсязаявления, которые не допускаются.Об этом позаботится объект BatchStatement.

Что касается этого утверждения:

Мне нужно вставить 50000 строк за один раз в Кассандре

Жуан абсолютно прав в том, что то, что вы делаете, является злоупотреблением функциональностью BATCH Кассандры.Пакет (в Кассандре) был разработан для атомарного применения одной записи к нескольким таблицам.Он не был создан для поддержки 50000 записей в одну таблицу.Я видел, что команды разработчиков непреднамеренно вызывали сбои узлов кластера при этом.

Причина, по которой это не работает, заключается в том, что Кассандра понимает, что у нее нет отдельного раздела для отправки пакета.Таким образом, он выбирает узел-координатор, который отвечает за извлечение и сборку 50000 результатов со всех других узлов.Этот узел быстро перегружается и падает.

Опять же, предложение Жуана о асинхронной записи ваших строк - это путь.Единственная корректировка, которую я хотел бы сделать, - это добавить механизм, ограничивающий количество активных потоков в любой момент времени, чтобы защитить ваши узлы от 50 тыс. Записей обратного давления.

...