流水线功能pipeline

redis的pipeline(管道)功能在命令行中没有,但redis是支持pipeline的,而且在各个语言版的client中都有相应的实现。
Redis本身是一个cs模式的tcp server, client可以通过一个socket连续发起多个请求命令。 每个请求命令发出后client通常会阻塞并等待redis服务端处理,redis服务端处理完后将结果返回给client。

一次redis的网络通信

一次通讯

1次时间=1次网络时间+一次命令时间。

批量redis网络通信

批量redis网络通信

n次时间=n次网络时间+n次命令时间

pipeline功能是把n条命令进行打包、变成一个发送到服务器、服务器在进行把打包的命令列队执行、计算结果并返回,这样能介绍很大一部分网络开销

多次命令一次打包
注意点:


1、redis的命令时间是微妙级别。
2、pipeline每次条数要控制(网络)。

举个例子

光的速度是299792458米/秒 、等于299792公里/秒,约等于300000公里/秒

我的服务器在香港

地理图

直线距离是1954.9公里、告诉公路的距离是2199.1公里。

光纤传输速度约等于光速的2/3。一次命令传输的时间=(19552)/(3000002/3)=19.55毫秒。

这还是最理想化的。

redis命令执行是微秒级别,网络执行是毫秒级别

pipeline每次只能作用在一个Redis节点上

<?php

set_time_limit(0);

//计时函数
function G($start,$end='',$dec=4)
{
    static $_info = array();
    if (!empty($end))
    {
        if(!isset($_info[$end])) $_info[$end] = microtime(TRUE);
        $sconds = number_format(($_info[$end]-$_info[$start]), $dec) * 1000;
        echo "{$sconds}ms<br />";
    }
    else
    {
        $_info[$start] = microtime(TRUE);
    }
}

$redis = new Redis();
$redis->connect('127.0.0.1');
$redis->auth("123321");

G('t');
$redis->pipeline();
for ($i=0; $i < 100000 ; $i++) {
    $redis->set("test_{$i}", pow($i, 2));
    $redis->get('test_{$i}');
}
$redis->exec();
G('t','r');

G('m');
$redis->multi();
for ($i=0; $i < 100000 ; $i++) {
    $redis->set("test_{$i}", pow($i, 2));
    $redis->get('test_{$i}');
}
$redis->exec();
G('m','i');

$redis->flushdb();

G('f');
for ($i=0; $i < 100000 ; $i++) {
    $redis->set("test_{$i}", pow($i, 2));
    $redis->get('test_{$i}');
}
G('f','e');

执行结果:

本地环境测试。


//pipeline的执行时间:662.3ms
//multi的执行时间:6138ms
//正常情况下:5554.3ms

本地的相差8倍

把代码$i改成100。香港vps执行结果:

//pipeline的执行时间:128ms
//multi的执行时间:14633.2ms
/正常情况下:14683ms

我的香港vps网络不好:pipeline和正常的相差114倍.

hyperloglog

hyperloglog本质是string类型、也算新的数据结构,用于极小空间完成独立数量统计

type hyperloglog_key 结果是string

hyperloglog的三个命令

命令:pfadd

向hyperloglog添加元素

127.0.0.1:6379> pfadd success:user  time1  time2
(integer) 1
127.0.0.1:6379> type success:user
string
127.0.0.1:6379> pfcount success:user
(integer) 2
127.0.0.1:6379> pfadd success:user time1 time2 time3
(integer) 1
127.0.0.1:6379> pfcount success:user
(integer) 3
127.0.0.1:6379>

命令:pfcount

计算hyperloglog的独立总数命令

127.0.0.1:6379> pfcount success:user
(integer) 2
127.0.0.1:6379> pfcount access:user
(integer) 1
127.0.0.1:6379> pfcount success:user  access:user
(integer) 2
127.0.0.1:6379>

命令:pfmerge

合并多个hyperloglog

语法:pfmerge destkey sourcekey sourcekey

127.0.0.1:6379> pfmerge access_and_sccess:merge success:user  access:user
OK
127.0.0.1:6379> pfcount access_and_sccess:merge
(integer) 3
127.0.0.1:6379>

补充:hyperloglog:添加操作会对已经有的数据进行覆盖、pfmerge命令也是,success:user 是3个 access是两个,其中他两有time1和time2是一样的,合并结果为3位。hyperloglog的结果是一种特殊的字符串、它不能删除或者取出数据。

如果统计100w条独立用户统计的内存消耗

1天是15KB,1个月450KB,1年是15kb*365约等于5mb。

缺点:错误率是0.81%。无法取出添加的数据

GEO(地理信息定位)

v:3.2版本

用于存储经纬度:计算两地距离,范围计算

命令:geoadd

语法:geoadd key longitudel latitude member [longitudel latitude member ]

增加地理位置信息

添加几条数据 、北京、黑龙江伊春、成都、香港

127.0.0.1:6379> geoadd cities:locations 116.405285 39.904989 Bejing
(integer) 1
127.0.0.1:6379> geoadd cities:locations 128.899396 47.724775 Yichun
(integer) 1
127.0.0.1:6379> geoadd cities:locations 104.065735 30.659462 Chengdu  114.173355 22.320048 HongKong

命令:geopos

语法:geopos key member [member ...]

获取地理位置信息

127.0.0.1:6379> geopos cities:locations Chengdu
1) 1) "104.06573742628097534"
   2) "30.65946118872339099"
127.0.0.1:6379>

命令:geodist

计算两个地理位置的距离

语法:geodist key member1 member2 [unit]

获取两个地理位置的距离
unit:m(米)、km(千米)、mi(英里)、ft(尺)

计算北京和香港之间的距离

127.0.0.1:6379> geodist cities:locations Bejing HongKong  km
"1967.2319"
127.0.0.1:6379>

结果1967km

命令:georadius

语法:georadius key longitude latitude radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]

命令:georadiusbymember key menber radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key]

获取指定位置范围内的地理位置信息集合

withcoord:返回结果中包含经纬度。

withdist:返回结果中包含距离中心节点位置。

COUNT count:执行返回结果的数量。

asc|desc:返回结果按照距离中心节点的距离做升序或者降序。

store key:将返回结果的地理位置信息保存到指定键

storedist key:将返回结果距离中心节点的距离保存到指定键.

127.0.0.1:6379>  GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
127.0.0.1:6379> GEORADIUS Sicily 15 37 200 km WITHDIST
1) 1) "Palermo"
   2) "190.4424"
2) 1) "Catania"
   2) "56.4413"
127.0.0.1:6379> GEORADIUS Sicily 15 37 200 km WITHCOORD
1) 1) "Palermo"
   2) 1) "13.361389338970184"
      2) "38.115556395496299"
2) 1) "Catania"
   2) 1) "15.087267458438873"
      2) "37.50266842333162"
127.0.0.1:6379> GEORADIUS Sicily 15 37 200 km WITHDIST WITHCOORD
1) 1) "Palermo"
   2) "190.4424"
   3) 1) "13.361389338970184"
      2) "38.115556395496299"
2) 1) "Catania"
   2) "56.4413"
   3) 1) "15.087267458438873"
      2) "37.50266842333162"
127.0.0.1:6379>

type geoKey=zset 类型是zset

用命令zrem 进行删除 : zrem key member

官网文档:http://www.redis.cn/commands/georadiusbymember.html

Last modification:February 10, 2020
如果觉得我的文章对你有用,请随意赞赏