StackExchange.Redis - LockTake/LockRelease 用法 [英] StackExchange.Redis - LockTake / LockRelease Usage

查看:126
本文介绍了StackExchange.Redis - LockTake/LockRelease 用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将 Redis 与 StackExchange.Redis 一起使用.我有多个线程将在某个时候访问和编辑同一个键的值,所以我需要同步数据的操作.

I am using Redis with StackExchange.Redis. I have multiple threads that will at some point access and edit the value of the same key, so I need to synchronize the manipulation of the data.

查看可用函数,我看到有两个函数,TakeLock 和 ReleaseLock.然而,这些函数需要一个键和一个值参数,而不是预期的要锁定的单个键.GitHub 上的智能文档和源代码没有解释如何使用 LockTake 和 LockRelease 函数或为 key 和 value 参数传递什么.

Looking at the available functions, I see that there are two functions, TakeLock and ReleaseLock. However, these functions take both a key and a value parameter rather than the expected single key to be locked. The intellisene documentation and source on GitHub don't explain how to use the LockTake and LockRelease functions or what to pass in for the key and value parameters.

问:StackExchange.Redis 中 LockTake 和 LockRelease 的正确用法是什么?

我的目标的伪代码示例:

Pseudocode example of what I'm aiming to do:

//Add Items Before Parallel Execution
redis.StringSet("myJSONKey", myJSON);

//Parallel Execution
Parallel.For(0, 100, i =>
    {
        //Some work here
        //....

        //Lock
        redis.LockTake("myJSONKey");

        //Manipulate
        var myJSONObject = redis.StringGet("myJSONKey");
        myJSONObject.Total++;
        Console.WriteLine(myJSONObject.Total);
        redis.StringSet("myJSONKey", myNewJSON);

        //Unlock
        redis.LockRelease("myJSONKey");

        //More work here
        //...
    });

推荐答案

锁有 3 个部分:

  • 密钥(数据库中锁的唯一名称)
  • 值(调用者定义的令牌,可用于指示谁拥有"锁,并检查释放和扩展锁是否正确完成)
  • 持续时间(有意锁定是有限持续时间的东西)

如果没有想到其他值,guid 可能会生成一个合适的值".我们倾向于使用机器名(如果多个进程可以在同一台机器上竞争,则使用机器名的修改版).

If no other value comes to mind, a guid might make a suitable "value". We tend to use the machine-name (or a munged version of the machine name if multiple processes could be competing on the same machine).

另外,请注意获取锁是推测性,而不是阻塞.您完全有可能未能获得锁,因此您可能需要对此进行测试并添加一些重试逻辑.

Also, note that taking a lock is speculative, not blocking. It is entirely possible that you fail to obtain the lock, and hence you may need to test for this and perhaps add some retry logic.

一个典型的例子可能是:

A typical example might be:

RedisValue token = Environment.MachineName;
if(db.LockTake(key, token, duration)) {
    try {
        // you have the lock do work
    } finally {
        db.LockRelease(key, token);
    }
}

请注意,如果工作很长(尤其是循环),您可能希望在中间添加一些偶尔的 LockExtend 调用 - 再次记住检查是否成功(以防超时).

Note that if the work is lengthy (a loop, in particular), you may want to add some occasional LockExtend calls in the middle - again remembering to check for success (in case it timed out).

还要注意所有单独的 redis 命令是原子的,因此您不必担心两个谨慎的操作相互竞争.对于更复杂的多操作单元,transactionsscripting 是选项.

Note also that all individual redis commands are atomic, so you don't need to worry about two discreet operations competing. For more complexing multi-operation units, transactions and scripting are options.

这篇关于StackExchange.Redis - LockTake/LockRelease 用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆