¿Por qué la escalabilidad es un problema para el inicio tecnológico cuando existen servicios como Amazon Web Services o Google App Engine?

Mientras no tenga muchos usuarios (donde muchos se definen como la cantidad de usuarios que requerirían que obtenga de 50 a 100 visitas por segundo en un solo servidor), la escalabilidad no es un problema. Sin embargo, cuando cruza ese umbral, debe comenzar a pensar cómo funcionará su aplicación en presencia de múltiples servidores conectados a través de redes. La gran mayoría de los sitios en la web nunca se topa con este problema porque no tienen tantos usuarios; sin embargo, aquellos que siempre tienen que rediseñar sus aplicaciones para la escalabilidad.

El problema más común que se enfrenta en este rediseño es que debe decidir cómo fluyen los datos a través de su sistema para que todos no accedan al mismo almacén de datos (de lo contrario, puede escalar solo a la capacidad de respuesta de su almacén de datos). En el caso de AWS o GAE, el almacenamiento es relativamente escalable, pero es posible que no cumpla con otros criterios (por ejemplo, puede que no sea lo suficientemente rápido, puede que no brinde garantías estrictas sobre la coherencia, puede requerir que exista un estado global)

El teorema de Brewer [1] establece que solo puede obtener 2 de las 3 propiedades deseables en un sistema distribuido:

  1. Consistencia
  2. Disponibilidad
  3. Tolerancia de partición

Este es el desafío fundamental de la escalabilidad. En presencia de una red distribuida de servidores, ¿qué intercambia? Idealmente, querrías los 3 pero, dado que eso no es posible en la práctica, las personas intercambian la consistencia de los otros 2 y lo manejan usando modelos de “consistencia eventual”. [2]

Sin embargo, en el momento en que decide usar la coherencia eventual, ha introducido inmediatamente la complejidad del código porque no puede confiar en sus propios datos porque podría estar en el medio de una transacción que podría no completarse con éxito o parcialmente exitosa. Por lo tanto, debe poder deshacer cualquier conjunto de cambios de datos. Eso es realmente desagradable.

Desafortunadamente, las alternativas son mucho peores:

  1. Optar por cambiar la tolerancia de partición significa que la pérdida de unos pocos servidores o enlaces de red será suficiente para que toda su aplicación deje de funcionar, una perspectiva bastante desagradable (pero definitivamente podría ser lo correcto, por ejemplo, para un sistema de pagos).
  2. Optar por intercambiar la disponibilidad significa que su aplicación parecerá defectuosa para sus usuarios, así como para sus sistemas internos, ya que los sistemas pueden no responder a una solicitud de datos durante un período esencialmente indefinido.

Dado este contexto, ¿puede ver cuán desordenadas se vuelven las cosas una vez que ya no tiene un código que se encuentra en una sola caja y habla con un único almacén de datos consistente? Es por eso que hay tanto ruido en torno a la escalabilidad: se ha demostrado que es un problema difícil incluso en teoría y mucho más en la práctica, y los ingenieros inteligentes de estas empresas son los que están creando todo este ruido. No es un problema común del hombre. 🙂

Además, CAP es solo un concepto de alto nivel. Es posible que desee leer las cosas con mayor detalle. Sugeriría comenzar desde [3].

[1] http://en.wikipedia.org/wiki/CAP…
[2] http://en.wikipedia.org/wiki/Eve…
[3] http://dbmsmusings.blogspot.com/…

La escalabilidad es mucho más que simplemente usar un servicio escalable, es una mentalidad completamente diferente.

Al diseñar un sistema escalable, debe abstraer el sistema, tomar cada desafío como un proyecto separado y comprender cuál es el patrón de uso, la unidad de escala a la que apunta, qué interfaz de alta concurrencia usar (egyaws, node.js, etc.) qué infraestructura de datos, qué interfaces con otros sistemas internos, planificar el mecanismo de inserción, calentamiento, actualización y consulta, POC todo, organizar el monitoreo adecuado para que todo esté bajo control y repetir eso para cada desafío.

Como joven startup, rara vez tiene el tiempo, la inclinación o los recursos para dedicar tanto tiempo a cada subsistema. Por lo tanto, elige una solución simple que le servirá hasta que llegue el momento y tenga suficientes usuarios y dinero para justificar el esfuerzo.

El uso de servicios escalables de Amazon como DynamoDB, ElastiCache y AutoScale de EC2 puede ayudar mucho en el departamento rápido y sucio, pero no es suficiente si el servicio que los consulta o actualiza no es escalable. Sin una planificación y ejecución adecuadas, su sistema semiescalable alcanzará su eslabón débil en poco tiempo.

La buena noticia es que una vez que decide agregar una escalabilidad decente, es un proceso que se puede hacer gradualmente, tomando un desafío a la vez.

Yo diría que la escalabilidad no es una ocurrencia tardía. Si se apega a algunos principios fundamentales, puede probar su aplicación en el futuro, independientemente del conjunto de herramientas que utilice:

  • Tienes que distribuir. Los datos, el procesamiento, los mensajes, el front-end web: todos deben ser capaces de aprovechar múltiples núcleos y servidores y no tener ningún punto central de contención. Algunos servicios de Amazon lo harán por usted en secreto (por ejemplo, dynamoDB), otros no (por ejemplo, RDS). Según la ley de Amdahl (que incluso supone memoria infinita y ancho de banda de red), su límite de escalabilidad es 1/1-p, siendo p el paralelismo de grado I en su aplicación. Entonces, si, por ejemplo, la mitad de su carga de trabajo llega a un punto central de contención y tiene que procesarse en serie (por ejemplo, al leer el mismo bloque de disco de varios subprocesos), solo puede escalar dos veces, sin importar cuántos servidores / núcleos arroje a la cosa.
  • Datos sabios: en algún momento no tiene más opción que desnormalizar. Tiene que pensar las cosas desde una perspectiva de caso de uso en lugar de una perspectiva de modelado de datos. Esta presentación de la ingeniería de Twitter es un gran ejemplo de eso: cómo pasaron de un modelo de datos relacional centralizado a un modelo distribuido desnormalizado: http://www.slideshare.net/nkalle
  • Acerque el procesamiento a los datos: una vez que haya distribuido sus datos, tendría sentido procesarlos en los nodos en los que reside. es decir, envíe el código o impleméntelo junto con sus datos, y no los datos, que pueden ser mucho más pesados. Es algo así como los procedimientos almacenados en una base de datos, solo que las herramientas modernas le permiten invocar / enviar código sin problemas a través de un clúster.
  • Use RAM tanto como sea posible. Cuantas más cosas hagas en la memoria, menos contención y más paralelismo tendrás. La memoria es infinitamente más rápida que el disco, pero también es mucho más concurrente que el disco.