-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fd65fdd
commit e6bd279
Showing
1 changed file
with
49 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Введение | ||
Наш проект представляет из себя социальную сеть. На мой взгляд ключевой сущностью социальной сети являются пользователи, | ||
так как помимо частых изменений таблицы с пользователями, вызванных появлением новых пользователей и изменением аккаунтов | ||
старыми пользователями, часто появляется необходимость поиска пользователя по имени или id для корректного отображения | ||
поста, комментария или чата. В связи с этим было выбрать ключевой сущностью для нагрузочного тестирования именно пользователей. | ||
|
||
# Основная часть | ||
Для начала был сделан бэкап базы при помощи pg_dump. Следом за этим были установлены инструменты для проведения | ||
нагрузочного тестировани: wrk и vegeta. Для vegeta были написаны скрипты на Python по созданию случайных пользователей и | ||
запросам к API для регистрации. Для wrk был написан скрипт на lua, создающий пользователя и отправляющий запрос на его | ||
создание. К сожалению и первый и второй инструмент не только вызвали ошибки, решить которые нам не удалось, так еще и смогли | ||
дважды превратить докер контейнер с сервисом регистрации в виртуальный кирпич, не реагирующий ни на какие команды. | ||
В связи с этими удручающими новостями я решил предположить, как можно оптимизировать запрос на создание и поиск пользователя. | ||
Для начала стоит сразу же отбросить идею с денормализацией, так как у таблички пользователей нет отнощений, денормализовав | ||
которые производительность можно было бы улучшить. Значит переходим к анализу самих запросов. | ||
Начнем с создания пользователя: | ||
``` | ||
INSERT INTO profile (first_name, last_name, email, hashed_password) | ||
VALUES ($1, $2, $3, $4) | ||
ON CONFLICT (email) DO NOTHING RETURNING id; | ||
``` | ||
На первый взгляд этот запрос не может быть улучшен. Однако, исходя из рекомендаций проведения валидации на всех возможных уровнях, нам стоит проверить, | ||
существует ли пользователь с таким email на стороне сервера: | ||
``` | ||
SELECT id | ||
FROM profile | ||
WHERE email = $1 | ||
LIMIT 1; | ||
``` | ||
Такой запрос может быть улучшен наложением обычного btree индекса на поле email. Делать, однако, это следует только в том случае, если создание пользователя | ||
происходит достаточно часто и становится бутылочным горлышком. | ||
|
||
Теперь рассмотрим выборку пользователя: | ||
``` | ||
SELECT id, first_name, last_name, bio, avatar | ||
FROM profile | ||
WHERE profile.id = $1 | ||
LIMIT 1; | ||
``` | ||
|
||
Кажущийся очевидным способ ускорения этого запроса: наложения btree индекса на поле id, на самом деле не так хорош как кажется. Этот запрос действительно обладает | ||
хорошей селективностью, но стоит обратить внимание также на другие запросы. Дело в том, что многие сущности связаны с профилем: у каждого поста, | ||
комментария и чата должно отображаться имя пользователя и его автарка. Значит, мы можем наложить покрывающий btree индексы на id с полями first_name, last_name, | ||
avatar, чем значительно ускорим другие запросы, в которых проводится JOIN с таблицей профилей. | ||
|
||
# Заключение | ||
В заключение хочется сказать, что, конечно, вышеописанные рассуждения мало чего стоят без заполнения базы данными и анализа запросов, сопровождаемых EXPLAIN`ом и | ||
его визуализацией. Тем не менее хочется верить, что моих знаний хватило на то, чтобы правильно спрогнозировать поведение таблицы и запросов под нагрузкой, а также | ||
написать правильные рекомендации по ускорению запросов. |