О, Роберт,
Мы мигрировали на новый VPS с 4 ядрами (Ryzen 9 5950x),
но загрузка процессора всё ещё почти 100%. Я действительно не понимаю, в чём проблема.
Я думал, вы собирались перейти на сервер Scaleway с 8 ядрами?
Какая заявленная пропускная способность у этого сервера? Неужели низкая пропускная способность может стать узким местом, вызывая медленные подключения или разрывы?
У Scaleway есть VPS с пропускной способностью в сотни мегабит в секунду, а не 30.
Мне кажется, 30 — это крайне мало.
Это спецификация.
4096 МБ DDR3 ECC RAM
4 виртуальных ядра CPU (3,4+ ГГц E3-1231 v3/1241 v3/1240 v5)
200 ГБ HDD-хранилище в RAID 10
5 ТБ трафика @ 1 Гбит/с (после исчерпания лимита скорость ограничивается до 5 Мбит/с)
1 IPv4, /64 IPv6
Защита от DDoS: 20 Гбит/с по TCP, доступна апгрейд до 200 Гбит/с
Сиэтл, штат Вашингтон, США
Панель управления Virtualizor
Не управляется
Из-за задержек мы в итоге выбрали этого провайдера облачных услуг. Они оптимизировали сеть для посетителей из нашей страны.
Кстати, вывод htop:
Использование CPU на 100 % — это ненормально.
Всё в порядке, кроме нагрузки и использования процессора.
Что-то необычное в логах доступа?
Да, именно так!
Хм, тебе стоит ориентироваться на SSD.
Отлично подмечено, Бенджамин!
У Scaleway и других есть NVMe SSD. Это гораздо лучше!
ЦП мог ожидать завершения операций на диске.
Ой, извините, я просто вставил неправильную спецификацию.
Спецификация следующая:
4096 МБ DDR4 ECC ОЗУ
4 vCPU ядра (3.4 ГГц AMD Ryzen 5950X)
100 ГБ RAID NVMe SSD накопитель
5 ТБ трафика @ 10 Гбит/с (скорость ограничена 5 Мбит/с после исчерпания квоты)
1 IPv4, /64 IPv6
Защита от DDoS 20 Гбит/с по TCP, доступно обновление до 200 Гбит/с
Сиэтл, штат Вашингтон, США
Панель управления Virtualizor
Неуправляемый
Это NVMe. ![]()
Я думаю, что возможно, установленные нами плагины увеличили нагрузку.
Плагин внес такое изменение в модель пользователя, что при переходе к маршруту discovery мы многократно вычисляем баллы модели пользователя в модели темы.
add_to_class(:user, :total_earned_points) do
self.user_points.sum(:reward_points)
end
add_to_class(:user, :available_points) do
self.total_earned_points - self.user_rewards.sum(:points)
end
add_to_class(:user, :rewards) do
DiscourseRewards::Reward.where(created_by_id: self.id)
end
add_to_serializer(:basic_user, :total_earned_points) do
user&.total_earned_points
end
add_to_serializer(:basic_user, :available_points) do
user&.available_points
end
add_to_serializer(:current_user, :total_earned_points) do
scope.user.total_earned_points
end
add_to_serializer(:current_user, :available_points) do
scope.user.available_points
end
add_to_serializer(:current_user, :user_rewards) do
scope.user.user_rewards
end
add_to_serializer(:current_user, :rewards) do
scope.user.rewards
end
Я думал, вы сказали, что удалили все плагины, и поведение осталось прежним?
Есть ли у этого индекс?
Сколько строк в таблице user_rewards? Интересно, что разделение по пользователям здесь не учитывается… (но я предполагаю, что на более низком уровне это как-то реализовано).
Ох, боюсь, что индекс не устанавливается.
Модель показана ниже.
module DiscourseRewards
class Reward < ActiveRecord::Base
self.table_name = 'discourse_rewards_rewards'
has_many :user_rewards
belongs_to :created_by, class_name: 'User'
default_scope { where(deleted_at: nil) }
end
end
module DiscourseRewards
class UserPoint < ActiveRecord::Base
self.table_name = 'discourse_rewards_user_points'
belongs_to :user
belongs_to :user_badge
belongs_to :user_points_category
def self.user_total_points(user)
UserPoint.where(user_id: user.id).sum(:reward_points)
end
end
end
module DiscourseRewards
class UserReward < ActiveRecord::Base
self.table_name = 'discourse_rewards_user_rewards'
belongs_to :user
belongs_to :reward
enum status: [:applied, :granted]
end
end
Я отключил все плагины в безопасном режиме. Однако, как вы знаете, база данных не изменилась. ![]()
Думаю, это стоит обсудить с автором.
Кажется, проблема может быть в масштабировании из-за большого количества ваших пользователей?
Возможно, вам потребуется пересобрать систему без плагина. Это будет хорошим сравнением и, возможно, подтвердит, вызваны ли проблемы плагином или нет.
Наличие таблиц не имеет значения, если запросы не выполняются.
discourse_rewards_user_points | 233525 | 27 МБ | 5152 КБ | 32 МБ
discourse_rewards_user_rewards | 61 | 16 КБ | 16 КБ | 32 КБ
discourse_rewards_user_points_categories | 9 | 16 КБ | 16 КБ | 32 КБ
discourse_rewards_rewards | 4 | 16 КБ | 16 КБ | 32 КБ
Таблица discourse_rewards_user_points огромна.
Полностью удалите его (из сборки, таблицы удалять не нужно), посмотрите, что произойдет.
Спасибо, я сейчас же попробую.
О, Роберт, я пересобрал без плагина: время отклика для страниц маршрута обнаружения сократилось с 2–3 секунд до менее 200 мс. ![]()
Вот и всё. Я бы обсудил оптимизацию с автором или, если у вас есть навыки, отправил бы pull request?
Я прошу помощи у нашего друга, который разбирается в базах данных.
Но он работает на Java. Думаю, это займёт некоторое время.




