Redis cung cấp hai cơ chế để xử lý giao dịch - giao dịch dựa trên MULTI / EXEC và đánh giá tập lệnh Lua. Tập lệnh Redis Lua là cách tiếp cận được khuyến nghị và được sử dụng khá phổ biến.
Khách hàng Redis ™ của chúng tôi đã triển khai tập lệnh Lua thường báo cáo lỗi này - “ BẬT MÍ Redis đang bận chạy một tập lệnh. Bạn chỉ có thể gọi SCRIPT KILL hoặc SHUTDOWN NOSAVE ”. Trong bài đăng này, chúng tôi sẽ giải thích thuộc tính giao dịch Redis của tập lệnh, lỗi này là gì và tại sao chúng tôi phải hết sức cẩn thận về nó trên các hệ thống do Sentinel quản lý có thể chuyển đổi dự phòng.
Bản chất giao dịch của Tập lệnh Redis Lua
Redis “giao dịch” thực sự không phải là giao dịch như được hiểu theo cách thông thường - trong trường hợp có lỗi, sẽ không có bản ghi nào được thực hiện bởi tập lệnh.
“Tính nguyên tử” của các tập lệnh Redis được đảm bảo theo cách sau:
- Khi một tập lệnh bắt đầu thực thi, tất cả các lệnh / tập lệnh khác sẽ bị chặn cho đến khi tập lệnh hoàn tất. Vì vậy, những khách hàng khác có thể thấy những thay đổi do tập lệnh thực hiện hoặc họ không thấy. Điều này là do chúng chỉ có thể thực thi trước tập lệnh hoặc sau tập lệnh.
- Tuy nhiên, Redis không khôi phục, vì vậy nếu xảy ra lỗi trong tập lệnh, mọi thay đổi mà tập lệnh đã thực hiện sẽ được giữ lại và các lệnh / tập lệnh trong tương lai sẽ thấy những thay đổi một phần đó.
- Vì tất cả các ứng dụng khách khác đều bị chặn trong khi tập lệnh thực thi, điều quan trọng là tập lệnh phải hoạt động tốt và kết thúc đúng lúc.
Giá trị ‘lua-time-limit’
Chúng tôi khuyên bạn nên hoàn thành tập lệnh trong một thời hạn. Redis thực thi điều này một cách yếu ớt với giá trị "lua-time-limit". Đây là thời gian tối đa cho phép (tính bằng mili giây) mà tập lệnh được phép chạy. Giá trị mặc định là 5 giây. Đây là một khoảng thời gian thực sự dài đối với hoạt động liên quan đến CPU (các tập lệnh có quyền truy cập hạn chế và không thể chạy các lệnh truy cập đĩa).
Tuy nhiên, tập lệnh không bị hủy khi thực thi quá thời gian này. Redis bắt đầu chấp nhận các lệnh của khách hàng một lần nữa, nhưng phản hồi lại các lệnh đó với lỗi BỀN.
Nếu bạn phải hủy tập lệnh tại thời điểm này, có hai tùy chọn có sẵn:
- GIẾT LỪA ĐẢO lệnh có thể được sử dụng để dừng một tập lệnh chưa thực hiện bất kỳ quá trình ghi nào.
- Nếu tập lệnh đã thực hiện ghi vào máy chủ và vẫn phải bị hủy, hãy sử dụng SHUTDOWN NOSAVE để tắt hoàn toàn máy chủ.
Thông thường tốt hơn là bạn chỉ cần đợi tập lệnh hoàn thành hoạt động của nó. Thông tin đầy đủ về các phương pháp để loại bỏ việc thực thi tập lệnh và hành vi liên quan có sẵn trong tài liệu.
Redis Giao dịch &Tập lệnh Lua dài hạnNhấp vào TweetHành vi trên các Hệ thống sẵn có cao do Sentinel giám sát
Hệ thống tính sẵn sàng cao do Sentinel quản lý tạo thêm một điểm nhấn mới cho vấn đề này. Trên thực tế, cuộc thảo luận này áp dụng cho bất kỳ hệ thống có tính khả dụng cao nào phụ thuộc vào việc thăm dò tình trạng của các máy chủ Redis:
- Các tập lệnh chạy dài ban đầu sẽ chặn các lệnh của khách hàng. Sau đó, khi hết "lua-time-limit", máy chủ sẽ bắt đầu phản hồi với lỗi BẬN.
- Sentinels sẽ coi một nút như vậy là không khả dụng và nếu điều này vẫn tiếp diễn vượt quá giá trị không hoạt động sau mili giây được định cấu hình trên Sentinels, họ sẽ xác định nút ngừng hoạt động.
- Nếu một nút như vậy là nút chính, quá trình chuyển đổi dự phòng sẽ được bắt đầu. Một nút bản sao có thể được thăng cấp và có thể bắt đầu chấp nhận các kết nối mới từ khách hàng.
- Trong khi đó, bản chính cũ hơn cuối cùng sẽ hoàn tất việc thực thi tập lệnh và trở lại trực tuyến. Tuy nhiên, Sentinel cuối cùng sẽ cấu hình lại nó như một bản sao và nó sẽ bắt đầu đồng bộ hóa với bản chính mới. Mọi dữ liệu do tập lệnh viết sẽ bị mất.
|
Trình diễn
Chúng tôi thiết lập một hệ thống có tính khả dụng cao nhạy cảm để chứng minh hành vi chuyển đổi dự phòng này. Thiết lập có 2 máy chủ Redis chạy trong cấu hình chính / bản sao đang được giám sát bởi túc số 3 người gửi.
Giá trị lua-time-limit được đặt thành 500 ms để nó bắt đầu phản hồi các ứng dụng khách có lỗi nếu tập lệnh chạy lâu hơn 500 ms. Giá trị giảm xuống sau mili giây trên Sentinels được đặt thành 5 giây để nút báo cáo lỗi được đánh dấu XUỐNG sau 5 giây.
Chúng tôi thực thi tập lệnh Lua sau trên bản chính:
local i = 0 while (true) do local key = "Key-" .. i local value = "Value-" .. i redis.call('set', key, value) i = i + 1 redis.call('time') end
Thao tác này tiếp tục ghi các mục nhập vào Redis master. Chúng tôi đăng ký tham gia các sự kiện trên một trong các đội canh gác để quan sát hành vi.
Tập lệnh được khởi tạo trên trang cái:
$ redis-cli -a --eval test.lua Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
Đây là một chuỗi các hoạt động được cắt ngắn như đã thấy trên Sentinel:
3) "+vote-for-leader" 4) "9096772621089bb885eaf7304a011d9f46c5689f 1" 1) "pmessage" 2) "*" 3) "+sdown" <<< master marked DOWN 4) "master test 172.31.2.48 6379" 1) "pmessage" 2) "*" 3) "+odown" 4) "master test 172.31.2.48 6379 #quorum 3/2" 1) "pmessage" 2) "*" 3) "-role-change" << role change initiated 4) "slave 172.31.28.197:6379 172.31.28.197 6379 @ test 172.31.2.48 6379 new reported role is master" 1) "pmessage" 2) "*" 3) "+config-update-from" 4) "sentinel 9096772621089bb885eaf7304a011d9f46c5689f 172.31.2.48 26379 @ test 172.31.2.48 6379" 1) "pmessage" 2) "*" 3) "+switch-master" 4) "test 172.31.2.48 6379 172.31.28.197 6379"
Sau đó, khi bản gốc cũ được đưa lên mạng, nó sẽ được đổi thành bản sao:
3) "-role-change" 4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379 new reported role is master" 1) "pmessage" 2) "*" 3) "-sdown" 4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379" 1) "pmessage" 2) "*" 3) "+role-change" 4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379 new reported role is slave"
Tất cả dữ liệu được ghi vào bản chính cũ thông qua tập lệnh đều bị mất.
Đề xuất
- Bạn phải biết trước các đặc điểm của các tập lệnh dài hạn của mình trước khi triển khai chúng trong sản xuất.
- Nếu tập lệnh của bạn thường xuyên vi phạm giới hạn thời gian lua, bạn phải xem lại tập lệnh kỹ lưỡng để có thể tối ưu hóa. Bạn cũng có thể chia nhỏ thành nhiều phần để hoàn thành trong khoảng thời gian có thể chấp nhận được.
- Nếu bạn phải chạy các tập lệnh vi phạm giới hạn thời gian lua, hãy cân nhắc lên lịch cho các tập lệnh này trong những khoảng thời gian mà hoạt động của khách hàng khác sẽ thấp.
- Giá trị của giới hạn thời gian lua cũng có thể được tăng lên. Đây sẽ là một giải pháp có thể chấp nhận được nếu các ứng dụng khách khác thực thi song song với tập lệnh có thể chấp nhận việc nhận phản hồi cực kỳ chậm trễ hơn là lỗi BẬN và thử lại sau.
Các cân nhắc bổ sung về hệ thống sẵn sàng cao do Sentinel giám sát:
- Nếu các tập lệnh chỉ thực hiện các thao tác đọc và bạn có sẵn các bản sao, bạn có thể di chuyển các tập lệnh này sang các bản sao.
Thay đổi thông số Sentinel xuống sau mili giây thành một giá trị sẽ đảm bảo rằng quá trình chuyển đổi dự phòng không được bắt đầu. Bạn chỉ phải thực hiện việc này sau khi đã cân nhắc kỹ lưỡng vì việc tăng giá trị mạnh mẽ sẽ ảnh hưởng đến các đặc tính sẵn có cao của hệ thống của bạn. Điều này cũng có thể gây ra lỗi máy chủ chính hãng bị bỏ qua.
|