Configuración del antorno y datos
Estas pruebas evalúan el rendimiento de Redis en un nodo único sin optimizaciones, con 64 GB de memoria. Se trabajó con un conjunto de datos de 10,058,624 registros, totalizando aproximadamente 1.1 GB. El objetivo es comparar métodos de inserción y lectura para los tipos String y List utilizando la biblioteca Jedis en Java.
Operaciones con tipo String
Inserción con Jedis estándar
public void insertarRegistros() {
Jedis cliente = new Jedis("servidor-redis-local");
BufferedInputStream flujoEntrada = new BufferedInputStream(new FileInputStream(RUTA_ARCHIVO));
DBFReader lectorDBF = new DBFReader(flujoEntrada);
Object[] valoresFila;
long inicio = System.currentTimeMillis();
int contador = 0;
while ((valoresFila = lectorDBF.nextRecord()) != null) {
if (valoresFila.length > 0) {
contador++;
if (contador % 10000 == 0) {
long actual = System.currentTimeMillis();
System.out.println("Progreso: " + contador + " registros, Tiempo: " + (actual - inicio) / 1000 + " s, Velocidad: " + (contador / ((actual - inicio) / 1000)) + " reg/s");
}
cliente.set("clave:" + contador, convertirArrayACadena(valoresFila));
}
}
cliente.close();
}
Con una velocidad estimada de 2800 registros por segundo, insertar todos los datos tomaría alrededor de 3593 segundos (aproximadamente 1 hora).
Inserción con Pipeline
public void insertarConPipeline() {
Jedis cliente = new Jedis("servidor-redis-local");
Pipeline tuberia = cliente.pipelined();
BufferedInputStream flujoEntrada = new BufferedInputStream(new FileInputStream(RUTA_ARCHIVO));
DBFReader lectorDBF = new DBFReader(flujoEntrada);
Object[] valoresFila;
long inicio = System.currentTimeMillis();
int contador = 0;
while ((valoresFila = lectorDBF.nextRecord()) != null) {
if (valoresFila.length > 0) {
contador++;
if (contador % 10000 == 0) {
long actual = System.currentTimeMillis();
System.out.println("Progreso: " + contador + " registros, Tiempo: " + (actual - inicio) / 1000 + " s, Velocidad: " + (contador / ((actual - inicio) / 1000)) + " reg/s");
}
tuberia.set("clave:" + contador, convertirArrayACadena(valoresFila));
}
}
tuberia.sync();
cliente.close();
}
El uso de Pipeline redujo el tiempo total a 62 segundos, alcanzando una velocidad de 162,235 registros por segundo. Esto representa una mejora de rendimiento de aproximadamente 58 veces en comparación con el método estándar.
Lectura de datos String
Con Jedis estándar
public void leerRegistros() {
Jedis cliente = new Jedis("servidor-redis-local");
long inicio = System.currentTimeMillis();
int totalRegistros = 10058624;
for (int i = 1; i <= totalRegistros; i++) {
if (i % 10000 == 0) {
long actual = System.currentTimeMillis();
System.out.println("Progreso lectura: " + i + " claves, Tiempo: " + (actual - inicio) / 1000 + " s, Velocidad: " + (i / ((actual - inicio) / 1000)) + " reg/s");
}
String clave = "prefijo:" + i;
String valor = cliente.get(clave);
}
cliente.close();
}
La lectura secuencial tomó aproximadamente 2012 segundos, con una velocidad de 5000 registros por segundo.
Con Pipeline
public void leerConPipeline() {
Jedis cliente = new Jedis("servidor-redis-local");
Pipeline tuberia = cliente.pipelined();
long inicio = System.currentTimeMillis();
Map<String, Response<String>> respuestas = new HashMap<>();
int totalRegistros = 10058624;
for (int i = 1; i <= totalRegistros; i++) {
if (i % 10000 == 0) {
long actual = System.currentTimeMillis();
System.out.println("Progreso lectura: " + i + " claves, Tiempo: " + (actual - inicio) / 1000 + " s, Velocidad: " + (i / ((actual - inicio) / 1000)) + " reg/s");
}
String clave = "prefijo:" + i;
respuestas.put(clave, tuberia.get(clave));
}
tuberia.sync();
cliente.close();
}
El tiempo total de lectura con Pipeline fue de 48 segundos, con una velocidad de 209,554 registros por segundo, lo que supone un aumento de rendimiento de más de 41 veces.
Operaciones con tipo List
Inserción con Jedis estándar
public void insertarEnLista() {
Jedis cliente = new Jedis("servidor-redis-local");
BufferedInputStream flujoEntrada = new BufferedInputStream(new FileInputStream(RUTA_ARCHIVO));
DBFReader lectorDBF = new DBFReader(flujoEntrada);
Object[] valoresFila;
long inicio = System.currentTimeMillis();
int contador = 0;
while ((valoresFila = lectorDBF.nextRecord()) != null) {
if (valoresFila.length > 0) {
contador++;
if (contador % 10000 == 0) {
long actual = System.currentTimeMillis();
System.out.println("Progreso: " + contador + " registros, Tiempo: " + (actual - inicio) / 1000 + " s, Velocidad: " + (contador / ((actual - inicio) / 1000)) + " reg/s");
}
cliente.lpush("listaDatos", serializarAJson(valoresFila));
}
}
cliente.close();
}
La inserción estándar en listas alcanzó una velocidad de 2600 registros por segundo, requiriendo unos 3869 segundos en total.
Inserción con Pipeline
public void insertarEnListaConPipeline() {
Jedis cliente = new Jedis("servidor-redis-local");
Pipeline tuberia = cliente.pipelined();
BufferedInputStream flujoEntrada = new BufferedInputStream(new FileInputStream(RUTA_ARCHIVO));
DBFReader lectorDBF = new DBFReader(flujoEntrada);
Object[] valoresFila;
long inicio = System.currentTimeMillis();
int contador = 0;
while ((valoresFila = lectorDBF.nextRecord()) != null) {
if (valoresFila.length > 0) {
contador++;
if (contador % 10000 == 0) {
long actual = System.currentTimeMillis();
System.out.println("Progreso: " + contador + " registros, Tiempo: " + (actual - inicio) / 1000 + " s, Velocidad: " + (contador / ((actual - inicio) / 1000)) + " reg/s");
}
tuberia.lpush("listaDatos", serializarAJson(valoresFila));
}
}
tuberia.sync();
cliente.close();
}
Pipeline mantuvo la misma velocidad de 162,235 registros por segundo, con un tiempo total de 62 segundos, mostrando una mejora de rendimiento de 62.5 veces.
Lectura de datos List
Con Jedis estándar
public void leerListaCompleta() {
Jedis cliente = new Jedis("servidor-redis-local");
long inicio = System.currentTimeMillis();
List<String> datos = cliente.lrange("listaDatos", 0, 10058624);
long fin = System.currentTimeMillis();
System.out.println("Lectura completada: " + datos.size() + " elementos, Tiempo: " + (fin - inicio) / 1000 + " s, Velocidad: " + (datos.size() / ((fin - inicio) / 1000)) + " reg/s");
cliente.close();
}
La lectura directa de la lista tomó 15 segundos, con una velocidad de 670,574 registros por segundo.
Con Pipeline
public void leerListaConPipeline() {
Jedis cliente = new Jedis("servidor-redis-local");
Pipeline tuberia = cliente.pipelined();
long inicio = System.currentTimeMillis();
Response<List<String>> respuesta = tuberia.lrange("listaDatos", 0, 10058624);
tuberia.sync();
long fin = System.currentTimeMillis();
List<String> datos = respuesta.get();
System.out.println("Lectura completada: " + datos.size() + " elementos, Tiempo: " + (fin - inicio) / 1000 + " s, Velocidad: " + (datos.size() / ((fin - inicio) / 1000)) + " reg/s");
cliente.close();
}
El enfoque con Pipeline redujo el tiempo a 12 segundos, alcanzando 838,218 registros por segundo. Aunque Pipeline mejora significativamente la velocidad, es importante notar que puede incrementar el consumo de memoria durante las operaciones.