Optimizando SQLite para aplicaciones Laravel en producción
Soy fan de utilizar SQLite en mis proyectos de Laravel. Sin embargo, la configuración por defecto de SQLite en Laravel no es óptima para ambientes de producción, principalmente por dos motivos.
Primero, la conexión de SQLite no utiliza el journal_mode
en WAL, que ofrece un mejor rendimiento. Además, por defecto, el busy_timeout
no está configurado, ni el modo synchronous
está establecido en NORMAL
.
Segundo, dado que SQLite solo permite un único escritor, si usamos la misma base de datos de SQLite para el almacenamiento en caché y para las colas, el rendimiento de la aplicación puede verse afectado.
Comencemos con el primer problema relacionado con la conectividad.
Afortunadamente, el archivo de configuración de la base de datos de Laravel incluye opciones para ajustar el busy_timeout
, el journal_mode
y el synchronous
. Por lo tanto, simplemente debemos modificar la configuración en config/database.php
para establecer mejores valores.
return [
// ...
'connections' => [
'sqlite' => [
// ...
'busy_timeout' => 5000,
'journal_mode' => 'WAL',
'synchronous' => 'NORMAL',
],
],
];
Ahora, para mejorar el rendimiento, utilizaremos bases de datos separadas para la caché y para las colas.
En el archivo de configuración config/database.php
, copiamos la conexión de sqlite
para crear dos nuevas: una para la caché y otra para las colas.
// ...
'sqlite_cache' => [
// ...
'database' => env('CACHE_DATABASE', database_path('cache_database.sqlite')),
// ...
],
'sqlite_queue' => [
// ...
'database' => env('QUEUE_DATABASE', database_path('queue_database.sqlite')),
// ...
],
// ...
Básicamente, estamos especificando dos nuevos archivos SQLite para las nuevas conexiones: cache_database.sqlite
y queue_database.sqlite
.
También debemos actualizar nuestras variables de entorno en el archivo .env
para especificar las nuevas conexiones para la caché y las colas.
# ...
DB_CONNECTION=sqlite
DB_CACHE_CONNECTION=sqlite_cache
DB_QUEUE_CONNECTION=sqlite_queue
# ...
Finalmente, actualizamos las migraciones de las tablas de caché y de colas para especificar qué conexión debe utilizar la migración al crear las tablas.
Primero, para la migración 0001_01_01_000001_create_cache_table.php
:
return new class extends Migration
{
protected $connection = 'sqlite_cache';
public function up(): void
{
Schema::create('cache', function (Blueprint $table) {
// ...
});
Schema::create('cache_locks', function (Blueprint $table) {
// ...
});
}
};
Y después, para la migración 0001_01_01_000002_create_jobs_table.php
:
return new class extends Migration
{
protected $connection = 'sqlite_queue';
public function up(): void
{
Schema::create('jobs', function (Blueprint $table) {
// ...
});
Schema::create('job_batches', function (Blueprint $table) {
// ...
});
}
};
Separar las bases de datos es comparable a tener tres escritores al mismo tiempo. La caché y las colas suelen ser intensivas en escritura, mientras que nuestra base de datos principal de la aplicación gestiona toda la lógica de negocio.
Este es el enfoque que utilizo para ejecutar SQLite en producción y que mejora enormemente el rendimiento de la aplicación.