time synchronization distributed

time - Sincronización distribuida de tiempo y aplicaciones web



synchronization distributed (5)

La sincronización de tiempo es muy difícil de corregir y, en mi opinión, la forma incorrecta de hacerlo. Necesita un sistema de eventos que pueda notificar a los observadores registrados cada vez que se envíe un evento ( patrón de observador ). Todos los observadores serán notificados simultáneamente (o lo más cerca posible de eso), eliminando la necesidad de sincronización de tiempo.

Para adaptarse a la latencia, al navegador se le debe enviar la marca de tiempo del envío del evento, y debe esperar un poco más de lo que espera que sea la máxima latencia. De esta forma, todos los eventos se activarán al mismo tiempo en todos los navegadores.

Actualmente estoy tratando de crear una aplicación que inherentemente necesita una buena sincronización en todo el servidor y cada cliente. Hay diseños alternativos para mi aplicación que pueden eliminar esta necesidad de sincronización, pero mi aplicación comienza a chupar rápidamente cuando no está presente.

En caso de que me esté perdiendo algo, mi problema básico es este: disparar un evento en múltiples ubicaciones exactamente en el mismo momento. Lo mejor que puedo decir es que la única manera de hacer esto requiere algún tipo de sincronización de tiempo, pero puedo estar equivocado. He intentado modelar el problema de forma diferente, pero todo se resume en a) una aplicación sucky, ob) que requiere sincronización de tiempo.

Supongamos que realmente realmente necesito tiempo sincronizado.

Mi aplicación está basada en Google App Engine. Si bien AppEngine no ofrece garantías sobre el estado de la sincronización de tiempo en sus servidores, generalmente es bastante bueno, en el orden de algunos segundos (es decir, mejor que NTP), sin embargo, algunas veces es malo, digamos, del orden de 10 segundos de sincronización. Mi aplicación puede manejar 2-3 segundos fuera de sincronización, pero 10 segundos están fuera de cuestión con respecto a la experiencia del usuario. Así que, básicamente, mi plataforma de servidor elegida no brinda un concepto de tiempo muy confiable.

La parte del cliente de mi aplicación está escrita en JavaScript. De nuevo, tenemos una situación en la que el cliente tampoco tiene un concepto confiable de tiempo. No he realizado ninguna medición, pero espero que algunos de mis eventuales usuarios tengan relojes de computadora configurados en 1901, 1970, 2024, etc. Entonces, básicamente, mi plataforma de cliente no proporciona un concepto confiable de tiempo.

Este problema comienza a volverme un poco loco. Hasta ahora, lo mejor que puedo hacer es implementar algo como NTP en la parte superior de HTTP (esto no es tan loco como puede parecer). Esto funcionaría al encargar 2 o 3 servidores en diferentes partes de Internet y utilizando los medios tradicionales (PTP, NTP) para tratar de garantizar que su sincronización sea al menos del orden de cientos de milisegundos.

Luego crearía una clase de JavaScript que implementara el algoritmo de intersección NTP usando estas fuentes de tiempo HTTP (y la información de ida y vuelta asociada que está disponible desde XMLHTTPRequest).

Como puede ver, esta solución también apesta a lo grande. No solo es terriblemente complejo, sino que solo resuelve la mitad del problema, es decir, brinda a los clientes una buena idea de la hora actual. Luego tengo que comprometerme en el servidor, ya sea permitiendo que los clientes le digan al servidor la hora actual según ellos cuando hacen una solicitud (gran seguridad, no, no, pero puedo mitigar algunos de los abusos más obvios de esto), o hacer que el servidor haga una sola solicitud a uno de mis mágicos servidores HTTP sobre NTP, y esperando que la solicitud se complete lo suficientemente rápido.

Todas estas soluciones apestan, y estoy perdido.

Recordatorio: quiero que un grupo de navegadores web, con suerte hasta 100 o más, puedan lanzar un evento al mismo tiempo.


Me parece que necesitas escuchar un evento de transmisión desde un servidor en muchos lugares diferentes. Dado que puede aceptar una variación de 2-3 segundos, puede poner a todos sus clientes en solicitudes de cometas de larga vida y obtener la respuesta del servidor. Me parece que los clientes no tendrían que lidiar con el tiempo de esta manera?

Podría usar ajax para hacer esto, así evitaría cualquier bloqueo en el lado del cliente mientras espera nuevos datos.

Me puede estar perdiendo algo totalmente aquí.


Permítanme resumir, para asegurarme de que entiendo la pregunta.

Usted tiene una aplicación que tiene un componente de cliente y servidor. Hay varios servidores que pueden atender a muchos (cientos) de clientes. Los servidores están más o menos sincronizados entre sí; los clientes no son Desea que un gran número de clientes ejecute el mismo evento aproximadamente al mismo tiempo, independientemente de qué servidor sea el que inicialmente se conectó.

Suponiendo que describí la situación con mayor o menor precisión:

¿Podría hacer que los servidores mantengan cierto estado para cada cliente (como la hora inicial de conexión, la hora del servidor) y cuando se conozca la hora del evento que se debe realizar, notifique al cliente un mensaje que contenga la cantidad de milisegundos? después del valor inicial que debe transcurrir antes de disparar el evento?

Para ilustrar:

client A connects to server S at time t0 = 0 client B connects to server S at time t1 = 120 server S decides an event needs to happen at time t3 = 500 server S sends a message to A: S->A : {eventName, 500} server S sends a message to B: S->B : {eventName, 380}

Esto no depende en absoluto del tiempo del cliente; solo en la capacidad del cliente para realizar un seguimiento del tiempo durante un período razonablemente corto (una sola sesión).


Si puede suponer que los relojes son razonablemente estables, es decir, están mal configurados, pero funcionan a una velocidad más o menor.

Haga que los servidores obtengan su compensación de una única fuente definida (por ejemplo, uno de sus servidores, o un servidor de base de datos o algo así).

Luego haga que cada cliente calcule su compensación desde su servidor (posibles complicaciones de ida y vuelta si quiere mucha precisión).

Almacene eso, luego el offset combinado en cada cliente para activar el evento en el momento correcto.

(client-time-to-trigger-event) = (scheduled-time) + (client-to-server-difference) + (server-to-reference-difference)


Google encontró la manera de definir el tiempo como absoluto. Suena herético para un físico y con respecto a la Relatividad General: el tiempo fluye a un ritmo diferente dependiendo de su posición en el espacio y el tiempo, en la Tierra, en el Universo ...

Es posible que desee echarle un vistazo a la base de datos de Google Spanner: http://en.wikipedia.org/wiki/Spanner_(database)

Supongo que ahora lo usa Google y estará disponible a través de Google Cloud Platform.