StackExchange.Redis
профилирование
Поиск…
замечания
Возможности профилирования StackExchange.Redis состоят из интерфейса IProfiler
и ConnectionMultiplexer.RegisterProfiler(IProfiler)
, ConnectionMultiplexer.BeginProfiling(object)
, ConnectionMultiplexer.FinishProfiling(object)
.
Начинайте и завершайте профилирование с помощью object
контекста, чтобы связанные команды можно группировать вместе.
Эта группировка работает, запрашивая ваш интерфейс IProfiler
для объекта контекста в начале команды, прежде чем произойдут какие-либо потоки с использованием потоковой передачи, и связывая эту команду с любыми другими командами, которые имеют один и тот же объект контекста. Begin должен вызываться с тем же контекстным объектом, что и StackExchange.Redis знает, чтобы запускать команды профилирования с этим объектом контекста, а Finish вызывается для остановки профилирования и возврата результатов.
Группировать все команды из набора потоков вместе
class ToyProfiler : IProfiler
{
public ConcurrentDictionary<Thread, object> Contexts = new ConcurrentDictionary<Thread, object>();
public object GetContext()
{
object ctx;
if(!Contexts.TryGetValue(Thread.CurrentThread, out ctx)) ctx = null;
return ctx;
}
}
// ...
ConnectionMultiplexer conn = /* initialization */;
var profiler = new ToyProfiler();
var thisGroupContext = new object();
conn.RegisterProfiler(profiler);
var threads = new List<Thread>();
for (var i = 0; i < 16; i++)
{
var db = conn.GetDatabase(i);
var thread =
new Thread(
delegate()
{
var threadTasks = new List<Task>();
for (var j = 0; j < 1000; j++)
{
var task = db.StringSetAsync("" + j, "" + j);
threadTasks.Add(task);
}
Task.WaitAll(threadTasks.ToArray());
}
);
profiler.Contexts[thread] = thisGroupContext;
threads.Add(thread);
}
conn.BeginProfiling(thisGroupContext);
threads.ForEach(thread => thread.Start());
threads.ForEach(thread => thread.Join());
IEnumerable<IProfiledCommand> timings = conn.FinishProfiling(thisGroupContext);
В конце тайминги будут содержать 16 000 объектов IProfiledCommand - по одному для каждой команды, выпущенной для redis.
Групповые команды, основанные на выпуске потока
ConnectionMultiplexer conn = /* initialization */;
var profiler = new ToyProfiler();
conn.RegisterProfiler(profiler);
var threads = new List<Thread>();
var perThreadTimings = new ConcurrentDictionary<Thread, List<IProfiledCommand>>();
for (var i = 0; i < 16; i++)
{
var db = conn.GetDatabase(i);
var thread =
new Thread(
delegate()
{
var threadTasks = new List<Task>();
conn.BeginProfiling(Thread.CurrentThread);
for (var j = 0; j < 1000; j++)
{
var task = db.StringSetAsync("" + j, "" + j);
threadTasks.Add(task);
}
Task.WaitAll(threadTasks.ToArray());
perThreadTimings[Thread.CurrentThread] = conn.FinishProfiling(Thread.CurrentThread).ToList();
}
);
profiler.Contexts[thread] = thread;
threads.Add(thread);
}
threads.ForEach(thread => thread.Start());
threads.ForEach(thread => thread.Join());
perThreadTimings
заканчивается 16 входами 1000 IProfilingCommands, с помощью Thread, которые их выпустили.