Sistema de notificación de redes sociales

10

Antecedentes

Estoy trabajando en una aplicación para un cliente que incluye algunas funciones de redes sociales. Originalmente estaba desarrollando el front-end móvil, pero las circunstancias me han dejado a cargo del desarrollo del back-end también.

Como antecedentes generales, nuestro sistema permite a los usuarios seguir a otros usuarios y recibir notificaciones sobre los que están siguiendo, como es de esperar de una red social. Una advertencia es que solo se podrá seguir a un pequeño subconjunto (a lo sumo unos pocos cientos) de usuarios, con la expectativa de que la mayoría de la base de usuarios seguirá al menos a uno de estos individuos.

En el lado de la interfaz de usuario, tendremos un botón de notificación con un número y al hacer clic en el botón lo llevará a la pantalla de notificación.

El problema

He estado investigando estrategias para implementar notificaciones y la mayoría de los recursos que he encontrado apuntan a crear una o más tablas de notificaciones en la base de datos. (Un ejemplo que me gusta es la respuesta aceptada aquí: /programming/9735578/building-a-notification-system ).

Lo que me desconcierta es que la mayoría de las estrategias basadas en bases de datos para notificaciones requieren insertar una fila para cada notificación para cada seguidor. Entonces, si mil personas siguen a Sally, insertamos mil filas en la tabla correspondiente. ¿Es eso escalable? ¿Qué sucede si llegamos al punto en el que decenas o cientos de miles de usuarios siguen a Sally y ella hace unas pocas docenas de publicaciones por día?

Mi idea original había sido manejar todo con consultas: el número en el botón de notificación se obtendría solicitando recuentos de filas en el contenido publicado más recientemente que la última vez que visitó la pantalla de notificación, mientras que se generarían notificaciones individuales a partir de consultas más detalladas cuando visitaste la pantalla de notificaciones. Este enfoque no requeriría escrituras o almacenamiento adicional, pero es inflexible y probablemente perjudicaría bastante al servidor.

PREPARAR

El backend (según lo establecido por el desarrollador anterior) usa CodeIgniter y una base de datos MySQL . Actualmente se está ejecutando en una cuenta de alojamiento compartido GoDaddy, pero supongo (¿espero?) Que se actualizará antes de que entremos en producción y el paquete de alojamiento se ampliará con el crecimiento del usuario.

Actualmente, nuestro único front-end es una aplicación móvil, pero también planeamos construir un sitio web más adelante. En este momento no me preocupa obtener actualizaciones automáticas en tiempo real del servidor sobre las notificaciones.

APÉNDICE

No me especializo en backends y estoy en mi cabeza en ese departamento. El cliente lo sabe, y he hecho todo lo posible para tratar de explicar el alcance de un proyecto de esta naturaleza, pero han dejado en claro que en este punto no confiarán en nadie más para trabajar en el proyecto. Probablemente tengamos otro mes de trabajo por hacer antes de que podamos comenzar a agregar probadores y pueda obtener cualquier tipo de métrica de rendimiento. Realmente no puedo estimar cuántos usuarios podríamos tener o qué hardware podríamos tener en los próximos 5 años, pero creo que el cliente espera cientos de miles de usuarios o más.

Espero que este problema sea lo suficientemente específico como para publicarlo aquí; Puedo refinarlo si es necesario. Pregunte si tiene alguna pregunta o si he omitido detalles importantes.

tl; dr

  • ¿Un sistema de notificación basado en bases de datos tiene implicaciones negativas para la escalabilidad a largo plazo cuando todos los usuarios solo siguen a algunos de los mismos cientos de personas?
  • ¿Hay alguna manera de hacer que las notificaciones estén basadas en la base de datos sin necesidad de una fila de notificaciones separada para cada notificación para cada seguidor?
  • ¿Sería escalable un sistema de notificación totalmente orientado a consultas o tendría alguna ventaja además de no escribir ningún dato en la base de datos?
  • ¿Estoy pensando demasiado en esto demasiado temprano? ¿Debo construir algo que funcione por ahora y podemos preocuparnos por optimizarlo si se convierte en un problema, dado que el cliente tiene un presupuesto limitado y aún no sabemos si el producto final será popular?
usuario45623
fuente
¿Pueden caducar las notificaciones? Por ejemplo, elimine cualquier cosa que tenga más de 2 semanas. Eso debería equilibrar más o menos el tamaño de la tabla utilizada a medida que el sitio madura.
GrandmasterB
Eso no será un problema, estaba más preocupado por las implicaciones de rendimiento de bloquear la base de datos escribiendo 50,000 entradas en la tabla de notificaciones cada vez que un usuario popular hace una publicación.
user45623
Trabajé en un proyecto con un sistema de notificación similar (pero más pequeño). Tuve un proceso en segundo plano que miraba una cola de nuevas publicaciones y manejaba las notificaciones (que en este caso en realidad estaba insertando un correo electrónico en una segunda cola para enviar). No fue en tiempo real, pero generalmente manejó todo en un par de minutos.
GrandmasterB

Respuestas:

10

Entonces, si mil personas siguen a Sally, insertamos mil filas en la tabla correspondiente. ¿Es eso escalable?

Sí, siempre que las tablas de la base de datos estén indexadas correctamente.

¿Qué sucede si llegamos al punto en el que decenas o cientos de miles de usuarios siguen a Sally y ella hace unas pocas docenas de publicaciones por día?

Generará unas pocas docenas de decenas o cientos de miles de registros de notificaciones por día para Sally, suponiendo que desea realizar un seguimiento de cada notificación a perpetuidad. El porcentaje de usuarios como Sally con ese tipo de tráfico siempre es muy pequeño.

Mi idea original había sido manejar todo con consultas: el número en el botón de notificación se obtendría solicitando recuentos de filas en el contenido publicado más recientemente que la última vez que visitó la pantalla de notificación, mientras que se generarían notificaciones individuales a partir de consultas más detalladas cuando visitaste la pantalla de notificaciones.

Esto parece innecesariamente complicado. Si necesita estadísticas detalladas sobre las notificaciones, simplemente almacene las notificaciones.

¿Un sistema de notificación basado en bases de datos tiene implicaciones negativas para la escalabilidad a largo plazo cuando todos los usuarios solo siguen a algunos de los mismos cientos de personas?

Por eso funciona ... un pequeño número de personas siempre genera la gran mayoría del tráfico.

¿Hay alguna manera de hacer que las notificaciones estén basadas en la base de datos sin necesidad de una fila de notificaciones separada para cada notificación para cada seguidor?

Sí ... no almacene las notificaciones; simplemente envíe los correos electrónicos de notificación, en el estilo de disparar y olvidar. O bien, almacene las notificaciones durante un cierto período de tiempo y luego deséchelas. O bien, descarte cada notificación después de que se haya leído.

¿Sería escalable un sistema de notificación totalmente orientado a consultas o tendría alguna ventaja además de no escribir ningún dato en la base de datos?

No estoy seguro de lo que quieres decir con esto. Si desea consultar notificaciones, debe almacenarlas en la base de datos. De lo contrario, no hay nada que consultar.

¿Estoy pensando demasiado en esto demasiado temprano?

Hable con alguien que pueda ayudarlo a diseñar una base de datos indexada correctamente normalizada con las tablas correctas. No veo ninguna razón por la cual dicha base de datos no pueda manejar de manera efectiva los escenarios que usted describe.

Un ejemplo de la vida real.

Hasta donde yo sé, Stack Exchange almacena todo a perpetuidad, incluidas todas las notificaciones. Utilizan tecnología de base de datos similar a MySql y algunas tecnologías de almacenamiento en caché. Si bien su hardware y espacio de almacenamiento es considerable, la cantidad de tráfico que reciben es un buen problema.

Robert Harvey
fuente
¡Vaya, te has dirigido a todo! Gracias Robert! La base de datos está normalizada pero aún no he mirado la indexación. Desafortunadamente, no puedo "hablar con alguien que pueda ayudarme", ya que los términos son estrictos y no puedo discutir detalles específicos del proyecto con nadie, y el cliente ha llegado al punto de no confiar en nadie pero yo en el proyecto ... Bueno, debería poder investigar un poco sobre indexación. ¡Gracias!
user45623
1
Reglas generales para la indexación: cada clave externa debe indexarse ​​con posibles duplicados. Cada clave principal ya debe estar indexada. Deben indexarse ​​los campos en los que deberá buscar o aplicar una cláusula WHERE; esos deberían ser pocos.
Robert Harvey
1
Esto es incorrecto. Esto NO es escalable. Por cada "Sally" estás generando N filas donde N es tu número de usuarios. Esto se convertirá en un problema rápido si tiene un número razonable de usuarios. 100 publicaciones de "Sallys" 10 veces para 10,000 usuarios son 10 millones de filas al día, no suena demasiado bien, ¿eh? Lo que realmente quieres hacer es invertir esto y crear una fila por publicación "Sally" y hacer que todos los usuarios que siguen a Sally los tomen en lugar de su propia copia personal. Por supuesto, esto va a causar problemas si necesita una lógica específica del usuario (por ejemplo, agregación) ...
Ben
1
... la explicación de "evitar una fila por publicación" aquí es obviamente un hombre de paja ya que la mayoría de los sistemas requerirán que estas publicaciones permanezcan. Además, no evita las consultas "porque son complicadas", las evita porque causarán una sobrecarga insostenible a medida que el sistema escala.
Ben