पाठ 5 / 25

Keys और Partitioning

ऐसी keys चुनें कि संबंधित events एक partition साझा करें, और समझें कि डिफ़ॉल्ट partitioner keys को कैसे map करता है।

एक key, एक partition

जब record में key होती है, डिफ़ॉल्ट partitioner key bytes को murmur2 से hash करता है और नतीजे का partitions की संख्या से शेषफल लेता है, इसलिए उस key वाला हर record एक ही partition में जाता है और अपना क्रम रखता है। बिना key वाले records संतुलन के लिए partitions में फैलाए जाते हैं (sticky batching, फिर round-robin जैसा) पर प्रति-इकाई क्रम नहीं होता। ऐसी key चुनें जो उन events को समूहित करे जिनका क्रम बना रहना चाहिए, जैसे order_id, customer_id या device_id, और ऐसी एक बहुत "गर्म" key से बचें जो एक partition पर बोझ डाले।

Record से partition और disk तक

Producer partition चुनता है, records को batch करता है, compress करता है और acknowledgements का इंतज़ार करता है।

चार चरण: serialise, partition, batch, acknowledge।
चित्र 2.1 — Serialise, partition, batch और acknowledge।

Kafka का partitioner दोहराना, चलाकर

मैंने Python में murmur2 लागू किया और असली broker से तुलना की। 6 partitions के लिए यह user-1→2, user-2→2, user-3→5, user-4→1, user-5→4, user-6→5 देता है, जो पहले असली consumer द्वारा दिखाए partitions से ठीक मेल खाता है।

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

for k in ("user-1", "user-2", "user-3", "user-4", "user-5", "user-6"):
    print(k, partition_for(k, 6))

Output:

user-1 2
user-2 2
user-3 5
user-4 1
user-5 4
user-6 5

Key का चुनाव डिज़ाइन का निर्णय है

बाद में key बदलने से बदल जाता है कि कौन-सा partition क्या रखता है और बदलाव के आर-पार प्रति-key क्रम टूटता है। इसे जल्दी, उस इकाई के आधार पर तय करें जिसके events को सख़्त क्रम चाहिए।

त्वरित जाँच: Keyed record के लिए डिफ़ॉल्ट partitioner partition कैसे चुनता है?

  • एक random संख्या
  • Key का murmur2 hash, partition संख्या से शेषफल
  • Value का आकार
  • सबसे ज़्यादा ख़ाली disk वाला broker
Answer

Key का murmur2 hash, partition संख्या से शेषफल — Key hash करने से चुनाव निश्चित होता है: वही key, वही partition।