Active Record       &Projeto OctopusThiago Pradi - Ruby Masters Conf 2011
Thiago Pradi• Desenvolvedor Web na Taoweb Zinfinit• Desenvolvedor Ruby a 3 anos• Bacharelando em Ciência da Computação• Par...
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 tabel...
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ó b...
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...
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• Th...
Diagrama doFuncionamento
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 requ...
Connection Adapter• Classe abstrata responsável por definir os  métodos básicos necessários para suportar  um novo banco• “...
Adapters Inclusos no        Rails• Mysql (Mysql e MySQL2 Adapters)• PostgreSQL (PostgreSQL Adapter)• Sqlite (SQLite e SQLi...
Voltando ao nosso         tema...• Como temos uma conexão por model, uma  classe interna é utilizada para gerenciar as  in...
Modelsclass User < ActiveRecord::Base  establish_connection :development_2endclass Post < ActiveRecord::Baseend
database.ymldevelopment:  adapter: sqlite3  database: db/development.sqlite3  pool: 5  timeout: 5000development_2:  adapte...
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 ba...
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 ...
Prós / Sharding• Bases menores significa mais performance• Se um servidor cair, os outros continuam  operando• Consultas di...
Contras / Sharding• Consultas entre Shards• Dificuldade de balanceamento futuro• Implementações não oficiais• Conflito entre ...
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 ...
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 fic...
Master/Slaves• Dados não particionados• Suporte oficial pela maioria dos banco de  dados• Somente uma instância escreve os ...
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.postg...
Oracle• Replicação built-in• Várias soluções para Replicação entre  diferentes bases de dados:• http://www.oracle.com/tech...
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 Repli...
Implementações• Masochism(https://github.com/  technoweenie/masochism)• DataFabric (https://github.com/mperham/  data_fabr...
Infelizmente• Falta de documentação• Falta de exemplos• Bibliotecas complexas e difíceis de  customização.• Não compatívei...
Então, resolvi meu   próprio problema!• O Projeto Octopus foi aprovado para o  Ruby Summer of Code 2010.• Trabalhei em con...
Idéia Inicial• Implementação simples e flexível• Possibilidade de escolher quais consultas  devem ser enviadas para qual sh...
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 ...
Arquivo de        Configuração• localizado em config/shards.yml• Salva as informações sobre o modo de  operação, e o shards ...
Exemplo:octopus:  replicated: true shards:   slave1:     database: octopus_shard2     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!(:nam...
Exemplo:class CreateUsersOnShardsOfAGroup < ActiveRecord::Migration  using_group(:country_shards)  def self.up    User.cre...
Modos de Operação• Replicação• Sharding
Sharding• Base de dados “Repartida”• Alguns dados separados em cada base• Leituras/Escritas enviadas conforme  controle do...
SintaxeOctopus.using(:master) do  User.create!(:name => "Block test")endUser.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@u...
Relacionamentos@permission_brazil_2 = Permission.using(:brazil).create!(:name=> "Brazil Item 2")role = @permission_brazil_...
Stack do Railsclass ApplicationController < ActionController::Base     around_filter :select_shard     def select_shard(&b...
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://githu...
Octopus + Model          based connectionsclass CustomConnection < ActiveRecord::Base  octopus_establish_connection(:adapt...
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  ...
Participe do Projeto!• O Octopus não é perfeito• Submeta idéias/patches• Arquivo TODO.txt na raiz do projeto• Leia a Wiki ...
Agradecimento ao    Mentor!
Contato• twitter.com/thiagopradi• github.com/tchandy• thiago.pradi@gmail.com• Restou alguma dúvida? entre em contato.
Obrigado!
Upcoming SlideShare
Loading in …5
×

Projeto Octopus - Database Sharding para ActiveRecord

4,350 views

Published on

Apresentação sobre o Projeto Octopus, e sobre Database Sharding. Link para o projeto: https://github.com/tchandy/octopus

Published in: Technology
1 Comment
0 Likes
Statistics
Notes
  • Link para o projeto: https://github.com/tchandy/octopus
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

No Downloads
Views
Total views
4,350
On SlideShare
0
From Embeds
0
Number of Embeds
1,952
Actions
Shares
0
Downloads
37
Comments
1
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Projeto Octopus - Database Sharding para ActiveRecord

    1. 1. Active Record &Projeto OctopusThiago Pradi - Ruby Masters Conf 2011
    2. 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. 3. Tópicos• ActiveRecord• Database Sharding• Projeto Octopus
    4. 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
    5. 5. ActiveRecord - Padrão
    6. 6. ActiveRecord + Ruby Fonte: http://www.flickr.com/photos/54087404@N00/243781036
    7. 7. ActiveRecord + Ruby• Parte da stack do Rails• Simples• Convenção sobre Configuração• DRY• Migrations• Validações
    8. 8. Acesso ao Banco• Encapsulado internamente• Cada aplicação utiliza uma instância de banco por ambiente
    9. 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. 10. Funcionamento Fonte: http://www.flickr.com/photos/19487674@N00/9720923/
    11. 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. 12. Múltiplas Threads?! Fonte: http://www.geograph.org.uk/photo/1429992
    13. 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
    14. 14. Diagrama doFuncionamento
    15. 15. Porém...• Como o ConnectionPool cria novas conexões?!• Como ele sabe os atributos, endereço do banco e opções?
    16. 16. Tarô? Buzios? Videntes?
    17. 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. 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. 19. Adapters Inclusos no Rails• Mysql (Mysql e MySQL2 Adapters)• PostgreSQL (PostgreSQL Adapter)• Sqlite (SQLite e SQLite3 Adapters)
    20. 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. 21. Modelsclass User < ActiveRecord::Base establish_connection :development_2endclass Post < ActiveRecord::Baseend
    22. 22. database.ymldevelopment: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000development_2: adapter: sqlite3 database: db/development2.sqlite3 pool: 5 timeout: 5000
    23. 23. Classe em Ação!
    24. 24. Conexão por Modelo - Casos de Uso• Base de dados legadas• Integração com outros sistemas
    25. 25. Problemas• Aplicações diferentes, necessidades diferentes• Aplicações grandes acabam dividindo dados entre diferentes bases
    26. 26. Soluções• Sharding• Replicação
    27. 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. 28. Prós / Sharding• Bases menores significa mais performance• Se um servidor cair, os outros continuam operando• Consultas distribuidas, possibilitando trabalhos em paralelo.
    29. 29. Contras / Sharding• Consultas entre Shards• Dificuldade de balanceamento futuro• Implementações não oficiais• Conflito entre bases
    30. 30. Replicação• Master/Master• Master/Slave
    31. 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. 32. Master/Master• Resolve gargalo de escrita• Configuração complexa• Conflito entre bases
    33. 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. 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. 35. Master/Slaves• Base de dados contém backup em tempo real• Processamento de leitura distribuído entre vários servidores
    36. 36. MySQL• Master/Slaves suporte oficial• Funciona com Log Binário• Master/Master com o MySQLMM ( Não Oficial)• Mysql Cluster
    37. 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. 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. 39. Database Sharding + Active Record = ?
    40. 40. Database Sharding + ActiveRecord =Projeto Octopus!
    41. 41. Projeto Octopus Fonte: http://www.flickr.com/photos/shalvas/4782107423/
    42. 42. Projeto Octopus• Implementação de Database Sharding para ActiveRecord• Projeto patrocinado pelo Ruby Summer of Code 2010.
    43. 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. 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. 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. 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. 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. 48. Conversa com Mentor• Foco nas primeiras features, e mais importantes• Inicio da implementação
    49. 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. 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. 51. Exemplo:octopus: replicated: true shards: slave1: database: octopus_shard2 adapter: mysql host: localhost slave2: database: octopus_shard3 adapter: mysql host: localhost
    52. 52. Migrations• Suporte para enviar migrações a diferente shards• Suporte: múltiplos shards e grupos
    53. 53. Exemplo:class CreateUsersOnBothShards < ActiveRecord::Migration using(:brazil, :canada) def self.up User.create!(:name => "Both") end def self.down User.delete_all() endend
    54. 54. Exemplo:class CreateUsersOnShardsOfAGroup < ActiveRecord::Migration using_group(:country_shards) def self.up User.create!(:name => "Group") end def self.down User.delete_all() endend
    55. 55. Modos de Operação• Replicação• Sharding
    56. 56. Sharding• Base de dados “Repartida”• Alguns dados separados em cada base• Leituras/Escritas enviadas conforme controle do usuário.
    57. 57. SintaxeOctopus.using(:master) do User.create!(:name => "Block test")endUser.using(:master).find_by_name("Block")
    58. 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. 59. Relacionamentos@permission_brazil_2 = Permission.using(:brazil).create!(:name=> "Brazil Item 2")role = @permission_brazil_2.roles.create(:name => "BuildedRole")#Faz a busca e retorna a role corretarole.permission
    60. 60. Stack do Railsclass 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. 61. Replicação• Uma base Master• Vários Slaves• Escritas enviadas para o Master• Leituras enviadas para os Slaves
    62. 62. Stack do Rails• Totalmente integrado com a stack inteira do Rails• Permite uma experiência de usuário simples e funcional.
    63. 63. Octopus Off Rails• Pensado para funcionar off da stack do Rails• Funciona com Sinatra, etc
    64. 64. Exemplos• https://github.com/tchandy/octopus_sinatra• https://github.com/tchandy/ octopus_sharding_example• https://github.com/tchandy/ octopus_replication_example
    65. 65. Octopus + Model based connectionsclass CustomConnection < ActiveRecord::Base octopus_establish_connection(:adapter => "mysql", :database => "octopus_shard2", :username => "root", :password => "")end
    66. 66. Octopus é...• Uma lib para facilitar Database Sharding no ActiveRecord• Helpers para facilitarem a migração de dados
    67. 67. Octopus não é...• Rails OMG! SCALE EDITION!
    68. 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. 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. 70. Agradecimento ao Mentor!
    71. 71. Contato• twitter.com/thiagopradi• github.com/tchandy• thiago.pradi@gmail.com• Restou alguma dúvida? entre em contato.
    72. 72. Obrigado!

    ×