Histórico :
criei um aplicativo Web que gostaria de poder escalar razoavelmente bem. Sei que não sou Google ou Twitter, mas meu aplicativo usa uma quantidade bastante grande de dados para cada usuário e, portanto, possui requisitos de dados bastante altos. Quero estar pronto para escalar razoavelmente bem sem ter que re-arquitetar tudo mais tarde.
Eu me considero um desenvolvedor de software, não um especialista em banco de dados. É por isso que estou postando aqui. Espero que alguém com muito mais experiência em banco de dados possa me dar conselhos.
Com um número relativamente grande de usuários, mas nada como os números do Facebook, espero ter um banco de dados parecido com este:
Uma "mesa grande":
- 250 milhões de registros
- 20 colunas
- Aproximadamente 100 GB de dados
- Possui uma chave estrangeira bigint (20) indexada
- Possui uma coluna varchar indexada (500) string_id
- Possui uma coluna "valor" int (11)
4 outras tabelas:
- 10 milhões de registros cada
- Aproximadamente 2 a 4 GB de dados cada
- cada uma dessas tabelas possui de 4 a 8 colunas
- uma coluna é datetime date_created
- uma coluna é a coluna varchar (500) string_id
- uma ou duas colunas de cada uma dessas tabelas serão selecionadas em uma junção
Uma dessas tabelas é usada para armazenar médias - seu esquema é bigint (20) id, varchar (20) string_id, datetime date_created, float average_value
O que eu quero fazer - duas consultas relativamente caras:
Calcular novos valores médios:
- Usando uma chave estrangeira, selecione até vários milhões de registros separados na tabela grande.
- Calcule uma nova média, agrupando pelo string_id.
- Inserir resultados na tabela de médias.
- Conforme construída atualmente, essa consulta usa duas junções.
Crie registros não normalizados, somente leitura, para atender aos usuários:
- Use uma chave estrangeira para selecionar de 1.000 a 40.000 registros da tabela grande.
- Associe-se a cada uma das outras quatro tabelas no registro mais recente com a coluna de identificação da sequência.
- Insira os resultados em uma tabela não normalizada.
- Esses registros devem ser usados pelo front-end para exibir informações aos usuários.
- Conforme construída atualmente, essa consulta usa quatro junções.
Planejo executar cada uma dessas consultas caras em um banco de dados de back-end em lote que enviará seus resultados para um servidor de banco de dados front-end em tempo real que lida com solicitações de usuários. Essas consultas serão executadas em intervalos regulares. Não decidi com que frequência. A consulta média pode ser feita talvez uma vez por dia. A consulta de desnormalização precisará ser mais frequente - talvez a cada poucos minutos.
Atualmente, cada uma dessas consultas é executada em poucos segundos no MySQL em uma máquina muito simples, com um conjunto de dados com 100 mil registros na "grande tabela". Estou preocupado com minha capacidade de escalar e com os custos de escalar.
Perguntas :
- Essa abordagem parece sólida? Existe algo obviamente errado com isso do ponto de vista geral?
- Um RDBMS é a ferramenta certa ou devo procurar outras soluções de "big data" como algo da família Hadoop? Minha inclinação é usar um RDBMS porque os dados são estruturados e se encaixam perfeitamente no modelo relacional. Em um determinado momento, porém, entendo que eu não consiga mais usar um RDBMS. Isso é verdade? Quando essa troca seria necessária?
- será que vai dar certo? Essas consultas podem ser executadas em um período de tempo razoável? Posso esperar talvez horas pela consulta nº 1, mas a consulta nº 2 deve terminar em minutos.
- O que devo considerar da perspectiva do hardware? Quais são meus gargalos de RAM e CPU? Presumo que manter índices na RAM seja importante. Há mais alguma coisa que eu deva considerar?
- Em algum momento, provavelmente terei que particionar meus dados e usar vários servidores. Meu caso de uso parece que já está nessa categoria ou poderei dimensionar uma única máquina verticalmente por um tempo? Isso funcionará com 10x os dados? 100x?