not - ¿Cuál es el límite del lote en Cassandra?
number in cassandra (4)
Tengo un cliente de Java que empuja (INSERTAR) registros por lotes al clúster de Cassandra. Todos los elementos del lote tienen la misma clave de fila, por lo que todos se colocarán en el mismo nodo. Además, no necesito que la transacción sea atómica, así que he estado usando un lote sin registrar.
El número de comandos INSERT en cada lote depende de diferentes factores, pero puede ser cualquier cosa entre 5 y 50000. Primero simplemente puse tantos comandos como tenía en un lote y los envié. Esto arrojó com.datastax.driver.core.exceptions.InvalidQueryException: Batch too large
. Luego usé un límite de 1000 INSERT por lote y luego hasta 300. Observé que estoy adivinando al azar sin saber exactamente de dónde viene este límite, lo que puede causar problemas en el camino.
Mi pregunta es, ¿cuál es este límite? ¿Puedo modificarlo? ¿Cómo puedo saber cuántos elementos se pueden colocar en un lote? Cuando mi lote está "lleno"?
Yo recomendaría no aumentar el límite, y simplemente dividir en múltiples solicitudes. Poner todo en una sola solicitud gigante tendrá un impacto negativo en el coordinador de manera significativa. Tener todo en una partición puede mejorar el rendimiento en algunos lotes de tamaño al reducir algo de latencia, pero los lotes nunca deben usarse para mejorar el rendimiento. Por lo tanto, tratar de optimizar para obtener el máximo rendimiento mediante el uso de diferentes tamaños de lote dependerá en gran medida del uso de caso / esquema / nodos y requerirá pruebas específicas, ya que generalmente hay un precipicio en el tamaño donde comienza a degradarse.
Hay un
# Fail any batch exceeding this value. 50kb (10x warn threshold) by default.
batch_size_fail_threshold_in_kb: 50
opción en tu cassandra.yaml
para aumentarla, pero asegúrate de probar para asegurarte de que realmente estás ayudando y no perjudicando tu rendimiento.
Solucioné este problema cambiando el valor CHUNKSIZE a un valor inferior (por ejemplo, 1) https://docs.datastax.com/en/cql/3.1/cql/cql_reference/copy_r.html
COPY mytable FROM ''mybackup'' CON CHUNKSIZE = 1;
La operación es mucho más lenta, pero al menos funciona ahora
Al mirar los registros de Cassandra, podrás ver cosas como:
ERROR 19:54:13 El lote de [matches] tiene un tamaño de 103.072KiB, excediendo el umbral especificado de 50.000KiB por 53.072KiB. (ver batch_size_fail_threshold_in_kb)
Encontré un problema similar en Java, aquí hay un ejemplo funcional de cómo lotes de lotes:
import com.datastax.driver.core.BatchStatement;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.Session;
import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.stream.Collectors;
public class CassandraBatchOfBatchesExample {
private final PreparedStatement statement;
private final Session session;
private final int batchSize;
public CassandraBatchOfBatchesExample(Session session, int batchSize) {
this.session = session;
this.batchSize = batchSize;
statement = session.prepare("INSERT_INTO some_table JSON ?");
}
public void execute(Collection<String> jsons) {
Lists.partition(jsons
.stream()
.map(statement::bind)
.collect(Collectors.toList()
), batchSize).stream()
.map(statements -> new BatchStatement().addAll(statements))
.forEach(session::execute);
}
}
batchSize
variable batchSize
tendrá que cambiar en función del tamaño de los registros individuales que se inserten.