Страницы

Поиск по вопросам

пятница, 7 июня 2019 г.

Как работает Redis при одновременном доступе нескольких клиентов?

Первый клиент (локальный) пишет в список редис строку 50 байт 20 раз в секунду. Допустим набрали 200 000 строк = 10 мегабайт Второй клиент пытается получить первые 100 000 строк. Передача через инет займет какое-то время. Что в это время происходит с первым клиентом?


Ответ

Все операции в Redis атомарны.
Версионности в Redis, насколько я знаю, нет.
Следовательно, будет блокировка: пока один клиент читает данные, второй будет ждать.

Цитата:
пишет в список
Если речь именно о списках - List, то общий размер списка не будет влиять на работу клиентов: один клиент пишет данные в список, другой клиент читает. Как я уже сказал ранее, одному из клиентов приходится ждать, пока завершится операция другого. Но общий размер списка не влияет на это, ведь другой клиент будет читать за раз одну короткую строку размером 50 байт, а не всё содержимое списка разом.
Я попытался проиллюстрировть это следующим кодом на C#:
using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using StackExchange.Redis;
namespace ConAppRedis { class Program { static void Main(string[] args) { ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost,allowAdmin=true"); redis.GetServer("localhost", 6379).FlushAllDatabases();
var are = new AutoResetEvent(false); const int count = 10000; RedisKey key = "key";
var t1 = Task.Run(() => { IDatabase db = redis.GetDatabase(); var list = new List(); are.WaitOne();
for (int i = 0; i < count; i++) { list.Add(db.ListRightPop(key)); } });
var t2 = Task.Run(() => { IDatabase db = redis.GetDatabase(); var s = new string('a', 25); // 50 bytes
for (int i = 0; i < count * 2; i++) { db.ListLeftPush(key, s); if (i == count) { are.Set(); } } Console.WriteLine(db.ListLength(key)); });
Task.WaitAll(t1, t2); } } }
Запускаются две задачи (клиента): первая сперва ждёт разрешения на старт (его выдаст вторая задача, записав половину данных), потом начинает считывать данные.
Вторая задача пишет данные в список. В конце эта задача получает текущий размер списка и выводит его. Значение каждый раз разное, что естественно, и равно где-то 10055.
То есть к тому времени когда вторая задача заканчивает записывать 20000 значений, первая уже успела прочитать почти половину. Следовательно, они обращались к серверу по очереди совместно.

А вот если бы речь шла о конкатенации одной строки с помощью APPEND, что приводило бы к её увеличению, то вторая задача довольно долго ждала бы, когда первая будет получать её полностью за раз (иначе никак).

Комментариев нет:

Отправить комментарий