Assim, a maior parte do que você tem lá é bastante simples de escalar. PgSQL em sua própria máquina para aliviar uma pilha de I / CPU / disco IO / consumo de memória como um primeiro passo. Esfinge em seu próprio mundinho também. Definitivamente, mude para o resque para permitir um escalonamento horizontal fácil de seus funcionários.
Mas os arquivos ... sim, os arquivos são difíceis. Eles são sempre difíceis. E suas opções são perigosamente finas.
Algumas pessoas recomendam a rota do sistema de arquivos em cluster, o superaglomerado mágico (GFS2 / OCFS2) ou a opção um pouco mais pobre de algo como GlusterFS. Eu executei muitos sistemas (1000+) usando o GFS, e nunca, nunca faço isso novamente. (Pode até não rodar na rede do EC2, na verdade). O GFS2 / OCFS2 é uma confusão de partes móveis, sub-documentadas, supercomplicadas e propensas a modos de falha confusos que apenas causam problemas de tempo de inatividade. Ele também não vale nada, especialmente em um ambiente pesado de gravação - ele simplesmente cai, derrubando todo o seu cluster e levando de 10 a 30 minutos de trabalho em nível de guru para colocá-lo em funcionamento novamente. Evite isso e sua vida é muito mais fácil. Eu nunca corri o GlusterFS, mas isso é porque eu nunca fiquei particularmente impressionado com isso. Qualquer coisa que você possa fazer com isso, geralmente há uma maneira melhor de fazer isso de qualquer maneira.
A melhor opção, na minha opinião, é o venerável servidor NFS. Uma máquina com um grande (ou não tão grande) volume EBS e um daemon NFS rodando, e todo mundo monta isso. Tem gotchas (não é realmente um sistema de arquivos POSIX, então não o trate como tal), mas para simples operação "lá, eu consertei" para 99% dos casos de uso, não é ruim . No mínimo, pode ser um paliativo enquanto você trabalha em uma solução melhor, que é ...
Use seu conhecimento do seu aplicativo para classificar seu armazenamento. Essa é a abordagem que eu fiz mais recentemente (escalando o Github) e funcionou lindamente. Basicamente, em vez de tratar o armazenamento de arquivos como um sistema de arquivos, você o trata como um serviço - fornece uma API inteligente para usar as partes do seu aplicativo para fazer o que você precisa fazer . No seu caso, você pode precisar apenas armazenar e recuperar imagens para IDs pré-alocados (a PK para sua tabela de "imagens" no banco de dados, por exemplo). Isso não precisa de um sistema de arquivos POSIX inteiro, ele só precisa de alguns métodos HTTP super otimizados (os POSTs precisam ser manipulados dinamicamente, mas se você for realmente inteligente, você pode fazer com que os GETs venham disco direto como arquivos estáticos). Inferno, você provavelmente está servindo essas imagens diretamente para os clientes, então corte o intermediário e torne esse servidor seu servidor de ativos publicamente acessível enquanto você está nisso.
O fluxo de trabalho pode ser algo como:
- O servidor frontend recebe a imagem
- envia para o servidor de arquivos
- Adiciona trabalho para processar imagens
- (Alternativamente, o POST para o servidor de arquivos faz com que ele reconheça a necessidade de um trabalho de pós-processamento e cria o trabalho sozinho)
- O trabalhador obtém trabalho de processamento de imagem
- Recupera a imagem do servidor de arquivos
- Processos de imagem
- envia a imagem processada de volta ao servidor de arquivos
- A página da web precisa incluir imagem na página da web
- Grava URL para o servidor de imagens em HTML
- o navegador da Web acessa e obtém imagem diretamente
Você não precisa necessariamente usar HTTP POST para colocar as imagens no servidor - o Github, por exemplo, fala com seus servidores de arquivos usando o Git-over-SSH, que funciona bem para eles. A chave, no entanto, é colocar mais cuidado em onde o trabalho deve ser feito e evitar o uso desnecessário de recursos escassos (rede IO para uma solicitação do servidor NFS), trocando por um conjunto mais restrito de opções de uso ("Você só pode solicitar arquivos inteiros atomicamente! ") que funcionam para o seu aplicativo.
Finalmente, você terá que considerar o fator de escalabilidade. Se você está usando um transporte inteligente, no entanto, é fácil - adicione a lógica (pequena quantidade) necessária para determinar com qual servidor de arquivos você precisa falar em cada lugar que fala com o servidor de arquivos, e você basicamente tem escalabilidade infinita . Na sua situação, você pode perceber que seu primeiro servidor de arquivos estará cheio em, digamos, 750.000 imagens. Portanto, sua regra é "Fale com o servidor de arquivos com hostname fs#{image_id / 750_000}
", que não é difícil de codificar em todos os lugares.
Eu costumava me divertir com essa parte do meu trabalho ...