¿Cuáles son las mejores prácticas para construir algo así como un servicio de noticias?

Me encantaría recibir comentarios, comentarios o enfoques alternativos sobre esta respuesta.

Editar
Para aquellos interesados, desde entonces escribí una buena cantidad de código y arrojé parte de él a la naturaleza en StackOverflow. Si desea leer más o proporcionarme comentarios (muy necesarios), sea mi invitado: http://stackoverflow.com/questio…

Fondo

Los usuarios en la mayoría de los sitios de redes sociales se pueden describir en términos de un gráfico social. Las relaciones entre usuarios están representadas por listas de adyacencia. Si Jack y Jill son amigos, se dice que son adyacentes. Esto se conoce como un “borde” en el gráfico.

Determinando Importancia

Es probable que desee clasificar los bordes por importancia en lugar de simplemente las actualizaciones más recientes, lo que significa que necesita calcular algún tipo de puntaje. EdgeRank de Facebook fue descrito por la fórmula ∑e = ue we de, en donde ise es la suma del rango del borde, ue es el puntaje de afinidad con el usuario que creó el borde, nosotros es el peso para el tipo de contenido, y de es un factor de descomposición del tiempo.

Calcular el puntaje de afinidad de un amigo se puede hacer de la siguiente manera: ∑i = li ni wi, en donde isi es la suma de las interacciones con ese amigo, li es el tiempo transcurrido desde su última interacción (esto debería ponderarse para que 1 día> 30 días), ni es el número de interacciones y wi es el peso de esas interacciones. Este método le permite clasificar a los amigos en una base de datos separada y luego tal vez solo muestre diez actualizaciones de los diez amigos más cercanos, lo que no es una mala idea, ya que pocos de nosotros es probable que tengamos más amigos cercanos que este.

Qué almacenar

Determinar qué datos almacenar depende de su front-end (incluidas las actividades en las que participan sus usuarios) y su back-end. Describiré información general que puede almacenar. La cursiva es información especial y opcional que puede desear o necesitar según su esquema.

Actividad (id, user_id, source_id, activity_type, edge_rank , parent_id , parent_type , data, time)

  • user_id: usuario que generó actividad
  • source_id: la actividad de registro está relacionada con
  • activity_type: tipo de actividad (álbum de fotos, comentario, etc.)
  • edge_rank: el rango para esta actividad en particular
  • parent_type: el tipo de actividad principal (interés particular, grupo, etc.)
  • parent_id: ID de clave principal para el tipo primario
  • datos – objeto serializado con metadatos

Suponiendo que está utilizando MySQL como su almacén de bases de datos, puede indexar (user_id, time) y luego realizar sus consultas básicas. Un ejemplo de fila de feed para una foto sería:

(id: 1, user_id: 1, source_id: some_source, activity_type: PHOTO, data: (photo_id: 1, photo_name: Casarse)).

En MySQL, sus tablas estarían fuertemente desnormalizadas ya que realizar uniones perjudicará el rendimiento.

Problemas potenciales

  • Visibilidad: debe mostrar actividades interesantes
  • Rendimiento: se debe minimizar el tiempo de clasificación
  • Publicación: multiplica los puntos de falla según su método de publicación

Métodos de publicación

Modelo “Push” o Fan-out-on-write

Este método implica desnormalizar los datos de actividad del usuario y enviar los metadatos a todos los amigos del usuario en el momento en que ocurre. Solo almacena una copia de los datos como en el esquema anterior, luego envía punteros a los amigos con los metadatos. El problema con este método es que si tienes un gran despliegue (un gran número de seguidores), corres el riesgo de que se rompa mientras tu feed acumula una acumulación. Si sigue esta estrategia, también corre el riesgo de una gran cantidad de búsquedas de disco y escrituras aleatorias. Querrá algún tipo de almacén de datos optimizado para escritura, como Cassandra, HBase o BigTable.

Modelo “Pull” o Fan-out-on-load

Este método implica mantener todos los datos de actividad recientes en la memoria y extraer (o desplegar) esos datos en el momento en que un usuario carga su página de inicio. No es necesario que los datos se envíen a todos los suscriptores tan pronto como sucedan, por lo que no es necesario realizar un registro de respaldo ni buscar discos. El problema con este método es que es posible que no pueda generar las noticias de un usuario por completo. Para mitigar este riesgo, debe tener un mecanismo alternativo que se aproxime al feed del usuario o sirva como una buena alternativa.

Algunas sugerencias

  • Si está utilizando MySQL, querrá asegurarse de que su tabla de actividades sea lo más compacta posible, que sus claves sean pequeñas y que esté indexada adecuadamente.
  • Es posible que desee utilizar Redis para acceder rápidamente a datos de flujo de actividad nuevos. Redis está optimizado para lectura y almacena todos los datos en la memoria. Este es un buen enfoque para el modelo “Push” descrito anteriormente.

Conclusiones
Si bien esta no es una respuesta exhaustiva, estoy tratando de resumir tanta información como pueda. Mis fuentes para esta respuesta se recopilan en los enlaces a continuación, por lo que cualquier información en esta respuesta lamentablemente no tiene atribución directa. Sin embargo, un agradecimiento especial para Ari Steinberg por su respuesta muy detallada a ¿Cuáles son los problemas de escala a tener en cuenta al desarrollar un feed de redes sociales?

Como dije al principio, me encantaría recibir comentarios, comentarios o enfoques alternativos sobre esta respuesta.

Fuentes

  • http://stackoverflow.com/questio…
  • http://stackoverflow.com/questio…
  • ¿Cuáles son los problemas de escala a tener en cuenta al desarrollar un feed de red social?
  • http://stackoverflow.com/questio…
  • http://stackoverflow.com/questio…
  • http://stackoverflow.com/questio…
  • http://stackoverflow.com/questio…
  • http://stackoverflow.com/questio…
  • http://stackoverflow.com/questio…
  • http://stackoverflow.com/questio…
  • http://stackoverflow.com/questio…
  • http://stackoverflow.com/questio…

Aprecio lo lejos que ha llegado la web en los últimos años que toda la discusión sobre este tema considera solo soluciones en tiempo real. La versión original de News Feed en Facebook, que estuvo activa durante más de dos años antes de ser reemplazada, en realidad no era en tiempo real. Recorrimos a todos los usuarios cada 15 o 30 minutos y escribimos las nuevas historias a MySQL en grandes actualizaciones. Publicaríamos historias a intervalos de 5 minutos en el futuro para dar la apariencia de un flujo constante de información.

Si su aplicación necesita ser en tiempo real, entonces creo que las soluciones discutidas aquí y en la pregunta que Adam hace referencia resumen mis pensamientos. Dicho esto, todavía pienso que para muchas aplicaciones excelentes de la idea de un News Feed (y, en particular, una con un fuerte enfoque en la relevancia en lugar de la actualidad como Josh parece describir) un modelo fuera de línea funciona muy bien. También se necesita mucho menos dinero y esfuerzo para construir y operar.

Mi sesgo en esto es bastante claro dado el sistema que construí. Creo que para Quora y los usuarios avanzados en Facebook en tiempo real es súper importante, pero sospecho que ese no es el caso para la larga cola de usuarios a la que la mayoría de las aplicaciones esperan atraer. Si inicio sesión una vez al día y quiero ver las mejores historias, creo que sería mejor que la mayoría de los desarrolladores pasaran el tiempo trabajando en la relevancia que en la entrega.

Diseñar un servicio de noticias desde cero puede sonar intimidante, especialmente si desea que el sistema sea escalable. No hay duda de que hay muchos factores que debe tener en cuenta al construir dicho sistema si desea hacerlo eficiente incluso después de escalarlo a cierto nivel. Me gustaría cubrir algunas ideas básicas básicas aquí.

Estos dos artículos tienen un gran resumen de todos estos:

  • Sistema de diseño de noticias (Parte 1)
  • Sistema de diseño de noticias (Parte 2)

Resumiré brevemente algunos conceptos básicos aquí.

Modelo
Para empezar, podemos hablar sobre cómo modelar el sistema. Para simplificar, podemos tener dos objetos en la base de datos primero: objeto de usuario y objeto de alimentación. Para el objeto de usuario, podemos almacenar ID de usuario, nombre, fecha de registro, etc. Y para el objeto de alimentación, hay feedId, feedType, contenido, metadatos, etc., que también deben admitir imágenes y videos. Si estamos utilizando una base de datos relacional, también necesitamos modelar dos relaciones: relación de usuario-feed y relación de amigo. Todos estos son muy sencillos.

Para la relación de amigos, la lista de adyacencia es uno de los enfoques más comunes. Si vemos a todos los usuarios como nodos en un gráfico gigante, los bordes que conectan los nodos denotan una relación de amistad. Podemos usar una tabla de amigos que contiene dos ID de usuario en cada entrada para modelar el borde (relación de amigos).

Clasificación
La forma más sencilla de clasificar los feeds es cuando se creó. Obviamente, podemos hacer más que eso. Una estrategia común es calcular una puntuación de feed basada en varias características y feeds de clasificación por su puntuación, que es uno de los enfoques más comunes para todos los problemas de clasificación. Más específicamente, podemos seleccionar varias características que son relevantes para la importancia del feed, por ejemplo, compartir / me gusta / números de comentarios, hora de la actualización, si el feed tiene imágenes / videos, etc. Y luego, se puede calcular una puntuación por estas características, tal vez una combinación lineal. Esto suele ser suficiente para un ingenuo sistema de clasificación.

Publicación de feeds
Cuando un usuario carga todos los feeds de sus amigos, puede ser una acción extremadamente costosa. Básicamente, hay dos enfoques comunes aquí: empujar y tirar. Para un sistema push, una vez que un usuario ha publicado un feed, inmediatamente enviamos este feed (en realidad, el puntero al feed) a todos sus amigos. La ventaja es que al buscar el feed, no necesita revisar su lista de amigos y obtener feeds para cada uno de ellos. Reduce significativamente la operación de lectura. Sin embargo, la desventaja también es obvia. Aumenta la operación de escritura especialmente para personas con una gran cantidad de amigos.

Para un sistema de extracción, los feeds solo se obtienen cuando los usuarios están cargando sus páginas de inicio. Por lo tanto, no es necesario enviar los datos del feed inmediatamente después de su creación. Puede ver que este enfoque se optimiza para la operación de escritura, pero puede ser bastante lento para obtener datos incluso después de usar la desnormalización.

More Interesting

¿Qué es mejor: zipfian o información para el campo de entrenamiento de ciencia de datos?

¿Cuáles son las mejores universidades de minería en Estados Unidos?

Cómo comenzar mi carrera en ciencia de datos como estudiante de primer año en India

Estoy interesado en una carrera en Big Data. Cómo y por dónde empiezo.

¿Qué escuela es mejor para la ciencia de datos? Master of Computer Science - Data Science en UIUC o Master of Information - Data Science en UC Berkeley

¿Cómo podrían relacionarse dos conjuntos de datos y datos completamente diferentes para generar datos completamente nuevos y un conjunto de datos, y cómo el lenguaje de programación, las herramientas de modelado de datos y Excel me ayudan a realizar dicho análisis de datos?

¿Cuáles son las categorías de big data?

¿Qué se entiende por indexar datos en términos de Elasticsearch?

¿Cómo es útil aprender Big Data a Hadoop?

¿Cuál es el instituto superior para enseñar ciencia de datos con R?

¿Cómo podemos estar seguros de que podemos confiar en los científicos? ¿Cómo sabemos realmente que los científicos no son los clérigos modernos? Parece que la ciencia toma tanto la fe como la religión.

¿Cómo debo diseñar mi curso en visión artificial / aprendizaje automático / robótica para mi maestría en EE?

¿Qué compañías en la India ofrecen trabajos de nivel básico para científicos de datos?

¿Cuál tiene el mejor alcance, Big Data o AWS?

¿Quién gana más? Analista de datos o analista de negocios?