로버트님,
4코어(Ryzen 9 5950x)가 장착된 새로운 VPS로 이전했습니다.
CPU 사용률이 여전히 거의 100%입니다. 무엇이 문제인지 정말 모르겠습니다.
8코어 Scaleway 서버로 이전할 거라고 생각했는데?
이 서버의 공칭 대역폭은 얼마인가요? 대역폭이 낮으면 연결/연결 해제 속도가 느려져 병목 현상이 생길 수 있을지 궁금합니다.
Scaleway의 VPS는 30Mbps가 아니라 수백 Mbps의 대역폭을 제공하는데요.
30Mbps는 제 생각에 매우 낮은 수치입니다.
이것이 스펙입니다.
4096MB DDR3 ECC RAM
4 CPU vCores (3.4+ GHz E3-1231 v3/1241 v3/1240 v5)
200GB Raid 10 HDD Storage
5TB bandwidth @ 1Gb/s (speed limited to 5Mb/s after allocation used)
1 IPv4, /64 IPv6
20Gb/s TCP DDoS Protection, 200Gb/s upgrade available
Seattle, Washington, US
Virtualizor Control Panel
Unmanaged
시간 지연 때문에 결국 이 클라우드 서비스 제공업체를 선택했습니다. 그들은 우리나라 방문자를 위해 네트워크 최적화를 수행해 주었습니다.
참고로, htop 출력은 다음과 같습니다.
100% CPU 사용률은 비정상입니다.
로드와 CPU 사용률을 제외하고는 모든 것이 정상입니다.
액세스 로그에 이상한 점이 있나요?
오, 그래! 그렇게 하면 될 거야!
음, SSD를 노리는 게 좋겠어
좋은 지적입니다, 벤자민!
Scaleway 등 다른 업체들도 NVMe SSD를 제공합니다. 훨씬 낫네요!
CPU가 디스크 I/O를 기다리고 있을 수 있습니다.
아, 죄송합니다. 잘못된 스펙을 붙여넣었네요.
스펙은 다음과 같습니다.
4096MB DDR4 ECC RAM
4 CPU vCores (3.4GHz AMD Ryzen 5950X)
100GB Raid NVMe SSD Storage
5TB bandwidth @ 10Gb/s (speed limited to 5Mb/s after allocation used)
1 IPv4, /64 IPv6
20Gb/s TCP DDoS Protection, 200Gb/s upgrade available
Seattle, Washington, US
Virtualizor Control Panel
Unmanaged
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 MB | 5152 kB | 32 MB
discourse_rewards_user_rewards | 61 | 16 kB | 16 kB | 32 kB
discourse_rewards_user_points_categories | 9 | 16 kB | 16 kB | 32 kB
discourse_rewards_rewards | 4 | 16 kB | 16 kB | 32 kB
discourse_rewards_user_points 테이블은 매우 큽니다.
완전히 제거하세요(빌드에서 제거, 테이블 삭제는 불필요). 그 후 어떤 일이 일어나는지 확인해 보세요.
감사합니다. 지금 바로 시도해 보겠습니다.
오, 로버트, 플러그인을 제거하고 재구축했는데, 디스커버리 라우트의 페이지 응답 시간이 이전의 2~3초에서 200ms 미만으로 줄었습니다. ![]()
자, 여기까지입니다. 최적화 문제는 저자와 논의해 보거나, 관련 기술이 있으시다면 PR을 올려보시는 건 어떨까요?
데이터베이스에 익숙한 친구에게 도움을 요청했습니다.
하지만 그는 JAVA로 작업 중이라 시간이 좀 걸릴 것 같습니다.




