불행히도 /logs 자체에서 특별히 유용한 정보를 찾지 못했지만, 로컬에서 이 문제를 재현해 보면 요청이 들어온 후 404가 발생하는 것을 확인할 수 있습니다. 단, 이는 최신 알림의 id를 bigint로 설정할 때만 발생하며(int32 범위 내에서는 정상 작동합니다).
notifications.id 자체뿐만 아니라 notification_id를 참조하는 다른 테이블의 컬럼들도 마이그레이션해야 한다는 점을 인지했습니다. 그렇지 않으면 services/notifications.rb 또는 services/badge_granter.rb에서 오류가 발생했습니다.
향후 대용량(big) 포럼 환경에서 알림 관련 문제를 겪는 분들을 위해, 우리가 수행한 작업을 공유합니다.
총 4개 테이블의 4개 컬럼을 마이그레이션해야 했습니다:
notifications.id
user.seen_notification_id
user_badges.notification_id
shelved_notifications.notification_id
처음에는 #1에 대해 위에서 제안된 ALTER 명령을 사용하려 했지만, 언급했듯이 마이그레이션 파일이 스키마에 누적되도록 하기 위해 ActiveRecord 마이그레이션을 사용하는 것으로 결정했습니다.
# frozen_string_literal: true
class ChangeNotificationsIdToBigint < ActiveRecord::Migration[6.1]
def change
change_column :notifications, :id, :bigint
end
end
# frozen_string_literal: true
class ChangeUserSeenNotificationIdToBigint < ActiveRecord::Migration[6.1]
def change
change_column :users, :seen_notification_id, :bigint
end
end
# frozen_string_literal: true
class ChangeUserBadgesNotificationIdToBigint < ActiveRecord::Migration[6.1]
def change
change_column :user_badges, :notification_id, :bigint
end
end
# frozen_string_literal: true
class ChangeShelvedNotificationsNotificationIdToBigint < ActiveRecord::Migration[6.1]
def change
change_column :shelved_notifications, :notification_id, :bigint
end
end
우리의 설정에는 커스텀 Dockerfile이 있습니다( Kubernetes에서 discourse와 sidekiq를 별도의 리소스에서 실행할 수 있도록 이미지를 빌드합니다). 따라서 Dockerfile의 일부로 이 파일들을 /db/migrate로 복사하는 작업은 간단했습니다.
그 후, rake db:migrate를 실행하여 나머지를 처리하도록 두었습니다. 모든 discourse와 sidekiq 포드에 롤링 재시작을 수행한 후, 모든 것이 예상대로 작동하기 시작했습니다 .
훌륭한 데이터입니다. 우리는 이를 받아들이고 코어 디스코스로 bigint 마이그레이션을 진행할 것입니다. 비용이 많이 드는 작업이지만, 대형 포럼에서 다시 발생할 것이 확실하므로 이제 해결하는 것이 좋습니다.
참고로 … OP(원문 게시글)의 주제는 post_id입니다. post_id가 오버플로되는 것을 해결하는 것은 notification보다 훨씬 더 어렵습니다. 21억 개의 게시글은 분명히 발생할 수 있지만, post_id를 bigint로 변경하는 비용은 notification id보다 훨씬 더 큽니다. 그 시간 폭탄은 조금 더 기다려도 될 것입니다.