Александр Воробьев

Александр Воробьев
Рейтинг
56
Регистрация
03.02.2020
ArbNet #:
Поэтому такое не безумие при увеличении нагрузки сделает вам бяку..

Какая должна быть нагрузка по вашему мнению, чтоб ощутить бяку? На нагрузке 1500 rps (без учета статики) - проблем нет (при этом была необходимость в одну очень нагруженную таблицу: читать, обновлять, писать и при этом практически нельзя кешировать. Нащупали предел - убрали ее в отдельную БД и все пошло без проблем). Более того, при большой нагрузке и если сконцентрироваться на том, что мы рассматриваем случай, когда результаты не закешированы и идет запрос в базу. В общем случае в первую очередь затыкается база, особенно если запросы на обновление присутствуют. (а если MyIASM - так там вообще легко базу заткнуть).

Как считаете для многих сайтов нагрузка в 1500 rps является обычной?


PS Да конечно, 1500 это еще не хайлоад, но хайлоад вообще живет по своим законам.

MrPi #:
Эммм..
Что не так? Правда этот код будет полностью выкинут, т.к. я решил уйти от конфигурационных массивов. Но все же.
ArbNet #:
Так в том то и суть, что в твоём классе формирования запросов не будет гибкости это раз. Не все подобные сложные запросы сможешь реализовать таким способом, да и ещё потеря времени на их формировании сначала добавляя команды и параметры, а потом сам запрос.. это два.

Ну существующие билдеры вполне себе справляются. У меня на первом этапе нет необходимости реализовывать абсолютно все возможности всех SQL диалектов.  По времени. Вопрос спорный и смотря с чем сравнивать.  Это все же фреймворк тоесть инструмент которому нужна гибкость. По факту я подумывал (заметь подумывал, но  в итоге так и не отрефакторил) уйти от кверибилдера только на проекте где RPS бывает до 1500 . Мой прогноз твоя история с тем как именно ты работаешь с XML будет тормозить сильно больше чем кверибилдер.  И тут может показать реальный тест: в идеале с профайлером, можно придумать иной тест и даже сравнительный :)

Опять же при грамотном подходе кверибилдеры не гоняются на каждом хите. Ну да ладно. посмотрим ;)

Ну тут такое. все зависит от сложности и логики генерации запросов.  Если количество ограниченно, и они заранее известны или тривиальны, то может быть, да и то с условием, что мы гарантированно не будем менять хранилище данных. (а это вполне себе реальная задача, у меня, например, на одном из проектов часть таблиц поехала в БД другого типа).

А так... ну представим запрос

SELECT
o.id AS order_id,
o.total_amount,
o.created_at,
u.name AS user_name,
m.name AS manager_name
FROM orders o
INNER JOIN users u ON o.user_id = u.id
LEFT JOIN users m ON o.manager_id = m.id
WHERE u.status = 'active'
AND u.city IN ('Москва', 'Санкт-Петербург')
AND o.status != 'return'
AND o.id IN (
SELECT id
FROM orders
WHERE user_id = u.id
AND status = 'paid'
AND created_at > DATE_SUB(NOW(), INTERVAL 1 MONTH)
)
GROUP BY o.id, u.name, m.name
HAVING COUNT(o.id) >= 1
ORDER BY o.created_at DESC
LIMIT 5

т.е. если тут же его реализовывать то будет так (пока только само формирование запроса)

$queryBuilder
    ->select([
        'o.id as order_id',
        'o.total_amount',
        'o.created_at',
        'u.name as user_name',
        'm.name as manager_name'
    ])
    ->from('orders', 'o')
    ->join('users', 'u', 'o.user_id', '=', 'u.id')
    ->leftJoin('users', 'm', 'o.manager_id', '=', 'm.id')
    ->where('u.status', '=', 'active')
    ->whereIn('u.city', ['Москва', 'Санкт-Петербург'])
    ->where('o.status', '!=', 'return')
    ->whereExists(function ($q) use ($queryBuilder) {
        return $q->selectRaw('1')
                 ->from('orders')
                 ->whereColumn('user_id', 'o.user_id')
                 ->where('status', '=', 'paid')
                 ->where('created_at', '>', now()->subMonth());
    })
    ->groupBy(['o.id', 'u.name', 'm.name'])
    ->havingRaw('COUNT(o.id) >= 1')
    ->orderBy('o.created_at', 'DESC')
    ->limit(5)
    ->getQuery();

и далее особенности возникают нюансы. Что если нам требуется событийная модель и запрос у нас формируется в разных местах.

т.е у нас

$query = $queryBuilder
    ->select([
        'o.id as order_id',
        'o.total_amount',
        'o.created_at',
    ])
    ->from('orders', 'o')
    ->where('o.status', '!=', 'return')
    ->groupBy(['o.id'])
    ->havingRaw('COUNT(o.id) >= 1')
    ->orderBy('o.created_at', 'DESC');
Event::send(new OrderSelectEvent($query));

$query->getQuery();

И слушатели событий, если сочтут необходимым, достраивают этот запрос. Как с "готовыми" запросами такие решать задачи? А ведь это фреймворк, т.е. инструмент для решения любых задач.

Эти две недели "пожинал" плоды пропуска этапа проектирования.

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

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

Реализовал систему сервиспровайдеров, для удобной интеграции модулей и сервисов (в т.ч. и потенциальными пользователями). При этом тут уже есть точка сравнения  с тем же ларавел.  У меня строится граф зависимостей и сервиспровайдеры загружаются в порядке согласно задекларированных ими зависимостей. (с защитой от цикличности)

Так же сделал и систему загрузки окружения и конфигов. И сделал на основе конфиг файлов возвращающих массив, но вчера решил поступить иначе - конфигурации будут организованны на объектах, что позволит использовать типизацию, избавит от возможностей опечаток (в ключах массива), а так же поможет в IDE с теми же подсказками какие параметры есть. Т.е. тоже еще одна точка для сравнения.

В общем у меня все движется. Но релиза еще нет. Состояние на данный момент в ветке next

ArbNet у тебя есть движение?

Volovikov #:
т, акб садится быстро, разваливаются, ржавеют мгновенно
Расскажешь когда сядет аккум? А сколько лет/дней ждать ржавчину?
ivanko44 #:
Миф. Профильные тематические форумы снимают сливки,

Ой да ладно... Чет я этого не заметил. На форуме где по программированию, практически нет интересных тем.  99% от ленивых студентов которым завтра сдавать, при этом вопросы уровня "как вывести привет мир".

Здесь так же посмотрите на список популярных тем. Я конечно не СЕОшник, но что то кажется тоже "не совсем" про СЕО.

MrPi #:
Полную реализацию можно для примера? Откуда прилетело getName()? 

А это как раз элемент магии. UserTable имеет описание для всех столбцов (по сути массив). Может быть посмотрю, что под капотом позднее.

softerra #:
Когда презентация?
Устали ждать ..
Которая?
MrPi #:
Вы пришли в школу и вас учат, что 2x2=4, а после, какой-то фреймворк решил, что 5. Какая разница, ведь выполняет?

Ну хоть php в этом плане не плюсы где можно плюс и минус переопределить :)

class MyInt {
    int value;
public:
    MyInt(int v) : value(v) {}

    MyInt operator+(const MyInt& other) const {
        return MyInt(value + other.value * 2);
    }

    int get() const { return value; }
};

MyInt a(5), b(3);
MyInt c = a + b;
Всего: 627