This is a mobile optimized page that loads fast, if you want to load the real page, click this text.

Мануал Уменьшаем нагрузку на 50% в моде RedAge (NeptuneEvo)

Harland David Sanders

Куратор портала
Автор темы
Команда форума
Куратор портала
VIP
high coder
media
10 Сен 2020
3,067
2,459
219
Как вы знаете мод ведет логи в отдельную базу данных serverlogs ради этого в коде создан отдельный поток с циклом while(true)
Мод автоматически выстраивает очередь из запросов в базу данных (сделано это для того, чтобы при большом потоке запросов они не терялись и выполнялись по очереди).
Код внутри конструкции Worker() дожидается пока в очереди запросов будет хотя бы 1 и выполняет его, в холостой нагрузке (без игроков и очереди) мод просто бесконечно выполняет while(true). Зачем?

Стандартная нагрузка любого мода на основе RedAge (NeptuneEvo):




Нагрузка мода после моих изменений:



Для того чтобы сделать также, находим у себя файл - dotnet\resources\client\Core\GameLog.cs
в начало файла ко всем переменным добавляем:

C#:
private static string timer = null;

Что получилось:

C#:
private static Thread thread;
private static nLog Log = new nLog("GameLog");
private static Queue<string> queue = new Queue<string>();
private static Dictionary<int, DateTime> OnlineQueue = new Dictionary<int, DateTime>();

private static Config config = new Config("MySQL");

private static string DB = config.TryGet<string>("DataBase", "") + "logs";

private static string insert = "insert into " + DB + ".{0}({1}) values ({2})";

private static string timer = null; // Эту строчку я добавил

Затем в конце файла заменяем конструкции кода Worker() и Stop():

C#:
private static void Worker()
{
    string CMD = "";
    try
    {
        Log.Debug("Worker started");

        timer = Timers.StartTask(500, () => TimerExec());
    }
    catch (Exception e)
    {
        Log.Write($"{e.ToString()}\n{CMD}", nLog.Type.Error);
    }
}
private static void TimerExec()
{
    var list = queue.ToList();

    if (list.Any())
    {
        MySQL.Query(queue.Dequeue());
    }
}
public static void Stop()
{
    Timers.Stop(timer);
    thread.Join();
}

В самое начало файла не забудьте добавить юзинг недостающие функции (чтобы не было ошибок из-за Any() ):
C#:
using System.Linq;

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

Лайк обязателен.
 
Последнее редактирование:

DaVilka

Гуру
16 Сен 2020
607
228
108
Зачем вообще писать логи в бд
 
Реакции: Evbej

Harland David Sanders

Куратор портала
Автор темы
Команда форума
Куратор портала
VIP
high coder
media
10 Сен 2020
3,067
2,459
219
Зачем вообще писать логи в бд
Чтобы потом вычислять как чел надюпал себе триллионы
Жалобы на ДМ как будешь обрабатывать? поверишь на слово? кому?
И т.д., и т.п.
 
Реакции: Gastello

DaVilka

Гуру
16 Сен 2020
607
228
108
Я спросил зачем писать логи в бд, а не зачем писать логи лол
 

Harland David Sanders

Куратор портала
Автор темы
Команда форума
Куратор портала
VIP
high coder
media
10 Сен 2020
3,067
2,459
219

MeFFoS

Участник портала
26 Июл 2021
2
0
21
а зачем создавать новый объект, если можно проверить саму очередь?

 
Последнее редактирование модератором:

Harland David Sanders

Куратор портала
Автор темы
Команда форума
Куратор портала
VIP
high coder
media
10 Сен 2020
3,067
2,459
219

kcomba

Начинающий специалист
9 Янв 2022
104
40
50
Я спросил зачем писать логи в бд, а не зачем писать логи лол
Результат действия "Записи" это "Хранить"
Хранение происходит в хранилище
Хранилище === База данных

Это взаимосвязанные вещи.

СУБД ты можешь использовать любую, начиная от записи на листке, заканчивая облаками в AWS.
 

DaVilka

Гуру
16 Сен 2020
607
228
108
пнхдц
 

Vernetti

Активный участник
23 Янв 2022
19
11
28
28
А в этом моде что данные собираются по интервалу? Если да, то единственный способ оптимизации полностью переписывать логи, чтобы они писались ситуативно, человек что-то сделал - > пишется лог, и желательно не сразу в бд, а в эдакий кеш логов на сервере, а затем перед перезапуском сервера можно выгрузить их сразу все в бд, во время работы сервера в бд и в её абстракцию в процессе должны напрямую писаться только очень ценные данные, потеря которых ударит по репутации сервера, остальные данные пишутся только в абстракцию, а уже после как и сказал выгружается в базу, так же чтение ведётся из абстракции
 
Последнее редактирование:

OGPRussia

Специалист
7 Окт 2020
132
36
85
Я могу ошибаться разве данный способ по интервалу не является достаточным (?) может не идеальным, но разумным. Он же проверяет очередь и по степенно записывает в базу.
Возможно не спорю можно разделить данные (ценные данные от не ценных), но не будет это уже более ресурсоемким процессом???
И вообще писать в "эдакий кеш логов" предположительно может привести к проблемам. На скидку назову 2 причины которые могут возникнуть.
1. Выгрузка логов "перезапуском сервера можно выгрузить их сразу все в бд", возникнет большая очередь на запись, а тут нужен контроль на стороне сервера что бы сервер не ушел раньше в перезагрузку чем логи выгрузятся.
2. Сервер может подвиснуть (DOS атака или что либо другое) и тут произойдет падения сервера, все и все логи потеряны.

Могу ошибаться, прошу меня подправить если что.
 

Vernetti

Активный участник
23 Янв 2022
19
11
28
28

Да, в чем то ты прав, ddos возможен, отключение электричества в дата центре, или бухой сис админ нассал и наблевал на именно ту стойку где твой сервак xD но как я уже сказал выше нужно разделять данные на ценные и те потеря которых не будет таким уж ударом, а то какие это данные уже решать тебе, я лишь привёл пример оптимизации, подобный подход неплохо себя показывает в геймдеве, когда к базе данных огромное количество запросов. Плюс это уменьшает задержку в потоке данных, чтение производится не из базы данных, а с образа в памяти.

Возможно не понял что за очередь, так понимаю это массив с логами, который проверяется каждые 500мс на наличие логов, но зачем тогда проверять каждые 500мс, а не раз в секунду, две или пять?)


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

В Mysql тоже есть возможность записи n-количества записей, но прописанного в sql запросе, но написать на коленке парсер для этого не так уж и сложно.

Это на случай если выгружать данные с образа в бд перед перезапуском.
 

Randomchik

Гуру
high coder
19 Сен 2020
822
319
141
Тут согласен. Да и нагрузку логов на серве не видно, ведь они работают в своем отдельном потоке. Выгружать перед рестартом это бред. У тебя будет условно несколько десятков тысяч логов, сколько ждать придётся что бы выгрузить их перед рестартом? По моему интервалом самый лучший вариант.
 

Vernetti

Активный участник
23 Янв 2022
19
11
28
28
Лучший вариант вовсе без интервала, создаёшь на сервере ивент который срабатывает при создании лога, и записываешь его в бд, а не проверяешь массив на наличие элементов каждые n-время, создаёшь на клиенте ивент ( или через websocket) , а затем в сеф, вот тебе реалтайм отражение логов
 

IronPython

Специалист
high coder
7 Ноя 2020
169
64
82
Нужно для начала ещё понять есть ли вообще смысл сохранять их в бд, или будет достаточно хранить это все в файлах
 

Vernetti

Активный участник
23 Янв 2022
19
11
28
28
В файлах нет смысла, иначе тебе нужно будет замарачиваться с парсингом
Хранить в бд оптимально
Ты легко выводишь и если нужно отобразить выводишь в ui
 

IronPython

Специалист
high coder
7 Ноя 2020
169
64
82
Хммм, ну еще нужно понять как часто эти все логи будут выводиться куда-то, а то если их читают раз в 500 лет то зачем грузить БД лишними данными
 

Vernetti

Активный участник
23 Янв 2022
19
11
28
28
Затем что когда нибудь ты их разгребешь и можешь получить ценную инфу, а на счёт отображения можно всякое придумать