2013-08-22 36 views
26

Tôi không chắc tại sao báo chí nói chung rằng API TrueTime của Google khó tái tạo (Có dây, Slashdot, v.v.).Tại sao API TrueTime của Google lại khó sao chép?

Tôi có thể hiểu rằng sẽ khó khăn như thế nào để nhận được khoảng thời gian lỗi thấp mà Google đang đạt được, nhưng tôi không thấy bản thân API sẽ rất khó khăn như thế nào.

Ví dụ: tôi đã bỏ một phiên bản bị tấn công cùng nhau. Đây là khoảng thời gian.

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

Đây là chức năng hiện tại.

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

Cuối cùng, đây là chức năng trước và sau (có hàm bao quanh hàm hiện tại và có thể sử dụng một chút phép tái cấu trúc 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; 
    } 

Dường như tôi nhận được lỗi khoảng 5.000us đến 350.000us (sử dụng NTP công khai). Đây là một con số rất xa so với con số của Google, nhưng bạn cần phải bắt đầu từ đâu đó.

Khác với hiệu suất mờ nhạt, có một lỗ hổng lớn nào trong thiết kế này có thể ngăn chặn thứ gì đó giống như Spanner được xây dựng trên đầu trang không?

Trả lời

35

Thách thức trong việc triển khai API TrueTime nằm trong bảo đảm mà bạn phải cung cấp. Cụ thể, thời gian tuyệt đối phải không bao giờ nằm ngoài khoảng thời gian TrueTime trên bất kỳ máy chủ nào trong hệ thống. Nếu điều này có thể xảy ra, thì thứ tự tuyệt đối của các sự kiện sẽ bị mất, như hầu hết các bảo đảm của Spanner.

Các Spanner paper đạt được điều này bằng cách kết hợp các phương tiện (phần 3):

  1. Nhiều máy chủ thời gian, với các nguồn khác nhau (GPS, đồng hồ nguyên tử), bao gồm các máy chủ thời gian từ trung tâm dữ liệu khác.
  2. Thuật toán của Marzullo để phát hiện những kẻ nói dối và ghép các nguồn thời gian đáng tin cậy khác nhau vào bản cập nhật đồng hồ máy địa phương.
  3. Độ lệch xung đồng hồ giả định là 200us/s tại bộ chia tỷ lệ, được áp dụng giữa đồng bộ hóa đồng hồ.
  4. Kicking máy từ hệ thống hiển thị độ trễ đồng hồ cục bộ đo được> ngưỡng (ngưỡng < < 200us/s do cần thiết).

Bây giờ, bạn có thể đạt được điều này với phương tiện đơn giản hơn - NTP và khoảng thời gian lỗi giả định là 10 phút sẽ không đáng kể. Nhưng như đã lưu ý trong câu hỏi, có những tác động về hiệu suất đối với điều này. Các giao dịch đọc-ghi (4.2.1) phải chờ cam kết, với thời gian chờ đợi dự kiến ​​là 2 * errorAverage - 20 phút trong ví dụ này. Tương tự như vậy, các giao dịch chỉ đọc (4.2.2) tại thời điểm "bây giờ" - chứ không phải là thời gian trong quá khứ - phải chờ đợi cho thời gian an toàn tiến lên đủ xa; ít nhất 10 phút trong ví dụ này. Vì vậy, để có một hệ thống hiệu suất cao, bạn cần phải giảm thiểu khoảng thời gian lỗi càng nhiều càng tốt, mà không cần mất bảo lãnh của bạn, đó là nơi phức tạp phát sinh.

Tôi không chắc chắn làm thế nào ntp_adjtime đang được gọi trong hệ thống của bạn - có thể nó đã được thiết lập bằng cách sử dụng nhiều nguồn thời gian không đáng tin cậy và không tương quan, trong trường hợp này bạn đang ở hầu hết mọi cách.Nếu bạn cũng có thể đảm bảo rằng giá trị maxerror được đảm bảo tiến nhanh hơn khả năng trôi dạt đồng hồ của hệ thống của bạn, bạn nên làm tốt. Hầu hết hiệu suất của Spanner, không có đồng hồ nguyên tử của riêng bạn :).

+2

Chúng tôi vừa xuất bản một tài liệu mới về TrueTime và cách nó được sử dụng - https://cloud.google.com/spanner/docs/true-time-external-consistency –

Các vấn đề liên quan