Blaapps 0.5.0 Released

After 21 months of sporadic work, I’ve finished the application for my «Thesis». Today I’m proud to announce the release of Blaapps Application Framework version 0.5.0.

Blaaps Logo for version 0.5.0

I’ve done lots of work transforming rudder Application Server, a previous project, into an Application Framework.

Blaapps Architecture

The Kernel of Blaapps is based on core Subsystems. Two of them are the most important:

  • Deployer
  • Messaging

The Deployer reads components called Modules, and loads them into memory. Modules are like plugins, hot plug-gable extensions to the application.

Messaging brings the infrastructure for the inter-module comunication.

Other features which are usually needed for Application development are packaged as Kernel Modules. In this version, two modules are included:

  • Remote
  • Persistence

Remote helps you to publish objects into a RMI Registry.

Persistence Is a JPA (Hibernate) wrapper.

As you can see, blaapps 0.5.0 is reinventing the wheel. There’s lots of plugin frameworks, and the EJB 3.0 standards helps you with persistence and remote objects. So why develop something like blaapps?

The first reason was that I wanted to learn how to do cool stuff, like Dependency Injection. Blaapps contains «only» 1800 lines of code, so it’s easier to learn from blaapps than from a real Application Server.

The second one is that I wanted something fast for my developments. Blaapps is very limited, but it starts in few seconds.

What’s next? Once I present my Thesis and became an official engineer, I’ll start with blaapps 0.6.0. There’s already a Milestone planning which will focus on making easier the building of GUIs.

Tiempo de importación en MySQL

Una de las formas para importar datos en MySQL es el comando LOAD DATA INFILE. Es más rápido que un dump, ya que se leen los datos en bruto, en lugar de sentencias SQL.

El tiempo de importación depende del motor que use la tabla, por ejemplo, MyISAM puede ser 40 times más rápido que Innodb. Vamos a probarlo:

Preparación

Voy a utilizar MySQL 5.1.36 (64 bits MacOS X) para hacer las pruebas. Necesitaré una tabla grande, así que partiré de la tabla City de la Base de datos world y crearé una tabla más grande que se llame «city_huge»:

CREATE TABLE city_huge LIKE CITY;

INSERT INTO city_huge 
    SELECT NULL, name, CountryCode, District, Population FROM city;
# Ejecuta 100 veces esta sentencia,
# así city_huge será 100 veces más grande que city.
# Un consejo, usa un script, una tabla temporal, 
# un procedimiento almacenado...
# o dile a tu mono que lo haga por tí.

SELECT COUNT(*) FROM city_huge;
#   +----------+
#   | COUNT(*) |
#   +----------+
#   |   407900 | 
#   +----------+

# Haz una copia de seguridad de tu tabla:
SELECT * FROM city_huge INTO OUTFILE 'city_huge.bak';

# Trunca la tabla, empezaremos con la tabla vacía.
TRUNCATE TABLE city_huge;

Importar diréctamente

Vamos a reestablecer la copia de seguridad en la tabla city_huge, usando MyISAM, InnoDB y MEMORY:

LOAD DATA INFILE 'city_huge.bak' INTO TABLE city_huge;
#   Query OK, ... (5.85 sec)
# Eso era usando MyISAM.

# Vaciamos la tabla y cambiamos el motor a InnoDB:
TRUNCATE TABLE city_huge;
ALTER TABLE city_huge ENGINE = InnoDB;
LOAD DATA INFILE 'city_huge.bak' INTO TABLE city_huge;
#   Query OK, ... (3 min 59.53 sec)

# Con Memory:
TRUNCATE TABLE city_huge;
SET @@max_heap_size= 128 * 1024 * 1024;
ALTER TABLE city_huge ENGINE = MEMORY;
LOAD DATA INFILE 'city_huge.bak' INTO TABLE city_huge;
#   Query OK, ... (2.18 sec)
MyISAM 0:5.85
InnoDB 3:59.53
MEMORY 0:2.18

Wow, MyISAM es unas 40 veces más rápido. MEMORY es incluso más rápido.

Alter Table

De acuerdo, InnoDB es un poco lento, pero a veces no se puede usar otro motor de bases de datos. En esos casos, podemos intentar importar en un motor y luego cambiar el motor de la tabla a InnoDB.

Sería algo así:

TRUNCATE TABLE city_huge;
ALTER TABLE city_huge ENGINE = MyISAM;
LOAD DATA INFILE 'city_huge.bak' INTO TABLE city_huge;
#   Query OK, ... (5.85 sec)
ALTER TABLE city_huge ENGINE = InnoDB;
#   Query OK, ... (4 min 11.24 sec)

Ooops, 4 min 17 sec es más que 3 min 59 sec.

Vamos a intentarlo con Memory:

TRUNCATE TABLE city_huge;
SET @@max_heap_size= 128 * 1024 * 1024;
ALTER TABLE city_huge ENGINE = MEMORY;
LOAD DATA INFILE 'city_huge.bak' INTO TABLE city_huge;
#   Query OK, ... (2.18 sec)
ALTER TABLE city_huge ENGINE = InnoDB;
# Query OK, ... (3 min 28.39 sec)

Sí, 3 min 31 sec es más rápido que 4 min. 30 seconds, es cerca de un 10% más rápido.

Exención de responsabilidad

Esta prueba se ha hecho usando la configuración por defecto, estoy seguro de que ajustando InnoDB se mejorarán los resultados. Tampoco soy muy estricto con mis pruebas, así que te animo a que prepares tus propias pruebas.

Esta solución no es algo aplicable siempre, el motor MEMORY necesita grandes cantidades de memoria. Esta NO siempre es la mejor manera de hacer las cosas, InnoDB debería ser más rápido por sí sólo.

De todas formas, es divertido encontrar estos comportamientos no tan obvios :D.

Leer Comentarios versión Inglesa

Importing times in MySQL

One of the ways to import data into MySQL is using the LOAD DATA INFILE. It is a faster method than recovering from a dump, as it’s raw data instead of SQL sentences.

The import time depends on the table engine, for example, MyISAM can be 40 times faster than Innodb. Let’s benchmark this:

Preparation

I’m gonna make some benchmarking using MySQL 5.1.36 (64 bits MacOS X). I’ll need a big table, so I’ll take City from the World Database and create a huge table called «city_huge»:

CREATE TABLE city_huge LIKE CITY;

INSERT INTO city_huge 
    SELECT NULL, name, CountryCode, District, Population FROM city;
# Run this sentence 100 times,
# so city_huge table will be 100 times bigger than city.
# Tip: use a script, temporary table, stored procedure...
# or tell your monkey to do so.

SELECT COUNT(*) FROM city_huge;
#   +----------+
#   | COUNT(*) |
#   +----------+
#   |   407900 | 
#   +----------+

# Make a table data backup:
SELECT * FROM city_huge INTO OUTFILE 'city_huge.bak';

# Truncate table, so we'll start with an empty table.
TRUNCATE TABLE city_huge;

Direct Import

Let’s import the backup into the city_huge table, using MyISAM, InnoDB and MEMORY:

LOAD DATA INFILE 'city_huge.bak' INTO TABLE city_huge;
#   Query OK, ... (5.85 sec)
# So, that was using MyISAM.

# Let's empty the table and change the engine to InnoDB:
TRUNCATE TABLE city_huge;
ALTER TABLE city_huge ENGINE = InnoDB;
LOAD DATA INFILE 'city_huge.bak' INTO TABLE city_huge;
#   Query OK, ... (3 min 59.53 sec)

# With Memory:
TRUNCATE TABLE city_huge;
SET @@max_heap_size= 128 * 1024 * 1024;
ALTER TABLE city_huge ENGINE = MEMORY;
LOAD DATA INFILE 'city_huge.bak' INTO TABLE city_huge;
#   Query OK, ... (2.18 sec)
MyISAM 0:5.85
InnoDB 3:59.53
MEMORY 0:2.18

Wow, MyISAM is almost 40 times faster. And MEMORY is even faster.

Alter Table

Ok, InnoDB is a bit slow, but sometimes you can’t use another storage engine. In those cases, you could import in the other engine and then change the table engine to InnoDB.

That would look like this:

TRUNCATE TABLE city_huge;
ALTER TABLE city_huge ENGINE = MyISAM;
LOAD DATA INFILE 'city_huge.bak' INTO TABLE city_huge;
#   Query OK, ... (5.85 sec)
ALTER TABLE city_huge ENGINE = InnoDB;
#   Query OK, ... (4 min 11.24 sec)

Ooops, 4 min 17 sec is more than 3 min 59 sec.

Let’s try Memory:

TRUNCATE TABLE city_huge;
SET @@max_heap_size= 128 * 1024 * 1024;
ALTER TABLE city_huge ENGINE = MEMORY;
LOAD DATA INFILE 'city_huge.bak' INTO TABLE city_huge;
#   Query OK, ... (2.18 sec)
ALTER TABLE city_huge ENGINE = InnoDB;
# Query OK, ... (3 min 28.39 sec)

Yes, 3 min 31 sec is faster than 4 min. 30 seconds are around 10% faster.

Disclaimer

This benchmark is done using the default configuration, I’m sure that tuning InnoDB will improve the results. Also, I’m not the most accurate benchmarker, so I encourage you to do your own benchmarks.

This solution is not a silver bullet, MEMORY engine needs lots of memory. And this is NOT always the best approach, InnoDB should be fast by it’s own.

Anyway, its funny to discover those not so obvious behaviours :D.

Read Spanish Comments

Sun Open Communities Forum

Estoy pasando unos días estupendos en el «Sun Open Communities Forum», en Bohadilla del Monte, Madrid.

Una oportunidad estupenda para reunirse con la comunidad sun/mysql de españa.

Esta tarde imparto una charla «No mueras de éxito» a las 3:45 pm. En ella trataré de manera divulgativa temas como la SQL Caché, replicación o el Enterprise Monitor. Puedes seguir la charla en directo desde la página del evento

Después de mi charla, Jorge Sanchez presentará la recién creada comunidad española de mysql, comunidadmysql.org.

Saludos ¡Nos vemos en la comunidad!