Нужна идея взаимодействия игрока и базы данных

Статус
В этой теме нельзя размещать новые ответы.

nesss

Путник
Участник
Сообщения
128
Розыгрыши
0
Решения
3
Репутация
-2
Реакции
14
Баллы
85
Хроники
  1. Interlude
Исходники
Присутствуют
Сборка
Собственная
Не знал куда лучше написать, вот пишу тут, сейчас обдумываю как связать игрока и БД наиболее оптимизированным способом, к примеру игрок обновил макрос, или создал эго, стоит ли обновлять это сразу в БД или может сделать метод и запускать его при выходе персонажа с игры и тем методом обновлять все, что связанно с персонажем, но если сервер потухнет, тогда вся инфа собранная сервером будет обнулена до момента эго запуска, или может частично обновлять сразу важную инфу, а скажем если чел экипировал оружие, то такую можно не обновлять. Ну в общем все в таком ключе, если есть минутка, можем вместе подумать )))
 
Можно использовать методику BatchUpdate. То есть берем и ждем по крайней мере десять секунд, и собираем всю информацию что-бы перекинуть ее в базу данных.

Я обычно просто применяю методику debounce. Там два типа временных интервалов, один на то сколько ждать перед тем как переслать данные в БД, а другой на сколько можно продолжить ожидание если обновления постоянно приходят. Не знаю как это можно написать на Яве, но самый простой принцип это пересылка данных через Х секунд. То есть что ты и описал.

Проблема и в Яве (синхронное сохранение данных через БД, так что процесс может просто тупо ждать и ничего не делать), да и в самой базе данных, так как обычно используют БД через какую-нибудь сеть. А если по сети переговариться, то и лаг появиться. Да и сетевые соединения тоже надо считать.... Но это так, к слову.
 
Ну это как вариант, но скажем если 1000 чел и более играет, одним махом всех обновить это будет хорошо подвисать думаю, а так идея норм, даже можно в списке онлайн в каждом из объектов создать флаг обновлять или нет персонажа, если он не сделал не каких действий, скажем стоит, тогда эго и трогать не нужно.

Вот смотри, я сделал к примеру с предметами так, у меня каждый предмет это отдельная строка в БД, там меняется идентификатор владельца, если передаю скажем эго, если я эго удаляю с инвентаря или выкидываю, просто меняется идентификатор владельца в БД на NULL, тем самым я не удаляю целую строку, просто меняю значение, так же легче БД. А когда рестарт делать буду, тогда все предметы с владельцем NULL очищу.
 
Можно и обнулить, но будут проблемы потом так как данные все-равно индексируются и таким образом могут повлиять на другие факторы в БД. Я бы посоветовал просто удалять и не оптимизировать что-либо в отношении данных, ну кроме их размера.

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

Так как Ява сервера обычно используют несколько потоков (thread) то можно всю логику сохранений данных перенести в дополнительный поток, что-бы если поток будет ждать ответа от БД, то он никак не повлияет на остальные функции сервера.
 
Вот смотри, я сделал к примеру с предметами так, у меня каждый предмет это отдельная строка в БД, там меняется идентификатор владельца, если передаю скажем эго, если я эго удаляю с инвентаря или выкидываю, просто меняется идентификатор владельца в БД на NULL, тем самым я не удаляю целую строку, просто меняю значение, так же легче БД. А когда рестарт делать буду, тогда все предметы с владельцем NULL очищу.
интересно откуда такая информация, если нет констрейнта, то удаление происходит практически так же как и UPDATE (иногда кстати даже быстрее), плюс выборки при использовании такого метода - логично будут идти медленнее (индексы то всё равно распухшие), если правильно указывать типы данных, и верно отправлять запросы, то никаких проблем с этим не будет.
как пример - стараться не хранить много полей с типом varchar (например, видел в некоторых сборках положение инвентаря указывалось с помощью varchar, а не enum).

База линейки - тупой набор циферок и имен персонажа, базовые методы реализованные уже во многих сборках более чем подходят (save при выходе + таймер, полная загрузка всего из базы данных в момент старта), забивать себе голову до появления явных проблем - так себе затея. Даже размер в 100мб (здесь я имею ввиду информацию о персонажах) - не всем покорится, говорить о бОльших размерах и не приходится.
 
Не знал куда лучше написать, вот пишу тут, сейчас обдумываю как связать игрока и БД наиболее оптимизированным способом, к примеру игрок обновил макрос, или создал эго, стоит ли обновлять это сразу в БД или может сделать метод и запускать его при выходе персонажа с игры и тем методом обновлять все, что связанно с персонажем, но если сервер потухнет, тогда вся инфа собранная сервером будет обнулена до момента эго запуска, или может частично обновлять сразу важную инфу, а скажем если чел экипировал оружие, то такую можно не обновлять. Ну в общем все в таком ключе, если есть минутка, можем вместе подумать )))
Кажется, вы уже хорошо подумали. Приоритетные изменения (большой эксп, ценный дроп) синхронизировать с БД сразу (об этом ниже). Менее приоритетное (расходники, соски, стрелы) - интервалами. Еще менее приоритетное (как вы заметили, тот же эквип) - синхронизировать при выходе или с бОльшими интервалами. Не забывать, что делиты дорогие, и использовать флаги или подобие.

По поводу "синхронизировать сразу". Конечно же лучше всего батчить. Например, в конце текущего фрейма ранлупа. Хотя серверов L2 с тикрейтом и ранлупом в публичном доступе я еще не встречал (что странно, это сильно упрощает игровую логику и добавляет больше контроля).
 
интересно откуда такая информация, если нет констрейнта, то удаление происходит практически так же как и UPDATE (иногда кстати даже быстрее), плюс выборки при использовании такого метода - логично будут идти медленнее (индексы то всё равно распухшие), если правильно указывать типы данных, и верно отправлять запросы, то никаких проблем с этим не будет.
как пример - стараться не хранить много полей с типом varchar (например, видел в некоторых сборках положение инвентаря указывалось с помощью varchar, а не enum).

База линейки - тупой набор циферок и имен персонажа, базовые методы реализованные уже во многих сборках более чем подходят (save при выходе + таймер, полная загрузка всего из базы данных в момент старта), забивать себе голову до появления явных проблем - так себе затея. Даже размер в 100мб (здесь я имею ввиду информацию о персонажах) - не всем покорится, говорить о бОльших размерах и не приходится.
Ну скажем, если я передаю предмет другому персонажу или выкидываю его, делаю 1 запрос в бд на замену владельца и готово, а если без этого, то мне нужно будет сначала удалить строчку с бд, а затем создать новую уже с другим владельцем.
Кажется, вы уже хорошо подумали. Приоритетные изменения (большой эксп, ценный дроп) синхронизировать с БД сразу (об этом ниже). Менее приоритетное (расходники, соски, стрелы) - интервалами. Еще менее приоритетное (как вы заметили, тот же эквип) - синхронизировать при выходе или с бОльшими интервалами. Не забывать, что делиты дорогие, и использовать флаги или подобие.

По поводу "синхронизировать сразу". Конечно же лучше всего батчить. Например, в конце текущего фрейма ранлупа. Хотя серверов L2 с тикрейтом и ранлупом в публичном доступе я еще не встречал (что странно, это сильно упрощает игровую логику и добавляет больше контроля).
Ну думаю, для предметов, а именно для манипуляций, продал, купил, выкинул, поднял делать сразу обнову в бд, предметы рассходников либо после выхода игрока с игры либо если игрок потерял соединение с сервером, то можно обновлять после повторного входа, а если он не заходит, то обновлять при рестарте, так же по макросам, по надетой, снятой броне, по экпе можно сделать, что-бы сохраняло скажем каждые 10-15% по отношению к уровню, скажем нужно 100 експ с 5 до 6 лвл, у тебя 5, нужно 100 експ, набил 10 експ пошло обновление, еще 10, получается 20 уже, еще обновил и т.д. так же по другим параметрам персонажа.
 
Ну думаю, для предметов, а именно для манипуляций, продал, купил, выкинул, поднял делать сразу обнову в бд, предметы рассходников либо после выхода игрока с игры либо если игрок потерял соединение с сервером, то можно обновлять после повторного входа, а если он не заходит, то обновлять при рестарте, так же по макросам, по надетой, снятой броне, по экпе можно сделать, что-бы сохраняло скажем каждые 10-15% по отношению к уровню, скажем нужно 100 експ с 5 до 6 лвл, у тебя 5, нужно 100 експ, набил 10 експ пошло обновление, еще 10, получается 20 уже, еще обновил и т.д. так же по другим параметрам персонажа.
Ну вот у меня к примеру для тех же стакуемых предметов давно уже сделано "ленивое" обновление, т.е. не апдейтит в бз каждое изменение количества к примеру, а вместо этого запускается таск, который сделает апдейт только через определенное время, за которое вполне количество этого предмета могло еще не раз поменяться и в итоге уже в бд уйдет итоговое значение на этот момент.
Подобное поведение очень значительно снижает количество запросов к бд, за счет уменьшения тех же апдейтов количества соул/спиритшотов например и т.п.
 
Ну вот у меня к примеру для тех же стакуемых предметов давно уже сделано "ленивое" обновление, т.е. не апдейтит в бз каждое изменение количества к примеру, а вместо этого запускается таск, который сделает апдейт только через определенное время, за которое вполне количество этого предмета могло еще не раз поменяться и в итоге уже в бд уйдет итоговое значение на этот момент.
Подобное поведение очень значительно снижает количество запросов к бд, за счет уменьшения тех же апдейтов количества соул/спиритшотов например и т.п.
А как у тебя выполненно передача предмета другому чару? Удаляеш строку в бд и создаеш новую?
 
зачем ради такого удалять и снова создавать запись? просто апдейтится существующая.
 
сейчас обдумываю как связать игрока и БД наиболее оптимизированным способом
Лучшая оптимизация - это качественное железо, конфигурация базы. Всё другое, типо записывать все данные в каждую 10 секунду по вторникам не стоит внимание.
В твоем случае, я бы парился такими вопросами, если кол-во чтения/записи доходит до 4-5 тыс. в секунду.
 
Лучшая оптимизация - это качественное железо, конфигурация базы. Всё другое, типо записывать все данные в каждую 10 секунду по вторникам не стоит внимание.
В твоем случае, я бы парился такими вопросами, если кол-во чтения/записи доходит до 4-5 тыс. в секунду.
Я согласен тоже. Но хочу привести пример с L2J и около 300 ботов, все лучники. Так вот при таком тестировании там получилось то что предметы, поднимаемые игроками/ботами, негативно влияют на стабильность сервера. Запросы на сохранение данных просто постоянно тормозят потоки в Ява. Это просто к слову что одним железом не справишся, если сам сервер коряво написан.

Из того что я видел, особенно это касается Явы, это не-знание что вообще происходит при использовании БД. То есть как подсоединение вообщe влияет либо на сам процесс, либо память процесса. Вот люди и делают как могут. И потом узнаеш от разработчиков что им надо по сотни подсоединений что-бы все хорошо работало. Я нe против таких опрометчивых заявлений, но можно же лучше сделать.

Например, то что я обычно делаю, и это достаточно простая оптимизация, то использую bitset (Roaring32) структуру данных. Потом собираю objectId в этот bitset . Ну и после просто делаю batchUpdate/Write/Delete в БД через некоторый промежуток времени. Есть нюансы, но все достаточно прямолинейно по тому как код будет работать. И главное что намного меньше проблем думать о том сколько тебе нужно железа, либо сетевых подсоединений к БД, либо как вдруг не получить странные ошибки когда различные потоки будут перезаписывать одинаковые данные.

А как у тебя выполненно передача предмета другому чару? Удаляеш строку в бд и создаеш новую?
Если предмет уже записан в БД, то нужно изменить objectId игрока в данных предметa (не имя, так как имя персонажа может изменяться). Нету смысла все-перезаписывать все заново, ведь изменился только один параметер (из многих) . Если посмотреть на то что может изменятся в предмете, там не так уж и много параметров, так вот из затачиваешь свои запросы к БД что-бы изменить толко иx.
 
Не нужно устраивать помойки из тем форума, в одной теме должен содержаться только один вопрос
Если предмет уже записан в БД, то нужно изменить objectId игрока в данных предметa (не имя, так как имя персонажа может изменяться). Нету смысла все-перезаписывать все заново, ведь изменился только один параметер (из многих) . Если посмотреть на то что может изменятся в предмете, там не так уж и много параметров, так вот из затачиваешь свои запросы к БД что-бы изменить толко иx.
Да я тоже сделал только Id_owner перезаписывает.
Да к слову немного от темы, по поводу формул вычисления характеристик, есть у кого список формул? расчет pAtk, mDef и т.д. По инету смотрю и по разным сборкам, там все по разному пишут их ))))
 
Берешь за основу Prima Guide где самые базовые формулы еще со времен С0 приведены.
Ну а дальше уже берешь экзешник например птс грации или С4, что тебе ближе и начинаешь разбирать его в IDA, в поисках нужного.
 
Да все тут разобрался, с вашей помощью )) по итемам применил твое ленивое обновление ))))) закинул в конфиги время, поставил 1 минуту, ну на все стакуемые итемы.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху Снизу