ПрограммированиеФорумСеть

Использование запросов к базе данных в отдельном потоке (2 стр)

Страницы: 1 2 3 Следующая »
#15
19:37, 27 мая 2010

AntonV
> У меня около 10 млн объектов, которые иногда надо обрабатывать. Создать индексы
> по всем полям? В необходимые 10 мс точно не уложусь.
10миллионов объектов надо обрабоать за 10мс.? может расскажешь поподробней что за задача? есть подозрение что ты ее решаешь через зад...

#16
1:30, 28 мая 2010

При чем тут зад? На геймдеве когда-нибудь научатся вежливости и желанию помочь, а главное читать? Написал вроде четко. Есть долгий запрос, который не должен вешать логику игры. Логика должна работать с 10 мс шагами. База обычно отвечает дольше, поэтому, как тема звучит БАЗА В ОТДЕЛЬНОМ ПОТОКЕ. И как этот результат нормально получить в одном из 10 возможных мест, в этом и заключается вопрос.

#17
2:40, 28 мая 2010

Какие-то вопросы и сами постеры последние дни на геймдеве неадекватные...
Один память распределил, не может освободить, другой пишет "движок" и не отличает геймплей от материала 3Д поверхности, а этот миллионы объектов за 10 мс обработать хочет.

Простые запросы можно сразу прямо в коде игры или в параллельном треде одном на всех делать, база быстро отвечает, справится если что можно второй, третий и так далее пустить. Логин и пароль проверяться должны за 1-2 мс, да и нельзя ставить в поток логики постоянные запросы к базе - вся ценная инфа должна по возможности быть загружена в память и там оставаться, а время запроса к базе данных паролей в таймер логики не должно вписываться, логин вообще операция медленная.
Выгружать данные игрока можно ленивой задачей, независимо от хода игры, раз в минуту например. Загружать один раз, медленно, при логине.
Если не хватает скорости файловой базы - ставь мемкеш, довешивай памяти на машинку.
Долгие обработки вообще нельзя во время игры делать, запускай их отдельно по таймеру, может вообще в другом процессе, чтоб с игрой не мешаться.

#18
3:13, 28 мая 2010

иш студенты накинулись. Квакушка и Клоун, великие заклинатели конспектов :)))

ну хочет он поставить запросы к базе в отдельном потоке, хочет. и правильно делает. бывают такие случаи, когда это удобно и хорошо работает. в логин сервере как раз, совершенно не нужно никакое кеширование.

#19
10:02, 28 мая 2010

kvakvs
> а этот миллионы объектов за 10 мс обработать хочет
Я такого не писал. У меня запросы иногда по 200-300 мс. Такие задержки для логики неприемлемы.

#20
11:23, 28 мая 2010

AntonV
Ключевая идея - не делать в главном цикле логики запросов к базе. Ни на чтение, ни на запись.
То есть продублировать функционал доступный из базы через кэш в памяти.
Долгие запросы (списки друзей, гильдия, поиск товаров в магазине или аукционе) делаются отдельным тредом или даже процессом, и возвращают результат спустя много циклов логики, через функцию callback.

#21
12:16, 28 мая 2010

Кэшировать базу невозможно. Запросы подобны запросам в Гугле - следующий запрос будет абсолютно не похож на предыдущие. Ответ в принципе ясен, только не понятно какой из возможных вариантов лучше:

1. Логика делает запрос в базу и получает через колбек результат когда запрос завершится - некую структуру и ее тип. Необходимо создать столько объектов, сколько вариантов база может возвратить. Нужен список игроков - нужна структура DbPlayerList. Нужны питомцы - DbPetList. Объекты - DbObjectList. Нужен статус игрока - DbPlayerStatus. Статус проверки логина - DbLoginStatus. Плохо создавать десятки структур... Да и если посылать 10 запросов по очереди, не ясно ответ на какой приходит первым (через ThreadPool и подобные). Пример:
void callback(CbType type, void* data)
{
    if(type == PLAYER_STATUS)
    {
    }
    else if(type == ONLINE_PLAYERS)
    {
    }
}

2. Запрашивать поток базы - типа addDatabaseTask(this). А у базы крутится отдельный поток, который вызовет колбек у this. И уже в самом колбеке идут долгие обращения к базе и получается результат который необходим. Хотим в определенной очередности обработать запросы - в этом колбеке делаем хоть 100 запросов. Их порядок выполнения гарантируется.

void callback()
{
    if(logic.state == ACTIVE)
    {
        if(database.isPlayerOnline(player))
        {
            player.setVisibleObjects(database.getVisibleObjects(player));
        }
    }
}

#22
12:34, 28 мая 2010

AntonV
> Кэшировать базу невозможно
Ой, да ладно. Возможно, память нынче недорогая, ставится отдельно сервер, набивается туда 128 ГБ памяти, или сколько влезет.
Ты зачем тему создал, если и так всё ясно ;) Мы не переубедим тебя.

Вариант 2 выглядит более упорядоченным. Но тогда не получится получить результат запроса к базе сразу же, потому не получится писать прямой код if (базаданных.чтото) { делать чтото }, придётся создавать колбек и ждать прихода результата в него.

Для колбеков с разными структурами данных в параметрах бери boost::bind. Тогда все колбеки с любыми параметрами можно привести к одному виду, например void callback (CDatabaseQueryResult * r); а дополнительные параметры, и даже при необходимости this для функций-членов класса, связываются bind'ом, можно состояние хранить в полях класса, а this вклеить в boost::bind.

class CUser
{
public:
  void Login (const std::string & login, const std::string & passwd);

protected:
  void OnLoginCheck (CDatabaseQueryResult * r);
};

void CUser::Login (const std::string & login, const std::string & passwd)
{
  std::string q =  "SELECT COUNT(*) FROM users WHERE login=\"" + DB::Quote (login) + "\"";
  DB::Query (q,  boost::bind (& CUser::OnLoginCheck, this, _1));
}

void CUser::OnLoginCheck (CDatabaseQueryResult * r)
{
  if (r.RowCount == 0)
  { 
    Socket.Send (new CErrorMessage ("Login failed"));
    return;
  }

  ура, логин удачный;
}
#23
12:50, 28 мая 2010

kvakvs
> Ты зачем тему создал, если и так всё ясно ;) Мы не переубедим тебя.
Тема какой заголовок имеет? Про отдельный поток. Не про мое знание и оптимизацию работы с базами. Не про кэширование.

P.S. Ну хорошо, купить сотню гигабайт памяти, загнать всю базу в оперативку в виде, чтобы было удобно осуществлять поиск. Тогда возникает вопрос: а база зачем? Можно все хранить в файле и грузить сразу в игровые данные в виде, который удобен. Когда-то я заявлял на геймдеве, что играм база и не нужна, можно хранить все прямо в игре. Меня опять назвали (как обычно бывает на геймдеве) умалишенным и т.п.

#24
13:10, 28 мая 2010

AntonV
Кэш в памяти желателен, и в целом нужен. И база нужна. Вдруг чо, омон набежит, сервер рухнет, свет выключат, второй-третий-пятый сервер понадобится установить, загружать данные только из базы. В памяти хранить хорошо, но отдельная задача должна периодически из памяти сливать всё в базу.

А если без кэша, то как делать колбеки я свои 5 копеек сказал в посте #22

#25
16:09, 28 мая 2010

Может лучше тогда не связывать часть где требуется быстрота  с базой данных ?

#26
16:11, 28 мая 2010

>Сомневаюсь, что она сделает выборку из 100 тысяч строк, с сортировкой, и при этом сразу вернет управление.
Это называется ошибки проектирования. И решать их надо не отдельным потоком, а прямыми руками, ИМХО.

>Создать индексы по всем полям?
Не по всем, а по ключевым.

>В необходимые 10 мс точно не уложусь.
Про кэширование выше верно упомянули - если это не научные расчеты (а это не они - я уверен), то пользователю глубоко пофиг, придут ли его данные сейчас или через следующие 10 мсек или даже 30 мсек.

С записью в базу ещё проще - тут можно спокойно потерять 0.5-1 сек, т.е. делать не 100 раз в секунду, а всего 1 или реже. К тому же, писать надо только информацию, которая изменилась, т.е. крошечную долю % от общего объёма данных.

>У меня запросы иногда по 200-300 мс. Такие задержки для логики неприемлемы.
Давно придуман нормальный вариант решение проблемы - выполняем задачу длиной 200 мсек, потом 20 раз апдейтим логику - на глаз разница заметна крайне редко (а если код не кривой - её вообще не должно быть).

Ну и коллбэки, конечно, это вполне даже вариант, если уж совсем приспичило....

#27
16:12, 28 мая 2010

мну тож гнетёт это , пока ещё не решёный вопрос:  "где разумный предел  использования СУБД ?"

Если запросов будет много , то бд сюдет на задницу..    Или расширять СУБД ?  (аля кластеризовать) .

#28
23:35, 28 мая 2010

AntonV
> При чем тут зад? На геймдеве когда-нибудь научатся вежливости и желанию помочь,
> а главное читать? Написал вроде четко.
если этот запрос такой долгий - ему не место в реал-тайм сервере. долгие запросы - это либо группировка либо хотябы сортировка, большого набора данных. где это нужно в игре? а если наборы данных маленькие - то запрос не должен быть медленным. а если медленный - значит ты делаешь выборку не по индексированным полям!
зы.
если это нужно для админики какой-нибудь - тут логично вынести всю админку в отдельный поток ))

#29
23:39, 28 мая 2010

А верно ли то, что при быстрой выборке по индексированым полям    вставка напротив медленее ?
(логично, но так ли это ?).

Страницы: 1 2 3 Следующая »
ПрограммированиеФорумСеть

Тема в архиве.