2013-01-11 20 views
17

Khi đọc số recipe for lock của ZooKeeper, tôi thấy bối rối. Dường như công thức này cho khóa phân phối không thể đảm bảo "bất kỳ ảnh chụp nhanh nào trong thời gian không có hai khách hàng nghĩ rằng chúng giữ cùng một khóa". Nhưng kể từ khi ZooKeeper được áp dụng rộng rãi như vậy, nếu có những sai lầm như vậy trong tài liệu tham khảo, ai đó đã chỉ ra nó từ lâu rồi, vậy tôi đã hiểu lầm điều gì?Những quan tâm về khóa công thức của người sở thú

Trích dẫn the recipe for distributed locks:

Khóa

khóa phân phối đầy đủ được đồng bộ trên toàn cầu, ý nghĩa tại bất kỳ ảnh chụp trong thời gian không có hai khách hàng nghĩ rằng họ giữ cùng khóa. Đây có thể được thực hiện bằng cách sử dụng ZooKeeeper. Giống như các hàng đợi ưu tiên, trước tiên hãy xác định một nút khóa.

  1. Gọi tạo() với một tên đường dẫn của "locknode/guid-lock-" và trình tự và cờ phù du thiết lập.
  2. Gọi getChildren() trên nút khóa mà không cần đặt cờ đồng hồ (điều này rất quan trọng để tránh hiệu ứng đàn).
  3. Nếu tên đường dẫn được tạo ở bước 1 có hậu tố số thứ tự thấp nhất, máy khách có khóa và máy khách thoát khỏi giao thức.
  4. Cuộc gọi của khách hàng tồn tại() với cờ đồng hồ được đặt trên đường dẫn trong thư mục khóa có số thứ tự thấp nhất tiếp theo.
  5. nếu tồn tại() trả về false, đi đến bước 2. Nếu không, chờ một thông báo cho tên đường dẫn từ bước trước trước khi đi bước 2.

Hãy xem xét các trường hợp sau đây:

  • Client1 đã mua khóa thành công (ở bước 3), với nút ZooKeeper "locknode/guid-lock-0";
  • Client2 tạo nút "locknode/guid-lock-1", không thể lấy khóa và hiện đang xem "locknode/guid-lock-0";
  • Sau đó, vì một số lý do (ví dụ, tắc nghẽn mạng), Client1 không gửi thông báo nhịp tim đến cụm ZooKeeper đúng giờ, nhưng Client1 vẫn hoạt động, giả sử nhầm rằng nó vẫn giữ khóa.
  • Nhưng, Zookeeper có thể nghĩ rằng phiên trạm Client1 được timed out, và sau đó

    1. delete "locknode/guid-lock-0",
    2. gửi thông báo cho Client2 (hoặc có thể gửi thông báo đầu tiên?),
    3. nhưng không thể gửi thông báo "hết thời gian chờ" cho Client1 đúng lúc (giả sử do tắc nghẽn mạng).
  • Client2 nhận được thông báo, đi lại bước 2, được nút duy nhất "" locknode/guid-lock-1" , mà nó tạo ra bản thân;. Do đó, Client2 giả định nó giữ khóa
  • Nhưng tại Đồng thời, Client1 giả định nó giữ khóa.

Đây có phải là kịch bản hợp lệ không?

+1

Thảo luận song song về danh sách gửi thư của _zookeeper-users_: http://thread.gmane.org/gmane.comp.java.hadoop.zookeeper.user/5065 – seh

Trả lời

15

Kịch bản bạn mô tả có thể phát sinh. Khách hàng 1 nghĩ rằng nó có khóa, nhưng trên thực tế phiên của nó đã hết thời gian chờ, và Client 2 mua lại khóa.

Thư viện máy khách ZooKeeper sẽ thông báo cho Khách hàng 1 rằng kết nối của nó đã bị ngắt kết nối (nhưng máy khách không biết phiên đã hết hạn cho đến khi máy khách kết nối với máy chủ), để khách hàng có thể viết mã và giả định rằng khóa đã bị mất nếu anh ta bị ngắt kết nối quá lâu. Tuy nhiên, chủ đề sử dụng khóa cần phải kiểm tra định kỳ rằng khóa vẫn hợp lệ, vốn vốn đã có hiệu lực.

+0

cảm ơn; điều này có nghĩa rằng, "bất biến" - ** tại bất kỳ ảnh chụp nhanh nào trong thời gian không có hai khách hàng nghĩ rằng họ giữ cùng một khóa ** không giữ? – hulunbier

+0

đúng là – sbridges

+3

Một cách tầm thường khác để vi phạm "bất kỳ lúc nào trong ảnh chụp nhanh" bất thường (và do đó chứng minh tuyên bố sai) là một tạm dừng GC dài trên máy khách đang giữ khóa. Ví dụ: khách hàng C mua lại khóa, trong khi giữ nó java GC đá và đóng băng quá trình trong 60 giây. Sau 10 giây đó, phiên C sẽ hết hạn và một quá trình khác sẽ lấy khóa. Thời gian 11 là "một bản chụp trong thời gian khi 2 khách hàng nghĩ rằng họ giữ cùng một khóa". – Marco

0

... Nhưng, Zookeeper có thể nghĩ rằng phiên client1 được timeouted, và sau đó ...

Từ các tài liệu Zookeeper:

  • Việc loại bỏ một nút sẽ chỉ khiến một khách hàng thức dậy từ mỗi nút được xem chính xác bởi một khách hàng. Bằng cách này, bạn tránh hiệu ứng đàn.
  • Không có phiếu thăm dò ý kiến ​​hoặc thời gian chờ.

Vì vậy, tôi không nghĩ rằng vấn đề bạn mô tả phát sinh. Nó nhìn tôi như nghĩ rằng có thể có một nguy cơ treo khóa nếu một cái gì đó xảy ra với khách hàng tạo ra chúng, nhưng kịch bản bạn mô tả không nên phát sinh.

+0

cảm ơn; nhưng tôi không hiểu rõ ý tưởng của bạn; với tôi, "tránh hiệu ứng đàn" && "không bỏ phiếu hoặc hết giờ" không thể đảm bảo rằng client2 không thể lấy khóa trong khi client1 giữ khóa. Bên cạnh đó, nút tạm thời sẽ bị xóa tự động bởi ZK sau khi hết thời gian chờ, vì vậy tôi không thể thấy "nguy cơ treo khóa" ... – hulunbier

+0

Nếu phiên của Client1 đã hết thời gian thì khóa không còn tồn tại trong trường hợp đó, nhưng Client1 sẽ nhận được SESSION_EXPIRED hoặc CONNECTION_LOSS trở lại từ Zookeeper tại thời điểm đó, vì vậy họ sẽ biết rằng họ đã mất kết nối. – glenatron

+0

Nhưng nếu thông báo SESSION_EXPIRED không được gửi đến Client1 ** đúng lúc ** thì sao? Do tỷ lệ mất gói tin tạm thời cao, ví dụ (kết nối TCP vẫn được thiết lập) – hulunbier