**이 글에서는 타입스크립트를 기준으로 설명합니다.**
서버 수가 많은 디스코드 봇에는 "샤딩"이 필요해요.
디스코드에서는 봇의 서버 수가 2000개가 넘어간다면 하나의 연결로 모두 처리할 수 없기 때문에 그 연결을 여러 개로 나누는데, 그걸 샤딩이라고 해요.
discord.js에서는 자체적으로 샤드 샤드 매니저를 지원해요. 이 샤드 매니저는 샤드 하나당 하나의 프로세스(또는 워커)를 만들어서 샤딩을 해요(discord.js 문서 참고).
하지만 이렇게 샤드 하나당 프로세스 하나를 사용하면 사용하는 리소스의 양도 엄청나게 클 거에요. 그래서 하나의 프로세스(또는 워커)에서 정해놓은 개수만큼의 샤드를 실행하게 해주는 라이브러리가 바로 discord-hybrid-sharding입니다! 프로세스 하나가 프로세스 여러개가 가져야 할 데이터를 한 번에 가지고 있으니 리소스 사용량도 엄청 줄어들 거예요!
+ 프로세스를 나누는 게 아닌 한 프로세스 안에서 모든 샤드의 데이터를 처리하는 방법도 존재하지만, 큰 봇에서는 사용량도 많을 것이기 때문에 추천하지 않는 방법이에요.
..어쨌든 이제 시작합니다...
discord.js 기본 샤딩과 discord-hybrid-sharding의 차이
왼쪽 사진처럼 discord.js의 기본 샤드 매니저는 프로세스 하나당 샤드 하나를 처리해요. 이것과 다르게 오른쪽 사진을 보면 discord-hybrid-sharding에서는 프로세스 하나가 샤드 여러개를 가지고 있어요!
discord-hybrid-sharding 설치하기
일단 기존 디스코드 봇 코드를 준비해 주세요. 저는 간단하게 discord.js 기본 클라이언트를 가져와 보겠습니다.
import { Client } from 'discord.js'
const client = new Client({
intents: ['Guilds']
})
이제 그 프로젝트에 discord-hybrid-sharding 패키지를 설치해 주세요.
yarn add discord-hybrid-sharding
discord.js 샤드매니저 처럼, 이 라이브러리도 메인 프로세스(매니저)와 워커 프로세스(디스코드 클라이언트)가 분리되어 있어요!
만약 아직 샤딩을 하지 않았다면 봇의 메인 파일을 cluster.ts(다른 이름 가능)으로 옮겨주세요. 그 후 새로운 메인 파일을 만들어 주세요.
- src
- index.ts
- cluster.ts
먼저 클러스터 매니저를 만들어 볼게요.
// index.ts
import * as Cluster from 'discord-hybrid-sharding'
import path from 'path'
import { token } from './config'
const isTS = true // ts-node 등으로 실행되고 있는지 확인하는 코드 필요함
const manager = new Cluster.Manager(path.join(__dirname, 'cluster.ts'), {
totalShards: 'auto',
shardsPerClusters: 8 // 하나의 클러스터에 몇 개의 샤드가 들어갈 지 정함,
token, // 디스코드 봇 토믄
mode: 'process', // 또는 worker
})
manager.on('clusterCreate', (cluster) => {
console.log(`[Cluster Manager] Launched Cluster #${cluster.id}`)
})
manager.spawn({ timeout: 1000 * 60 * 10, delay: 7000 })
사실 이 라이브러리의 사용법은 기본 샤드매니저와 거의 비슷해요. 샤드매니저에 이미 있는 설정은 넘어갈게요.
- shardsPerClusters 옵션은 하나의 클러스터(프로세스)에 몇 개의 샤드가 들어갈 지 정하는 옵션이에요! 위 코드에서는 샤드 8개를 하나의 프로세스에서 처리하기로 되어 있어요.
- 이 모듈에서는 shardCreate 이벤트 대신 clusterCreate 이벤트를 호출해요.
- spawn의 timeout은 클러스터가 레디되기까지의 대기 시간을 설정해요.
클러스터 코드 작성
이제 매니저 코드가 완성되었으니 클러스터 코드를 써볼까요?
위에 있는 디스코드 클라이언트를 확장해 discord-hybrid-sharding의 클라이언트를 포함시켜 보겠습니다
// client.ts
import { Client } from 'discord.js'
import Cluster from 'discord-hybrid-sharding'
export class HybridClient extends Client {
cluster = new Cluster.Client(this)
constructor() {
const shardData = Cluster.Client.getInfo()
super({
intents: ['Guilds'],
shards: shardData.SHARD_LIST,
shardCount: shardData.TOTAL_SHARDS
})
}
}
이런 식으로 클라이언트를 확장해 준 뒤 봇 코드에서 클라이언트 코드를 그 코드로 교체해 주세요.
const client = new HybridClient()
그 다음 봇을 실행해 보면 정상적으로 작동합니다...? 안된다면 제 디스코드 서버에서 불러주시길 바랍니다
어쨌든 discord-hybrid-sharding으로 효율적으로 샤딩을 하는 방법을 알아봤어요!