Redis realizes the idea of caching likes

Redis implementation of cached like ideas

As we all know, live broadcast platforms such as Youku and Douyin will have the function of clicking the screen to like. It is best to leave this kind of less important data to redis for processing. It can be stored in the MySQL database regularly to realize the data processing. of persistence.
This blog is based on tp6 framework technology, combined with think-queue message queue and middleware middleware.
Realize the synchronization of likes from redis to mysql.

This blog uses message queue: composer require topthink/think-queue

1. Controller layer

The main purpose is to store the front-end data in redis and use the hash table of redis to store it;
The hash table of redis stores key-value pairs: cache()->hset(v5_like_num’, user_1’,0);
The hash table of redis obtains key-value pairs: cache()->hget(v5_like_num’, user_1’);
Redis hash table stepping value: cache()->hincrby(v5_like_num’, user_1’, stepping integer’);

namespace app\v5\controller;

use app\BaseController;
use think\facade\Db;

/**
 * redis likes
 */
class Redis extends BaseController
{<!-- -->
    /**
     * Display view: The view here is only for convenience of display
     */
    public function index()
    {<!-- -->
        $data['res'] = Db::table('v5_like_num')->select()->toArray();
        $data['redis_like_num'] = cache()->hget('v5_like_num', 'user_1');
        // halt($data);
        return view('redis/index', $data);
    }

    /**
     * Add data to the redis interface
     */
    public function add()
    {<!-- -->
        $step = (int)request()->post('step', 0);
        //Add redis
        cache()->hincrby('v5_like_num', 'user_1', $step);
        // dump($step);
        // dump(cache()->hget('v5_like_num', 'user_1'));
    }
}

View layer reference: view/redis/index
Source code: https://github.com/xiaopacairq/tpAdmin/blob/main/app/v5/view/redis/index.php
The core code is as follows:

// Likes accumulate points and are cached to redis every 3 seconds.
setInterval(function() {<!-- -->
            $.post('/v5/redis/add', {<!-- -->
                step,
            }, function(res) {<!-- -->
                step = 0;
            }, '')
        }, 3000)

2. Database layer

  1. Mysql database
  2. Reids database

3. Job type

  1. The configuration option of queue is config/queue.php. The default is sync execution, which can be modified to redis cache.
<?php
// + -------------------------------------------------- -----------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// + -------------------------------------------------- -----------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// + -------------------------------------------------- -----------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// + -------------------------------------------------- -----------------------
// | Author: yunwuxin <[email protected]>
// + -------------------------------------------------- -----------------------

return [
    'default' => 'redis',
    'connections' => [
        'sync' => [
            'type' => 'sync',
        ],
        'database' => [
            'type' => 'database',
            'queue' => 'default',
            'table' => 'jobs',
            'connection' => null,
        ],
        'redis' => [
            'type' => 'redis',
            'queue' => 'default',
            'host' => '127.0.0.1',
            'port' => 6379,
            'password' => '',
            'select' => 0,
            'timeout' => 0,
            'persistent' => false,
        ],
    ],
    'failed' => [
        'type' => 'none',
        'table' => 'failed_jobs',
    ],
];

To write a Job class, please refer to the documentation: https://packagist.org/packages/topthink/think-queue
Specific work content: Store the redis cached data into mysql at a scheduled time of 5 seconds.

<?php

namespace app\job;

use think\queue\Job;
use think\facade\Db;

classJob1
{<!-- -->

    public function fire(Job $job, $data)
    {<!-- -->
        $isJob = $this->redisToMysql($data);
        if ($isJob) {<!-- -->
            $job->delete();
        } else {<!-- -->
            //This method can be used to check how many times this task has been retried.
            $attempts = $job->attempts();
            if ($attempts == 0 || $attempts == 1) {<!-- -->
                //Reissue this task
                $job->release(5); //$delay is the delay time, and execution will continue after a delay of 5S
            } elseif ($attempts == 2) {<!-- -->
                $job->release(5); // Continue execution after a 5S delay
            }
        }
    }

    public function failed($data)
    {<!-- -->

        // ...the task failed after reaching the maximum number of retries.
    }

    private function redisToMysql($number)
    {<!-- -->
//Save redis data into mysql database
        $isAdd = Db::table('v5_like_num')
            ->where('title', 'Article 1')
            ->inc('like_num', $number)
            ->update();
        if ($isAdd) {<!-- -->
            return true;
        } else {<!-- -->
            return false;
        }
    }
}

4. Middleware middleware

Middleware work: scheduled execution queue Queue::later(5, 'Job1@fire', $number, 'jobdemo');
When working in a queue, you need to execute it on the command line: php think queue:work --queue jobdemo

  1. Register middleware
<?php
//Global middleware definition file
return [
    //Global request cache
    // \think\middleware\CheckRequestCache::class,
    // Multi-language loading
    // \think\middleware\LoadLangPack::class,
    //Session initialization
    \think\middleware\SessionInit::class,
//Initialize message middleware
    app\v5\middleware\RedisToMysql::class,
];
  1. Implement middleware
<?php

namespace app\v5\middleware;

use think\facade\Queue;

class RedisToMysql
{<!-- -->
    public function handle($request, \Closure $next)
    {<!-- -->
        $number = (int)cache()->hget('v5_like_num', 'user_1');
        //execution queue
        $isPushed = Queue::later(5, 'Job1@fire', $number, 'jobdemo');
        if ($isPushed) {<!-- -->
            cache()->hset('v5_like_num', 'user_1', 0); //The queue is executed successfully and the like step value is 0
        }
        return $next($request);
    }
}

Execute php think queue:work --queue jobdemo. Only when the processed state appears, the queue execution is considered successful. It is always in the processing state. There is a high probability that the Job class is written incorrectly!

The implementation result is:

  • Likes on the front end will be passed to the back end interface after 3 seconds.
  • The back-end interface caches the front-end likes collection to redis
  • The middleware automatically caches redis data to mysql every 5 seconds and clears the redis cache.

This blog ends here, thinkphp, and your hardworking self!