Usar Replicas de Bases de Datos en Ruby on Rails con la gema Octopus

| 2018-12-1 | No hay comentarios »

Hace poco tiempo me tocó resolver el problema de una app en Ruby on Rails, la base de datos de dicha app creció considerablemente en muy poco tiempo. Estábamos usando una instancia db.t2.medium (AWS RDS) y dicha instancia ya se encontraba al límite (el 80% de todos los requests eran de lectura y solo en 20% de escritura), lo que significaba que la performance de la app era muy mala porque la app tiene mucha cantidad de visitas diarias.

Para subsanar ese problema decidí crear una replica de la base de datos (db.t2.medium AWS RDS) y hacer todo lo relacionado a lecturas en dicha base de datos y en el maestro solamente las escrituras, ahora bien, cómo lo hice?

Busqué soluciones listas para usar, en lugar de reinventar la rueda con una solución propia. Discubrí que una de las mejores maneras de lograrlo es utilizando la gema Octopus.

Se agrega al Gemfile así:

gema “ar-octopus”, “> = 0.9.0”, git: “https://github.com/thiagopradi/octopus”

Utilicé una bifurcación diferente, una que tiene soporte para Rails 5. Si desea usarlo con una aplicación Rails 4 solamente bastante con declarar el nombre de la gema:

gema “ar-octopus”

Para cualquier aplicación normal de Rails, el archivo de configuración estándar config/database.yml se vería así:

development:
  host: db
  database: base_de _datos
  username: usuario
  password: contraseña

Este archivo se mantendrá sin cambios. Pero para que Octopus se configure con la lista de réplicas debe leerlas desde otro archivo de config/shards.yml. La ausencia de este archivo significa que la replicación está completamente deshabilitada, incluso si Octopus Gem está instalado.

octopus:
  replicated: true
  fully_replicated: true
  environments:
  – development

  development:
     replica_1:
       host: read_replica_1_host
       database: base_de_datos
       username: user
       password: pass

Ya que Octopus gem admite fragmentación además de replicación:

replicated: true significa: Octopus asumirá todos los fragmentos como esclavos y la base de datos especificada en database.yml como base de datos maestra

fully_replicated: true significa: Octopus utilizara las replicas para lecturas en todas las partes de la aplicación automáticamente, si no queremos este comportamiento hay que setearlo como “false” y utilizar esto:

Octopus.using(:replica_1) do

  @user = User.find(1)

end

Básicamente, usted debe rodear todo el código que desea con el bloque Octopus.using (: replica) {}, y Octopus enviará cualquier consulta de base de datos dentro de ese bloque a su réplica en lugar de a la base de datos maestra, también se puede hacerlo de esta forma:

@user = User.find(1).using(:replica_1)

Haciendo esto pude reducir considerablemente el uso de la base de datos maestro y ahora mejoró mucho la perfomance de la app, ya que solamente las escrituras se hacen en la base de datos maestro y todas las lecturas en la base de datos réplica. De momento solamente con una sola réplica solucione el problema de perfomance pero a futuro si la app sigue creciendo voy a tener que crear más replicas y eso no será un problema de manejar en Rails con la gema Octopus.

Espero que este artículo les sirva de mucho.

Acerca del autor: Rodrigo Paszniuk

Ingeniero Informático, amante de la tecnología, la música, el ciclismo y aprender cosas nuevas.

Posts Relacionados

  • Recursos – Ruby on Rails
  • Seguridad – Ruby on Rails
  • Borrando comentarios – Ruby on Rails
  • Refactorización – Ruby on Rails



SEGUÍNOS EN FACEBOOK


GITHUB