5

Nói rằng tôi có hai quá trình phân phối chạy đoạn mã sau sử dụng Zookeeper và người phụ trách cho một khóa chia sẻ:Làm thế nào để xử lý Apache Phụ trách phân phối mất Khóa kết nối

public static void main(String[] args) throws Exception { 
    CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", new ExponentialBackoffRetry(500, 2)); 
    client.start(); 
    InterProcessMutex lock = new InterProcessMutex(client, "/12345"); 

    System.out.println("before acquire"); 
    lock.acquire(); 
    System.out.println("lock has been acquired"); 
    //do some things that need to be done in an atomic fashion 
    lock.release(); 
    System.out.println("after release"); 
} 

Trong trường hợp "làm một số việc" bình luận đại diện cho nhiều các câu lệnh cần được thực hiện chỉ bằng một quá trình tại một thời điểm. ví dụ. nhiều ghi vào cơ sở dữ liệu khác nhau.

Tất cả điều này có vẻ ổn cho đến khi một trong quá trình java mất kết nối với người quản lý sau khi đã mua khóa.

Theo tài liệu:

Người ta khuyên bạn nên thêm một ConnectionStateListener và xem cho lơ lửng và LOST thay đổi trạng thái. Nếu trạng thái SUSPENDED là báo cáo bạn không thể chắc chắn rằng bạn vẫn giữ khóa trừ khi bạn sau đó nhận được trạng thái RECONNECTED. Nếu một trạng thái LOST được báo cáo , chắc chắn rằng bạn không còn giữ khóa nữa.

Nếu tôi hiểu điều này một cách chính xác, tại bất kỳ thời điểm nào sau khi lấy khóa, tôi có thể nhận được thông báo rằng khóa đã bị mất do sự cố mạng. Nếu điều đó đúng thì không có gì đảm bảo rằng sau khi lấy khóa, bạn là quá trình duy nhất có khóa. Những tuyên bố quý giá của tôi chỉ được thực hiện bởi một quá trình tại một thời điểm có thể xen kẽ với một quá trình khác.

Tôi đã hiểu sai ở trên chưa? Nếu vậy, hãy làm rõ ý nghĩa của nó. Nếu tôi đã không hiểu lầm ở trên như thế nào là một khóa phụ trách hữu ích nếu nó không thể đảm bảo truy cập độc quyền?

Trả lời

7

Đó là quy tắc chung của các hệ thống phân tán: mạng và các phiên bản khác không ổn định. Nếu cá thể của bạn mất liên lạc với bộ sưu tập của ZooKeeper thì không có cách nào để bạn có thể chắc chắn về trạng thái của nút khóa của mình. Đây là ý nghĩa của việc thay đổi trạng thái kết nối SUSPENDED. Bên trong, ZooKeeper đã thông báo cho Curator rằng kết nối với cá thể ZooKeeper của nó đã bị mất.

Điều này cho biết, bạn có thể giả định rằng không có trường hợp nào khác nhận khóa trước khi phiên của bạn hết giờ để những gì bạn làm có phần tùy thuộc vào bạn. Lưu ý thêm rằng ý nghĩa của trạng thái kết nối LOST đã thay đổi trong Curator 3.x. Trước Curator 3.x trạng thái LOST chỉ có nghĩa là chính sách thử lại của bạn đã hết hạn. Trong 3.x, Curator bây giờ thiết lập một bộ đếm thời gian bên trong khi kết nối là SUSPENDED và trạng thái kết nối LOST có nghĩa là phiên đã hết hạn. Vì vậy, đối với nhiều ứng dụng, bạn có thể bỏ qua SUSPENDED một cách an toàn và chỉ thoát khỏi khóa khi nhận được LOST.

Tất cả điều này sang một bên. Ngay cả khi sử dụng khóa JDK trong một JVM đơn lẻ, bạn phải có khả năng xử lý việc ngắt chuỗi của mình. Có các khóa ứng dụng Curator của bạn xử lý SUSPENDED/LOST là cùng một điều ngữ nghĩa.

Hope this helps (lưu ý Tôi là tác giả chính của Apache phụ trách)

+0

Đặc biệt khóa không đảm bảo truy cập độc quyền khi kết nối được tốt và lên đến giá trị một thời gian chờ phiên của thời gian sau một thất bại kết nối. Và bạn có thể biết có một lỗi kết nối bằng cách nhận thấy một sự thay đổi trạng thái kết nối SUSPENDED. Có đúng không? –

+0

Tôi nghĩ việc so sánh với việc ngắt chuỗi của bạn không phải là sự so sánh công bằng. Một InterruptedException chỉ được ném từ một phương thức chặn gián đoạn, bạn không nhận được một ngoại lệ như vậy sau khi bạn đã có được khóa giữa đường thông qua mã của bạn.Và ngay cả khi trạng thái Thread.isInterrupted() không được đặt sau khi bạn lấy khóa, điều đó không có nghĩa là người khác có thể lấy khóa của bạn. Chỉ cần được rõ ràng, tôi hiểu rằng bạn đang nói rằng tại thời điểm bạn nhận được một thông báo SUSPENDED/LOST bạn nhập một điều kiện chủng tộc với thời gian phiên của bạn ra, đó là chính xác? – bhspencer

+0

@ RobertTupelo-Schneck đúng là – Randgalt

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