tag - ¿Por qué la API de TrueTime de Google es difícil de duplicar?
gtm container (1)
No estoy seguro de por qué la prensa en general dice que la API TrueTime de Google es difícil de replicar (con cable, Slashdot, etc.).
Puedo entender cómo sería difícil obtener los intervalos de error bajos que Google está logrando, pero no veo cómo la API en sí misma sería muy difícil.
Por ejemplo, preparé una versión pirateada. Aquí está el intervalo.
typedef struct TT_interval {
struct timeval earliest;
struct timeval latest;
} TT_interval;
Aquí está la función ahora.
int TT_now(TT_interval* interval)
{
struct ntptimeval tv;
struct timeval delta;
struct timeval* earliest_p = &(interval->earliest);
struct timeval* latest_p = &(interval->latest);
struct timeval* now_p = &(tv.time);
struct timeval* delta_p = δ
timerclear(&delta);
timerclear(&interval->earliest);
timerclear(&interval->latest);
if(ntp_gettime(&tv) == 0) {
tv.maxerror = tv.maxerror > 0 ? tv.maxerror : -(tv.maxerror);
delta.tv_sec = delta.tv_sec + (tv.maxerror / 1000);
delta.tv_usec = delta.tv_usec + ((tv.maxerror % 1000) * 1000);
if(delta.tv_usec > 1000000) {
delta.tv_usec -= 1000000;
delta.tv_sec++;
}
timeradd(now_p, delta_p, latest_p);
timersub(now_p, delta_p, earliest_p);
} else {
printf("error on ntp_gettime. %s/n", strerror(errno));
return ERROR;
}
return SUCCESS;
}
Finalmente, aquí están las funciones antes y después (que son envoltorios alrededor de la función now y podrían usar un poco de refactorización DRY).
int TT_before(TT_interval* interval, bool* success)
{
struct timeval* latest_p;
struct timeval* earliest_p;
TT_interval now;
if(TT_now(&now) != SUCCESS) {
return ERROR;
}
latest_p = &(interval->latest);
earliest_p = &(now.earliest);
if(timercmp(latest_p, earliest_p, <) != 0) {
*success = true;
return SUCCESS;
} else {
*success = false;
return SUCCESS;
}
return ERROR;
}
int TT_after(TT_interval* interval, bool* success)
{
struct timeval* latest_p;
struct timeval* earliest_p;
TT_interval now;
if(TT_now(&now) != SUCCESS) {
return ERROR;
}
earliest_p = &(interval->latest);
latest_p = &(now.earliest);
if(timercmp(latest_p, earliest_p, <) != 0) {
*success = true;
return SUCCESS;
} else {
*success = false;
return SUCCESS;
}
return ERROR;
}
Parece que estoy recibiendo errores de intervalo de alrededor de 5,000 a 350,000 (usando un NTPd público). Esto está muy lejos de los números de Google, pero necesitas comenzar en algún lado.
Además de un rendimiento mediocre, ¿hay algún defecto importante en este diseño que impida que algo como Spanner se construya en la parte superior?
El desafío al implementar una API TrueTime reside en las garantías que debe brindar. A saber, el tiempo absoluto nunca debe estar fuera del intervalo TrueTime en ningún servidor del sistema. Si esto puede suceder, se pierde el orden absoluto de los eventos, como lo son la mayoría de las garantías de Spanner.
El papel Spanner logra esto por una combinación de medios (sección 3):
- Múltiples servidores de tiempo, con fuentes dispares (GPS, relojes atómicos), incluidos los servidores de tiempo de otros centros de datos.
- El algoritmo de Marzullo para detectar mentirosos y multiplexar las diversas fuentes de tiempo de confianza en una actualización del reloj de la máquina local.
- Una deriva de reloj supuesta de 200us / s en servidores espaciales, aplicada entre sincronizaciones de reloj.
- Patear las máquinas del sistema que exhiben el umbral de desplazamiento del reloj local medido (umbral << 200us / s por necesidad).
Ahora, puede lograr esto con medios más simples: NTP y un intervalo de error supuesto de 10 minutos lo haría trivialmente. Pero como se señala en la pregunta, hay implicaciones de rendimiento para esto. Las transacciones de lectura y escritura (4.2.1) deben esperar en la confirmación, con un tiempo de espera esperado de 2 * errorAverage - 20 minutos en este ejemplo. De forma similar, las transacciones de solo lectura (4.2.2) en el momento "ahora" (en lugar de un momento anterior) deben esperar a que el tiempo de seguridad avance lo suficiente; al menos 10 minutos en este ejemplo. Por lo tanto, para tener un sistema de alto rendimiento, debe minimizar los intervalos de error en la medida de lo posible, sin perder sus garantías, que es donde surge la complejidad.
No estoy seguro de cómo se llama a ntp_adjtime en su sistema; es posible que ya se esté configurando con varias fuentes de tiempo no confiables y no confiables, en cuyo caso ya está casi todo el camino. Si también puedes asegurarte de que se garantiza que el valor de maxerror avance más rápido que la posible deriva del reloj de tu sistema, deberías estar listo. La mayor parte del rendimiento de Spanner, sin su propio reloj atómico personal :).