2015-02-11 2 views
2

У меня недавно возникли проблемы с Service Stack - я выяснил, что это, по-видимому, вызвано наличием нескольких потоков, каждый из которых подключается к Redis для выполнения операций. Если у меня есть только один поток, который работает в любой момент, он работает нормально, но уже и я получаю несколько разных ошибок. Я видел в другом месте, что лучше всего использовать PooledRedisClientManager и вызывать GetClient на нем, но это все еще вызывает у меня проблемы. Я просто хотел бы знать, является ли Redis потокобезопасным и какие шаги вы можете предпринять, чтобы гарантировать, что он не будет разбиваться на параллельные потоки.Защита потолка Service Stack Redis соединений

Я создал программу специально для тестирования этого, что ниже.

class Program 
{ 
    static IRedisClient redis = new PooledRedisClientManager(ConfigurationManager.AppSettings["RedisServer"]).GetClient(); 

    static void Main(string[] args) 
    { 
     LimitedConcurrencyLevelTaskScheduler scheduler = new LimitedConcurrencyLevelTaskScheduler(10); 

     List<Task> tasks = new List<Task>(); 

     // Create a TaskFactory and pass it our custom scheduler. 
     TaskFactory factory = new TaskFactory(scheduler); 

     for (int i = 0; i < 100; i++) 
     { 
      Task task = factory.StartNew(() => AsyncMethod1(i)); 
      tasks.Add(task); 
     } 

     Task.WaitAll(tasks.ToArray()); 

     for (int i = 0; i < 100; i++) 
     { 
      Task task2 = factory.StartNew(() => AsyncMethod2(i)); 
      tasks.Add(task2); 
     } 

     Task.WaitAll(tasks.ToArray()); 

     Console.ReadKey(); 
    } 

    public static void AsyncMethod1(int i) 
    { 
     redis.SetEntry("RedisTest" + i, "TestValue" + i); 
    } 

    public static void AsyncMethod2(int i) 
    { 
     List<string> result = redis.ScanAllKeys("RedisTest" + i).ToList(); 
     if (result[0] == "RedisTest" + i) Console.Out.Write("Success! " + result[0] + "\n"); 
     else Console.Out.Write("Failure! " + result[0] + " :(\n"); 
    } 
} 

ответ

3

Вы не должны делиться экземплярами RedisClient по нескольким потокам, поскольку они не являются ThreadSafe. Вместо этого вы должны разрешить и освободить их от поточных менеджеров клиентов Redis - also mentioned in the docs.

+1

Большое спасибо за это. Вместо этого я использую RedisManagerPool и получаю клиент для каждого потока. Нет проблем. У меня также были проблемы, потому что я сосать многопоточность - мне нужно было пройти локальные переменные, и когда я не добрался до 100 штук. Во всяком случае, эта проблема решена довольно хорошо. Btw, спасибо за ServiceStack сам - впечатляющий кусок работы. – PointlessSpike

Смежные вопросы