Một cách để giải quyết vấn đề này là sử dụng kịch bản Lua phía máy chủ.
Hãy xem xét kịch bản sau đây:
local res = {}
local result = {}
local tmp = redis.call('zrange', KEYS[1], 0, -1, 'withscores')
for i=1,#tmp,2 do
res[tmp[i+1]]=true
end
for k,_ in pairs(res) do
table.insert(result,k)
end
return result
Bạn có thể thực hiện nó bằng cách sử dụng lệnh EVAL.
Nó sử dụng lệnh zrange để trích xuất nội dung của zset (với điểm số), sau đó nó xây dựng một bộ (được biểu diễn bằng một bảng trong Lua) để loại bỏ điểm dư thừa và cuối cùng xây dựng bảng trả lời. Vì vậy, các giá trị của zset không bao giờ được gửi qua mạng.
Kịch bản này có một lỗ hổng nếu số lượng mục trong zset thực sự cao, bởi vì nó sao chép toàn bộ zset trong đối tượng Lua (vì vậy nó có bộ nhớ). Tuy nhiên, nó rất dễ dàng để thay đổi nó để lặp lại trên zset tăng dần (20 mục cho mỗi 20 mặt hàng). Ví dụ:
local res = {}
local result = {}
local n = redis.call('zcard', KEYS[1])
local i=0
while i<n do
local tmp = redis.call('zrange', KEYS[1], i, i+20, 'withscores')
for j=1,#tmp,2 do
res[tmp[j+1]]=true
i = i + 1
end
end
for k,_ in pairs(res) do
table.insert(result,k)
end
return result
Xin lưu ý Tôi là tổng số người mới ở Lua, vì vậy có lẽ có nhiều cách thanh lịch hơn để đạt được điều tương tự.
tôi biết rằng, nhưng vấn đề là các v alues là quá lớn trong trường hợp của tôi, nó là vấn đề để theo dõi chỉ có điểm số. – biztiger
@biztiger Đã cập nhật. Rõ ràng không phải là giải pháp hoàn hảo, nhưng là một giải pháp khả thi nếu bạn thực sự cần chức năng. –