Redis 定位IP地址的妙用

目录

Redis 命令解析

ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

Available since 2.2.0. Time complexity: O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. If M is constant (e.g. always asking for the first 10 elements with LIMIT), you can consider it O(log(N)).

Returns all the elements in the sorted set at key with a score between max and min (including elements with score equal to max or min). In contrary to the default ordering of sorted sets, for this command the elements are considered to be ordered from high to low scores. The elements having the same score are returned in reverse lexicographical order. Apart from the reversed ordering, ZREVRANGEBYSCORE is similar to ZRANGEBYSCORE. Return value

Array reply: list of elements in the specified score range (optionally with their scores). Examples

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZREVRANGEBYSCORE myzset +inf -inf
1) "three"
2) "two"
3) "one"
redis> ZREVRANGEBYSCORE myzset 2 1
1) "two"
2) "one"
redis> ZREVRANGEBYSCORE myzset 2 (1
1) "two"
redis> ZREVRANGEBYSCORE myzset (2 (1
(empty list or set)
redis> 

数据结构


PHP代码
<?php

namespace App\Console\Commands\Tmp;

use Illuminate\Console\Command;
use RedisClient;
use DB;

class TmpCompareIP2 extends Command {

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'tmp:compare_ip2';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '测试根据iplong获取IP省份城市';

    public function __construct()
    {
        parent::__construct();

    }

    public function getDbData()
    {
        return DB::select("select * from t_ip_ip where country = :country", ['country' => '中国']);
    }

    public function setRedis()
    {
        $data  = $this->getDbData();
        $total = count($data);
        foreach ($data as $k => $v) {

            $val = $v->country . ':' . $v->province . ':' . $v->city . ":" . $v->ip_start;

            $min_score = $v->ip_start;

            $this->info($v->ip_start . ':' . $v->ip_end . ':' . $val);

            RedisClient::zadd("ip_location", $min_score, $val);

            $this->info("score:{$min_score}, {$k}/{$total}");
        }
    }

    public function getIPLocation($iplong)
    {

        $res = RedisClient::zrevrangebyscore('ip_location', $iplong, '-inf', [
            'limit' => [0, 1],
        ]);

        $res = array_get($res, 0);
        $res = explode(':', $res);

        return [
            'country'  => array_get($res, 0, '未知'),
            'province' => array_get($res, 1, '未知'),
            'city'     => array_get($res, 2, '未知'),
        ];
    }

    public function handle()
    {
        ini_set("memory_limit", "-1");

        try {

            //$this->setRedis();

            $ip = '183.64.63.98';
            $this->info(ip2long($ip));

            $res = $this->getIPLocation(ip2long($ip));

            dd($res);

        } catch (\Exception $e) {

        }
    }

}