¿Cuál es la mejor manera de diseñar un sitio web para que sea altamente escalable?


35

Para los sitios web que necesitan ser altamente escalables, como las redes sociales como Facebook, ¿cuál es la mejor manera de diseñar el sitio web?

  1. ¿Debería tener un servicio web que el sitio consulta para obtener los datos que necesita?

    o

  2. ¿Debería el sitio consultar bases de datos directamente? (se puede hacer usando construcciones de lenguaje incorporadas para llenar tablas automáticamente, etc.)

Creo que el servicio web es el mejor diseño, ya que proporciona acceso centralizado a datos y cosas como el almacenamiento en caché y similares se vuelven mucho más fáciles de controlar, pero ¿qué piensan los demás?


También está la cuestión de qué arquitectura usar (como MVC o similar).
Ivan

Sin saber más sobre qué es exactamente lo que va a lanzar, es muy difícil dar la respuesta, pero tenga en cuenta los "servicios en la nube", probablemente su aplicación se ajuste a una especie de aplicación SaaS. (Está centralizado).
deepcell

en general, diría que, nada en particular en mente ..
Daniel

1
Constrúyalo en 'la nube' y pase mucho tiempo leyendo HighScalability.com.
Evan Plaice

Respuestas:


37

Wow, esta es una pregunta simple, que tiene una gran variedad de posibles respuestas. La parte más explícita de su pregunta es si es más escalable interactuar con su base de datos directamente o mediante un servicio web. Esa respuesta es simple: consulta la base de datos directamente. Pasar por el servicio web agrega una gran cantidad de latencia que es completamente innecesaria para el código que opera detrás de un firewall (en general). Un servicio web, por ejemplo, requiere algún componente para recibir una solicitud, deserializarla, consultar la base de datos, serializar una respuesta y devolverla. Entonces, si su código está funcionando detrás de un firewall, ahórrese el problema y simplemente consulte la base de datos directamente.

Sin embargo, hacer que un sitio web sea escalable va mucho más allá de la pregunta que planteó inicialmente. Así que perdóname si salgo por una tangente aquí, pero pensé que podría ser útil teniendo en cuenta que mencionaste Facebook en particular.

Le recomendaría que lea sobre el trabajo y las herramientas creadas por Brad Fitzpatrick (fundador de LiveJournal y ahora en Google). Cuando trabajé con él en Six Apart, estas son algunas de las cosas que aprendí de él y sobre la arquitectura de LiveJournal que lo hizo tan escalable.

  1. Utilice tablas de bases de datos estrechas en lugar de anchas . Lo fascinante de esto fue aprender lo que motivó esta arquitectura, que era crear un sistema que fuera fácil y rápido.actualizado Si usa tablas anchas, o tablas para las cuales cada campo o propiedad es una columna en la tabla, cuando llega el momento de actualizar el esquema de la base de datos, por ejemplo, agregando una nueva columna, entonces el sistema necesitará bloquear la tabla mientras el esquema Se implementa el cambio. Cuando se opera a escala, esto significaría que un simple cambio en el esquema de la base de datos podría provocar una gran interrupción de la base de datos. Lo que obviamente apesta. Por otro lado, una tabla estrecha simplemente almacena cada propiedad individual asociada con un objeto como una sola fila en la base de datos. Por lo tanto, cuando desee agregar una nueva columna a la base de datos, todo lo que necesita hacer es INSERTAR los registros en una tabla, que es una operación sin bloqueo. Ok, eso es un poco de historia, veamos cómo este modelo se traduce realmente en un sistema de trabajo como LiveJournal.

    Supongamos que desea cargar las últimas 10 entradas de diario en el blog de una persona, y supongamos que cada entrada de diario tiene diez propiedades. En un diseño clásico de tabla ancha, cada propiedad se correlacionaría con una columna en una tabla. Un usuario luego consultaría la tabla una vez para obtener todos los datos que necesita. La consulta devolvería 10 filas y cada fila tendría todos los datos que necesitan (por ejemplo, SELECCIONAR * DESDE las entradas ORDENAR POR fecha LÍMITE 10). Sin embargo, en un diseño de tabla estrecho las cosas son un poco diferentes. En este ejemplo, en realidad hay dos tablas: la primera tabla (tabla A) almacena criterios simples que uno desearía buscar, por ejemplo, la identificación de la entrada, la identificación del autor, la fecha de la entrada, etc. Una segunda tabla (tabla B) luego almacena todas las propiedades asociadas con una entrada. Esta segunda tabla tiene tres columnas: entry_id, key y value. Por cada fila en la tabla A, habría 10 filas en la tabla B (una fila para cada propiedad). Por lo tanto, para obtener y mostrar las últimas diez entradas, necesitará 11 consultas. La primera consulta le proporciona la lista de ID de entrada, y luego las siguientes diez consultas obtendrían las propiedades asociadas con cada una de las entradas devueltas en la primera consulta.

    "¡Santo Moly!" dices, "¿cómo puede eso ser más escalable?" Es totalmente contrario a la intuición, ¿verdad? En el primer escenario, solo tuvimos una consulta a la base de datos, pero en la segunda solución "más escalable" tenemos 11 consultas a la base de datos. Eso no tiene sentido. La respuesta a esa pregunta se basa completamente en la siguiente viñeta.

  2. Use memcache generosamente. En caso de que no lo supiera, memcache es un sistema de almacenamiento en caché distribuido, sin estado, de baja latencia y basado en red. Lo utilizan Facebook, Google, Yahoo y casi todos los sitios web populares y escalables del planeta. Fue inventado por Brad Fitzpatrick parcialmente para ayudar a compensar la sobrecarga de la base de datos inherente a un diseño de base de datos de tabla estrecha. Echemos un vistazo al mismo ejemplo que se discutió en el punto 1 anterior, pero esta vez, presentemos memcache.

    Comencemos cuando un usuario visita por primera vez una página y no hay nada en la memoria caché. Comienza por consultar la tabla A que devuelve los ID de las 10 entradas que desea mostrar en la página. Para cada una de esas entradas, consulta la base de datos para recuperar las propiedades asociadas con esa entrada, y luego usar esas propiedades constituye un objeto con el que su código puede interactuar (por ejemplo, un objeto). Luego oculta ese objeto (o una forma serializada de ese objeto) en memcache.

    La segunda vez que alguien carga la misma página, comienza de la misma manera: al consultar en la tabla A la lista de ID de entradas que mostrará. Para cada entrada, primero vaya a memcache y diga: "¿tiene la entrada #X en el caché?" En caso afirmativo, memcache le devuelve el objeto de entrada. De lo contrario, debe volver a consultar la base de datos para obtener sus propiedades, constituir el objeto y guardarlo en Memcache. La mayoría de las veces, la segunda vez que alguien visita la misma página solo hay una consulta de base de datos, todos los demás datos se extraen directamente de memcache.

    En la práctica, lo que terminó sucediendo para la mayoría de LiveJournal es que la mayoría de los datos del sistema, especialmente los datos menos volátiles, se almacenaron en caché en Memcache y las consultas adicionales a la base de datos necesarias para admitir el esquema de tabla estrecha se compensaron por completo.

    Este diseño hizo que resolver el problema asociado con el ensamblaje de una lista de publicaciones asociadas con todos tus amigos en una transmisión, o "muro", fuera mucho , mucho más fácil.

  3. Luego, considere particionar su base de datos. El modelo discutido anteriormente presenta otro problema, y ​​es que sus tablas estrechas tenderán a ser muy grandes / largas. Y mientras más filas tengan esas tablas, más difíciles se volverán otras tareas administrativas. Para compensar esto, podría tener sentido administrar el tamaño de sus tablas mediante la partición de las tablas de alguna manera, de modo que los grupos de usuarios sean atendidos por una base de datos, y otro grupo de usuarios sea atendido por una base de datos separada. Esto distribuye la carga en la base de datos y mantiene las consultas eficientes.

  4. Finalmente, necesitas índices increíbles. La velocidad de sus consultas dependerá en gran medida de lo bien indexadas que estén las tablas de su base de datos. No pasaré demasiado tiempo discutiendo qué es un índice, excepto para decir que es muy parecido a un sistema de catálogo de tarjetas gigante para hacer que la búsqueda de agujas en un pajar sea más eficiente. Si usa mysql, le recomiendo activar el registro lento de consultas para monitorear las consultas que demoran mucho tiempo en completarse. Cuando aparezca una consulta en su radar (por ejemplo, porque es lenta), descubra qué índice necesita agregar a la tabla para acelerarla.

"Gracias por todos estos excelentes antecedentes, pero santo cielo, es mucho código que tendré que escribir".

No necesariamente. Se han escrito muchas bibliotecas que facilitan la interacción con memcache. Aún otras bibliotecas han codificado todo el proceso descrito anteriormente; Data :: ObjectDriver en Perl es solo una biblioteca de este tipo. En cuanto a otros idiomas, deberá hacer su propia investigación.

Espero que hayas encontrado útil esta respuesta. Lo que he encontrado la mayoría de las veces es que la escalabilidad de un sistema a menudo se reduce cada vez menos al código, y cada vez más a una estrategia de almacenamiento de datos y un diseño técnico.


3
+1 Realmente amo este Wow, esta es una pregunta simple, que tiene una gran variedad de posibles respuestas.
Pankaj Upadhyay

1
Estoy completamente en desacuerdo con 'consultar la base de datos directamente'. Usted menciona la partición de la base de datos para el rendimiento cuando sería más fácil implementar una arquitectura de maestro único y esclavo múltiple con una interfaz API. El beneficio de desacoplar la base de datos de la aplicación es que la capa API puede distribuir las solicitudes como desee. La API es una abstracción que le permite cambiar la implementación subyacente y / o reutilizar los datos sin interrumpir la aplicación.
Evan Plaice

1
(cont) La serialización siempre agregará gastos generales, pero solo en la capa API, que probablemente consistirá en múltiples instancias que se ejecutan simultáneamente. Si le preocupa la velocidad de transferencia a través del cable, conviértalo a JSON y, de todos modos, lo más probable es que se comprima con gzip. Las mejoras de rendimiento más fáciles se pueden encontrar cuando el trabajo se envía del servidor al cliente. La pregunta importante es, ¿preferiría distribuir las solicitudes dentro de la aplicación o en el nivel del servidor? ¿Cuál es más fácil de duplicar?
Evan Plaice

1
@EvanPlaice: excelentes puntos sobre la reutilización y el cambio de la implementación de la lógica de servicio cuando se utilizan servicios. Además, la infraestructura de caché también puede ser utilizada por los servicios en lugar de llamadas directas a la base de datos.
Ashish Gupta

1
@AshishGupta Exactamente, la única diferencia en particionar los datos en un servicio separado es lo que recibe el usuario. En su lugar, ensamblar el contenido html + en el servidor. El usuario recibe datos y html por separado y el navegador del cliente maneja el reensamblaje. Con los datos como un servicio separado, también es posible ponerlos a disposición para aplicaciones móviles u otros clientes no basados ​​en la web (por ejemplo, aplicaciones de televisión inteligente).
Evan Plaice

13

Para los sitios web que necesitan ser altamente escalables, como las redes sociales como Facebook, ¿cuál es la mejor manera de diseñar el sitio web?

Medida.

Yo pensaría que el ...

Mala política

Se requiere una medición real.


Métrica cuantitativa FTW.
bhagyas

1
Ok ... entonces, ¿qué hay después de la medición?
Pacerier

9

La escalabilidad no es función de estrategias de implementación específicas, sino de diseñar la arquitectura de su aplicación para que la capa de acceso a datos pueda evolucionar sin una refactorización y reescritura masiva.

Una técnica importante en la construcción de un sistema que se escala es comprender sus requisitos de acceso a datos de alto nivel y crear un contrato de interfaz en torno a ellos. Por ejemplo, es posible que tenga el requisito de obtener un usuario o enumerar las 50 fotos publicadas más recientemente por cualquier usuario .

No necesariamente necesita un canal de red entre la lógica empresarial de su aplicación y la lógica de acceso a datos; una llamada indirecta a un método con un método por operación lógica estaría bien para comenzar.

Para comenzar, haga que estos métodos de acceso a datos sean lo más simples posible. Es muy difícil predecir dónde se encontrarán los problemas de rendimiento hasta que su aplicación esté sirviendo patrones de uso reales y esté recopilando datos sobre dónde tiene cuellos de botella.

Al tener una interfaz de acceso a datos bien definida, puede evolucionar su implementación de acceso a datos sin realizar grandes cambios en toda su aplicación. También puede decidir cambiar a una arquitectura de servicio web de forma transparente a su lógica empresarial.

Muchas de las respuestas anteriores brindan excelentes consejos sobre cómo proceder una vez que haya descubierto sus cuellos de botella en el rendimiento, pero si los aplica demasiado pronto, puede verse afectado por la complejidad de su código antes de saber si esa complejidad es necesaria.


4

Desarrolle un sitio web simple y deje que alcance cierto nivel de tráfico. A lo largo de las líneas aprenderá cómo hacer sitios web escalables.

Hasta que no enfrentes el problema, no puedes pensar en una solución .

Confíe en mí una vez que tenga el sitio funcionando y enfrentando el requisito de escalado, definitivamente sabrá cómo hacerlo. :-)


Buena cita !!!!!!!!!!
AmirHossein

2

Se acepta que las aplicaciones web deben diseñarse con tres niveles de forma predeterminada: web (presentación), aplicación y capas de base de datos. Esta división se debe a diferentes requisitos en cada una de las capas: típicamente acceso / almacenamiento de disco de calidad para la base de datos, CPU / Memoria alta en la capa de la aplicación, y alto ancho de banda externo / memoria / dispersión geográfica en la capa web. La capa de aplicación / base de datos a menudo se fusionan en una sola hasta mucho más tarde en el ciclo de vida de la aplicación, ya que las máquinas de bases de datos a menudo tienden a ser servidores masivos que se pueden construir para manejar la carga temprana de la aplicación.

Sin embargo, el número específico de capas y la arquitectura adecuada para su aplicación no tienen que coincidir con este ni con ningún otro modelo.

Planee necesitar medir y monitorear toda la actividad en su sistema. Comience desde un diseño de dos o tres niveles, y concéntrese en las partes que, a medida que lo construye, requerirán la mayor cantidad de recursos. Deje que la aplicación en ejecución guíe su diseño, a este nivel. Cuanta más información recopile y más precisa y detallada sea, mejores decisiones podrá tomar sobre el diseño de la aplicación a medida que crece.

Elija un marco y una arquitectura que, más adelante, le permitirán pivotar / realizar los cambios necesarios de la manera más rápida e indolora posible. Incluso si su acceso a datos / almacenamiento / procesamiento y procesamiento de aplicaciones se realizan en el mismo ejecutable, si se factorizan correctamente, no será tan difícil dividirlos en dos capas más adelante, por ejemplo.


2

Cualquier paso adicional en la conexión a la base de datos es solo una sobrecarga. Por ejemplo, entre UI -> Business Facade -> Business -> Data Access -> Databasey UI -> Database, el segundo enfoque es más rápido. Sin embargo, cuantos más pasos elimines, menos mantenible será tu sistema y más duplicación aparecerá. Imagine escribir el código necesario para recuperar la lista de amigos en el perfil, la página de inicio, la página de administración de demonios, etc.

Por lo tanto, debe hacer un equilibrio aquí entre un mayor rendimiento (que, por supuesto, afecta directamente a una mayor escalabilidad) y una mejor capacidad de mantenimiento .

Pero, no se limite al tema de conexión de base de datos cuando piense en crear sitios web altamente escalables. Considere estos artículos también:

  1. Elegir la plataforma correcta (PHP es más rápido debido a su naturaleza de secuencias de comandos, pero ASP.NET necesita compilar el archivo solicitado sobre la marcha para procesarlo y servir algo. También se afirma que node.js es más escalable, debido a su devolución de llamada. arquitectura basada )
  2. Uso de la arquitectura RESTful en lugar del modelo de servicio web (SOA)
  3. Usar JSON para la transferencia de datos en lugar de XML (lo que da como resultado menos bytes para transferir)
  4. Seguir las pautas de rendimiento de Yahoo
  5. Temas de red y hardware como equilibrio de carga o arquitectura de niveles

2
No se puede decir que PHP es más rápido. Las aplicaciones ASP.NET escritas correctamente pueden superar a PHP en muchos casos. naspinski.net/post/AspNet-vs-php--speed-comparison.aspx
Andrew Lewis

+1 En realidad, su solución 'simple' será, UI -> Acceso a datos -> Base de datos. 2 REST es 'fácil' porque ya está integrado en la mayoría de los navegadores. No es necesario volver a crear la rueda de API de respuesta de comando. 3 JSON no solo es más pequeño, sino que requiere menos pasos para serializar-deserializar porque no es necesario verificar las entidades HTML. Buen material.
Evan Plaice

1

Hay dos formas principales de escalar, hacia arriba y hacia afuera.

Ampliar es reemplazar una máquina por una más poderosa. La reducción gradual significa agregar otra máquina para hacer el trabajo que están haciendo las máquinas existentes.

Cualquier sitio web de alto tráfico necesita la capacidad de escalar. La arquitectura del software debe hacerse de tal manera que se puedan agregar más máquinas fácilmente a medida que el sitio esté más ocupado.

Por lo general, esto significa dividir la aplicación en niveles para que uno pueda conectar y reproducir más servidores en cada nivel.

Haría la opción 1, tener un servicio en lugar de hacerlo directamente. Solo puede escalar una aplicación monolítica hasta ahora.


0

Desarrolle su sitio utilizando una plataforma tecnológica que tiene soporte completamente integrado para la nube.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.