Piénsalo de esta manera:
Tienes un producto que habla con los clientes, para darles resultados.
Su base de datos y su código y su servidor están todos en el mismo cuadro, y la aplicación funciona con un solo subproceso, confiando en la memoria compartida para mejorar la velocidad.
Tu aplicación se vuelve popular.
Su base de usuarios se duplica.
Pero ahora estás golpeando un muro de rendimiento. Las conexiones que entran están empantanando la caja, debido a sus búsquedas de base de datos, y debido a sus algoritmos con los resultados finales en el otro lado.
Te conduces a la tierra, escribiendo a mano tus consultas SQL para tu versión particular de tu motor de base de datos particular.
Te rompes, confiando en más caché en memoria, bucles de desenrollado manual y más algoritmos hardcore.
A pesar de todo eso, su tiempo de ejecución es 100% más rápido de lo que era antes, un gran logro.
Entonces su producto y su velocidad de entrega se mencionan en Reddit.
¿Qué haces cuando tu base de usuarios aumenta por decenas de miles de personas?
¿Puedes mejorar tanto tus algoritmos?
Por supuesto que no, a menos que fueran terribles para empezar.
Entonces tratas de multiprocesarlo …
Todo el almacenamiento en caché en memoria y el acceso a recursos en memoria ahora está siendo pisoteado por hilos competidores.
Incluso después de solucionarlo (una tarea repugnante que es ridícula depurar de cualquier manera comprobable), su servidor está teniendo dificultades para generar suficientes hilos para servir a todos los consumidores.
Entonces imaginas que sacaste otra caja, con la misma configuración y eres dorado.
… pero recuerda que su producto es llamar y responder, y toda la comunicación que un usuario tiene debe estar con la misma caja, para siempre, porque la base de datos (y sus datos) son parte de esa máquina.
Pones una fachada y escribes un servicio para acceder a la base de datos a través de la red, reemplazando cada línea de acceso a la base de datos en toda tu aplicación con este servicio en red (y ahora pagando 40 ms adicionales por consulta) para que los usuarios ya no estén bloqueados en un cuadro por sus datos.
Sin embargo, los usuarios todavía están bloqueados en un cuadro para su sesión. El equilibrio de carga sigue siendo totalmente impredecible, porque los servidores deben ser equilibrados por usuario, no por solicitud, y la carga generada por usuario es mucho menos predecible que la carga generada por solicitud.
Mientras tanto, en otro universo, alguien escribe un producto similar de arriba hacia abajo.
Lo construyen utilizando mucha más memoria inicial, pero sus procesos son puros (las variables se definen pero nunca cambian, etc.).
Su aplicación es segura para subprocesos.
Tienen un servicio frente a su capa de base de datos para comenzar.
Todos sus algoritmos son bastante modestos, pero ninguno de los clientes sabe realmente la diferencia entre algo que tarda 0.4 segundos en regresar y 0.6 segundos.
Su tráfico se duplica y no se dan cuenta, porque sus modestos algoritmos ahora se ejecutan en paralelo para diferentes usuarios en diferentes subprocesos.
Los usuarios tampoco notan el aumento de carga.
Reciben una mención de Digg, y su base de usuarios se dispara.
Por lo tanto, mueven el DB a la nube, configuran un clúster en la nube y el equilibrador realiza las solicitudes.
En el futuro, pueden paralelizar aún más sus algoritmos, ya que son simples y puros, o pueden hacer llamadas de red a una granja de servidores altamente paralelos, para dicho cálculo de números.
Es importante porque mejorar un tiempo de ejecución ayuda a una persona.
Eso no ayuda mucho cuando tienes un millón de personas.
No hasta que ese sea el nivel más alto de optimización que le queda, de todos modos.
Si está escribiendo controladores de mouse, no dude en ignorar este ejemplo.