Мы оцениваем db4o (OO-СУБД из http://www.db4o.com).). Мы собрали тест производительности для режима клиент / сервер, где мы раскручиваем сервер, а затем забиваем его несколькими клиентами одновременно. Похоже, что сервер может обрабатывать только один клиентский запрос за раз.
Мы где-то пропустили переключатель конфигурации, который учитывает этот сценарий? Реализация сервера ниже. Клиент подключается, запрашивает (только для чтения) и отключается для каждой операции, и операции выполняются один за другим сразу из нескольких рабочих потоков в клиентском процессе. Мы видим такое же поведение, если мы раскручиваем один клиентский процесс с одним рабочим на одном сервере.
Есть предложения?
Edit: мы теперь обнаружили и опробовали Lazy и Snapshot QueryModes, и хотя это частично (частично) устраняет проблему с блокирующим сервером, мы по-прежнему видим значительные проблемы с параллелизмом, когда наши клиенты (мы запускаем 40 одновременных тестовых клиентов которые ждут 1-300 мс, прежде чем выдать случайный запрос операции) забивают на сервер. По-видимому, существуют исключения, исходящие от поставщика LINQ и внутренних устройств ввода-вывода: - (
public class Db4oServer : ServerConfiguration, IMessageRecipient
{
private bool stop;
#region IMessageRecipient Members
public void ProcessMessage(IMessageContext con, object message)
{
if (message is StopDb4oServer)
{
Close();
}
}
#endregion
public static void Main(string[] args)
{
//Ingestion.Do();
new Db4oServer().Run(true, true);
}
public void Run(bool shouldIndex, bool shouldOptimizeNativeQueries)
{
lock (this)
{
var cfg = Db4oFactory.NewConfiguration();
if (shouldIndex)
{
cfg.ObjectClass(typeof (Sequence))
.ObjectField("<ChannelID>k__BackingField")
.Indexed(true);
cfg.ObjectClass(typeof (Vlip))
.ObjectField("<ChannelID>k__BackingField")
.Indexed(true);
}
if (shouldOptimizeNativeQueries)
{
cfg.OptimizeNativeQueries(true);
}
var server = Db4oFactory.OpenServer(cfg, FILE, PORT);
server.GrantAccess("0", "kieran");
server.GrantAccess("1", "kieran");
server.GrantAccess("2", "kieran");
server.GrantAccess("3", "kieran");
//server.Ext().Configure().ClientServer().SingleThreadedClient(false);
server.Ext().Configure().MessageLevel(3);
server.Ext().Configure().Diagnostic().AddListener(new DiagnosticToConsole());
server.Ext().Configure().ClientServer().SetMessageRecipient(this);
try
{
if (!stop)
{
Monitor.Wait(this);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
server.Close();
}
}
public void Close()
{
lock (this)
{
stop = true;
Monitor.PulseAll(this);
}
}
}