LRUELS - जब तेज़ क्षमता आपके तंत्र को बेहतर बनाती है (हिन्दी (Hindi))

LRUELS - जब तेज़ क्षमता आपके तंत्र को बेहतर बनाती है

Tuesday, 09 December 2025

//

25 minute read

अधिकांश तंत्र जब लोड हो जाते हैं तो अपमानित होते हैं ।

कुछ असाधारण लोग पाते हैं बेहतर.

यह लेख बताता है कि कैसे एलआरयू आधारित व्यवहारिक मेमोरी जब यह क्षमता हिट हो जाता है - और कैसे इस पैटर्न मेरी में सीखने की क्षमता प्रणाली बॉट टेस्ट इंजिन.. यह भी सबसे छोटा संभव संस्करण है डिथरिंग - ऊर्जा दबाव के माध्यम से विकासवाद नियंत्रित.

यदि तुमने मेरे लेख को पढ़ लिया है CQRS और घटना सोरिंग, आप यहाँ पैटर्न के कुछ रूप को पहचान लेंगे. लेकिन यह सीक्यूआरएस है हड्डी - कोई घटना दुकान, कोई प्रक्षेपण, नहीं मारटन. बस एक स्मरण पत्र, एक पृष्ठभूमि कर्मचारी, और finitary.

मूल इडिआ - व्यवहार मेमोरी एक बजट पर

इससे पहले कि हम आगे बढ़ते हैं, मुझे एक शब्द को परिभाषित करते हैं मैं पूरे में उपयोग करेंगे: हस्ताक्षर. एक हस्ताक्षर किसी स्थिर कुंजी है जो एक व्यवहार पैटर्न का प्रतिनिधित्व करता है - आईपी + उपयोक्ता- एजेंट का एक फिंगरप्रिंट, शीर्ष संयोजन का एक फिंगरप्रिंट, "यह अनुरोध एक्स की तरह दिखता है." कैश इन हस्ताक्षरों को पता है कि समय के साथ पता चलता है।

क्या आप एक ऐसी व्यवस्था बना सकते हैं जो:

  • 1ms के तहत प्रतिक्रिया
  • डाटाबेस में कोई पिण्ड नहीं
  • दबाव के तहत स्व-शिक्षित
  • भूल जाता है कि क्या बात नहीं है
  • याद रखता है

यह बिल्कुल वैसा ही है IMemoryCache एक्सपायरेशन के साथ आपको देता है - आप समझ सकते हैं कि आप क्या निर्माण कर रहे हैं।

वास्तव में एक एलआरयू कैश क्या करता है

LRU (जो हाल ही में उपयोग में लिया गया) कैश्स प्रविष्टियों को हाल ही में एक्सेस नहीं किया गया है. जब कैश भर दिया जाता है, गर्म लोगों के लिए कक्ष बनाने के लिए ठंडा प्रविष्टियों को बाहर निकाल दिया जाता है.

अधिकांश विकासकर्ता इसे एक सीमा के रूप में देखते हैं. "ओह नहीं, मेरा कैश पूरा है, डेटा खो दिया जा रहा है!"

लेकिन व्यवहारिक सिस्टम के लिए, यह एक विशेषता है.

// From WeightStore.cs - the bounded memory window
_cache = new MemoryCache(new MemoryCacheOptions
{
    SizeLimit = _cacheSize,           // e.g., 1000 entries
    CompactionPercentage = 0.25       // Remove 25% when limit reached
});

कि SizeLimit बस एक स्मृति प्रतिबंध नहीं है. यह एक है चयन दबाव. यह निर्धारित करता है कि कितना प्रणाली "याद" और बल क्या मामलों पर ध्यान केंद्रित करने के लिए।

घड़ी जो भूल जाती है

स्लाइडिंग एक्सपायल के साथ मिला हुआ, आप स्वचालित भूल जाते हैं:

// From WeightStore.cs:254-259
private MemoryCacheEntryOptions GetCacheEntryOptions()
{
    return new MemoryCacheEntryOptions()
        .SetSlidingExpiration(_slidingExpiration)  // 30 minutes
        .SetSize(1);  // Each entry counts as 1 toward size limit
}

यदि एक हस्ताक्षर 30 मिनट के भीतर पहुँचा नहीं है, तो यह निकाल दिया गया है. नहीं क्योंकि यह गलत है क्योंकि यह अब संबंधित नहीं है.

यह उत्पन्न किया स्वाभाविक भूल गए:

  • आईपीस भेजा गया
  • लेबलों को घुमाता है
  • ट्रैफिक पैटर्न शिफ्ट
  • कल के हमले आज नहीं कर रहे हैं

स्थिर ब्लॉकल जाती है. एक्सपायरेशन स्मरण को ताज़ा रखता है.

CQRS के बिना मैं स्मिट - छोटा पैटर्न - छोटा सीक्यूट

यह पैटर्न है कि यह काम करता है। SqliteWeightStore वर्ग:

/// <summary>
///     SQLite implementation of the weight store with sliding expiration memory cache.
///     Uses a CQRS-style pattern with write-behind:
///     - Reads: Hit memory cache first (fast path), fall back to SQLite on miss
///     - Writes: Update cache immediately, queue SQLite writes for background flush
///     Sliding expiration provides automatic LRU-like eviction behavior.
/// </summary>

public class SqliteWeightStore : IWeightStore, IAsyncDisposable
{
    // Memory cache with sliding expiration - auto-evicts least recently used entries
    private readonly MemoryCache _cache;

    // Write-behind queue for batched SQLite persistence
    private readonly ConcurrentDictionary<string, PendingWrite> _pendingWrites = new();
    private readonly Timer _flushTimer;
    private readonly TimeSpan _flushInterval = TimeSpan.FromMilliseconds(500);

यह है अनौपचारिक सीआरएस - लेकिन खराब कैश के बगैर. लिखने के बाद कैश प्रविष्टियों को अवैध बनाने के बजाए, कैश लिखने का मॉडल है. शैतान सिर्फ स्थायी संग्रह है.

flowchart LR
    subgraph Cache["In-Memory Behaviour Store"]
        A[Hot Signatures] --- B[Sliding Expiry]
    end
    subgraph DB["SQLite Ledger"]
        C[(Durable Write-Behind)]
    end

    A --Periodic Flush--> C
    B --Eviction--> D[Forgotten]

    style Cache fill:none,stroke:#10b981,stroke-width:2px
    style DB fill:none,stroke:#6366f1,stroke-width:2px

मुख्य अन्तर्दृष्टि: पढ़ना और लिखना स्मृति में जाता है. डाटाबेस अंत में लगातार - है और यह ठीक है.

पहले पढ़ा पथ - कैश, हमेशा

जब एक सीखने वाले वज़न की जरूरत होती है, तो यह कैश को मारता है:

// From WeightStore.cs:421-472
public async Task<double> GetWeightAsync(
    string signatureType,
    string signature,
    CancellationToken ct = default)
{
    var key = CacheKey(signatureType, signature);

    // Check cache first (fast path - no DB access)
    if (_cache.TryGetValue(key, out LearnedWeight? cached) && cached != null)
    {
        _metrics?.RecordCacheHit(signatureType);
        return cached.Weight * cached.Confidence;
    }

    _metrics?.RecordCacheMiss(signatureType);

    // Cache miss - load from DB
    await EnsureInitializedAsync(ct);

    await using var conn = new SqliteConnection(_connectionString);
    await conn.OpenAsync(ct);

    var sql = $@"
        SELECT weight, confidence, observation_count, first_seen, last_seen
        FROM {TableName}
        WHERE signature_type = @type AND signature = @sig
    ";

    // ... execute query ...

    if (await reader.ReadAsync(ct))
    {
        // Cache the result for future reads
        var learnedWeight = new LearnedWeight { /* ... */ };
        _cache.Set(key, learnedWeight, GetCacheEntryOptions());

        return weight * confidence;
    }

    return 0.0;  // No learned weight exists
}

महत्वपूर्ण पथ डाटाबेस कभी नहीं मारा. कैश पढ़ने के लिए सत्य का स्रोत है. finitary सिर्फ बैकअप भंडारण है.

लेखन पथ - कैश तत्काल, लगन से बाद में

जब तंत्र कुछ नया सीखते हैं, यह कैश तत्काल अद्यतन करता है तथा कतार में लिखते हैं:

// From WeightStore.cs:551-582
public Task UpdateWeightAsync(
    string signatureType,
    string signature,
    double weight,
    double confidence,
    int observationCount,
    CancellationToken ct = default)
{
    var key = CacheKey(signatureType, signature);

    // Update cache immediately (source of truth for reads)
    var learnedWeight = new LearnedWeight
    {
        SignatureType = signatureType,
        Signature = signature,
        Weight = weight,
        Confidence = confidence,
        ObservationCount = observationCount,
        FirstSeen = DateTimeOffset.UtcNow,
        LastSeen = DateTimeOffset.UtcNow
    };
    _cache.Set(key, learnedWeight, GetCacheEntryOptions());

    // Queue for async SQLite persistence (write-behind)
    QueueWrite(signatureType, signature, weight, confidence, observationCount);

    return Task.CompletedTask;
}

सूचना: UpdateWeightAsync लौटाता है Task.CompletedTask - यह अनिवार्य रूप से वर्गीकृत है. लिखने कतार है, नहीं चलाने के लिए. इसका मतलब है:

  • उप- सेकेंड लिखने में देर हो रही है
  • आई/ ओ पर कोई ब्लॉक नहीं
  • लिखने से कोयले की मात्रा कम हो जाती है (एक्स लिखने की जीत)

बोज़ मैजिक का पृष्ठभूमि फ्लश - 500ms

हर 500ms, स्थगित लिखना एक ही बैच में विसर्जन करने के लिए फ्लश किया जाता है:

// From WeightStore.cs:274-357
public async Task FlushPendingWritesAsync(CancellationToken ct = default)
{
    if (_pendingWrites.IsEmpty) return;

    // Only one flush at a time
    if (!await _flushLock.WaitAsync(0, ct)) return;

    try
    {
        await EnsureInitializedAsync(ct);

        // Snapshot and clear pending writes atomically
        var writes = new List<PendingWrite>();
        foreach (var key in _pendingWrites.Keys.ToList())
        {
            if (_pendingWrites.TryRemove(key, out var write))
            {
                writes.Add(write);
            }
        }

        if (writes.Count == 0) return;

        await using var conn = new SqliteConnection(_connectionString);
        await conn.OpenAsync(ct);
        await using var transaction = await conn.BeginTransactionAsync(ct);

        try
        {
            var sql = $@"
                INSERT INTO {TableName}
                    (signature_type, signature, weight, confidence,
                     observation_count, first_seen, last_seen)
                VALUES (@type, @sig, @weight, @conf, @count, @now, @now)
                ON CONFLICT(signature_type, signature) DO UPDATE SET
                    weight = @weight,
                    confidence = @conf,
                    observation_count = @count,
                    last_seen = @now
            ";

            foreach (var write in writes)
            {
                await using var cmd = new SqliteCommand(sql, conn, transaction);
                // ... add parameters and execute ...
            }

            await transaction.CommitAsync(ct);
            _logger.LogDebug("Flushed {Count} pending writes in {Duration:F1}ms",
                writes.Count, sw.ElapsedMilliseconds);
        }
        catch
        {
            await transaction.RollbackAsync(ct);
            throw;
        }
    }
    finally
    {
        _flushLock.Release();
    }
}

यह है फिर (उनको) फाड़ कर जुदा कर देती हैं.. आप पाते हैं:

  • बैच ने लिखा (AApt I/O)
  • लेन देन संगतता
  • Casesses अद्यतन किया गया (यदि एक ही हस्ताक्षर 500 बजे में 10 बार अद्यतन किया जाता है, केवल अंतिम मूल्य लिखा जाता है)
  • जी हाँ, यह संभव है कि आप इस पहुँच पैटर्न के साथ पूरी तरह से खुश हों

EMMA अद्यतन - Casles के साथ सीखना औसत

जब एक नया दृश्‍य आता है, तब तंत्र अधिकतम तीव्रता से भारों को अद्यतन करने के लिए प्रयोग करता है:

// From WeightStore.cs:584-635
public Task RecordObservationAsync(
    string signatureType,
    string signature,
    bool wasBot,
    double detectionConfidence,
    CancellationToken ct = default)
{
    var key = CacheKey(signatureType, signature);

    // Calculate new weight using EMA in memory
    var alpha = 0.1;  // Learning rate
    var weightDelta = wasBot ? detectionConfidence : -detectionConfidence;

    double newWeight;
    double newConfidence;
    int newObservationCount;

    if (_cache.TryGetValue(key, out LearnedWeight? existing) && existing != null)
    {
        // Apply EMA: new_weight = old_weight * (1-α) + delta * α
        newWeight = existing.Weight * (1 - alpha) + weightDelta * alpha;
        newConfidence = Math.Min(1.0, existing.Confidence + detectionConfidence * 0.01);
        newObservationCount = existing.ObservationCount + 1;
    }
    else
    {
        // First observation
        newWeight = weightDelta;
        newConfidence = detectionConfidence;
        newObservationCount = 1;
    }

    // Update cache immediately
    var learnedWeight = new LearnedWeight
    {
        SignatureType = signatureType,
        Signature = signature,
        Weight = newWeight,
        Confidence = newConfidence,
        ObservationCount = newObservationCount,
        FirstSeen = existing?.FirstSeen ?? DateTimeOffset.UtcNow,
        LastSeen = DateTimeOffset.UtcNow
    };
    _cache.Set(key, learnedWeight, GetCacheEntryOptions());

    // Queue for persistence
    QueueWrite(signatureType, signature, newWeight, newConfidence, newObservationCount);

    return Task.CompletedTask;
}

संदेशों को पढ़ा जा रहा है. new_weight = old_weight × (1 - α) + new_value × α

  1. 1 के साथ:
  • नया सबूत 10% समर्थन करता है
  • ऐतिहासिक सबूत 90%
  • यह जंगली झूलों को अकेले विचारों से रोकता है

अतिप्रवाह तंत्र को क्यों बनाती है बेहतर

यहाँ महत्वपूर्ण अन्तर्दृष्टि है कि अधिकांश लोगों को याद आती है.

जब कैश भरने लगता है:

  • निम्न पहचान हस्ताक्षर गिर जाते हैं
  • सिर्फ गर्म (कभी प्रयोग में) हस्ताक्षर मेमोरी में रहता है
  • डाटाबेस एक फ्लश चक्र द्वारा जारी है - और यह ठीक है
  • तंत्र फोकस कर रहा है दबाव के नीचे

इसके बारे में सोचिए: यदि 50,000 अद्वितीय हस्ताक्षर आपके सिर में मारे जाते हैं, लेकिन आपके पास केवल १०,००० के लिए स्मरण है, कौनसा हस्ताक्षर विषय है?

अनुमानित १०,००० - जो आमतौर पर 90% वास्तविक यातायात का प्रतिनिधित्व करता है.

उत्पादन में, मैं हर दिन लगभग ४०,००० sreffing हस्ताक्षर देखते हैं (sworsings कोशिश कर रहे हैं एक बार, बेतरतीब जाँच, वैध उपयोक्ता जो कभी वापस नहीं आते हैं) और शायद 5 लाख लोग जो लगातार मर रहे हैं. इन 5 लाख लोगों के जीवन के जोखिम के 99% हैं. लंबे evils के हस्ताक्षर? ध्वनि से उन्हें चोट नहीं लगती है - यह गलत संभावनाओं से भी कम हो सकता है.

flowchart TB
    subgraph Input["50,000 Unique Signatures"]
        Hot[Hot Signatures\n~10,000]
        Cold[Cold Signatures\n~40,000]
    end

    subgraph Cache["Bounded Cache (10,000)"]
        Kept[Kept in Memory]
    end

    subgraph Evicted["Evicted"]
        Lost[Forgotten\nNoise Traffic]
    end

    Hot --> Kept
    Cold --> Lost

    style Hot fill:none,stroke:#10b981,stroke-width:2px
    style Cold fill:none,stroke:#94a3b8,stroke-width:2px
    style Kept fill:none,stroke:#10b981,stroke-width:2px
    style Lost fill:none,stroke:#ef4444,stroke-width:2px

अतिप्रवाह अनुपात: व्यवहारिक मेमोरी. तंत्र स्व- हस्ताक्षरित है.

जब लिंक किया जाता है तो मदद नहीं करता है

यह जादू नहीं है। वहाँ किनारे के मामले हैं जहां LRU दबाव आप के खिलाफ काम करता है:

  • कैश बहुत छोटा: अगर आपका कैश केवल 100 प्रविष्टियों को रखता है, लेकिन आपके पास 1,000 महत्वपूर्ण हस्ताक्षर हैं, आप लगातार चलते रहेंगे और उपयोगी पैटर्नों को खो देंगे इससे पहले कि वे पर्याप्त प्रमाण जमा करते हैं. आपका कैश आपके "शिष्टि सेट को सुरक्षित रखने के लिए.

  • ट्रैफिक जाम: यदि आप एक छोटे से आंतरिक प्रणाली पर चल रहे हैं जहाँ लगभग सब कुछ "शिष्ट" होता है (कम से कम अद्वितीय हस्ताक्षर, सब बार बढ़ जाता है) आप कम लाभ देता है. चयन दबाव के खिलाफ चयन करने के लिए कुछ भी नहीं है.

  • ठंडा- प्रारंभ समस्या: जब तक गर्म हस्ताक्षर अपने आप को स्थापित नहीं करते, तब तक पहले कुछ घंटों के लिए उतनी ही ठंड होती है ।

पैटर्न आपके पास है जब सबसे अच्छा काम करता है सत्ता वितरण के साथ उच्च कार्डिनल - अनोखी हस्ताक्षरों के बहुत सारे, लेकिन एक छोटा सा तत्व है कि ट्रैफिक के बारे में. यही सही है कि ट्रैफिक का पता लगाना क्या है.

कैश तथा डाटाबेस को सिंक - टैग- बेस्ड अवैध किया जा रहा है

जब वे बहाव करते हैं, तब क्या होता है?

सड़न

जब डाटाबेस वजन खराब हो जाता है, कैश को अनुसरण करने की आवश्यकता है. DecayOldWeightsAsync विधि दोनों संभालता है:

// From WeightStore.cs:725-766
public async Task DecayOldWeightsAsync(TimeSpan maxAge, double decayFactor, CancellationToken ct = default)
{
    await EnsureInitializedAsync(ct);

    await using var conn = new SqliteConnection(_connectionString);
    await conn.OpenAsync(ct);

    var cutoff = DateTimeOffset.UtcNow.Subtract(maxAge).ToString("O");

    // Decay old weights in the database
    var sql = $@"
        UPDATE {TableName}
        SET weight = weight * @decay,
            confidence = confidence * @decay
        WHERE last_seen < @cutoff
    ";

    await using var cmd = new SqliteCommand(sql, conn);
    cmd.Parameters.AddWithValue("@decay", decayFactor);
    cmd.Parameters.AddWithValue("@cutoff", cutoff);

    var updated = await cmd.ExecuteNonQueryAsync(ct);

    // Delete weights that have decayed below threshold
    var deleteSql = $@"
        DELETE FROM {TableName}
        WHERE confidence < 0.01 OR (ABS(weight) < 0.01 AND observation_count < 5)
    ";

    await using var deleteCmd = new SqliteCommand(deleteSql, conn);
    var deleted = await deleteCmd.ExecuteNonQueryAsync(ct);

    if (updated > 0 || deleted > 0)
    {
        _logger.LogInformation(
            "Weight decay: {Updated} decayed, {Deleted} deleted",
            updated, deleted);

        // Compact cache to remove stale entries
        _cache.Compact(0.25);
    }
}

डाटाबेस रिकॉर्ड बंद करने के बाद, हम फोन करते हैं _cache.Compact(0.25) - इस बलों MemoryCache इसकी प्रविष्टियों में से 25% को निकालने के लिए, कम से कम हाल में प्रयोग में आने से पहले. अगला पढ़ने योग्य मान को डेटाबेस से फिर लोड करेगा.

टैग- बेसिड एडव्शन

कभी कभी - कभी आपको कैश्ड प्रविष्टियों की पूरी श्रेणी को अवैध करना होगा - उदाहरण के लिए, जब आप फिर से किसी प्रवचन या बाहरी डाटा परिवर्तन का पुनः प्रयोग करते हैं:

// From WeightStore.cs:768-777
/// <summary>
///     Evicts all cached entries for a specific signature type (tag-based eviction).
/// </summary>

public void EvictByTag(string signatureType)
{
    // MemoryCache doesn't natively support tag-based eviction, but we can compact
    // For now, just compact - sliding expiration will handle stale entries
    _cache.Compact(0.1);
    _logger.LogDebug("Compacted cache for signature type: {SignatureType}", signatureType);
}

.नेट't MemoryCache अपने टैग को लालिस की तरह आधारित नहीं है, लेकिन यह एक ही प्रभाव प्राप्त करता है: बल से एक-एक-एक अक्षर बाहर लिखें, चलो डेटाबेस से फिर से लिखें.

सिंक्रोनाइज़ेशन कौशल

मुख्य अन्तर्दृष्टि है कि सही सिंक आवश्यक नहीं है.. सिस्टम बहाव सहन करता है क्योंकि:

  1. कैश को डीबी से फिर से लोड किया जा रहा है - अगर एक प्रविष्टि निकाल दी जाती है, अगला पढ़ने के बाद ताजा डाटा लाने के लिए
  2. एक्सपोजरी हैंडलिंग - प्रविष्टि 30 मिनट के भीतर प्राप्त नहीं है
  3. पूरा किया जा रहा बल नया हो गया - आवधिक कॉम्पैक्ट करने का दबाव पुराने प्रविष्टियों को बाहर करता है
  4. राइट- स्कैन कोयले अद्यतन - कई तेजी से अपडेट एक डीबी लिखना हो जाता है

यह DDDAQ सही किया गया है. कैश " काफी ज्यादा बंद रहता है" बिना जटिल अवैध तर्क की जरूरत के डाटाबेस में.

flowchart TB
    subgraph Sync["Cache-Database Synchronisation"]
        D[Database Decay] --> C[Cache Compact]
        E[Tag Eviction] --> C
        S[Sliding Expiration] --> M[Cache Miss]
        M --> R[Reload from DB]
    end

    style Sync fill:none,stroke:#6366f1,stroke-width:2px

कोई कैश नहीं है नरक. कोई जटिल phot/sub. सिर्फ सुधार और प्राकृतिक ई मार्च.

गहराई से आगे बढ़ते हुए: रीज़निंग सिस्टम

टिप्पणीः यदि आप सिर्फ LRU या लेखन मॉडल चाहते थे, आप यहाँ बंद कर सकते हैं. इस लेख के बाकी विचारों को दिखाता है कि कैसे मैं प्रतिष्ठा - राज्य मशीनों, सिस्टर्सिस, और समय सड़न के लिए लागू होता है. यह उन लोगों के लिए "आगे मील" है।

हाइवेस तथा सड़न

आदर्श प्रतिष्ठा के लिए (क्या हस्ताक्षर को समय पर बॉटल हो या मानव हो सकता है, वही सिद्धांत लागू होते हैं लेकिन अतिरिक्‍त अनुसंधायिकता के साथ:

// From PatternReputation.cs:42-108
public record PatternReputation
{
    public required string PatternId { get; init; }
    public required string PatternType { get; init; }
    public required string Pattern { get; init; }

    /// <summary>Current bot probability [0,1]. 0 = human, 1 = bot, 0.5 = neutral</summary>

    public double BotScore { get; init; } = 0.5;

    /// <summary>Effective sample count - decays over time, increases with observations</summary>

    public double Support { get; init; } = 0;

    /// <summary>Current reputation state - determines fast-path behavior</summary>

    public ReputationState State { get; init; } = ReputationState.Neutral;

    // Computed properties
    public double Confidence => Math.Min(1.0, Support / 100.0);

    public bool CanTriggerFastAbort =>
        State is ReputationState.ConfirmedBad or ReputationState.ManuallyBlocked;

    public bool CanTriggerFastAllow =>
        State is ReputationState.ConfirmedGood or ReputationState.ManuallyAllowed;
}

Hysters के साथ राज्य संक्रमण

पैटर्नों को सीधे ही अनियमित करने की पुष्टि करने के लिए न्यूट्रल से नहीं हटना पड़ता है.

// From PatternReputation.cs:367-421 - simplified
public PatternReputation EvaluateStateChange(PatternReputation reputation)
{
    if (reputation.IsManual)
        return reputation;

    var newState = reputation.State;
    var score = reputation.BotScore;
    var support = reputation.Support;

    switch (reputation.State)
    {
        case ReputationState.Neutral:
            // Can promote to Suspect or ConfirmedGood
            if (score >= 0.6 && support >= 10)
                newState = ReputationState.Suspect;
            else if (score <= 0.1 && support >= 100)
                newState = ReputationState.ConfirmedGood;
            break;

        case ReputationState.Suspect:
            // Can promote to ConfirmedBad or demote to Neutral
            if (score >= 0.9 && support >= 50)
                newState = ReputationState.ConfirmedBad;
            else if (score <= 0.4 || support < 10)
                newState = ReputationState.Neutral;
            break;

        case ReputationState.ConfirmedBad:
            // Can demote to Suspect (requires MORE evidence to forgive)
            if (score <= 0.7 && support >= 100)
                newState = ReputationState.Suspect;
            break;
    }

    // ... log state change and return ...
}

ध्यान दीजिए कि bymmition: यह बंद करने के लिए आसान है unped से बंद. ConfirmedBad → Suspect 100 समर्थन की आवश्यकता है, जबकि Neutral → Suspect केवल 10 की जरूरत है. यह मुश्किल से माफ करना मुश्किल है.

भूल जाने के लिए समय सड़न - पथ

जब पैटर्न शांत हो, वे तटस्थ की ओर सड़ता है:

// From PatternReputation.cs:334-361
public PatternReputation ApplyTimeDecay(PatternReputation reputation)
{
    if (reputation.IsManual)
        return reputation;

    var hoursSinceLastSeen = (DateTimeOffset.UtcNow - reputation.LastSeen).TotalHours;

    if (hoursSinceLastSeen < 1)
        return reputation;  // Too recent to decay

    // Score decay toward prior (0.5 = neutral)
    // new_score = old_score + (prior - old_score) × (1 - e^(-Δt/τ))
    var scoreDecayFactor = 1 - Math.Exp(-hoursSinceLastSeen / _options.ScoreDecayTauHours);
    var newScore = reputation.BotScore + (0.5 - reputation.BotScore) * scoreDecayFactor;

    // Support decay
    // new_support = old_support × e^(-Δt/τ)
    var supportDecayFactor = Math.Exp(-hoursSinceLastSeen / _options.SupportDecayTauHours);
    var newSupport = reputation.Support * supportDecayFactor;

    return reputation with
    {
        BotScore = Math.Clamp(newScore, 0, 1),
        Support = newSupport
    };
}

डिफ़ॉल्ट समय स्थिरांक:

  • अंक सड़न color: 168 घंटे (7 दिन) - अंक में 63% लोग निष्क्रियता के एक सप्ताह बाद निष्पक्ष रहने की ओर बढ़ते हैं
  • समर्थित सड़न एक्सपोजर: 336 घंटे (14 दिन) दो हफ्तों के अंदर 63%

इसका अर्थ है कि एक महीने के लिए शांत हो जाता है एक महीने के लिए अंत में न्यूट्रल करने के लिए वापस छोड़ दिया जाएगा. नहीं क्योंकि यह सुधार किया गया है क्योंकि इसके प्रमाण अपराज हो गया है.

पृष्ठभूमि में ज़्यादा - से - ज़्यादा लोग इस सेवा में लगे रहते हैं

वह ReputationMaintenanceService तीन आवधिक कार्यों को चलाता है:

// From ReputationMaintenanceService.cs:48-129
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    _logger.LogInformation("Reputation maintenance service starting");

    // Load persisted reputations on startup
    await _cache.LoadAsync(stoppingToken);

    var decayInterval = TimeSpan.FromMinutes(60);    // Hourly decay sweep
    var gcInterval = TimeSpan.FromHours(24);          // Daily garbage collection
    var persistInterval = TimeSpan.FromMinutes(5);   // Persist every 5 minutes

    var lastDecay = DateTimeOffset.UtcNow;
    var lastGc = DateTimeOffset.UtcNow;
    var lastPersist = DateTimeOffset.UtcNow;

    while (!stoppingToken.IsCancellationRequested)
    {
        await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
        var now = DateTimeOffset.UtcNow;

        // Decay sweep: push stale scores toward neutral
        if (now - lastDecay >= decayInterval)
        {
            await _cache.DecaySweepAsync(stoppingToken);
            lastDecay = now;
        }

        // Garbage collection: remove old neutral patterns
        if (now - lastGc >= gcInterval)
        {
            await _cache.GarbageCollectAsync(stoppingToken);
            lastGc = now;

            var stats = _cache.GetStats();
            _logger.LogInformation(
                "Reputation stats: {Total} patterns, {Bad} bad, {Suspect} suspect",
                stats.TotalPatterns, stats.ConfirmedBadCount, stats.SuspectCount);
        }

        // Persistence: save to SQLite
        if (now - lastPersist >= persistInterval)
        {
            await _cache.PersistAsync(stoppingToken);
            lastPersist = now;
        }
    }

    // Final persist on shutdown
    await _cache.PersistAsync(CancellationToken.None);
}

कचरा डाक्टर ऐसे पैटर्न हटाता है:

  • 90+ दिन पुराने
  • समर्थन समर्थन 1. 0
  • न्यूट्रल स्थिति में

यह गुण विकसित होने से रोकता है, जबकि मूल्यवान सीखा गया पैटर्न बनाए रखता है.

प्रमाण पत्र एक योक नहीं है - यह सही यहाँ है

बहुत से विकासकर्ताों में से बहुत सारे उपयोग-चिलिया या रेड तक पहुंचते हैं. लेकिन इस पैटर्न के लिए, सर्वोत्तम आदर्श है:

  1. लिखें- छुट्टी बोतलों को दूर करता है - PREACKS का एक-कार सीमा से कोई फर्क नहीं पड़ता जब लिख लिया जाता है
  2. स्थानीय भंडारण - कोई नेटवर्क देर से नहीं, कोई कनेक्शन पूल्स नहीं
  3. जीरो कॉन्फ़िगरेशन - बस एक फाइल पथ
  4. किनारे की तैनाती के लिए सही - एक राफेबर पि पर दौड़ता है
  5. पोर्टेबल - डाटाबेस सिर्फ एक फ़ाइल है जिसे आप चारों ओर कॉपी कर सकते हैं

स्कीमा न्यूनतम है:

CREATE TABLE IF NOT EXISTS learned_weights (
    signature_type TEXT NOT NULL,
    signature TEXT NOT NULL,
    weight REAL NOT NULL,
    confidence REAL NOT NULL,
    observation_count INTEGER NOT NULL DEFAULT 1,
    first_seen TEXT NOT NULL,
    last_seen TEXT NOT NULL,
    PRIMARY KEY (signature_type, signature)
);

CREATE INDEX IF NOT EXISTS idx_signature_type ON learned_weights(signature_type);
CREATE INDEX IF NOT EXISTS idx_confidence ON learned_weights(confidence);
CREATE INDEX IF NOT EXISTS idx_last_seen ON learned_weights(last_seen);

यदि आप बड़े पैमाने की जरूरत है, पैमाने पर एम्बेड करें. यदि आपको हब या पुनर्वास की जरूरत है, रेडिस या वितरण कैश की ओर पलटना है. संरचना सिर्फ कनेक्शन स्ट्रिंग में परिवर्तन नहीं करती है. finitary किनारे के लिए डिफ़ॉल्ट है, एक धर्म नहीं.

एवोल्यूशन के रूप में डिथरिंग टाई- इनेबल असफल

यदि डिथरिंग इस तरह के छोटे - से टुकड़े, विकासवाद पर विश्‍वास करते हैं ।

यह पैटर्न सबसे कम स्तर पर डायनर सिद्धांतों को लागू करता है:

  • संसाधन मास्क ✔ दबाव
  • एलआरयूपीक्यू ✔ स्वाभाविक चयन (आरसीआरसीज के योग्य हैं)
  • समय सड़न छोड़ने के लिए Escapeल समायोजन सक्षम करता है
  • एमएएम अद्यतन ▪ देखने के लिए तैयार रहिए
  • हबलिसिस परिवर्तन के लिए प्रतिरोध के माध्यम से स्थिरता

पूरा कैश एक विफलता नहीं है. विकासवाद का दबाव.. सिस्टम स्व-शंत्र: गर्म हस्ताक्षर रहता है, ठंडा हस्ताक्षर निकालता है, और व्यवहारिक मेमोरी वास्तव में क्या बात की ओर जा रही है.

कोई एमएल प्रशिक्षण. कोई बाहरी मॉडल नहीं. सिर्फ बनावट जो एक जीवित प्रणाली की तरह व्यवहार करती है.

समान्य - सरल स्ट्रक्चर, अव्यावहारिक व्यवहार

पूरा पैटर्न नीचे उतर जाता है:

  1. कैश पढ़ने के लिए सच्चाई का स्रोत है - सब फिल्टरों की पहुँच
  2. कैश तत्काल लिखता है, बाद में बना रहता है - कोई ब्लॉक नहीं मैं/ ओ
  3. एक्सपोजरिंग स्वचालित एलआरयू प्रदान करता है - .नेट में बनाया गया
  4. सीमा आकार चयन दबाव उत्पन्न करता है - तेज समायोजन
  5. पृष्ठभूमि फ्लश सिंक्रनाइज़ेशन में ग्रेब रहता है - आखिरकार संगतता ठीक है
  6. समय सड़ना गुम कर देता है - स्क्वर्ट सबूत गायब हो जाता है

अपने छोटे व्यवहार की दुकान एक जीवन प्रणाली की तरह काम करती है. यह याद है क्या बात है, भूल जाओ क्या नहीं करता है, और दबाव के तहत बेहतर हो जाता है.

कम - से - कम इमारत की बनावट सही साबित होती है । अति पाता है BAR अच्छा ध्यान दें. दबाव ढीले पड़ जाते हैं ।

यदि आप इस क्रिया में देखना चाहते हैं, तो जाँच करें अधिकतर अल्पपारदर्शिता. बोट्स - और डिथरिंग श्रृंखला गहरी तत्त्वज्ञान के लिए।

लिंक्स

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.