SlideShare a Scribd company logo
1 of 72
Active Record
       &
Projeto Octopus

Thiago Pradi - Ruby Masters Conf 2011
Thiago Pradi

• Desenvolvedor Web na Taoweb Zinfinit
• Desenvolvedor Ruby a 3 anos
• Bacharelando em Ciência da Computação
• Participou do Ruby Summer of Code 2010
Tópicos

• ActiveRecord
• Database Sharding
• Projeto Octopus
ActiveRecord - Padrão

• Objeto encapsula o acesso a base
• Objeto guarda regras de negócio
• Cada classe representa uma tabela
• Cada instância representa um registro
• Cada coluna representa um atributo
ActiveRecord - Padrão
ActiveRecord + Ruby




        Fonte: http://www.flickr.com/photos/54087404@N00/243781036
ActiveRecord + Ruby
• Parte da stack do Rails
• Simples
• Convenção sobre Configuração
• DRY
• Migrations
• Validações
Acesso ao Banco


• Encapsulado internamente
• Cada aplicação utiliza uma instância de
  banco por ambiente
Um Banco de Dados?!

• Gerenciamento de Conexão feito por
  Modelo
• Podemos lidar com mais de um banco,
  porém um modelo só busca dados em um
  Banco
Funcionamento




     Fonte: http://www.flickr.com/photos/19487674@N00/9720923/
Gerência de Conexão
• Cada instância pede ao “Gerenciador de
  conexões” uma conexão quando
  necessário
• O Model usa a conexão e a devolve ao
  gerenciador
• Proporcionando Economia de recursos
• e Problemas de concorrência?!
Múltiplas Threads?!




         Fonte: http://www.geograph.org.uk/photo/1429992
ConnectionPool

• Responsável pela gerência de conexão
• Controla as requisições de conexões
• Limita o número de conexões
• Thread-safe
Diagrama do
Funcionamento
Porém...

• Como o ConnectionPool cria novas
  conexões?!
• Como ele sabe os atributos, endereço do
  banco e opções?
Tarô? Buzios? Videntes?
Connection
         Specification
• Os atributos da conexão são carregados via
  Railties ou definidos manualmente.
• Faz o require do adapter necessário, e
  instância uma nova especificação da
  conexão, passando como parâmetro para o
  Construtor do ConnectionPool
• Adapters?!
Connection Adapter
• Classe abstrata responsável por definir os
  métodos básicos necessários para suportar
  um novo banco
• “Abstração” da conexão ao banco de
  dados
• Todos os Adapters herdam do Abstract
  Adapter
Adapters Inclusos no
        Rails

• Mysql (Mysql e MySQL2 Adapters)
• PostgreSQL (PostgreSQL Adapter)
• Sqlite (SQLite e SQLite3 Adapters)
Voltando ao nosso
         tema...
• Como temos uma conexão por model, uma
  classe interna é utilizada para gerenciar as
  instâncias de ConnectionPool
• Classe que implementa comportamento de
  Hash
• Utilizando o nome do modelo como chave,
  retorna o ConnectionPool adequado.
Models
class User < ActiveRecord::Base
  establish_connection :development_2
end


class Post < ActiveRecord::Base
end
database.yml
development:
  adapter: sqlite3
  database: db/development.sqlite3
  pool: 5
  timeout: 5000

development_2:
  adapter: sqlite3
  database: db/development2.sqlite3
  pool: 5
  timeout: 5000
Classe em Ação!
Conexão por Modelo -
   Casos de Uso

• Base de dados legadas
• Integração com outros sistemas
Problemas

• Aplicações diferentes, necessidades
  diferentes
• Aplicações grandes acabam dividindo dados
  entre diferentes bases
Soluções


• Sharding
• Replicação
Database Sharding
• Divisão dos dados entre várias instâncias
  de banco de dados
• Motivado por problemas de escalabilidade
  (Conexões paralelas, alto volume de
  trafego).
• Cada fragmento (instância) salva uma parte
  da base de dados
Prós / Sharding

• Bases menores significa mais performance
• Se um servidor cair, os outros continuam
  operando
• Consultas distribuidas, possibilitando
  trabalhos em paralelo.
Contras / Sharding

• Consultas entre Shards
• Dificuldade de balanceamento futuro
• Implementações não oficiais
• Conflito entre bases
Replicação


• Master/Master
• Master/Slave
Master/Master

• Cada instância fica com a replicação
  configurada, sendo slave e master ao
  mesmo tempo
• Geralmente, no caso de duas bases,
  números pares e ímpares são utilizados
  para ID.
Master/Master

• Resolve gargalo de escrita
• Configuração complexa
• Conflito entre bases
Master/Slaves
• Cada consulta é enviada para um log
• o banco escravo é configurado para ler o
  log do master
• Os escravos ficam na escuta do log
• Quando uma consulta de escrita chega, os
  escravos executam ela na sua instância.
Master/Slaves
• Dados não particionados
• Suporte oficial pela maioria dos banco de
  dados
• Somente uma instância escreve os dados, as
  outras funcionam somente para leitura
• Cada instância carrega uma cópia da base
Master/Slaves

• Base de dados contém backup em tempo
  real
• Processamento de leitura distribuído entre
  vários servidores
MySQL

• Master/Slaves suporte oficial
• Funciona com Log Binário
• Master/Master com o MySQLMM ( Não
  Oficial)
• Mysql Cluster
PostgreSQL

• Master/Slave incluso com a versão 9.0
• Funciona via streaming de Log
• Várias alternativas: http://
  wiki.postgresql.org/wiki/
  Replication,_Clustering,_and_Connection_
  Pooling
Oracle

• Replicação built-in
• Várias soluções para Replicação entre
  diferentes bases de dados:
• http://www.oracle.com/technetwork/
  database/features/data-integration/
  default-159085.html
Database Sharding
       +
 Active Record
       =
        ?
Database Sharding
        +
  ActiveRecord
        =
Projeto Octopus!
Projeto Octopus




       Fonte: http://www.flickr.com/photos/shalvas/4782107423/
Projeto Octopus

• Implementação de Database Sharding para
  ActiveRecord
• Projeto patrocinado pelo Ruby Summer of
  Code 2010.
Problemas
• Problema simples: alguns relatórios pesados
  estavam destruindo a performance do
  banco
• Existia um banco Replicado, para onde
  algumas consultas poderiam ser enviadas
• Simples! Vamos procurar uma
  implementação de Database Sharding!
Implementações
• Masochism(https://github.com/
  technoweenie/masochism)
• DataFabric (https://github.com/mperham/
  data_fabric)
• ShardTheLove (https://github.com/mixonic/
  ShardTheLove)
• DataCharmer (https://github.com/kovyrin/
  db-charmer)
Infelizmente

• Falta de documentação
• Falta de exemplos
• Bibliotecas complexas e difíceis de
  customização.
• Não compatíveis com Rails 3
Então, resolvi meu
   próprio problema!

• O Projeto Octopus foi aprovado para o
  Ruby Summer of Code 2010.
• Trabalhei em conjunto com meu mentor
  Mike Perham, autor da gem DataFabric
Idéia Inicial
• Implementação simples e flexível
• Possibilidade de escolher quais consultas
  devem ser enviadas para qual shard.
• Suportar Sharding e replicação
• Suporte a mover massas de dados entre
  Shards
Conversa com Mentor


• Foco nas primeiras features, e mais
  importantes
• Inicio da implementação
Octopus nascendo!

• Idéia baseada no Masochism e no
  DataFabric
• Monkey-patch no método que retorna a
  conexão, e ao invés de retornar a conexão
  real, um “Proxy” é retornado
• Classe Octopus::Proxy
Arquivo de
        Configuração

• localizado em config/shards.yml
• Salva as informações sobre o modo de
  operação, e o shards disponíveis.
• Possibilita agrupamento de shards
Exemplo:
octopus:
  replicated: true

 shards:
   slave1:
     database: octopus_shard2
     adapter: mysql
     host: localhost
   slave2:
     database: octopus_shard3
     adapter: mysql
     host: localhost
Migrations


• Suporte para enviar migrações a diferente
  shards
• Suporte: múltiplos shards e grupos
Exemplo:
class CreateUsersOnBothShards < ActiveRecord::Migration
  using(:brazil, :canada)

  def self.up
    User.create!(:name => "Both")
  end

  def self.down
    User.delete_all()
  end
end
Exemplo:
class CreateUsersOnShardsOfAGroup < ActiveRecord::Migration
  using_group(:country_shards)

  def self.up
    User.create!(:name => "Group")
  end

  def self.down
    User.delete_all()
  end
end
Modos de Operação


• Replicação
• Sharding
Sharding

• Base de dados “Repartida”
• Alguns dados separados em cada base
• Leituras/Escritas enviadas conforme
  controle do usuário.
Sintaxe

Octopus.using(:master) do
  User.create!(:name => "Block test")
end

User.using(:master).find_by_name("Block")
Controle de shards
# Busca o usuário no shard1
@user = User.using(:shard1).find_by_name("Joao")

# Busca o usuário no master
@user2 = User.find_by_name("Jose")

#Define um novo nome de usuário
@user.name = "Mike"

# Salva o usuário na base de dados correta.
@user.save
Relacionamentos
@permission_brazil_2 = Permission.using(:brazil).create!(:name
=> "Brazil Item 2")

role = @permission_brazil_2.roles.create(:name => "Builded
Role")

#Faz a busca e retorna a role correta
role.permission
Stack do Rails
class ApplicationController < ActionController::Base
     around_filter :select_shard

     def select_shard(&block)
       if logged_in?
         Octopus.using(current_user.shard, &block)
       else
         yield
       end
     end
   end
Replicação

• Uma base Master
• Vários Slaves
• Escritas enviadas para o Master
• Leituras enviadas para os Slaves
Stack do Rails

• Totalmente integrado com a stack inteira
  do Rails
• Permite uma experiência de usuário
  simples e funcional.
Octopus Off Rails


• Pensado para funcionar off da stack do
  Rails
• Funciona com Sinatra, etc
Exemplos

• https://github.com/tchandy/octopus_sinatra
• https://github.com/tchandy/
  octopus_sharding_example
• https://github.com/tchandy/
  octopus_replication_example
Octopus + Model
          based connections
class CustomConnection < ActiveRecord::Base
  octopus_establish_connection(:adapter => "mysql",
                               :database => "octopus_shard2",
                               :username => "root",
                               :password => "")
end
Octopus é...

• Uma lib para facilitar Database Sharding no
  ActiveRecord
• Helpers para facilitarem a migração de
  dados
Octopus não é...


•   Rails OMG! SCALE EDITION!
Idéias para o Futuro

• Configuração automática do banco de
  dados para replicação
• Ferramenta para mover/sincronizar dados
  entre os shards
• Melhores algoritmos de balanceamento
Participe do Projeto!

• O Octopus não é perfeito
• Submeta idéias/patches
• Arquivo TODO.txt na raiz do projeto
• Leia a Wiki / README no github
Agradecimento ao
    Mentor!
Contato

• twitter.com/thiagopradi
• github.com/tchandy
• thiago.pradi@gmail.com
• Restou alguma dúvida? entre em contato.
Obrigado!

More Related Content

What's hot

Minicurso Ruby e Rails (RailsMG UNA)
Minicurso Ruby e Rails (RailsMG UNA)Minicurso Ruby e Rails (RailsMG UNA)
Minicurso Ruby e Rails (RailsMG UNA)Daniel Lopes
 
TDC 2010: Ambiente de Integração Contínua
TDC 2010: Ambiente de Integração ContínuaTDC 2010: Ambiente de Integração Contínua
TDC 2010: Ambiente de Integração ContínuaHelder da Rocha
 
Conexão Java 2006: Introdução ao Ajax
Conexão Java 2006: Introdução ao AjaxConexão Java 2006: Introdução ao Ajax
Conexão Java 2006: Introdução ao AjaxHelder da Rocha
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)Helder da Rocha
 
Desenvolvemos para web?
Desenvolvemos para web?Desenvolvemos para web?
Desenvolvemos para web?Luis Vendrame
 
Wagner Bianchi, GUOB 2014 MySQL Cluster 7.3
Wagner Bianchi, GUOB 2014 MySQL Cluster 7.3Wagner Bianchi, GUOB 2014 MySQL Cluster 7.3
Wagner Bianchi, GUOB 2014 MySQL Cluster 7.3Wagner Bianchi
 
Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Helder da Rocha
 

What's hot (11)

Minicurso Ruby e Rails (RailsMG UNA)
Minicurso Ruby e Rails (RailsMG UNA)Minicurso Ruby e Rails (RailsMG UNA)
Minicurso Ruby e Rails (RailsMG UNA)
 
TDC 2010: Ambiente de Integração Contínua
TDC 2010: Ambiente de Integração ContínuaTDC 2010: Ambiente de Integração Contínua
TDC 2010: Ambiente de Integração Contínua
 
Otimizando a performance com in-memory no SQL 2016
Otimizando a performance com in-memory no SQL 2016Otimizando a performance com in-memory no SQL 2016
Otimizando a performance com in-memory no SQL 2016
 
Conexão Java 2006: Introdução ao Ajax
Conexão Java 2006: Introdução ao AjaxConexão Java 2006: Introdução ao Ajax
Conexão Java 2006: Introdução ao Ajax
 
Node.js: serious business
Node.js: serious businessNode.js: serious business
Node.js: serious business
 
Aula 06 - TEP - Introdução SQLite
Aula 06 - TEP - Introdução SQLiteAula 06 - TEP - Introdução SQLite
Aula 06 - TEP - Introdução SQLite
 
Treinamento Elasticsearch - Parte 1
Treinamento Elasticsearch - Parte 1Treinamento Elasticsearch - Parte 1
Treinamento Elasticsearch - Parte 1
 
Introdução a JPA (2010)
Introdução a JPA (2010)Introdução a JPA (2010)
Introdução a JPA (2010)
 
Desenvolvemos para web?
Desenvolvemos para web?Desenvolvemos para web?
Desenvolvemos para web?
 
Wagner Bianchi, GUOB 2014 MySQL Cluster 7.3
Wagner Bianchi, GUOB 2014 MySQL Cluster 7.3Wagner Bianchi, GUOB 2014 MySQL Cluster 7.3
Wagner Bianchi, GUOB 2014 MySQL Cluster 7.3
 
Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)Curso de WebServlets (Java EE 7)
Curso de WebServlets (Java EE 7)
 

Similar to Projeto Octopus - Database Sharding para ActiveRecord

Interoperabilidade entre bancos de dados
Interoperabilidade entre bancos de dadosInteroperabilidade entre bancos de dados
Interoperabilidade entre bancos de dadospichiliani
 
Interoperabilidade entre bancos de dados
Interoperabilidade entre bancos de dadosInteroperabilidade entre bancos de dados
Interoperabilidade entre bancos de dadospichiliani
 
Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça
Três anos de Scala em Produção: desafios, aprendizados e dores de cabeçaTrês anos de Scala em Produção: desafios, aprendizados e dores de cabeça
Três anos de Scala em Produção: desafios, aprendizados e dores de cabeçaFelipe Hummel
 
Microsoft Azure Storage - Tudo o que você precisa saber sobre armazenamento d...
Microsoft Azure Storage - Tudo o que você precisa saber sobre armazenamento d...Microsoft Azure Storage - Tudo o que você precisa saber sobre armazenamento d...
Microsoft Azure Storage - Tudo o que você precisa saber sobre armazenamento d...Lucas A. Romão
 
Ruby on Rails: um estudo de viabilidade em ambientes empresariais
Ruby on Rails: um estudo de viabilidade em ambientes empresariaisRuby on Rails: um estudo de viabilidade em ambientes empresariais
Ruby on Rails: um estudo de viabilidade em ambientes empresariaisRodrigo Recio
 
Tecnologias para mineração de dados nas nuvens
Tecnologias para mineração de dados nas nuvensTecnologias para mineração de dados nas nuvens
Tecnologias para mineração de dados nas nuvensAlessandro Binhara
 
Otimizacao de websites em PHP
Otimizacao de websites em PHPOtimizacao de websites em PHP
Otimizacao de websites em PHPFelipe Ribeiro
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation FrameworkLeandro Domingues
 
L'esprit de l'escalier
L'esprit de l'escalierL'esprit de l'escalier
L'esprit de l'escalierGleicon Moraes
 
Utilizando NoSQL no desenvolvimento de soluções inteligentes
Utilizando NoSQL no desenvolvimento de soluções inteligentesUtilizando NoSQL no desenvolvimento de soluções inteligentes
Utilizando NoSQL no desenvolvimento de soluções inteligentesChristiano Anderson
 
Palestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAPalestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAThiago Cifani
 
Introdução ao MongoDB (NoSQL)
Introdução ao MongoDB (NoSQL)Introdução ao MongoDB (NoSQL)
Introdução ao MongoDB (NoSQL)Thiago de Azeredo
 
PostgreSQL Tuning: O elefante mais rápido que um leopardo
PostgreSQL Tuning: O elefante mais rápido que um leopardoPostgreSQL Tuning: O elefante mais rápido que um leopardo
PostgreSQL Tuning: O elefante mais rápido que um leopardoelliando dias
 

Similar to Projeto Octopus - Database Sharding para ActiveRecord (20)

Interoperabilidade entre bancos de dados
Interoperabilidade entre bancos de dadosInteroperabilidade entre bancos de dados
Interoperabilidade entre bancos de dados
 
Interoperabilidade entre bancos de dados
Interoperabilidade entre bancos de dadosInteroperabilidade entre bancos de dados
Interoperabilidade entre bancos de dados
 
Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça
Três anos de Scala em Produção: desafios, aprendizados e dores de cabeçaTrês anos de Scala em Produção: desafios, aprendizados e dores de cabeça
Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça
 
Microsoft Azure Storage - Tudo o que você precisa saber sobre armazenamento d...
Microsoft Azure Storage - Tudo o que você precisa saber sobre armazenamento d...Microsoft Azure Storage - Tudo o que você precisa saber sobre armazenamento d...
Microsoft Azure Storage - Tudo o que você precisa saber sobre armazenamento d...
 
Web Scale Data Management
Web Scale Data ManagementWeb Scale Data Management
Web Scale Data Management
 
Ruby on Rails: um estudo de viabilidade em ambientes empresariais
Ruby on Rails: um estudo de viabilidade em ambientes empresariaisRuby on Rails: um estudo de viabilidade em ambientes empresariais
Ruby on Rails: um estudo de viabilidade em ambientes empresariais
 
Mongo db
Mongo dbMongo db
Mongo db
 
Tecnologias para mineração de dados nas nuvens
Tecnologias para mineração de dados nas nuvensTecnologias para mineração de dados nas nuvens
Tecnologias para mineração de dados nas nuvens
 
Otimizacao de websites em PHP
Otimizacao de websites em PHPOtimizacao de websites em PHP
Otimizacao de websites em PHP
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
 
Resque
ResqueResque
Resque
 
Por um Java mais funcional
Por um Java mais funcionalPor um Java mais funcional
Por um Java mais funcional
 
L'esprit de l'escalier
L'esprit de l'escalierL'esprit de l'escalier
L'esprit de l'escalier
 
Utilizando NoSQL no desenvolvimento de soluções inteligentes
Utilizando NoSQL no desenvolvimento de soluções inteligentesUtilizando NoSQL no desenvolvimento de soluções inteligentes
Utilizando NoSQL no desenvolvimento de soluções inteligentes
 
Palestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVAPalestra Desenvolvimento Ágil para Web com ROR UVA
Palestra Desenvolvimento Ágil para Web com ROR UVA
 
Tema3.pptx
Tema3.pptxTema3.pptx
Tema3.pptx
 
Tema3.pptx
Tema3.pptxTema3.pptx
Tema3.pptx
 
Tag Libraries e JSTL
Tag Libraries e JSTLTag Libraries e JSTL
Tag Libraries e JSTL
 
Introdução ao MongoDB (NoSQL)
Introdução ao MongoDB (NoSQL)Introdução ao MongoDB (NoSQL)
Introdução ao MongoDB (NoSQL)
 
PostgreSQL Tuning: O elefante mais rápido que um leopardo
PostgreSQL Tuning: O elefante mais rápido que um leopardoPostgreSQL Tuning: O elefante mais rápido que um leopardo
PostgreSQL Tuning: O elefante mais rápido que um leopardo
 

Projeto Octopus - Database Sharding para ActiveRecord

  • 1. Active Record & Projeto Octopus Thiago Pradi - Ruby Masters Conf 2011
  • 2. Thiago Pradi • Desenvolvedor Web na Taoweb Zinfinit • Desenvolvedor Ruby a 3 anos • Bacharelando em Ciência da Computação • Participou do Ruby Summer of Code 2010
  • 3. Tópicos • ActiveRecord • Database Sharding • Projeto Octopus
  • 4. ActiveRecord - Padrão • Objeto encapsula o acesso a base • Objeto guarda regras de negócio • Cada classe representa uma tabela • Cada instância representa um registro • Cada coluna representa um atributo
  • 6. ActiveRecord + Ruby Fonte: http://www.flickr.com/photos/54087404@N00/243781036
  • 7. ActiveRecord + Ruby • Parte da stack do Rails • Simples • Convenção sobre Configuração • DRY • Migrations • Validações
  • 8. Acesso ao Banco • Encapsulado internamente • Cada aplicação utiliza uma instância de banco por ambiente
  • 9. Um Banco de Dados?! • Gerenciamento de Conexão feito por Modelo • Podemos lidar com mais de um banco, porém um modelo só busca dados em um Banco
  • 10. Funcionamento Fonte: http://www.flickr.com/photos/19487674@N00/9720923/
  • 11. Gerência de Conexão • Cada instância pede ao “Gerenciador de conexões” uma conexão quando necessário • O Model usa a conexão e a devolve ao gerenciador • Proporcionando Economia de recursos • e Problemas de concorrência?!
  • 12. Múltiplas Threads?! Fonte: http://www.geograph.org.uk/photo/1429992
  • 13. ConnectionPool • Responsável pela gerência de conexão • Controla as requisições de conexões • Limita o número de conexões • Thread-safe
  • 15. Porém... • Como o ConnectionPool cria novas conexões?! • Como ele sabe os atributos, endereço do banco e opções?
  • 17. Connection Specification • Os atributos da conexão são carregados via Railties ou definidos manualmente. • Faz o require do adapter necessário, e instância uma nova especificação da conexão, passando como parâmetro para o Construtor do ConnectionPool • Adapters?!
  • 18. Connection Adapter • Classe abstrata responsável por definir os métodos básicos necessários para suportar um novo banco • “Abstração” da conexão ao banco de dados • Todos os Adapters herdam do Abstract Adapter
  • 19. Adapters Inclusos no Rails • Mysql (Mysql e MySQL2 Adapters) • PostgreSQL (PostgreSQL Adapter) • Sqlite (SQLite e SQLite3 Adapters)
  • 20. Voltando ao nosso tema... • Como temos uma conexão por model, uma classe interna é utilizada para gerenciar as instâncias de ConnectionPool • Classe que implementa comportamento de Hash • Utilizando o nome do modelo como chave, retorna o ConnectionPool adequado.
  • 21. Models class User < ActiveRecord::Base establish_connection :development_2 end class Post < ActiveRecord::Base end
  • 22. database.yml development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 development_2: adapter: sqlite3 database: db/development2.sqlite3 pool: 5 timeout: 5000
  • 24. Conexão por Modelo - Casos de Uso • Base de dados legadas • Integração com outros sistemas
  • 25. Problemas • Aplicações diferentes, necessidades diferentes • Aplicações grandes acabam dividindo dados entre diferentes bases
  • 27. Database Sharding • Divisão dos dados entre várias instâncias de banco de dados • Motivado por problemas de escalabilidade (Conexões paralelas, alto volume de trafego). • Cada fragmento (instância) salva uma parte da base de dados
  • 28. Prós / Sharding • Bases menores significa mais performance • Se um servidor cair, os outros continuam operando • Consultas distribuidas, possibilitando trabalhos em paralelo.
  • 29. Contras / Sharding • Consultas entre Shards • Dificuldade de balanceamento futuro • Implementações não oficiais • Conflito entre bases
  • 31. Master/Master • Cada instância fica com a replicação configurada, sendo slave e master ao mesmo tempo • Geralmente, no caso de duas bases, números pares e ímpares são utilizados para ID.
  • 32. Master/Master • Resolve gargalo de escrita • Configuração complexa • Conflito entre bases
  • 33. Master/Slaves • Cada consulta é enviada para um log • o banco escravo é configurado para ler o log do master • Os escravos ficam na escuta do log • Quando uma consulta de escrita chega, os escravos executam ela na sua instância.
  • 34. Master/Slaves • Dados não particionados • Suporte oficial pela maioria dos banco de dados • Somente uma instância escreve os dados, as outras funcionam somente para leitura • Cada instância carrega uma cópia da base
  • 35. Master/Slaves • Base de dados contém backup em tempo real • Processamento de leitura distribuído entre vários servidores
  • 36. MySQL • Master/Slaves suporte oficial • Funciona com Log Binário • Master/Master com o MySQLMM ( Não Oficial) • Mysql Cluster
  • 37. PostgreSQL • Master/Slave incluso com a versão 9.0 • Funciona via streaming de Log • Várias alternativas: http:// wiki.postgresql.org/wiki/ Replication,_Clustering,_and_Connection_ Pooling
  • 38. Oracle • Replicação built-in • Várias soluções para Replicação entre diferentes bases de dados: • http://www.oracle.com/technetwork/ database/features/data-integration/ default-159085.html
  • 39. Database Sharding + Active Record = ?
  • 40. Database Sharding + ActiveRecord = Projeto Octopus!
  • 41. Projeto Octopus Fonte: http://www.flickr.com/photos/shalvas/4782107423/
  • 42. Projeto Octopus • Implementação de Database Sharding para ActiveRecord • Projeto patrocinado pelo Ruby Summer of Code 2010.
  • 43. Problemas • Problema simples: alguns relatórios pesados estavam destruindo a performance do banco • Existia um banco Replicado, para onde algumas consultas poderiam ser enviadas • Simples! Vamos procurar uma implementação de Database Sharding!
  • 44. Implementações • Masochism(https://github.com/ technoweenie/masochism) • DataFabric (https://github.com/mperham/ data_fabric) • ShardTheLove (https://github.com/mixonic/ ShardTheLove) • DataCharmer (https://github.com/kovyrin/ db-charmer)
  • 45. Infelizmente • Falta de documentação • Falta de exemplos • Bibliotecas complexas e difíceis de customização. • Não compatíveis com Rails 3
  • 46. Então, resolvi meu próprio problema! • O Projeto Octopus foi aprovado para o Ruby Summer of Code 2010. • Trabalhei em conjunto com meu mentor Mike Perham, autor da gem DataFabric
  • 47. Idéia Inicial • Implementação simples e flexível • Possibilidade de escolher quais consultas devem ser enviadas para qual shard. • Suportar Sharding e replicação • Suporte a mover massas de dados entre Shards
  • 48. Conversa com Mentor • Foco nas primeiras features, e mais importantes • Inicio da implementação
  • 49. Octopus nascendo! • Idéia baseada no Masochism e no DataFabric • Monkey-patch no método que retorna a conexão, e ao invés de retornar a conexão real, um “Proxy” é retornado • Classe Octopus::Proxy
  • 50. Arquivo de Configuração • localizado em config/shards.yml • Salva as informações sobre o modo de operação, e o shards disponíveis. • Possibilita agrupamento de shards
  • 51. Exemplo: octopus: replicated: true shards: slave1: database: octopus_shard2 adapter: mysql host: localhost slave2: database: octopus_shard3 adapter: mysql host: localhost
  • 52. Migrations • Suporte para enviar migrações a diferente shards • Suporte: múltiplos shards e grupos
  • 53. Exemplo: class CreateUsersOnBothShards < ActiveRecord::Migration using(:brazil, :canada) def self.up User.create!(:name => "Both") end def self.down User.delete_all() end end
  • 54. Exemplo: class CreateUsersOnShardsOfAGroup < ActiveRecord::Migration using_group(:country_shards) def self.up User.create!(:name => "Group") end def self.down User.delete_all() end end
  • 55. Modos de Operação • Replicação • Sharding
  • 56. Sharding • Base de dados “Repartida” • Alguns dados separados em cada base • Leituras/Escritas enviadas conforme controle do usuário.
  • 57. Sintaxe Octopus.using(:master) do User.create!(:name => "Block test") end User.using(:master).find_by_name("Block")
  • 58. Controle de shards # Busca o usuário no shard1 @user = User.using(:shard1).find_by_name("Joao") # Busca o usuário no master @user2 = User.find_by_name("Jose") #Define um novo nome de usuário @user.name = "Mike" # Salva o usuário na base de dados correta. @user.save
  • 59. Relacionamentos @permission_brazil_2 = Permission.using(:brazil).create!(:name => "Brazil Item 2") role = @permission_brazil_2.roles.create(:name => "Builded Role") #Faz a busca e retorna a role correta role.permission
  • 60. Stack do Rails class ApplicationController < ActionController::Base around_filter :select_shard def select_shard(&block) if logged_in? Octopus.using(current_user.shard, &block) else yield end end end
  • 61. Replicação • Uma base Master • Vários Slaves • Escritas enviadas para o Master • Leituras enviadas para os Slaves
  • 62. Stack do Rails • Totalmente integrado com a stack inteira do Rails • Permite uma experiência de usuário simples e funcional.
  • 63. Octopus Off Rails • Pensado para funcionar off da stack do Rails • Funciona com Sinatra, etc
  • 64. Exemplos • https://github.com/tchandy/octopus_sinatra • https://github.com/tchandy/ octopus_sharding_example • https://github.com/tchandy/ octopus_replication_example
  • 65. Octopus + Model based connections class CustomConnection < ActiveRecord::Base octopus_establish_connection(:adapter => "mysql", :database => "octopus_shard2", :username => "root", :password => "") end
  • 66. Octopus é... • Uma lib para facilitar Database Sharding no ActiveRecord • Helpers para facilitarem a migração de dados
  • 67. Octopus não é... • Rails OMG! SCALE EDITION!
  • 68. Idéias para o Futuro • Configuração automática do banco de dados para replicação • Ferramenta para mover/sincronizar dados entre os shards • Melhores algoritmos de balanceamento
  • 69. Participe do Projeto! • O Octopus não é perfeito • Submeta idéias/patches • Arquivo TODO.txt na raiz do projeto • Leia a Wiki / README no github
  • 70. Agradecimento ao Mentor!
  • 71. Contato • twitter.com/thiagopradi • github.com/tchandy • thiago.pradi@gmail.com • Restou alguma dúvida? entre em contato.

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n