Heim  >  Artikel  >  Datenbank  >  Verwenden Sie Redis als Zähler, um das Abstimmungssystem zu verbessern

Verwenden Sie Redis als Zähler, um das Abstimmungssystem zu verbessern

齐天大圣
齐天大圣Original
2020-05-08 16:34:302138Durchsuche

Erster Blick auf die Anwendungsszenarien: Vor einigen Jahren gab es in WeChat viele Abstimmungssysteme. Viele Menschen suchen Menschen in ihrem Freundes- oder Freundeskreis, um Stimmen zu gewinnen. Zu dieser Zeit führte auch ein relativ großer Vergnügungspark diese Abstimmungsveranstaltung durch. Es schien, dass man kostenlos spielen konnte, wenn man eine bestimmte Anzahl an Stimmen überschritt. Ich wurde auch von meinen Freunden gebeten, für ihn zu stimmen. Es schien, als könnte ich drei oder fünf Stimmen pro Tag abgeben. Ich kann mich nicht an die genauen Details erinnern. Nachdem ich das System betreten hatte, klickte ich auf die Schaltfläche „Abstimmen“ für meinen Freund und stellte fest, dass nichts passierte. Ich dachte, es sei ein Problem mit meinem Netzwerk, aber später fand ich heraus, dass es ein Problem mit dem Programm war. Ich vermutete damals, dass zu viele Leute abstimmten und das System eine Zeit lang nicht damit umgehen konnte.

Weil ich zu dieser Zeit gerade Redis lernte. Daher denke ich, dass diese Funktion durch den Redis-Zähler verbessert werden kann.

Hier zählen wir nur die Gesamtzahl der von Benutzern abgegebenen Stimmen, ohne die spezifische Abstimmungssituation der Benutzer zu berücksichtigen. Beispielsweise berücksichtigen wir nicht die Aufzeichnung, wann A für B gestimmt hat. Wenn Sie diese Situation berücksichtigen, müssen Sie andere Lösungen verwenden (Nachrichtenwarteschlangen können verwendet werden).

Verifizierung

Zuerst muss die Anzahl der Stimmen jedes Benutzers überprüft werden. Benutzer haben jeden Tag drei Möglichkeiten zur Abstimmung, sodass wir einen Schlüssel erstellen und dessen Gültigkeitsdauer auf morgen früh festlegen können. Jedes Mal, wenn der Benutzer eine Stimme abgibt, wird 1 hinzugefügt. Wenn der Benutzer 3 Stimmen erreicht, wird ihm mitgeteilt, dass die Anzahl der Stimmen heute aufgebraucht ist.

// 投票次数校验
function checkVote($uid)
{
    $key = "uid:$uid:cnt";
    $tomrTime = mktime(0,0,0, date('m'), date('d')+1, date('Y'));
    
    if (!$redis->exsits($key)) {
        $redis->set($key, 0, ['ex' => $tomrTime - time()]);
        return true;
    } else if ( ($cnt = $redis->get($key)) < 3 ) {
        return true;
    } else {
        return false;
    }
}

Stimmen zählen

Nachdem die Anzahl der Stimmen überprüft wurde, ist es notwendig, die Anzahl der von den Benutzern erhaltenen Stimmen zu zählen.

// 得票数计数
// uid表示投票人id
// touid表示得票人id
function vote ($uid, $toUid)
{
    $key = "uid:$toUid:vote";
    
    // 投票数校验
    if (checkVote($uid)) {
        // 统计投票数及参选人得票数
        $redis->incr($key);
        $redis->incr("uid:$uid:cnt");
        
        return true;
    } else {
        return false;
    }
}

Meine eigene Alibaba Cloud-Hostkonfiguration verfügt nur über eine 1-Kern-CPU und eine 1G-Speicherkonfiguration. Die Steigerungsleistung kann mehr als 100.000 pro Sekunde erreichen. Die Redis-Leistung ist wirklich schrecklich.

# redis-benchmark -t incr -q
INCR: 105708.25 requests per second

Mysql aktualisiert asynchron die Anzahl der Benutzerstimmen

Schließlich müssen wir nur noch eine geplante Aufgabe ausführen und MySQL jeden Tag darauf zugreifen lassen bestimmte Zeit Synchronisieren Sie die Stimmenzahl des Benutzers.

Die Methode besteht darin, eine Endlosschleife zu erstellen und jedes Mal die Stimmen von 50 Benutzern zu erhalten, bis alle Benutzer durchlaufen sind, dann die Schleife zu verlassen und das Skript zu beenden.

$start = 0;
while (true) {
    // 每次循环取50个用户id
    $users = $DB->query("SELECT uid,votes FROM users LIMIT $start, 50");
    if (!$users) {
        exit();
    }
    $keys = [];
    foreach ($users as $userinfo) {
        $keys[] = "uid:{$userinfo[&#39;uid&#39;]}:vote";
    }
    $votes = $redis->mget($keys);
    foreach ($votes as $index => $vote) {
        if ($vote != $users[$index][&#39;votes&#39;]) {
            $DB->query("UPDATE users SET votes = &#39;$vote&#39; WHERE uid=&#39;{$users[$index][&#39;uid&#39;]}");
        }
    }
    $start += 50;
}

Der mget-Befehl von Redis besteht darin, die Werte mehrerer Schlüssel gleichzeitig abzurufen. Nachdem Sie die Anzahl der in Redis gespeicherten Redis-Stimmen ermittelt haben, müssen Sie diese zunächst mit der Anzahl der Stimmen in MySQL vergleichen. Aktualisieren Sie MySQL-Daten nur, wenn sie unterschiedlich sind.

Das obige ist der detaillierte Inhalt vonVerwenden Sie Redis als Zähler, um das Abstimmungssystem zu verbessern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn