Botunuz büyüdükçe bir gün şu soruyla karşılaşırsınız: "Sharding gerekiyor mu?" Belki loglarda 4011 Sharding required kapanış kodunu gördünüz, belki de bir rehberde ShardingManager'dan söz edildiğini okudunuz. Sharding, botunuzun gateway trafiğini birden fazla WebSocket bağlantısına bölmesidir ve belli bir büyüklükten sonra isteğe bağlı değil, zorunludur.

Bu rehberde shard'ın ne olduğunu, hangi sunucunun hangi shard'a düştüğünü belirleyen formülü, 2.500 sunucu sınırını, /gateway/bot uç noktasının önerdiği shard sayısını ve max_concurrency mantığını, discord.js ShardingManager ile internal sharding farkını ve discord.py AutoShardedBot kullanımını anlatıyoruz. Küçük bir botunuz varsa son bölümdeki "ne zaman gerekir?" kısmı size zaman kazandırabilir.

Shard nedir?

Bot Discord'a gateway adı verilen bir WebSocket bağlantısıyla bağlanır ve bulunduğu tüm sunucuların olayları bu bağlantıdan akar. Shard, bu olay akışının bir parçasını taşıyan ayrı bir gateway bağlantısıdır. Discord'un tanımıyla sharding, uygulamanın olayları birden fazla gateway bağlantısına bölmesini sağlayan ve tamamen uygulama tarafından kontrol edilen bir yöntemdir; bağlantılar arasında durum paylaşımı gerektirmez.

Sharding'i bağlantı sırasında Identify yükündeki shard dizisiyle açarsınız. Dizinin ilk elemanı sıfırdan başlayan shard numarası, ikincisi toplam shard sayısıdır. Örneğin üç shard için bağlantılar [0, 3], [1, 3] ve [2, 3] değerleriyle kurulur.

Sharding formülü: sunucu hangi shard'a düşer?

Bir sunucunun olaylarının hangi shard'a gideceği sunucu kimliğinden (guild_id) hesaplanır:

python
shard_id = (guild_id >> 22) % num_shards

Discord kimlikleri (snowflake) 64 bitlik sayılardır. JavaScript'te bu yüzden hesaplamayı BigInt ile yapmalısınız. discord.js aynı hesabı yapan ShardClientUtil.shardIdForGuildId(guildId, shardCount) statik metodunu da sunar:

javascript
const { ShardClientUtil } = require('discord.js');

const guildId = '123456789012345678';
const numShards = 4;

const elle = Number((BigInt(guildId) >> 22n) % BigInt(numShards));
const djs = ShardClientUtil.shardIdForGuildId(guildId, numShards);
console.log(elle, djs);

Belgede ilginç bir ayrıntı daha var: num_shards yalnızca trafiği yönlendirmek için kullanılır, toplam oturum sayısını sınırlamaz. Aynı [shard_id, num_shards] ile birden fazla oturum ya da farklı num_shards değerli oturumlar açabilirsiniz. Bu sayede daha yüksek shard sayılı yeni bir dağıtımı paralel hazırlayıp trafiği ona devrederek kesintisiz ölçekleme yapmak mümkündür.

/gateway/bot: önerilen shard sayısı ve oturum limiti

/gateway/bot: önerilen shard sayısı ve oturum limiti: max_concurrency ve shard başlatma sırası, Çok büyük botlar (150.000+ sunucu)

Kaç shard açmanız gerektiğini tahmin etmek zorunda değilsiniz. Bot token'ıyla çağrılan GET /gateway/bot uç noktası shards alanında önerilen shard sayısını döndürür. Bu değer bot sunuculara katılıp ayrıldıkça değişir; bu yüzden uzun süre önbelleğe alınmamalıdır.

json
{
  "url": "wss://gateway.discord.gg/",
  "shards": 9,
  "session_start_limit": {
    "total": 1000,
    "remaining": 999,
    "reset_after": 14400000,
    "max_concurrency": 1
  }
}
AlanAnlamı
shardsBağlanırken kullanılması önerilen shard sayısı
session_start_limit.totalİzin verilen toplam oturum başlatma sayısı
session_start_limit.remainingKalan oturum başlatma hakkı
session_start_limit.reset_afterLimitin sıfırlanmasına kalan süre (milisaniye)
session_start_limit.max_concurrency5 saniyede izin verilen Identify isteği sayısı

Oturum başlatma limiti önemlidir: botunuz sürekli çöküp yeniden başlarsa her Identify bu haktan düşer. Çökme döngüsüne giren bir bot hakkını tüketebilir. Botu kararlı çalıştırmak için Discord botunu 7/24 aktif tutma rehberine göz atın.

max_concurrency ve shard başlatma sırası

Birden fazla shard'ı aynı anda başlatabilirsiniz, ancak max_concurrency kadar. Her shard'ın hız sınırı anahtarı şöyle hesaplanır:

python
rate_limit_key = shard_id % max_concurrency

Bu, shard'ları max_concurrency boyutunda "kovalara" ayırır ve kovaları sırayla başlatmanız gerekir. Örneğin 32 shard ve max_concurrency 16 ise önce 0-15 numaralı shard'ları birlikte, ardından 16-31 numaralı shard'ları başlatırsınız. Sınırı aşarsanız gateway Invalid Session (opcode 9) ile yanıt verir. Kütüphaneler bu sıralamayı sizin yerinize yönetir.

Çok büyük botlar (150.000+ sunucu)

150.000'den fazla sunucuda bulunan botlar "large bot sharding" düzenine geçirilir ve sahiplerine sistem DM'i ile e-posta gönderilir. Çalıştırılan shard sayısı Discord'un bildirdiği sayının katı olmalıdır; aksi halde bağlantı 4010 Invalid shard ile kapanır. Bu botların günlük oturum başlatma limiti max(2000, (guild_count / 1000) * 5) olur ve max_concurrency artar. Ayrıca bu botlar Get Current User Guilds uç noktasında shard sorgu parametresini göndermek zorundadır; göndermeyen istekler 400 Bad Request ile döner.

discord.js ile sharding

discord.js ile sharding: ShardingManager (çoklu süreç), Kodunuzda değişmesi gerekenler, Internal sharding

discord.js rehberi önce önemli bir uyarı yapar: sharding 2.500 sunucuda zorunlu olur ve bot yaklaşık 2.000 sunucuya ulaştığında hazırlanmaya başlamak yeterli zaman bırakır. Ayrıca sharding yalnızca gateway olayları kullanan uygulamalar için anlamlıdır; yalnızca HTTP üzerinden etkileşim alan botlar için konu dışıdır (bkz. HTTP interactions ile bot).

ShardingManager (çoklu süreç)

Rehberin önerdiği yapı, mevcut bot dosyanızı bot.js olarak adlandırıp yeni bir index.js başlatıcı yazmaktır. ShardingManager her shard'ı ayrı bir süreç (veya mode: 'worker' ile iş parçacığı) olarak başlatır:

javascript
// index.js
const { ShardingManager } = require('discord.js');

const manager = new ShardingManager('./bot.js', {
  token: process.env.DISCORD_TOKEN,
  totalShards: 'auto', // /gateway/bot önerisini kullan
});

// spawn() öncesinde dinleyin, aksi halde shard 0 kaydı kaçabilir
manager.on('shardCreate', (shard) => console.log(`Shard ${shard.id} başlatıldı`));

manager.spawn();

bot.js içinde her zamanki gibi client.login(process.env.DISCORD_TOKEN) çağrılır. Rehbere göre önerilen sayı shard başına yaklaşık 1.000 sunucudur.

Kodunuzda değişmesi gerekenler

Sharding sonrası her süreç yalnızca kendi sunucularını bilir. client.guilds.cache.size artık toplam sunucu sayısını değil, o shard'ınkini verir. Toplam için client.shard.fetchClientValues() ve client.shard.broadcastEval() kullanılır:

javascript
const sonuclar = await client.shard.fetchClientValues('guilds.cache.size');
const toplamSunucu = sonuclar.reduce((acc, n) => acc + n, 0);

const uyeler = await client.shard.broadcastEval((c) =>
  c.guilds.cache.reduce((acc, g) => acc + g.memberCount, 0),
);
const toplamUye = uyeler.reduce((acc, n) => acc + n, 0);

Internal sharding

discord.js, ShardingManager dışında "internal sharding" modunu da destekler: tek süreç içinden birden fazla WebSocket bağlantısı açılır ve büyük kod değişikliği gerektirmez. Ancak rehber, ana sürecin bellek kullanımı yüksek olacağı için bu modun büyük botlar için ideal olmadığını belirtir. Birden fazla makineye ya da konteynere yayılmak gerektiğinde ise shard yönetimi ve shard'lar arası veri paylaşımı sizin sorumluluğunuzdadır.

YöntemÇalışma şekliNe zaman
ShardingManagerHer shard ayrı süreç veya workerTek makinede orta ve büyük botlar
Internal shardingTek süreç, çoklu WebSocketKüçük ölçek; bellek yükü artar
Özel dağıtımShard'lar farklı makinelerdeÇok büyük botlar; koordinasyon size kalır

discord.py ile sharding: AutoShardedBot

discord.py'de sharding tek süreç içinde çalışır ve IPC (süreçler arası iletişim) gerektirmez. discord.Client yerine discord.AutoShardedClient, commands.Bot yerine commands.AutoShardedBot kullanmanız yeterlidir. Belgeye göre bu sınıf /gateway/bot uç noktasını kullanarak gerektiği kadar shard açar (shard başına yaklaşık 1.000 sunucu).

python
import os
import discord
from discord.ext import commands

intents = discord.Intents.default()
bot = commands.AutoShardedBot(command_prefix=commands.when_mentioned, intents=intents)

@bot.event
async def on_shard_ready(shard_id):
    print(f'Shard {shard_id} hazır')

bot.run(os.getenv('DISCORD_TOKEN'))

Daha fazla kontrol isterseniz shard_count ve shard_ids parametrelerini verebilirsiniz. Örneğin discord.AutoShardedClient(shard_count=10, shard_ids=(1, 2, 5, 6)) toplam 10 shard'lık düzende yalnızca belirtilen shard'ları bu süreçte çalıştırır; bu, shard'ları birden fazla sunucuya bölmenin temelidir. Shard bazlı olaylar için on_shard_ready, on_shard_connect, on_shard_disconnect ve on_shard_resumed kullanılabilir. discord.py ile bot kurulumunun temelleri için discord.py ile bot yapımı.

Sharding ne zaman gerekir?

  • 2.500 sunucunun altındaysanız: zorunlu değildir. Pycord rehberi küçük bir botu shard'lamanın gereksiz olmanın ötesinde ek kaynak tükettiği için zararlı da olabileceğini belirtir.
  • 2.000 sunucu civarındaysanız: discord.js rehberinin önerisiyle hazırlığa başlayın; istatistik komutları gibi tüm sunucuları sayan kodları gözden geçirin.
  • 2.500 ve üzeri: zorunludur; aksi halde 4011 alırsınız.
  • Yalnızca HTTP interactions kullanıyorsanız: gateway bağlantınız olmadığı için sharding konusu sizi ilgilendirmez.

Sharding sunucu kaynaklarını da etkiler: ShardingManager ile her shard ayrı bir Node.js süreci demektir ve bellek ihtiyacı shard sayısıyla artar. Büyüyen botlar genellikle paylaşımlı hostingden bir VDS ya da VPS sunucuya geçer; konteyner kullanmak isterseniz Docker Compose rehberi iyi bir başlangıçtır.

Sık Sorulan Sorular

Shard başına kaç sunucu olmalı?

Discord'un kesin sınırı shard başına 2.500 sunucudur. discord.js ve discord.py belgeleri, otomatik modda shard başına yaklaşık 1.000 sunucu düşecek şekilde öneri yapıldığını belirtir. En doğru sayı için /gateway/bot uç noktasının shards değerini kullanın.

DM'ler hangi shard'a gelir?

guild_id içermeyen tüm olaylar, yani DM'ler, abonelik ve entitlement olayları yalnızca 0 numaralı shard'a gönderilir.

Shard sayısını sonradan değiştirebilir miyim?

Evet. num_shards yalnızca yönlendirme için kullanıldığından farklı shard sayısıyla yeni bir oturum kümesi başlatabilirsiniz. Büyük botlarda ise sayının Discord'un bildirdiği değerin katı olması gerekir.

Sharding botumu hızlandırır mı?

Sharding temel olarak gateway yükünü böler; REST rate limit'leri token başına uygulandığı için shard sayısını artırmak API sınırlarını yükseltmez. Rate limit konusu için Discord rate limit ve 429 hatası yazısına bakın.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Discord rate limit ve 429 · Discord API hata kodları · Botu 7/24 aktif tutma · Discord bot kütüphaneleri karşılaştırma · Discord intent nedir · Node.js cluster ve PM2 · VDS nedir