पाठ 13 / 25

Partition संख्या चुनना

लक्षित throughput और consumer समानांतरता से partitions का आकार तय करें और बाद में बदलने की क़ीमत जानें।

आकार तय करने का अंगूठा-नियम

लक्षित throughput (MB/s) का अनुमान लगाएँ, मापें कि एक partition producers और आपके consumer तर्क के लिए कितना सँभाल सकता है, और target / producer_per_partition तथा target / consumer_per_partition में से बड़ा लें। वृद्धि के लिए गुंजाइश रखें, क्योंकि partitions बाद में बढ़ाए जा सकते हैं पर घटाए कभी नहीं, और बढ़ाने से key-से-partition मैपिंग बदलती है (मौजूदा key वाले नए records दूसरे partition में जा सकते हैं, जिससे बदलाव के आर-पार प्रति-key क्रम टूटता है)। बहुत ज़्यादा partitions की भी क़ीमत है: ज़्यादा खुली files, लंबे leader चुनाव और ज़्यादा memory। प्रति topic सैकड़ों आम हैं; प्रति cluster दसियों हज़ार में सावधानी चाहिए।

Partitions, keys और अवधि चुनें

कितने partitions, कौन-सी key और डेटा कितनी देर रखना है, ये तीन निर्णय topic को आकार देते हैं।

तीन निर्णय: partitions, key, retention।
चित्र 4.1 — Partitions, key और retention।

आकार का गणित, चलाकर

मैंने यह चलाया: 300 MB/s लक्ष्य, producers के लिए 50 MB/s प्रति partition और consumers के लिए 30 MB/s प्रति partition पर max(6, 10) = 10 partitions चाहिए।

import math
target_mb, prod_mb, cons_mb = 300, 50, 30
print(max(math.ceil(target_mb / prod_mb), math.ceil(target_mb / cons_mb)))

Output:

10

Partitions बढ़ाने से key की जगह बदलती है, असली broker पर चलाकर

मैंने orders को 6 से 8 partitions किया और छह keys फिर produce कीं। पहले के murmur2 function से असली broker ने उन्हें ठीक वैसे रखा जैसा 8-partition मैपिंग बताती है: user-1 partition 2 से 4 पर गया, user-2 2 से 0 पर, user-3 5 से 3 पर।

def murmur2(data: bytes) -> int:
    length = len(data); seed = 0x9747b28c; m = 0x5bd1e995; r = 24
    h = (seed ^ length) & 0xFFFFFFFF
    for i in range(length // 4):
        i4 = i * 4
        k = (data[i4] & 0xff) | ((data[i4+1] & 0xff) << 8) | ((data[i4+2] & 0xff) << 16) | ((data[i4+3] & 0xff) << 24)
        k = (k * m) & 0xFFFFFFFF
        k ^= (k >> r) & 0xFFFFFFFF
        k = (k * m) & 0xFFFFFFFF
        h = (h * m) & 0xFFFFFFFF
        h ^= k
    rem = length % 4; base = length - rem
    if rem == 3: h ^= (data[base+2] & 0xff) << 16
    if rem >= 2: h ^= (data[base+1] & 0xff) << 8
    if rem >= 1:
        h ^= data[base] & 0xff
        h = (h * m) & 0xFFFFFFFF
    h ^= (h >> 13) & 0xFFFFFFFF
    h = (h * m) & 0xFFFFFFFF
    h ^= (h >> 15) & 0xFFFFFFFF
    return h

def partition_for(key: str, n: int) -> int:
    return (murmur2(key.encode()) & 0x7fffffff) % n

print({k: partition_for(k, 8) for k in ("user-1", "user-2", "user-3", "user-4", "user-5", "user-6")})
# kafka-topics.sh --alter --topic orders --partitions 8   (then produce the same keys again)

Output:

{'user-1': 4, 'user-2': 0, 'user-3': 3, 'user-4': 7, 'user-5': 6, 'user-6': 5}

त्वरित जाँच: Topic की partition संख्या बदलने के बारे में क्या सही है?

  • आप उसे खुलकर घटा सकते हैं
  • आप बढ़ा सकते हैं पर घटा नहीं सकते, और key की जगह बदल सकती है
  • यह क्रम पर कभी असर नहीं डालता
  • यह हमेशा के लिए तय है
Answer

आप बढ़ा सकते हैं पर घटा नहीं सकते, और key की जगह बदल सकती है — Partitions सिर्फ़ बढ़ सकते हैं, और अलग modulus मौजूदा keys की मैपिंग बदलता है।