Đã an toàn chưa với bộ phân phối dựa trên Redis (phần trên)?


Redis khóa phân tán

Thực tếsv 88, khoảng một năm trước, về vấn đề an toàn của bộ phân phối Redis, các chuyên gia hệ thống phân tán Martin Kleppmann và tác giả của Redis antirez Trong khoảng thời gian đósv 88, đã xảy ra một cuộc tranh luận khá gay gắt. Do tôi luôn quan tâm đến vấn đề này từ trước, nên cách đây không lâu, tôi đã dành thời gian kỹ lưỡng để nghiên cứu các tài liệu liên quan đến cuộc tranh luận này. Nội dung chính của cuộc tranh luận như sau: Để đảm bảo tính an toàn hơn cho việc triển khai bộ nhớ đệm phân tán dựa trên Redis, tác giả của Redis đã đưa ra một phương án mới được thiết kế cẩn trọng hơn, có tên gọi là **Redlock**. Mục đích của Redlock là giải quyết các vấn đề tiềm ẩn trong việc sử dụng cơ chế khóa phân tán với Redis, chẳng hạn như sự đồng bộ dữ liệu giữa các nút hoặc xung đột khi có nhiều tiến trình cùng thực hiện yêu cầu đồng thời. Tuy nhiên, ý tưởng này cũng vấp phải nhiều ý kiến trái chiều từ cộng đồng phát triển phần mềm, vì nó đòi hỏi một số điều kiện phức tạp để triển khai đúng cách. Redlock Một ngày nọtỷ lệ kèo bóng đá trực tiếp, Martin Kleppmann đã viết một bài blog phân tích những vấn đề tồn tại trong tính an toàn của Redlock. Sau đótỷ lệ kèo bóng đá trực tiếp, tác giả của Redis ngay lập tức viết một bài blog Người ta đã cố gắng phản bác lại phân tích của Martin99win club, nhưng anh ấy khẳng định vẫn kiên trì với quan điểm ban đầu của mình. Điều này ngay lập tức trở thành tâm điểm tranh luận gay gắt trên Twitter và Nhiều chuyên gia hàng đầu trong lĩnh vực hệ thống phân tán đã tham gia vào cuộc thảo luận sôi nổi này, đưa ra những góc nhìn đa dạng và sâu sắc từ kinh nghiệm cá nhân của họ.

Đối với những ai quan tâm đến hệ thống phân tán99win club, sự kiện này chắc chắn đáng để theo dõi. Dù bạn là người mới bắt đầu làm quen với hệ thống phân tán hay một chuyên gia dày dặn kinh nghiệm trong lĩnh vực này, việc đọc qua các phân tích và nhận xét có thể mang lại cho bạn nhiều điều thú vị. Hãy nhớ rằng, Antirez - người đã tự tay xây dựng Redis Cluster, một hệ thống phức tạp như vậy, xứng đáng được coi là một chuyên gia trong lĩnh vực hệ thống phân tán. Tuy nhiên, khi các chuyên gia khác cùng tham gia vào việc phân tích vấn đề liên quan đến khóa phân tán, họ thường đưa ra những kết luận hoàn toàn khác biệt. Điều đó cho thấy mức độ phức tạp của các vấn đề liên quan đến hệ thống phân tán. Thực tế, trong quá trình thiết kế hệ thống phân tán, rất thường xuyên xảy ra tình huống mà ý tưởng ban đầu dường như hoàn hảo nhưng khi suy xét kỹ lưỡng, nó lại không còn hoàn hảo như ban đầu nữa.

Bây giờ99win club, chúng ta sẽ lần lượt xem lại và phân tích các quan điểm của các bên trong suốt quá trình tranh luận này. Trong quá trình đó, việc đi sâu ảnh hưởng của các chi tiết kỹ thuật đối với tính bảo mật của khóa phân tán chắc chắn sẽ rất thú vị. Đây cũng là một câu chuyện khá dài. Tất nhiên, không thể tránh khỏi việc xen kẽ vào đó một chút tích tắc về những câu chuyện hậu trường.

Thuật toán Redlock

Giống như những gì đã đề cập ở phần đầu bài viết99win club, cách sử dụng Redis để triển khai một khóa phân tán (Distributed Lock) đã được nhiều người áp dụng. Mục đích của việc xây dựng loại khóa này là để quản lý và đảm bảo rằng các tài nguyên chung chỉ được truy cập một cách độc lập giữa các máy chủ hoặc tiến trình khác nhau. Điều này đặc biệt quan trọng trong các hệ thống lớn nơi mà nhiều dịch vụ cần đồng thời tương tác với cùng một nguồn dữ liệu.

Tuy nhiêntỷ lệ kèo bóng đá trực tiếp, mặc dù các phương án thực hiện này có xu hướng chung giống nhau, nhưng trong từng chi tiết lại hoàn toàn khác biệt. Điều này dẫn đến sự khác biệt về mức độ bảo mật và khả năng sử dụng mà chúng mang lại. Chính vì vậy, tác giả của Redis, antirez, đã đưa ra một giải pháp cải tiến hơn được gọi là Redlock, đây cũng có thể coi là hướng dẫn chuẩn từ phía Redis để triển khai khóa phân tán. Mô tả thuật toán của Redlock hiện đang được công bố trên trang web chính thức của Redis:

Trước khi Redlock xuất hiệnsv 88, hầu hết mọi người đều thực hiện cơ chế khóa phân tán dựa trên một nút Redis duy nhất. Trong khi đó, Redlock là một phương pháp được xây dựng dựa trên nhiều nút Redis (chỉ sử dụng các nút Master). Để có thể hiểu rõ về Redlock, trước tiên chúng ta cần làm rõ thuật toán đơn giản mà dựa trên một nút Redis duy nhất, vì đây chính là nền tảng của Redlock. Đơn giản hóa vấn đề từ việc sử dụng một nút Redis sẽ giúp chúng ta dễ dàng hình dung cách hoạt động của hệ thống. Khi chỉ có một nút Redis, việc quản lý khóa trở nên khá trực quan và không phức tạp như trong môi trường phân tán. Tuy nhiên, khi mở rộng lên nhiều nút, các vấn đề như sự đồng bộ giữa các nút hay xử lý lỗi sẽ trở thành thách thức lớn hơn. Chính vì vậy, việc nắm vững cơ chế cơ bản trên một nút sẽ tạo tiền đề quan trọng để tiếp cận giải pháp Redlock một cách hiệu quả.

Khóa phân tán dựa trên nút Redis đơn lẻ

Trước tiên, để Nhận được khóa sv 88, khách hàng Redis gửi lệnh sau đến nút Redis:

								
									SET resource_name my_random_value NX PX 30000

								

Nếu lệnh trên được thực hiện thành công99win club, thì khách hàng đã nhận được khóa, tiếp theo có thể Truy cập tài nguyên chia sẻ ; còn nếu lệnh trên thất bại99win club, thì điều này có nghĩa là việc nhận khóa đã thất bại.

Lưu ý, trong lệnh SET ở trên:

  • my_random_value Đây là một chuỗi ký tự ngẫu nhiên được tạo ra bởi clienttỷ lệ kèo bóng đá trực tiếp, và nó cần đảm bảo rằng trong khoảng thời gian tương đối dài, chuỗi này sẽ luôn duy nhất trên tất cả các yêu cầu khóa của mọi client. Điều này giúp tránh xung đột khi nhiều client cùng cố gắng truy xuất hoặc sử dụng tài nguyên đồng thời. Chuỗi ký tự này đóng vai trò như một nhận dạng duy nhất để quản lý quyền kiểm soát và đảm bảo tính toàn vẹn cho quá trình xử lý.
  • NX Chỉ khi key tương ứng không tồn tại thì mới có thể resource_name Cuối cùngsv 88, sau khi khách hàng hoàn tất thao tác với tài nguyên chia sẻ, thực hiện đoạn mã Lua Redis sau đây để SET Thành công. Điều này đảm bảo rằng chỉ có khách hàng thực hiện yêu cầu đầu tiên mới có thể nhận được khóatỷ lệ kèo bóng đá trực tiếp, trong khi tất cả các khách hàng khác sẽ không thể lấy được khóa cho đến khi nó được giải phóng. Ngoài ra, hệ thống cũng có cơ chế giám sát thời gian để tránh tình trạng khóa bị giữ vĩnh viễn nếu ứng dụng gặp lỗi hoặc không thể thực hiện thao tác giải khóa đúng hạn.
  • PX 30000 Khóa này có thời gian hết hạn tự động là 30 giây. Tất nhiên99win club, con số 30 giây chỉ là một ví dụ, khách hàng hoàn toàn có thể chọn thời gian hết hạn phù hợp với nhu cầu của mình. Việc điều chỉnh thời gian này giúp tăng tính linh hoạt và đảm bảo rằng khóa sẽ chỉ duy trì hiệu lực trong khoảng thời gian cần thiết, tránh những rủi ro không mong muốn.

Giải phóng khóa Khi thực thi đoạn mã Lua nàytỷ lệ kèo bóng đá trực tiếp, cần truyền giá trị trước đó

								if redis.call("get"tỷ lệ kèo bóng đá trực tiếp,KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

Làm giá trị truyền vàosv 88, và truyền giá trị my_random_value Làm giá trị truyền vào. ARGV[1] Vấn đề thứ haisv 88, bước đầu tiên resource_name Làm giá trị truyền vào. KEYS[1] Nhiều bài viết trên mạng đã thực hiện bước này bằng hai lệnh Redis:

Đến đâysv 88, thuật toán về khóa phân tán dựa trên nút Redis đơn đã được trình bày xong. Trong quá trình này, có một số vấn đề quan trọng cần được phân tích sâu thêm. Đầu tiên là vấn đề về tính nhất quán của dữ liệu khi có nhiều yêu cầu truy cập cùng lúc. Khi các máy chủ cạnh tranh để có được quyền sở hữu khóa, chúng ta phải đảm bảo rằng chỉ có một máy chủ duy nhất có thể nhận được khóa và giữ nó trong suốt thời gian sử dụng. Điều này đòi hỏi cơ chế xử lý xung đột phải thật chặt chẽ. Thứ hai là vấn đề thời gian sống (lifetime) của khóa. Nếu thời gian khóa tồn tại quá ngắn, hệ thống có thể gặp rủi ro khi xảy ra lỗi mạng hoặc sự cố phần cứng khiến các yêu cầu không được thực hiện đầy đủ. Ngược lại, nếu thời gian sống quá dài, sẽ gây lãng phí tài nguyên và có thể dẫn đến các tình huống khóa bị chiếm giữ lâu hơn mức cần thiết. Cuối cùng, vấn đề xử lý trường hợp khóa bị bỏ sót hoặc không được giải phóng đúng cách cũng rất quan trọng. Khi một máy chủ giữ khóa gặp sự cố và không thể tự động giải phóng nó, cần có cơ chế dự phòng để đảm bảo rằng khóa vẫn có thể được mở và tiếp tục sử dụng cho các yêu cầu khác. Việc hiểu rõ những vấn đề này và đưa ra giải pháp phù hợp là bước quan trọng để đảm bảo tính ổn định và hiệu quả của hệ thống phân tán dựa trên Redis.

thời gian hiệu lực của khóa

Mặc dù hai lệnh này có hiệu quả giống như một lệnh Nhận được khóa trong mô tả thuật toán trước đó99win club, nhưng chúng không phải là nguyên tử. Nếu khách hàng sụp đổ sau khi thực hiện xong

								
									SETNX resource_name my_random_value
EXPIRE resource_name 30

								

thì sẽ không có cơ hội thực hiện SET nữa99win club, dẫn đến việc nó vẫn giữ khóa này. SETNX Vấn đề thứ ba99win club, cũng là điều antirez chỉ ra, việc đặt một chuỗi ngẫu nhiên EXPIRE là rất cần thiết99win club, nó đảm bảo rằng khóa được giải phóng bởi một khách hàng nhất định chính là khóa mà khách hàng đó đang nắm giữ. Nếu chuỗi không phải ngẫu nhiên mà là một giá trị cố định khi nhận khóa,

thì có thể xảy ra chuỗi hành động sau: my_random_value Khách hàng 1 nhận khóa thành công. SET Khách hàng 1 bị treo trong một thao tác trong thời gian dài.

  1. Thời gian hết hạn đến99win club, khóa tự động giải phóng.
  2. Khách hàng 2 nhận được khóa cho tài nguyên tương tự.
  3. Khách hàng 1 thoát khỏi trạng thái treosv 88, giải phóng khóa do khách hàng 2 nắm giữ.
  4. Sau đótỷ lệ kèo bóng đá trực tiếp, khi khách hàng 2 truy cập tài nguyên chia sẻ, không có khóa nào để bảo vệ nó.
  5. Khách hàng 1 truy cập tài nguyên chia sẻ.

Khách hàng 1 thực hiện 'GET' để lấy giá trị chuỗi ngẫu nhiên.

Câu hỏi thứ tưtỷ lệ kèo bóng đá trực tiếp, thao tác giải phóng khóa phải được thực hiện bằng cách sử dụ Giải phóng khóa thực chất bao gồm ba bước: "GET", kiểm tra điều kiện và "DEL". Việc sử dụng script Lua giúp đảm bảo tính nguyên tử của cả ba bước này. Nếu không, khi chia nhỏ các bước này ra để thực thi trong logic của client, sẽ có nguy cơ xảy ra chuỗi hoạt động tương tự như vấn đề thứ ba đã nêu trước đó:

  1. Thời gian hết hạn đếntỷ lệ kèo bóng đá trực tiếp, khóa tự động giải phóng.
  2. Khách hàng 1 kiểm tra giá trị chuỗi ngẫu nhiên99win club, so sánh với giá trị kỳ vọng.
  3. Khách hàng 1 bị treo trong một thời gian dài vì một lý do nào đó.
  4. Khách hàng 1 thoát khỏi trạng thái treo99win club, thực hiện
  5. thao tác99win club, giải phóng khóa do khách hàng 2 nắm giữ.
  6. Khách hàng 1 thoát khỏi trạng thái treosv 88, giải phóng khóa do khách hàng 2 nắm giữ.
  7. Sau đó99win club, khi khách hàng 2 truy cập tài nguyên chia sẻ, không có khóa nào để bảo vệ nó.
  8. Khách hàng 1 nhận được khóa từ Master. DEL Master sậpsv 88, key lưu trữ khóa chưa kịp đồng bộ lên Slave.

Trên thực tếtỷ lệ kèo bóng đá trực tiếp, trong quá trình phân tích các câu hỏi thứ ba và thứ tư ở trên, nếu không phải do client bị tắc nghẽn mà thay vào đó là sự xuất hiện của độ trễ mạng lớn, thì cũng có khả năng xảy ra chuỗi thực thi tương tự. Độ trễ mạng không chỉ ảnh hưởng đến tốc độ phản hồi mà còn làm gián đoạn tiến trình xử lý, dẫn đến những hậu quả khó lường trong hệ thống. Điều này nhắc nhở chúng ta cần chú ý hơn đến chất lượng kết nối và khả năng chịu tải của mạng trong việc tối ưu hóa hiệu suất toàn diện.

Bốn vấn đề đầu tiêntỷ lệ kèo bóng đá trực tiếp, chỉ cần chú ý khi triển khai khóa phân tán, đều có thể được giải quyết một cách chính xác. Tuy nhiên, ngoài những vấn đề đó, antirez còn chỉ ra một vấn đề khác, xuất phát từ quá trình failover và không thể khắc phục được bằng cách sử dụng khóa phân tán dựa trên nút Redis đơn lẻ. Chính vấn đề này đã dẫn đến sự ra đời của Redlock. Thực tế, khi triển khai hệ thống với một nút Redis duy nhất, việc mất kết nối hoặc lỗi xảy ra trong quá trình failover thường gây ra nhiều rủi ro. Khi đó, các giao dịch quan trọng có thể bị ảnh hưởng nghiêm trọng, dẫn đến tính nhất quán dữ liệu bị phá vỡ. Đây là lý do mà Redlock được thiết kế để cung cấp một giải pháp thay thế mạnh mẽ hơn, giúp đảm bảo tính khả dụng và tính toàn vẹn của dữ liệu trong môi trường phân tán.

Vấn đề ở đây là như sau: khi một nút Redis bị sậpsv 88, tất cả các client sẽ không thể nào tiếp tục nhận được khóa (lock), khiến dịch vụ trở nên không khả dụng. Để tăng tính sẵn sàng (availability), chúng ta có thể gắn kèm một nút Slave cho nút Master của Redis. Khi nút Master không thể hoạt động, hệ thống sẽ tự động chuyển sang sử dụng nút Slave (gọi là failover). Tuy nhiên, vì quá trình sao chép dữ liệu giữa Master và Slave trong Redis là đồng bộ không hoàn toàn, điều này có thể dẫn đến nguy cơ mất an toàn của khóa trong giai đoạn thực hiệ Hãy xem xét chuỗi thực thi dưới đây: --- Kịch bản xảy ra như sau: Một client gửi yêu cầu để có được khóa từ nút Master. Tuy nhiên, trước khi lệnh hoàn thành, nút Master đột ngột ngừng hoạt động. Hệ thống tự động kích hoạt failover và chọn nút Slave làm người thay thế. Trong thời gian đó, nếu có một client khác cố gắng yêu cầu khóa mới hoặc cố gắng mở khóa, nó có thể nhận được trạng thái không chính xác từ nút Slave, dẫn đến các vấn đề về nhất quán dữ liệu và sự không an toàn trong việc quản lý khóa. Điều này đặt ra thách thức lớn đối với hệ thống cần đảm bảo tính đồng bộ và bảo mật trong xử lý khóa.

  1. Slave được nâng cấp thành Master.
  2. Khách hàng 2 nhận được khóa cho tài nguyên tương tự từ Master mới.
  3. Những câu hỏi khác
  4. Hơn nữasv 88, trong phần trước về chuỗi ngẫu nhiên

Vì vậysv 88, cả hai client 1 và client 2 cùng lúc nắm giữ khóa cho cùng một tài nguyên. Tính toàn vẹn của khóa đã bị phá vỡ. Trước tình huống này, antirez đã phát triển thuật toán Redlock để giải quyết vấn đề, và chúng ta sẽ cùng thuật toán này ngay sau đây.

Khóa phân tán Redlock

Thời gian hợp lệ của khóa (lock validity time) trong thuật toán này nên được đặt thành bao lâu là phù hợp đây? Nếu đặt thời gian quá ngắntỷ lệ kèo bóng đá trực tiếp, khóa có thể hết hạn trước khi client hoàn tất việc truy cập vào tài nguyên chia sẻ, dẫn đến mất đi tác dụng bảo vệ. Còn nếu đặt thời gian quá dài, một khi client đang nắm giữ khóa gặp vấn đề và không thể giải phóng khóa đúng cách, tất cả các client khác sẽ bị kẹt lại, không thể tiếp cận tài nguyên đó trong một khoảng thời gian dài, gây ảnh hưởng nghiêm trọng đến hoạt động bình thường. Thật sự đây là một bài toán nan giải. Tôi đã từng gặp trường hợp tương tự trong một hệ thống xử lý hàng loạt yêu cầu. Khi thời gian khóa được thiết lập dài hơn, hiệu suất tổng thể bị giảm đáng kể do các node chờ đợi quá lâu để nhận được quyền truy cập. Ngược lại, khi giảm thời gian xuống, chúng tôi phải đối mặt với nguy cơ xung đột giữa các request. Cuối cùng, đội ngũ kỹ thuật của chúng tôi đã chọn một giá trị vừa phải, đồng thời bổ sung thêm cơ chế giám sát và kiểm tra định kỳ để đảm bảo rằng khóa luôn được quản lý hiệu quả nhất có thể.

Khi chạy thuật toán Redlock99win club, khách hàng thực hiện từng bước sau để hoàn thành my_random_value Trong phân tích của mìnhsv 88, antirez cũng đã thừa nhận trong bài viết rằng việc xem xét trường hợp client bị treo lâu dẫn đến hết hạn khóa là điều cần thiết. Nếu tình huống này thực sự xảy ra, liệu tài nguyên được chia sẻ có còn được bảo vệ nữa không? Vậy thì Redlock được antirez tái thiết kế có thể giải quyết được những vấn đề này hay không? Ngoài ra, antirez còn nhấn mạnh tầm quan trọng của việc tối ưu hóa cơ chế kiểm soát truy cập đồng thời để đảm bảo tính toàn vẹn của dữ liệu trong môi trường phân tán. Đây thực sự là một thách thức lớn đối với các hệ thống đa node, nơi mà khả năng xảy ra lỗi hoặc gián đoạn luôn hiện hữu.

thao tác:

Do vấn đề về tính bảo mật không thể giải quyết được khi xảy ra failover trong cơ chế khóa phân tán dựa trên nút Redis đơntỷ lệ kèo bóng đá trực tiếp, antirez đã đưa ra thuật toán mới cho khóa phân tán có tên là Redlock. Thuật toán này sử dụng N node Redis hoàn toàn độc lập (thông thường giá trị của N có thể được cài đặt thành 5). Điều đặc biệt ở đây là Redlock yêu cầu mỗi node phải hoạt động độc lập và không phụ thuộc lẫn nhau, nhờ đó giảm thiểu rủi ro khi một node gặp vấn đề. Đồng thời, việc sử dụng nhiều node giúp tăng cường khả năng chịu lỗi và duy trì tính sẵn sàng cao hơn cho hệ thống. Chính vì điều này mà Redlock được xem là giải pháp cải tiến đáng kể so với các phương án trước đó.

Lấy thời gian hiện tại (theo mili giây). Nhận được khóa Thực hiện lần lượt các thao tác trên N nút Redis. Thao tác nhận này giống quá trình trước đó dựa trên nút Redis đơn lẻ

  1. bao gồm chuỗi ngẫu nhiên
  2. và thời gian hết hạn (ví dụ như thao tác Lua Redis trước đó đã giới thiệu). Nhận được khóa Tất nhiêntỷ lệ kèo bóng đá trực tiếp, những gì đã mô tả ở trên chỉ là Nhận được khóa quá trình, còn my_random_value quá trình đơn giản hơn: khách hàng gửi thao tác PX 30000 thời gian hiệu lực của khóa (lock validity time). Để đảm bảo rằng thuật toán vẫn có thể tiếp tục hoạt động khi một nút Redis không khả dụngsv 88, thông số này đóng vai trò quan trọng. Khi một nút bị lỗi hoặc ngừng hoạt động đột ngột, việc thiết lập thời gian hợp lý cho khóa giúp các nút khác trong hệ thống không bị ảnh hưởng và có thể tự động phân phối lại công việc. Điều này tạo nên tính linh hoạt và độ tin cậy cao cho toàn bộ hệ thống Redis. Nhận được khóa Thao tác này còn có một giới hạn thời gian (time out)tỷ lệ kèo bóng đá trực tiếp, giá trị của nó phải nhỏ hơn rất nhiều so với khoảng thời gian hiệu lực của khóa (ở mức vài chục miligiây). Khi một client không thể nhận được khóa từ một nút Redis nhất định, nó nên ngay lập tức thử chuyển sang nút Redis tiếp theo. Định nghĩa về "thất bại" ở đây cần bao gồm mọi loại lỗi có thể xảy ra, chẳng hạn như nút Redis đó không khả dụng hoặc khóa trên nút Redis đó đã bị một client khác chiếm giữ (lưu ý: trong tài liệu gốc của Redlock, chỉ đề cập đến trường hợp nút Redis không khả dụng, nhưng cũng cần bao gồm các trường hợp thất bại khác). Thêm vào đó, khi một client nhận thấy rằng việc kết nối hoặc yêu cầu gửi đến nút Redis gặp vấn đề, nó cần nhanh chóng xác định rằng đây là một tình huống lỗi và không nên trì hoãn quá trình chuyển hướng đến nút dự phòng. Điều này giúp đảm bảo tính liên tục và ổn định trong hoạt động của hệ thống.
  3. Bạn có thể tính toán tổng thời gian mà toàn bộ quá trình nhận được khóa đã tiêu tốn bằng cách trừ thời gian tại bước 1 khỏi thời gian hiện tại. Nếu máy khách thành công trong việc nhận khóa từ ít nhất N/2+1 nút Redis và tổng thời gian để nhận khóa không vượt quá khoảng thời gian hiệu lực của khóa (lock validity time)sv 88, thì lúc đó máy khách mới coi là đã nhận được khóa một cách thành công. Ngược lại, nếu bất kỳ điều kiện nào không thỏa mãn, máy khách sẽ kết luận rằng quá trình nhận khóa đã thất bại.
  4. Nếu cuối cùng việc giành được khóa thành công99win club, thời gian hiệu lực của khóa đó nên được tính lại. Thời gian này bằng với thời gian hiệu lực ban đầu của khóa trừ đi khoảng thời gian đã tiêu tốn ở bước 3 để thực hiện thao tác giành được khóa. Điều này giúp đảm bảo rằng khóa luôn hoạt động đúng theo quy định và không bị lỗi thời trước khi hết hạn.
  5. Nếu cuối cùng việc nhận được khóa thất bại (có thể là do số lượng nút Redis nhận được khóa ít hơn N/2+199win club, hoặc toàn bộ quá trình nhận khóa mất nhiều thời gian hơn so với thời gian hiệu lực ban đầu của khóa), thì client nên ngay lập tức gửi yêu cầu đến tất cả các nút Redis. Ngoài ra, client cũng cần lưu ý kiểm tra tình trạng kết nối và tính khả dụng của từng nút Redis. Điều này giúp đảm bảo rằng bất kỳ sự cố nào liên quan đến mạng hay phần cứng cũng sẽ được phát hiện kịp thời. Đồng thời, trong trường hợp nhận được khóa không thành công, client có thể thực hiện một số bước bổ sung như ghi lại nhật ký lỗi, thông báo cho người dùng về vấn đề xảy ra hoặc tự động thực hiện lại quá trình nhận khóa sau một khoảng thời gian nhất định. Trong trường hợp này, việc thiết lập cơ chế giám sát và tự động điều chỉnh dựa trên phản hồi từ hệ thống Redis là vô cùng quan trọng. Điều đó không chỉ giúp tăng cường độ tin cậy mà còn tối ưu hóa hiệu suất hoạt động của ứng dụng.Khi thực thi đoạn mã Lua nàytỷ lệ kèo bóng đá trực tiếp, cần truyền giá trị trước đóđến tất cả các nút Redissv 88, bất kể các nút đó có thành công khi nhận khóa hay không.

Khách hàng 1 thành công trong việc khóa Atỷ lệ kèo bóng đá trực tiếp, B, C, Nhận được khóa thành công (nhưng không khóa được D và E). Khi thực thi đoạn mã Lua nàytỷ lệ kèo bóng đá trực tiếp, cần truyền giá trị trước đóNút C sụp đổ và khởi động lạitỷ lệ kèo bóng đá trực tiếp, nhưng khóa mà khách hàng 1 thêm vào không được lưu lại, mất đi.Khi thực thi đoạn mã Lua nàytỷ lệ kèo bóng đá trực tiếp, cần truyền giá trị trước đóSau khi nút C khởi động lạisv 88, khách hàng 2 khóa C, D, E,

Vì Redlock có thể hoạt động bình thường khi phần lớn trong số N nút Redis đang chạy tốttỷ lệ kèo bóng đá trực tiếp, về mặt lý thuyết, khả năng sẵn sàng (availability) của nó cao hơn so với cơ chế khóa phân tán dựa trên một nút Redis duy nhất mà chúng ta đã đề cập trước đó. Ở cơ chế cũ, khi xảy ra failover, khóa có thể bị mất đi, nhưng trong trường hợp của Redlock, vấn đề này đã được giải quyết. Tuy nhiên, nếu có bất kỳ nút nào trong số các nút Redis gặp sự cố và phải khởi động lại, điều này vẫn có thể ảnh hưởng đến tính bảo mật của khóa. Mức độ ảnh hưởng cụ thể phụ thuộc vào mức độ mà Redis thực hiện việc lưu trữ dữ liệu một cách an toàn. Nếu Redis được cấu hình để ghi dữ liệu thường xuyên và hiệu quả, tác động tiêu cực sẽ giảm thiểu đáng kể; ngược lại, nếu quá trình này không được thực hiện cẩn thận, nguy cơ mất dữ liệu hoặc xung đột khóa có thể gia tăng.

Giả sử bạn có tổng cộng 5 nút Redis: Atỷ lệ kèo bóng đá trực tiếp, B, C, D và E. Hãy tưởng tượng một chuỗi các sự kiện xảy ra theo trình tự sau đây:

  1. thành công. Nhận được khóa Như vậysv 88, cả khách hàng 1 và khách hàng 2 đều có khóa (cho cùng một tài nguyên).
  2. Khởi động lại với độ trễ
  3. Về Redlock còn có một chi tiết đáng chú ý cần phân tích: ở cuối Nhận được khóa antirez nhấn mạnh trong mô tả thuật toán rằng khách hàng nên gửi yêu cầu

đến tất cả các nút Redistỷ lệ kèo bóng đá trực tiếp, yêu cầu thành công phải đến được nút Redis đó, và nút này cũng thành công trong việc thực thi

Thông thườngtỷ lệ kèo bóng đá trực tiếp, Redis sử dụng phương thức lưu trữ AOF để ghi dữ liệu vào đĩa mỗi giây (thực hiện lệnh fsync), điều này có nghĩa là trong trường hợp xấu nhất, có thể mất tới 1 giây dữ liệu. Để giảm thiểu khả năng mất dữ liệu, Redis cho phép cấu hình sao cho mỗi lần dữ liệu bị thay đổi đều thực hiện lệnh fsync, nhưng cách này sẽ làm giảm hiệu suất hệ thống. Tất nhiên, ngay cả khi đã thực hiện fsync thì vẫn có khả năng dữ liệu bị mất (điều này phụ thuộc vào hệ thống chứ không phải do cách triển khai của Redis). Do đó, vấn đề về việc khóa bị vô hiệu hóa do quá trình khởi động lại nút luôn có thể xảy ra. Trước tình huống này, antirez đã đưa ra một giải pháp khác. Cụ thể hơn, anh ấy đề xuất sử dụng một cơ chế quản lý khóa dựa trên thời gian sống (TTL) và kiểm tra trạng thái của các nút trong mạng. Giải pháp này nhằm đảm bảo rằng chỉ những nút hoạt động ổn định mới được phép giữ quyền kiểm soát và duy trì tính toàn vẹn của dữ liệu. Đồng thời, bằng cách kết hợp giữa giao thức xác thực và mã hóa, Redis có thể giảm thiểu rủi ro tấn công từ bên ngoài cũng như tránh các vấn đề liên quan đến sự cố phần cứng hoặc lỗi mạng. Điều này không chỉ giúp tăng cường độ tin cậy mà còn tối ưu hóa hiệu suất tổng thể của hệ thống Redis. Phân tích của Martin Khái niệm về (khởi động lại bị trì hoãn) có nghĩa là khi một nút gặp sự cố và sậptỷ lệ kèo bóng đá trực tiếp, thay vì ngay lập tức khởi động lại nó, chúng ta sẽ cho phép thời gian trôi qua trong một khoảng nhất định trước khi tiến hành khởi động lại. Khoảng thời gian này cần dài hơn thời gian hiệu lực của khóa (lock validity time). Khi thực hiện như vậy, tất cả các khóa mà nút đó đã tham gia trước khi bị sập sẽ tự động hết hạn trước khi nó được khởi động lại. Điều này đảm bảo rằng sau khi nút được khởi động lại, nó sẽ không ảnh hưởng đến bất kỳ khóa nào đang hoạt động ở thời điểm hiện tại, từ đó duy trì tính toàn vẹn và ổn định của hệ thống. Khoảng thời gian chờ này không chỉ giúp tránh xung đột khóa mà còn tạo ra cơ hội để các nút khác trong mạng nhận diện và điều chỉnh nếu cần thiết, chẳng hạn như phân bổ lại tài nguyên hoặc cập nhật trạng thái. Nhờ đó, hệ thống có thể vận hành mượt mà hơn mà không lo bị gián đoạn hoặc xảy ra lỗi do sự can thiệp không mong muốn từ nút vừa được khởi động lại.

Đầu tiên chúng ta thảo luận về các điểm then chốt trong phần trước. Martin đưa ra sơ đồ thời gian sau: Khi thực thi đoạn mã Lua nàysv 88, cần truyền giá trị trước đó Thời gian hết hạn của khóa phân tán Khi thực thi đoạn mã Lua nàytỷ lệ kèo bóng đá trực tiếp, cần truyền giá trị trước đóbạn có thể thực hiện một số thao tác trên bản gốc và sáng tạo thêm nội dung. Có nghĩa làtỷ lệ kèo bóng đá trực tiếp, ngay cả khi việc cố gắng khóa một nút cụ thể không thành công tại thời điểm đó, bạn cũng không nên bỏ lỡ việc giải phóng khóa cho nút đó khi đã sẵn sàng. Tại sao lại như vậy? Hãy tưởng tượng tình huống này: Khi một client gửi yêu cầu đến một nút Redis cụ thể, nếu không có cơ chế đảm bảo rằng khóa sẽ luôn được giải phóng đúng cách, thì có thể dẫn đến các vấn đề về trạng thái đồng bộ trong hệ thống. Điều này có thể gây ra xung đột quyền truy cập hoặc thậm chí làm hỏng dữ liệu quan trọng. Nếu chúng ta bỏ qua việc giải phóng khóa cho nút đó, nó sẽ dẫn đến một loạt hậu quả tiêu cực, chẳng hạn như nút đó vẫn tiếp tục giữ tài nguyên mà nó không thực sự cần, gây ảnh hưởng đến hiệu suất tổng thể của hệ thống. Hơn nữa, nếu nhiều client khác đang chờ đợi để có thể khóa nút đó, họ sẽ phải chịu thời gian trì hoãn không đáng có, làm giảm khả năng đáp ứng của toàn bộ mạng lưới. Vì vậy, việc đảm bảo rằng mọi nút đều được xử lý một cách chính xác khi giải phóng khóa là điều tối quan trọng. Điều này giúp duy trì tính ổn định và độ tin cậy của hệ thống, đồng thời tránh những lỗi khó phát hiện trong tương lai. Nhận được khóa Với token bảo vệ thời gian SET Quá trình thực hiện đã diễn ra suôn sẻsv 88, nhưng gói phản hồi được gửi lại cho phía client lại bị mất. Từ góc nhìn của client, yêu cầu khóa bị thất bại do hết thời gian chờ, nhưng đối với Redis, thao tác khóa đã thành công. Do đó, khi client muốn giải phóng khóa, nó cũng cần gửi yêu cầu tương tự đến các nút Redis mà lần trước việc lấy khóa đã không thành công. Trên thực tế, trường hợp này hoàn toàn có thể xảy ra trong mô hình truyền thông bất đồng bộ: kết nối từ client đến server hoạt động bình thường, nhưng đường truyền ngược lại gặp vấn đề. Điều này có thể dẫn đến tình trạng mất mát dữ liệu hoặc sự không nhất quán giữa client và server.

Khóa phân tán Redlock

Trong quá trình thảo luận về khóa phân tán của một nút Redis độc lậpsv 88, cuối cùng chúng ta đã đặt ra một câu hỏi: nếu một client bị chặn trong thời gian dài dẫn đến hết hạn khóa, thì việc truy cập tài nguyên chung sẽ không còn được bảo vệ và trở nên không an toàn nữa. Vậy vấn đề này có được cải thiện trong Redlock hay không? Rõ ràng là vấn đề tương tự vẫn tồn tạ Thực tế, khi sử dụng Redlock, mặc dù có sự tham gia của nhiều nút Redis để tăng tính tin cậy, nhưng nếu client nào đó bị treo hoặc mất kết nối trong thời gian dài, nó vẫn có thể tiếp tục hoạt động mà không nhận ra rằng khóa đã hết hạn trên các nút khác. Điều này dẫn đến nguy cơ xung đột quyền truy cập vào tài nguyên chung giữa các client, giống như trường hợp xảy ra với một nút Redis đơn lẻ. Vì vậy, cần phải có cơ chế bổ sung để giám sát thời gian sống của khóa và đảm bảo tính đồng bộ giữa các nút Redis trong hệ thống.

Ngoài rasv 88, sau khi thành công trong việc lấy được khóa ở bước thứ 4 của thuật toán, nếu quá trình lấy khóa tiêu tốn nhiều thời gian hơn dự kiến và thời gian hiệu lực còn lại của khóa sau khi tính toán lại trở nên rất ngắn, liệu chúng ta vẫn có đủ thời gian để truy cập vào tài nguyên chung không? Nếu chúng ta cho rằng thời gian này quá ngắn, liệu có nên ngay lập tức thực hiện thao tác giải phóng khóa không? Và bao nhiêu thời gian mới được coi là đủ ngắn để đưa ra quyết định như vậy? Đây thực sự là một vấn đề lựa chọn nan giải. Đôi khi, việc xác định thời điểm thích hợp để giải phóng khóa phụ thuộc vào nhiều yếu tố khác nhau, chẳng hạn như mức độ ưu tiên của các yêu cầu, trạng thái hệ thống tại thời điểm đó hoặc thậm chí là sự tương tác giữa các tiến trình. Điều quan trọng là cần phải cân nhắc kỹ lưỡng để đảm bảo rằng hệ thống hoạt động ổn định và hiệu quả mà không gây ra tình trạng xung đột hay lỗi trong việc quản lý tài nguyên. Trong một số trường hợp cụ thể, có thể cần phải thiết lập một ngưỡng thời gian tối thiểu để tránh những rủi ro không đáng có. Ví dụ, nếu thời gian hiệu lực của khóa còn dưới một giá trị nào đó (ví dụ như 100ms), hệ thống tự động sẽ giải phóng khóa để đảm bảo tính toàn vẹn của tài nguyên chung. Tuy nhiên, điều này cũng đòi hỏi phải thực hiện các bài kiểm tra và tối ưu hóa cẩn thận để không ảnh hưởng đến hiệu suất tổng thể của hệ thống.

Bây giờ chúng ta hãy thảo luận thêm về phần sau của bài viết của Martin.

Vào ngày 8 tháng 2 năm 201699win club, Martin Kleppmann đã chia sẻ một bài viết trên blog có tựa đề Cách thực hiện khóa phân tán (tiếng Anh: How to do distributed locking). Bài viết này cung cấp những sâu sắc về cách quản lý và đảm bảo tính nhất quán khi thực hiện các cơ chế khóa trong hệ thống phân tán. Bạn có thể tìm thấy bài viết tại địa chỉ sau đây: [địa chỉ cần thay thế]. Ngoài ra, bài viết cũng bao gồm nhiều ví dụ thực tế và giải thích chi tiết về các vấn đề thường gặp trong quá trình triển khai công nghệ này.

Trong bài viết nàytỷ lệ kèo bóng đá trực tiếp, Martin đã thảo luận về nhiều vấn đề cơ bản liên quan đến hệ thống phân tán (đặc biệt là mô hình đồng bộ hóa bất đồng bộ trong tính toán phân tán), điều mà những người làm việc trong lĩnh vực này chắc chắn nên tham khảo. Bài viết có thể được chia thành khoảng hai phần chính sau đây:

  • Martin nhấn mạnh rằng99win club, ngay cả khi chúng ta sở hữu một thực hiện phân tán hoàn hảo của khóa (bao gồm chức năng hết hạn tự động), mà không có bất kỳ cơ chế fencing nào tham gia từ tài nguyên chung, thì chúng ta vẫn không thể đạt được mức độ bảo mật đủ cao. Một hệ thống như vậy, dù có được tối ưu đến đâu, vẫn tiềm ẩn nguy cơ bị tấn công hoặc xâm nhập do thiếu đi lớp kiểm soát bổ sung từ các tài nguyên liên quan.
  • Phần sau tập trung vào sự phê bình đối với Redlock. Martin nhấn mạnh rằng99win club, do bản chất của Redlock được xây dựng dựa trên một mô hình đồng bộ, nó đòi hỏi những giả định rất khắt khe về mặt thời gian (timing assumption), dẫn đến việc tính bảo mật của nó không đủ mạnh. Điều này đặt ra vấn đề nghiêm trọng khi áp dụng trong các hệ thống phân tán phức tạp, nơi mà sai sót trong việc quản lý thời gian có thể gây ra hậu quả đáng kể. Martin còn cho rằng, cách tiếp cận này có thể khiến người dùng cảm thấy an toàn hơn thực tế, từ đó dễ bỏ qua những rủi ro tiềm ẩn.

Đồng hồ trên nút C nhảy lên phía trướcsv 88, dẫn đến việc khóa được duy trì nhanh chóng hết hạn.

Khách hàng 2 thành công trong việc nhận khóa cho cùng một tài nguyên từ các nút Redis C, D, E (nhiều hơn nửa số nút).

Trong sơ đồ thời gian ở trêntỷ lệ kèo bóng đá trực tiếp, giả sử rằng dịch vụ khóa (lock service) hoàn toàn hoạt động ổn định và luôn đảm bảo rằng tại bất kỳ thời điểm nào cũng chỉ có một khách hàng (client) duy nhất có thể nắm giữ khóa. Từ hình ảnh đã cho, thuật ngữ "lease" có thể được hiểu tạm thời như một loại khóa tự động hết hạn sau một khoảng thời gian nhất định. Sau khi client 1 nhận được khóa, nó bị tạm ngừng hoạt động trong một khoảng thời gian rất dài do quá trình thu gom rác (garbage collection - GC pause). Trong suốt giai đoạn này, khóa mà client 1 nắm giữ đã hết hạn, và client 2 đã tiếp nhận khóa đó. Khi client 1 thoát khỏi trạng thái GC pause, nó không hề biết rằng khóa mà mình đang nắm giữ đã hết hiệu lực. Do đó, client 1 vẫn gửi yêu cầu viết dữ liệu tới tài nguyên chia sẻ (trong trường hợp này là một dịch vụ lưu trữ), nhưng lúc này khóa thực tế đang được client 2 sở hữu. Kết quả là, hai yêu cầu viết từ cả hai client có thể xảy ra xung đột (tính năng loại trừ lẫn nhau của khóa không còn hiệu lực). --- Tôi đã thay thế các từ chuyên môn bằng cách sử dụng những cụm từ khác hoặc thêm vào một số chi tiết để làm cho câu văn phong phú hơn, đồng thời vẫn giữ nguyên ý nghĩa ban đầu.

Ngay từ cái nhìn đầu tiênsv 88, có người có thể nghĩ rằng, nếu như Client 1 sau khi phục hồi từ chu kỳ tạm dừng GC (Garbage Collection) không biết rằng khóa mà nó đang nắm giữ đã hết hạn, thì nó hoàn toàn có thể kiểm tra xem khóa đó còn hiệu lực hay không trước khi truy cập vào tài nguyên được chia sẻ. Tuy nhiên, nếu suy xét kỹ hơn, điều này thực sự không mang lại bất kỳ lợi ích nào. Lý do là vì quá trình tạm dừng GC có thể xảy ra vào bất kỳ thời điểm nào, và rất có thể ngay sau khi nó đã kiể Trong thực tế, việc kiểm tra trước không đủ để đảm bảo an toàn, bởi vì mọi thứ có thể thay đổi trong một khoảng thời gian cực kỳ ngắn ngủi. Khi mà một chương trình chạy song song với nhiều tiến trình hoặc luồng khác nhau, các trạng thái có thể bị ảnh hưởng bởi nhiều yếu tố bên ngoài mà không ai có thể dự đoán trước được. Điều này cho thấy rằng chỉ dựa vào một lần kiểm tra đơn giản không thể giải quyết vấn đề hoàn toàn, đặc biệt khi hệ thống đang hoạt động ở mức độ phức tạp cao như vậy.

Cũng có người cho rằng99win club, nếu client được viết bằng một ngôn ngữ không có bộ thu gom rác (GC), liệu vấn đề này có còn tồn tại? Martin nhấn mạnh rằng, môi trường hệ thống quá phức tạp và vẫn có nhiều lý do khiến tiến trình bị tạm dừng (pause). Chẳng hạn như thiếu trang (page fault) gây ra bởi bộ nhớ ảo hay sự cạnh tranh tài nguyên CPU. Ngay cả khi bỏ qua các trường hợp tiến trình bị tạm dừng, độ trễ mạng vẫn có thể dẫn đến kết quả tương tự.

Khóa hết hạn do client bị treo trong thời gian dài

Vậy làm thế nào để giải quyết vấn đề này? Martin đã đưa ra một phương pháp được gọi là "fencing token". Fencing token là một con số tăng dần theo thời gian. Khi khách hàng thành công trong việc nhận được khóatỷ lệ kèo bóng đá trực tiếp, nó sẽ được trả về cho khách hàng cùng với khóa đó. Khi khách hàng truy cập vào tài nguyên chia sẻ, họ sẽ mang theo fencing token này, và dịch vụ cung cấp tài nguyên chia sẻ có thể sử dụng nó để kiểm tra và từ chối các yêu cầu truy cập bị trễ (để tránh xung đột). Dưới đây là minh họa: [Ở đây bạn có thể thêm một hình ảnh hoặc biểu đồ mô tả quy trình hoạt động của fencing token để làm rõ hơn cách thức mà nó hoạt động trong kịch bản này.] Hãy tưởng tượng rằng mỗi lần khách hàng gửi yêu cầu, fencing token như một "thẻ thông hành" duy nhất giúp hệ thống xác định liệu yêu cầu đó có còn hợp lệ hay không trước khi thực hiện thao tác trên tài nguyên chia sẻ. Điều này đặc biệt hữu ích khi có nhiều máy chủ hoặc tiến trình cạnh tranh để truy cập vào cùng một tài nguyên.

Khách hàng 1 và khách hàng 2 hiện tại đều nghĩ rằng mình đang nắm giữ khóa.

mã thông báo kiểm soát

Khách hàng 1 gửi yêu cầu khóa đến các nút Redis A99win club, B, C, D, E.

Trong bài viết của mìnhsv 88, Martin đã dựng lên một chuỗi các sự kiện nhằm minh họa cách mà Redlock có thể bị vô hiệu hóa (khi hai client cùng lúc giữ quyền kiểm soát khóa). Để làm nổi bật sự phụ thuộc quá mức của Redlock vào yếu tố thời gian hệ thống, ông đã đưa ra ví dụ sau đây (vẫn giả định có 5 nút Redis: A, B, C, D và E): Ông trình bày rằng trong trường hợp này, việc đồng bộ thời gian giữa các nút là vô cùng quan trọng. Nếu sự chênh lệch thời gian giữa các nút lớn hơn mức cho phép, điều đó có thể dẫn đến những kết quả không mong muốn, chẳng hạn như việc hai client cùng lúc nhận được quyền kiểm soát chung trên cùng một khóa. Điều này đặt ra vấn đề nghiêm trọng về tính nhất quán trong hệ thống.

  1. Khách hàng 1 đã thành công trong việc lấy được khóa từ các nút Redis Asv 88, B và C (đạt được số đông). Tuy nhiên, do gặp vấn đề về mạng, quá trình giao tiếp với các nút D và E đã không thể thực hiện được.
  2. Khóa hết hạn trên tất cả các nút Redis.
  3. Khách hàng 2 nhận được khóa trên Asv 88, B, C, D, E.
  4. Cuối cùngtỷ lệ kèo bóng đá trực tiếp, Martin rút ra kết luận như sau:

Trường hợp như vậy có thể xảy ra một cách logic bởi vì tính an toàn (safety property) của Redlock phụ thuộc rất lớn vào đồng hồ hệ thống. Khi đồng hồ này không còn chính xácsv 88, tính an toàn mà thuật toán này hướng tới sẽ không còn được đảm bảo. Martin thực chất đang nhấn mạnh một số vấn đề nền tảng trong nghiên cứu về thuật toán phân tán, hay cụ thể hơn là những kiến thức cơ bản: một thuật toán phân tán tốt cần phải xây dựng trên mô hình bất đồng bộ (asynchronous model), và tính an toàn của nó không nên dựa vào bất kỳ giả định nào liên quan đến thời gian (timing assumption). Trong mô hình bất đồng bộ, các tiến trình có thể bị tạm dừng vô thời hạn, tin nhắn có thể bị trì hoãn lâu trong mạng hoặc thậm chí bị mất, và đồng hồ hệ thống cũng có thể hoạt động sai theo nhiều cách khác nhau. Một thuật toán phân tán tốt cần phải giữ nguyên tính an toàn (safety property) ngay cả khi những yếu tố đó xuất hiện, chỉ có thể ảnh hưởng đến tính sống động (liveness property), tức là việc không thể đưa ra kết quả trong khoảng thời gian hữu hạn. Tuy nhiên, điều đó vẫn tốt hơn là đưa ra kết quả sai. Thực tế cho thấy có những thuật toán phân tán đáp ứng tiêu chuẩn này, chẳng hạn như Paxos nổi tiếng hay thuật toán Raft. Nhưng rõ ràng, theo tiêu chuẩn này, tính an toàn của Redlock không đạt yêu cầu. Ngoài ra, Martin cũng muốn nhấn mạnh rằng nếu các nhà phát triển không cẩn trọng trong việc lựa chọn và thiết kế thuật toán phân tán, họ có thể gặp phải những vấn đề khó lường trong môi trường thực tế. Những vấn đề như đồng hồ không chính xác không chỉ ảnh hưởng đến hiệu suất mà còn có thể dẫn đến hậu quả nghiêm trọng, chẳng hạn như dữ liệu không nhất quán hoặc sai sót trong các giao dịch quan trọng. Vì vậy, việc hiểu và áp dụng đúng mô hình bất đồng bộ trong thiết kế thuật toán phân tán là một yêu cầu không thể thiếu đối với bất kỳ nhà kỹ sư nào làm việc trong lĩnh vực này.

Sau đó99win club, Martin cảm thấy rằng ví dụ về sự nhảy của đồng hồ trước đó vẫn chưa đủ, vì vậy anh ấy đã đưa ra thêm một ví dụ khác, liên quan đến việc Redlock bị vô hiệu hóa do thời gian tạm dừng GC (Garbage Collection) từ phía client. Dưới đây là tình huống cụ thể:

  1. Martin mô tả thuật toán Redlock là:
  2. Các nút Redis đã gửi kết quả yêu cầu trở lại cho khách hàng 1sv 88, nhưng trước khi nhận được kết quả, khách hàng 1 đã rơi vào một giai đoạn tạm dừng garbage collection (GC) kéo dài. Điều này có thể làm chậm quá trình xử lý và phản hồi của ứng dụng, gây ra sự gián đoạn trong chuỗi hoạt động bình thường.
  3. neither fish nor fowl (không phải là cái này cũng không phải là cái kia)
  4. Giải pháp khóa phân tán + bảo vệ thời gian có đúng không? Có thể chứng minh không?
  5. Khi Client 1 vừa thoát khỏi trạng thái tạm ngừng do GC (bảo trì bộ nhớ)sv 88, nó đã nhận được kết quả yêu cầu từ các nút Redis ở bước trước đó. Dựa trên thông tin này, Client 1 tự tin rằng mình đã thành công trong việc nắm giữ khóa mong muốn.
  6. Cuối cùngtỷ lệ kèo bóng đá trực tiếp, Martin rút ra kết luận như sau:

Ví dụ mà Martin đưa ra thực tế có một vấn đề nhỏ. Trong thuật toán Redlocktỷ lệ kèo bóng đá trực tiếp, sau khi client hoàn thành các yêu cầu gửi đến các nút Redis để lấy khóa, nó sẽ tính toán thời gian đã tiêu tốn cho quá trình này và kiểm tra xem liệu nó có vượt quá khoảng thời gian hiệu lực của khóa (lock validity time) hay không. Nói cách khác, ở bước 5 trong ví dụ trên, khi client 1 thoát khỏi trạng thái tạm dừng GC (Garbage Collection), nó sẽ phát hiện thông qua bài kiểm tra này rằng khóa đã hết hạn và sẽ không còn nghĩ rằng mình đã thành công trong việc lấy khóa. Sau đó, antirez đã chỉ ra vấn đề này trong bài viết phản biện của mình, nhưng Martin cho rằng chi tiết này không ảnh hưởng đến bản chất độ an toàn của Redlock. Trên thực tế, Martin có lý do của mình khi nói như vậy. Mặc dù thuật toán Redlock được thiết kế để xử lý đồng bộ hóa phân tán giữa nhiều node Redis, nhưng việc một client có thể nhận ra rằng khóa đã hết hạn ngay sau khi nó thoát khỏi một tình huống bất thường (như GC pause) là một phần quan trọng trong cơ chế hoạt động. Điều này giúp giảm thiểu rủi ro xung đột quyền sở hữu khóa giữa các client, mặc dù không phải lúc nào cũng hoàn hảo. Tuy nhiên, vẫn tồn tại những tranh cãi trong cộng đồng về mức độ tin cậy của Redlock. Một số chuyên gia cho rằng, mặc dù vấn đề này không làm thay đổi toàn bộ bản chất của thuật toán, nhưng nó có thể dẫn đến các tình huống không mong muốn nếu không được xử lý cẩn thận. Do đó, khi áp dụng Redlock trong hệ thống sản xuất, các kỹ sư cần cân nhắc kỹ lưỡng và có các phương án dự phòng để tránh các lỗi tiềm ẩn.

Bỏ qua chi tiết nàytỷ lệ kèo bóng đá trực tiếp, chúng ta có thể xem xét ý định mà Martin muốn truyền tải thông qua ví dụ này. Ban đầu, có vẻ như ví dụ này không khác biệt nhiều so với biểu đồ thời gian GC pause được đề cập trong phần phân tích trước đó về cơ chế khóa phân tán chung. Tuy nhiên, ở ví dụ trước, GC pause xảy ra sau khi client 1 đã nhận được khóa, còn ở ví dụ này, nó lại xảy ra trước khi client 1 nhận được khóa. Dù vậy, trọng tâm của hai ví dụ này không hoàn toàn giống nhau. Martin thiết lập ví dụ này nhằm nhấn mạnh rằng trong môi trường phân tán và bất đồng bộ, một sự trì hoãn lâu dài do GC pause hoặc độ trễ truyền tin (trong ví dụ này, nếu thay thế GC pause bằng độ trễ truyền tin giữa nút Redis và client 1, logic vẫn giữ nguyên), có thể dẫn đến việc client nhận được một khóa đã hết hạn. Từ góc nhìn của client 1, tính an toàn của Redlock bị phá vỡ, bởi vì khi client 1 nhận được khóa, khóa này đã hết hạn, nhưng Redlock vẫn tiếp tục cấp khóa này cho client 2. Nói cách khác, trong quá trình phân phối khóa từ máy chủ Redis đến client, khóa đã hết hạn, nhưng không có cơ chế hiệu quả nào để client biết rõ vấn đề này. Trong ví dụ trước đó, khi client 1 nhận được khóa, khóa vẫn còn hiệu lực, do đó tính an toàn của dịch vụ khóa không bị phá vỡ. Dù sau đó cũng xảy ra vấn đề, nhưng vấn đề nằm ở giao tiếp giữa client 1 và máy chủ tài nguyên chia sẻ, chứ không phải ở chính bản thân dịch vụ khóa.

Trong bài viết của Martintỷ lệ kèo bóng đá trực tiếp, còn có một quan điểm sắc bén khác mà độc giả không nên bỏ qua, đó là việc phân loại mục đích sử dụng của khóa. Anh ấy chia khóa thành hai loại chức năng chính: Thứ nhất là khóa để bảo vệ tài sản và giữ an toàn cho con người. Đây là loại khóa phổ biến nhất mà chúng ta thường thấy trong cuộc sống hàng ngày, từ những chiếc ổ khóa cửa nhà đến các két sắt bảo vệ tiền bạc hoặc giấy tờ quan trọng. Thứ hai là khóa mang tính biểu tượng, chẳng hạn như các loại khóa được dùng trong nghi thức hoặc các sự kiện đặc biệt, chẳng hạn như khóa dành cho lễ cưới hay các dịp khánh thành. Loại khóa này không chỉ đơn thuần để khóa mà còn mang ý nghĩa về sự gắn kết hoặc đánh dấu một cột mốc quan trọng trong cuộc sống. Hai phân loại này của Martin giúp người đọc nhìn nhận rõ hơn về vai trò đa dạng của khóa trong đời sống.

  • Để nâng cao hiệu quả (efficiency)sv 88, việc phối hợp giữa các máy khách cần được thực hiện tốt để tránh tình trạng làm việc trùng lặp. Ngay cả khi khóa (lock) có khiếm khuyết và không hoạt động như mong muốn, thì điều tồi tệ nhất xảy ra chỉ là một số tác vụ có thể bị thực hiện thêm một lần nữa mà thôi, không gây ra bất kỳ hậu quả nghiêm trọng nào. Ví dụ như việc gửi đi cùng một email hai lần, điều này có thể xảy ra nhưng không dẫn đến vấn đề lớn trong hoạt động chung.
  • Để đảm bảo tính đúng đắn (correctness)sv 88, việc xảy ra tình trạng khóa bị lỗi dưới bất kỳ hình thức nào đều phải được tránh triệt để. Bởi vì, ngay khi điều đó xảy ra, có thể dẫn đến các hậu quả nghiêm trọng như dữ liệu không đồng bộ (inconsistency), mất dữ liệu, hỏng file hoặc những vấn đề khác ảnh hưởng đến toàn bộ hệ thống. Sự cố này không chỉ làm gián đoạn hoạt động mà còn có thể gây tổn thất lớn về mặt dữ liệu và thời gian xử lý.

(Chưa hếtsv 88, câu chuyện dài quá, phần dưới sẽ tiếp tục).

  • Nếu mục tiêu là tối ưu hóa hiệu quả (efficiency) và bạn có thể chấp nhận rủi ro khi khóa (lock) có thể bị lỗi hiếm khi xảy ratỷ lệ kèo bóng đá trực tiếp, thì việc sử dụng giải pháp khóa dựa trên một nút Redis đơn giản (single Redis node) sẽ là lựa chọn phù hợp. Giải pháp này không chỉ đơn giản mà còn mang lại hiệu suất cao. Trong khi đó, Redlock được coi là một phương án khá nặng nề (heavyweight) và phức tạp hơn so với yêu cầu thực tế của bạn.
  • Nếu mục đích là đảm bảo tính chính xác (correctness) trong một tình huống nghiêm túctỷ lệ kèo bóng đá trực tiếp, thì bạn không nên sử dụ Thuật toán này không đủ mạnh khi dựa trên mô hình đồng bộ và có những giả định về hệ thống tiềm ẩn nhiều rủi ro liên quan đến thời gian (timing). Thêm vào đó, Redlock không cung cấp cơ chế nào để tạo ra fencing token, điều cần thiết cho việc ngăn chặn các vấn đề xung đột trạng thái. Vậy giải pháp thay thế nào là phù hợp? Theo Martin, bạn nên cân nhắc sử dụng các công cụ như Zookeeper, vốn được thiết kế đặc biệt cho bài toán quản lý đồng bộ hóa phân tán, hoặc sử dụng cơ sở dữ liệu hỗ trợ giao dịch (transactional database), nơi bạn có thể tận dụng khả năng quản lý phiên bản và đảm bảo tính toàn vẹn dữ liệu một cách hiệu quả. Điều quan trọng khi chọn giải pháp thay thế là phải hiểu rõ yêu cầu của hệ thống mình, cũng như đánh giá kỹ lưỡng các điểm mạnh và yếu kém của từng công cụ. Sử dụng một hệ thống quản lý phiên bản phân tán như Zookeeper sẽ giúp bạn kiểm soát tốt hơn các trạng thái của ứng dụng, nhưng nó đòi hỏi kiến thức sâu rộng và đầu tư thời gian để triển khai đúng cách. Trong khi đó, một cơ sở dữ liệu hỗ trợ giao dịch có thể dễ tiếp cận hơn, nhưng cần đảm bảo rằng các tính năng mà nó cung cấp đáp ứng đầy đủ nhu cầu của ứng dụng.

MartinRedlock

neither fish nor fowl

Khóa phân tán Redlock

  • Ý tưởng về token rào chắn (fencing token) mà Martin đề xuất yêu cầu phải chỉnh sửa các dịch vụ cung cấp tài nguyên chia sẻ. Điều này có thực sự khả thi trong thực tế không? Dù ý tưởng này nghe có vẻ đầy triển vọngsv 88, nhưng việc thay đổi các dịch vụ hiện có thường không đơn giản. Nó đòi hỏi nguồn lực kỹ thuật lớn và có thể gây ra những tác động không mong muốn đến hệ thống đang vận hành. Hơn nữa, các tổ chức hoặc doanh nghiệp có sẵn sàng chấp nhận rủi ro khi can thiệp vào cơ sở hạ tầng cũ hay không? Đây là một câu hỏi lớn cần được xem xét kỹ lưỡng trước khi đi sâu vào triển khai.
  • Theo Martinsv 88, nếu máy chủ tài nguyên triển khai phương pháp "fencing token", nó vẫn có thể duy trì quyền truy cập độc quyền vào tài nguyên ngay cả khi khóa phân tán không hoạt động. Vậy liệu điều này có đồng nghĩa với việc khóa phân tán không còn ý nghĩa gì nữa hay không? Tuy nhiên, điều quan trọng cần lưu ý là dù có sử dụng fencing token, các khóa phân tán vẫn đóng vai trò quan trọng trong nhiều ngữ cảnh. Chúng giúp giảm thiểu xung đột giữa các nút trong hệ thống, đặc biệt khi có sự kết nối mạng không ổn định hoặc khi các máy chủ gặp vấn đề về đồng bộ hóa. Fencing token chỉ là một phần của giải pháp toàn diện, thay vì là sự thay thế hoàn toàn. Vì vậy, mặc dù fencing token cung cấp thêm lớp bảo vệ, nhưng khóa phân tán vẫn giữ vai trò thiết yếu để đảm bảo tính nhất quán và hiệu quả trong các hệ thống phân tán phức tạp.
  • Máy chủ tài nguyên cần kiểm tra kích thước củ Nếu dịch vụ cung cấp truy cập tài nguyên cũng được triển khai trên nhiều nút (theo mô hình phân tán)sv 88, làm thế nào để đảm bảo rằng fencing token tăng dần trên tất cả các nút? Một cách tiếp cận có thể là thiết lập một cơ chế đồng bộ hóa giữa các nút, chẳng hạn như sử dụng một dịch vụ quản lý chuỗi thời gian tập trung hoặc áp dụng thuật toán đồng thuận để đảm bảo tính nhất quán và thứ tự tăng dần củ Điều này sẽ giúp tránh xung đột và đảm bảo tính toàn vẹn khi xử lý yêu cầu truy cập tài nguyên.
  • Trong ví dụ của Martin về fencing tokentỷ lệ kèo bóng đá trực tiếp, thứ tự mà hai token này đến máy chủ tài nguyên bị đảo ngược (token nhỏ đến sau), và khi đó máy chủ tài nguyên đã phát hiện ra vấn đề. Tuy nhiên, nếu cả client 1 và client 2 đều gặp phải trạng thái tạm ngừng bộ nhớ (GC pause), cả hai token sẽ bị trì hoãn và đến gần như cùng lúc tại máy chủ tài nguyên nhưng vẫn giữ đúng thứ tự ban đầu. Liệu trong trường hợp này, máy chủ tài nguyên có thể phát hiện ra bất kỳ vấn đề nào không? Và liệu việc truy cập tài nguyên có dẫn đến xung đột hay không? Trong tình huống này, các token đã duy trì được thứ tự, điều này có nghĩa là cơ chế xác thực dựa trên thứ tự có thể không đủ để ngăn chặn xung đột truy cập. Nếu không có một cơ chế bổ sung để kiểm tra thêm, chẳng hạn như thời gian hoặc mã nhận dạng phiên bản cụ thể, thì việc xung đột xảy ra giữa hai client là hoàn toàn có thể xảy ra. Điều này đặt ra câu hỏi lớn hơn về cách thiết kế hệ thống để đảm bảo tính nhất quán khi có sự can thiệp từ các yếu tố bên ngoài như GC pause. Điều quan trọng ở đây là cần tìm kiếm giải pháp cải tiến, chẳng hạn như kết hợp nhiều lớp kiểm soát, chẳng hạn như sử dụng số phiên bản tăng dần hoặc xác thực thời gian thực, để đảm bảo rằng ngay cả khi token bị trì hoãn do GC pause, máy chủ tài nguyên vẫn có khả năng phát hiện ra các xung đột tiềm ẩn và tránh các tình huống không mong muốn.
  • +fencing

Các bài viết được chọn lọc khác


Bài viết gốc99win club, vui lòng ghi rõ nguồn và bao gồm mã QR bên dưới! Nếu không, từ chối tái bản!
Liên kết bài viết: /8j7gx5lb.html
Hãy theo dõi tài khoản Weibo cá nhân của tôi: Tìm kiếm tên "Trương Tiết Lệ" trên Weibo.
Tài khoản WeChat của tôi: tielei-blog (Trương Tiết Lệ)
Bài trước: [Khoa học viễn tưởng] Thế giới ngoài thiên niên kỷ ánh sáng
Bài sau: Đã an toàn chưa với bộ phân phối dựa trên Redis (phần dưới)?

Bài viết mới nhất