Redis
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> Redis

API RedisClient LUA

IRedisClient Các API cho hỗ trợ LUA phía máy chủ redis đã được tái phân tích thành các API thân thiện với người dùng hơn bên dưới:

public interface IRedisClient 
{
    //Eval/Lua operations 
    T ExecCachedLua<T>(string scriptBody, Func<string, T> scriptSha1);

    RedisText ExecLua(string body, params string[] args);
    RedisText ExecLua(string luaBody, string[] keys, string[] args);
    RedisText ExecLuaSha(string sha1, params string[] args);
    RedisText ExecLuaSha(string sha1, string[] keys, string[] args);

    string ExecLuaAsString(string luaBody, params string[] args);
    string ExecLuaAsString(string luaBody, string[] keys, string[] args);
    string ExecLuaShaAsString(string sha1, params string[] args);
    string ExecLuaShaAsString(string sha1, string[] keys, string[] args);
    
    int ExecLuaAsInt(string luaBody, params string[] args);
    int ExecLuaAsInt(string luaBody, string[] keys, string[] args);
    int ExecLuaShaAsInt(string sha1, params string[] args);
    int ExecLuaShaAsInt(string sha1, string[] keys, string[] args);

    List<string> ExecLuaAsList(string luaBody, params string[] args);
    List<string> ExecLuaAsList(string luaBody, string[] keys, string[] args);
    List<string> ExecLuaShaAsList(string sha1, params string[] args);
    List<string> ExecLuaShaAsList(string sha1, string[] keys, string[] args);

    string CalculateSha1(string luaBody);
    
    bool HasLuaScript(string sha1Ref);
    Dictionary<string, bool> WhichLuaScriptsExists(params string[] sha1Refs);
    void RemoveAllLuaScripts();
    void KillRunningLuaScript();
    string LoadLuaScript(string body);
}

QUÉT hiệu quả trong LUA #

API C # bên dưới trả về 10 kết quả đầu tiên khớp với khóa key:* mẫu:

var keys = Redis.ScanAllKeys(pattern: "key:*", pageSize: 10)
    .Take(10).ToList();

Tuy nhiên, C # Streaming API ở trên yêu cầu số lượng Thao tác Redis không xác định (được giới hạn với số lượng khóa trong Redis) để hoàn thành yêu cầu. Có thể giảm số lượng cuộc gọi SCAN bằng cách chọn pageSize cao hơn để yêu cầu Redis quét nhiều khóa hơn mỗi khi thao tác QUÉT được gọi.

Vì số lượng lệnh gọi API có khả năng dẫn đến một số lượng lớn Hoạt động của Redis, nên nó có thể dẫn đến độ trễ không thể chấp nhận được do độ trễ của nhiều cuộc gọi mạng từ xa phụ thuộc. Một giải pháp dễ dàng thay thế là thực hiện nhiều cuộc gọi SCAN trong quá trình trên Máy chủ Redis, loại bỏ độ trễ mạng của nhiều cuộc gọi SCAN, ví dụ:

const string FastScanScript = @"
local limit = tonumber(ARGV[2])
local pattern = ARGV[1]
local cursor = 0
local len = 0
local results = {}
repeat
    local r = redis.call('scan', cursor, 'MATCH', pattern, 'COUNT', limit)
    cursor = tonumber(r[1])
    for k,v in ipairs(r[2]) do
        table.insert(results, v)
        len = len + 1
        if len == limit then break end
    end
until cursor == 0 or len == limit
return results";

RedisText r = redis.ExecLua(FastScanScript, "key:*", "10");
r.Children.Count.Print() //= 10

ExecLua API trả về phản hồi bảng LUA phức tạp này trong Children bộ sưu tập của RedisText Phản hồi.

Phản hồi API phức hợp thay thế #

Một cách khác để trả về cấu trúc dữ liệu phức tạp trong hoạt động LUA là tuần tự hóa kết quả dưới dạng JSON

return cjson.encode(results)

Cái mà bạn có thể truy cập dưới dạng JSON thô bằng cách phân tích cú pháp phản hồi dưới dạng Chuỗi với:

string json = redis.ExecLuaAsString(FastScanScript, "key:*", "10");

THÔNG TIN

Đây cũng là cách tiếp cận được sử dụng trong RedisServices của Redis React.

ExecCachedLua #

ExecCachedLua là một API cấp cao thuận tiện giúp loại bỏ việc ghi sổ kế toán cần thiết để thực thi Tập lệnh LUA của máy chủ hiệu suất cao gặp phải nhiều vấn đề mà các thủ tục được lưu trữ RDBMS gặp phải, tùy thuộc vào trạng thái tồn tại trước trong RDBMS cần được cập nhật với phiên bản mới nhất của Quy trình được lưu trữ.

Với Redis LUA, bạn có tùy chọn gửi, phân tích cú pháp, tải rồi thực thi toàn bộ tập lệnh LUA mỗi khi nó được gọi hoặc cách khác, bạn có thể tải trước Tập lệnh LUA vào Redis một lần trên StartUp và sau đó thực thi nó bằng cách sử dụng hàm băm SHA1 của tập lệnh. Vấn đề với điều này là nếu máy chủ Redis vô tình bị xóa, bạn sẽ bị bỏ lại với một ứng dụng bị hỏng dựa trên một tập lệnh có sẵn không còn ở đó nữa. ExecCachedLua mới API cung cấp tính năng tốt nhất của cả hai thế giới, nơi nó sẽ luôn thực thi tập lệnh SHA1 đã biên dịch, tiết kiệm băng thông và CPU nhưng cũng sẽ tạo lại Tập lệnh LUA nếu nó không còn tồn tại.

Thay vào đó, bạn có thể thực thi tập lệnh LUA đã biên dịch ở trên bằng số nhận dạng SHA1 của nó, tập lệnh này tiếp tục hoạt động bất kể nó chưa từng tồn tại hoặc đã bị xóa trong thời gian chạy, ví dụ:

// #1: Loads LUA script and caches SHA1 hash in Redis Client
r = redis.ExecCachedLua(FastScanScript, sha1 =>
    redis.ExecLuaSha(sha1, "key:*", "10"));

// #2: Executes using cached SHA1 hash
r = redis.ExecCachedLua(FastScanScript, sha1 =>
    redis.ExecLuaSha(sha1, "key:*", "10"));

// Deletes all existing compiled LUA scripts 
redis.ScriptFlush();

// #3: Executes using cached SHA1 hash, gets NOSCRIPT Error, 
//     re-creates then re-executes the LUA script using its SHA1 hash
r = redis.ExecCachedLua(FastScanScript, sha1 =>
    redis.ExecLuaSha(sha1, "key:*", "10"));

Ví dụ Sử dụng #

Đây là cách bạn có thể triển khai ZPOP trong Lua để xóa các mục có xếp hạng thấp nhất khỏi tập hợp đã sắp xếp:

var luaBody = @"
    local val = redis.call('zrange', KEYS[1], 0, ARGV[1]-1)
    if val then redis.call('zremrangebyrank', KEYS[1], 0, ARGV[1]-1) end
    return val";

var i = 0;
var alphabet = 26.Times(c => ((char)('A' + c)).ToString());
alphabet.ForEach(x => Redis.AddItemToSortedSet("zalphabet", x, i++));

//Remove the letters with the lowest rank from the sorted set 'zalphabet'
var letters = Redis.ExecLuaAsList(luaBody, keys: new[] { "zalphabet" }, args: new[] { "3" });
letters.PrintDump(); //[A, B, C]

Và cách triển khai ZREVPOP để xóa các mục có thứ hạng cao nhất khỏi một nhóm đã sắp xếp:

var luaBody = @"
    local val = redis.call('zrange', KEYS[1], -ARGV[1], -1)
    if val then redis.call('zremrangebyrank', KEYS[1], -ARGV[1], -1) end
    return val";

var i = 0;
var alphabet = 26.Times(c => ((char)('A' + c)).ToString());
alphabet.ForEach(x => Redis.AddItemToSortedSet("zalphabet", x, i++));

//Remove the letters with the highest rank from the sorted set 'zalphabet'
List<string> letters = Redis.ExecLuaAsList(luaBody, 
    keys: new[] { "zalphabet" }, args: new[] { "3" });

letters.PrintDump(); //[X, Y, Z]

Các ví dụ khác #

Trả lại int :

int intVal = Redis.ExecLuaAsInt("return 123"); //123
int intVal = Redis.ExecLuaAsInt("return ARGV[1] + ARGV[2]", "10", "20"); //30

Trả lại một chuỗi string :

//Hello, Redis Lua!
var strVal = Redis.ExecLuaAsString(@"return 'Hello, ' .. ARGV[1] .. '!'", "Redis Lua");

Trả lại List trong số các chuỗi:

Enum.GetNames(typeof(DayOfWeek)).ToList()
    .ForEach(x => Redis.AddItemToList("DaysOfWeek", x));

var daysOfWeek = Redis.ExecLuaAsList("return redis.call('LRANGE', 'DaysOfWeek', 0, -1)");
daysOfWeek.PrintDump(); //[Sunday, Monday, Tuesday, ...]

Có thể tìm thấy thêm các ví dụ trong các bài kiểm tra Redis Eval Lua


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Không tìm thấy ổ cắm mô-đun lua

  2. Lưu vào bộ đệm các đối tượng JSON ở phía máy chủ

  3. Giới thiệu về cấu trúc dữ liệu Redis:Tập hợp được sắp xếp

  4. Chiến lược tốt nhất để đồng bộ dữ liệu Redis với MySQL là gì?

  5. doRedis với lỗi kết nối ổ cắm lạ trong Ubuntu Linux, R và RStudio