2013-08-22 5 views
26

Я не уверен, почему пресса в целом говорит, что TrueTime API Google трудно реплицировать (Wired, Slashdot и т. Д.).Почему API TrueTime Google трудно дублировать?

Я могу понять, как было бы трудно получить низкие интервалы ошибок, которые достигнут Google, но я не вижу, как сам API будет очень сложным.

Например, я взломал взломанную вместе версию. Вот интервал.

typedef struct TT_interval { 
      struct timeval earliest; 
      struct timeval latest; 
    } TT_interval; 

Вот функция.

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; 
    } 

Наконец, вот до и после того, как функции (которые являются обертками вокруг теперь функции и может использовать немного 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; 
    } 

Я, кажется, получаю интервальные ошибки от 5 000 до 350 000 (используя публичный NTPd). Это далеко от цифр Google, но вам нужно где-то начинать.

Помимо отличной производительности, существует ли главный недостаток в этом дизайне, который предотвратил бы создание чего-то вроде Сппера на вершине?

ответ

35

Задача по внедрению API TrueTime заключается в гарантиях , которые вы должны предоставить. А именно, абсолютное время должно никогда не быть вне интервала TrueTime на любом сервере в системе. Если это может произойти, то теряется абсолютное упорядочение событий, как и большинство гарантий «Гаечного ключа».

Spanner paper достигает этого путем сочетания средств (раздел 3):

  1. несколько серверов времени, с разнородными источниками (GPS, атомные часы), в том числе серверов времени из других центров обработки данных.
  2. Алгоритм Marzullo для обнаружения лжецов и мультиплексирования различных источников надежного времени в обновление локальных машинных часов.
  3. Предполагаемый тактовый дрейф 200us/s в spanservers, применяемый между синхронизациями часов.
  4. Убирающие машины из системы, которые показывают измеренный локальный сдвиг часов> порог (порог < < 200us/s по необходимости).

Теперь вы можете добиться этого с более простыми средствами - NTP и предполагаемого интервала ошибки 10 минут будет тривиально сделать. Но, как отмечалось в этом вопросе, это связано с результатами. Операции чтения и записи (4.2.1) должны ждать при фиксации с ожидаемым временем ожидания 2 * errorAverage - 20 минут в этом примере. Точно так же транзакции только для чтения (4.2.2) в момент «сейчас» - а не время в прошлом - должны ждать, пока безопасное время продвинется достаточно далеко; не менее 10 минут в этом примере. Таким образом, чтобы иметь высокопроизводительную систему, вам необходимо максимально свести к минимуму интервалы ошибок, без, теряя ваши гарантии, в которых возникает сложность.

Я не уверен, как в вашей системе вызывается ntp_adjtime - возможно, он уже настроен с использованием нескольких ненадежных и некоррелированных источников времени, и в этом случае вы больше всего там.Если вы также можете гарантировать, что значение maxerror гарантированно будет продвигаться быстрее, чем возможный дрейф часов вашей системы, вам должно быть хорошо идти. Большая часть производительности Spanner, без ваших личных атомных часов :).

+2

Мы только что опубликовали новый документ в TrueTime и как он используется - https://cloud.google.com/spanner/docs/true-time-external-consistency –