Để tìm hiểu thêm về tại sao xóa đối tượng lớn chậm trong Redis, hãy đọc tổng quan nhanh này
Để xóa một hash lớn trong Redis:
-
Đổi tên khóa thành một khóa duy nhất, có namespace để hash xuất hiện như "đã xóa" đối với các Redis client khác ngay lập tức.
-
Xóa tăng dần các trường (fields) từ hash theo lô nhỏ cho đến khi nó rỗng. Bằng cách giới hạn kích thước các lệnh xóa, chúng ta đảm bảo không chặn server quá lâu.
Lưu ý rằng mã sau không xử lý nhẹ nhàng các lỗi kết nối Redis. Nếu bất kỳ lệnh Redis nào thất bại và ném ngoại lệ, bạn sẽ cần dọn dẹp thủ công.
Mã Giả (Pseudo-code)
# Đổi tên khóa
newkey = "gc:hashes:" + redis.INCR("gc:index")
redis.RENAME("my.hash.key", newkey)
# Xóa trường từ hash theo lô 100
cursor = 0
loop
cursor, hash_keys = redis.HSCAN(newkey, cursor, "COUNT", 100)
if hash_keys count > 0
redis.HDEL(newkey, hash_keys)
end
if cursor == 0
break
end
end
Ruby
$redis = Redis.new
def delete_hash(key)
# Đổi tên khóa
newkey = "gc:hashes:#{$redis.incr("gc:index")}"
$redis.rename(key, newkey)
# Xóa trường từ hash theo lô 100
cursor = "0"
loop do
cursor, fields = $redis.hscan(newkey, cursor, count: 100)
hkeys = fields.map { |pair| pair[0] }
$redis.hdel(newkey, hkeys) if hkeys.size > 0
break if cursor == "0"
end
end
# Ví dụ:
# delete_hash("my.large.hash")
Dưới đây là một số ví dụ triển khai trên sử dụng background jobs trong Ruby:
- Resque
- Sidekiq
← Quay lại "Xóa Đối Tượng Lớn Trong Redis"