我需要使用RedisLocks(ServiceStack.Redis)吗?

时间:2017-10-03 21:14:02

标签: caching servicestack servicestack.redis

  • 我目前在自动缩放的aws中有一个API,所以我可以运行7到12个服务。
  • 我的客户经理正在builder.register<IRedisClientsManager>(c => new PooledRedisClientManager(conection));
  • 我的客户正在做redis.GetCacheClient();
  • 设置我正在做的缓存条目: cache_client.Set<T>(generate_key<T>(key), values, TimeSpan.FromSeconds(ttl.Value));

  • 要获取我正在执行的缓存条目: using (var read_only_client = this.redis.GetReadOnlyClient()) { return read_only_client.GetValue(generate_key<T>(key)); }

ISSUE =&gt;我收到了无效的缓存值格式错误的JSON和错误放置的文本。

问题=&gt;我得到无效缓存值的原因是因为我需要在设置或获取缓存值之前使用Redis锁????

1 个答案:

答案 0 :(得分:1)

您很少需要使用RedisLocks来实现自定义分布式锁定。所有Redis操作都是原子操作,如果需要以原子方式发送多个操作,可以使用Redis Transactions或实现LUA脚本。

如果没有看到完整的Exception详细信息或损坏的数据,则问题很可能是在多个线程中重用相同的Redis Client实例。 IRedisClientsManager是ThreadSafe,应该注册为单例,但它返回的客户端实例不是ThreadSafe,不应在多个线程之间共享,用作单例,存储在静态变量中等。 为确保正确使用,每个使用它们的线程都应解决它们并

using (var redis = redisManager.GetClient())
{
    //...
}

Redis Client and Cache Registration Example

您应该将IRedisClientsManagerICacheClient注册为单身人士,例如:

container.Register<IRedisClientsManager>(c => 
    new RedisManagerPool(connection));

container.Register(c => c.Resolve<IRedisClientsManager>().GetCacheClient());

鉴于Redis ICacheClient是ThreadSafe,问题出在您的代码的另一个区域,您在多个线程中使用相同的Redis实例。请务必仔细查看Redis的所有用法,以确保每个Redis客户端都得到妥善处理,而不是在不同的线程之间共享。

如果在正确使用库的情况下问题仍然存在,请将一个独立的示例项目(例如GitHub)放在一起,我们可以运行该项目以查看问题,我们将对其进行审核。