喋太郎の規模が大きくなってきたので、複数のサーバでBotを運用する方法を探してたのだが、日本語のドキュメントが全くない(全ギレ)。 色々試行錯誤しながらなんとか実現できたので、同じ悩みを持っている方のために書いていく。大規模Botを開発できるぐらいなんだから英語くらい読めるだろっていうツッコミは無しで。(読めない人) pythonでやる場合について書いてるけど、他の言語でやっても同じだと思うので参考にしてもらえたら。雰囲気で書いてるので、間違ってたらコメントで教えていただきたい。
※2019 5/16 コメントで指摘があったため、良さげな形へ訂正
喋太郎については以下の記事から www.dayaman.work
シャーディングって何
よくわからない。俺たちは雰囲気でシャーディングしている。
何ができるようになるの?
複数のプロセスでBotを運用できるようになる。CPUが余ってるから並列処理した方がもっと効率的に運用できるのにな〜、とか、サーバの増設、いわゆるスケールアウトがしたい、だとかが実現するよ。 詳しくはDIscord公式のドキュメントを読んでほしい。どのような基準でギルドを振り分けるのかも書いてある。 discordapp.com
シャーディングをする目安
discord.pyのドキュメントでは1000ギルドからと書いてあった。Rythmのエンジニアさんは2000ギルドを超えたならシャーディングした方がいいと言っていた。そんな感じで。
やり方
複数サーバで運用する場合
2台のサーバに1プロセスずつ走らせるとする。
Clientのインスタンス生成時に、何番目のプロセスなのか示す shard_id
とプロセスの総数の shard_count
を指定する。
サーバA
client = discord.Client(shard_id=0, shard_count=2)
サーバB
client = discord.Client(shard_id=1, shard_count=2)
shard_id
は0から始まることに注意する。
あとはすべてのプロセスを立ち上げるだけで完了。
1つのサーバ上で複数プロセスを立ち上げたい場合
Client
クラスの代わりに、 AutoShardedClient
を使う。このクラスは、自動でいい感じにshardingしてくれるやつらしい。すごい。詳しくは公式のドキュメントを読んでほしい。
client = discord.AutoShardedClient()
これだけでOK。1000ギルドにつき1つプロセスを生やしてくれる。もし、生やしたいプロセス数があるならば、 shard_count
を渡してやればそれだけ立ててくれる。
複数サーバで、それぞれ複数のプロセスを立てたい場合
AutoShardedClient
に shard_ids
を渡す。
例えば、2台のサーバに4プロセスずつ、合計8プロセス生やす場合
サーバA
client = discord.AutoShardedClient(shard_count=8, shard_ids=(0, 1, 2, 3))
サーバB
client = discord.AutoShardedClient(shard_count=8, shard_ids=(4, 5, 6, 7))
どのサーバにどれだけプロセスを割り振るかは、スペックに応じて柔軟に臨機応変してほしい。
注意点
shard_count
の数だけプロセスが立ち上がらないと、Botはオンライン扱いにならない- DMは、
shard_id
が0のプロセスが受け取る
思うこと
それぞれ独立した複数のサーバで運用する場合は、1つでもプロセスが落ちたらBotが機能しなくなるので、その辺の工夫が必要になると思う。