page contents

Redis - set 慢查询与管道

Redis - set 慢查询与管道

<?php

require_once "common.php";


/*

 * Redis - set:集合类型与结构

 * 每个集合最多可以存储 232 - 1 个元素(40多亿)

 * 类型与list列表相似,都可以存储多个字符串元素的集合,但和list不同的是不允许重复额元素,而且set集合中的元素是没有顺序的,不存在元素下标。

 *

 *redis的set类型是使用哈希表构造的,因此复杂度是O(1),它支持集合内的增删改查,并且支持多个集合间的交集、并集、差集操作。可以利用这些集合操作,解决程序开发过程当中很多数据集合间的问题。

 *

 * set 使用哈希表结构:

 * 1 数字元素少于513个的时候使用Intset(整数集合)集合的内部实现,以减少内存的使用。

 * 2 数字元素大于512 或者 元素为字符串,则使用哈希表 作为集合的内部实现

 * */


//基础函数

sadd();//添加元素,格式是:sadd set的key item的项值,item项可以有多个

smembers();//获取集合中所有元素,格式是:smembers set的key

sismember();//判断元素是否在集合中,格式是:sismember set的key item的项值

srem();//删除元素,格式是:srem set的key item项的值

scard();//获取集合中元素的个数,格式是:scard set的key

srandmember()//随机获取集合中的元素,格式是:srandmember set的key[数量]。(数量为正数时,会随机获取这么多个不重复的元素;如果数量大于集合元素个数,返回全部;如果数量为负,会随机获取这么多个元素,可能有重复。)

spop()//弹出元素,格式是:spop set的key

smove();//移动元素。格式是:smove 源set的key 目的set的key item项的值 (ps:一次只能移动一个item)

sdiff();//差集,返回在第一个set里面而不在后面任何一个set里面的项。格式是:sdiff set的key 用来比较的多个set的key

sdiffstore();//差集并保留结果,格式是:sdiffstore 存放结果的set的key set的key 用来比较的多个set的key

sinter();//交集,返回多个set里面都有的项。格式是:sinter 多个set的key 

sinterstore();//交集并保留结果。格式是:sinterstore 存放结果的key 多个set的key

sunion();//并集。格式是:sunion 多个set的key

sunionstore();//并集并保留结果。格式是:sunionstore 存放结果的set的key 多个set的key


/*

  应用案例 1 商品筛选

  商城不同属性的产品ID集合 如:电脑的内存8G 一个集合,16G 一个集合等待,前段界面筛选的时候获取对应的集合ID ,并集/交集/差集 取出ID集合 再根据ID集合查询数据



  应用案例 2 抽奖

  使用 srandmember/spop 随机获取奖品

这两个命令功能非常相似,都是从集合中返回一个元素值。不同的是,sRandMember不会从集合中删除返回的元素,但是sPop会删除。这两个命令可以分别实现不同的抽奖算法。

比如,集合中有100个元素,值从数字1到数字100.我们定义抽到的是数字1的话,即表示中奖。

使用sRandMember的话,不管之前抽过多少次,下次抽中的概率都是1%。而使用sPop的话,则每次抽中的概率都不一样。第一个人抽中概率是1%,当第一个人没抽中的话,第二个人抽中概率就是1/99,以此类推。


应用案例 3

好友/关注/粉丝/感兴趣的人集合

  a. sinter命令可以获得A和B两个用户的共同好友

      b. sismember命令可以判断A是否是B的好友

       c. scard命令可以获取好友数量

       c. 关注时,smove命令可以将B从A的粉丝集合转移到A的好友集合


    应用案例 4 随机展示


    通常,app首页的展示区域有限,但是又不能总是展示固定的内容,

一种做法是先确定一批需要展示的内容,再从中随机获取。

如下图所示,酷狗音乐K歌擂台赛当日的打擂歌曲共29首,首页随机展示5首;

昨日打擂金曲共200首,首页随机展示30首。


 应用案例 5 黑名单/白名单

 经常有业务出于安全性方面的考虑,需要设置用户黑名单、ip黑名单、设备黑名单等,set类型适合存储这些黑名单数据,sismember命令可用于判断用户、ip、设备是否处于黑名单之中。

 */



/*

redis 慢查询

许多存储系统(例如MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作。所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阈值,就将这条命令的相关信息(例如:发生时间、耗时、命令的详细信息)记录下来,Redis也提供了类似的功能。


redis 命令的执行时间(排除tcp通讯和排挡等候等等耗时,只是Redis内部执行的时间)的时长,

时长以微秒计算(1秒=1000毫妙,1毫妙=1000微秒)

设置参数:

slowlog-log-slower-than:指定执行时间超过多少微秒(1秒等于1000000微秒) 的命令请求会被记录到日志上

slowlog-max-len:指定服务器最多保存多少条慢查询操作

设置命令:

CONFIG  SET  slowlog-log-slower-than  num

CONFIG  SET  slowlog-max-len  num

查看慢查询命令:

SLOWLOG GET   


慢查询日志的添加和删除

当慢查询的条数达到最大值时,采用先进先出的方式删除最老的记录,所以可以使用工具vc-redis-sniffer,从redis中抓取慢日志。保存起来 方便分析


 */



/*

Redis pipeline管道命令:

客户端与Redis服务器之间TCP通讯是有耗时的,如果大量的一组设置 如 给list/zset/set 添加大量的元素,就会有通讯间耗时比较多,这时候利用pipeline管道,把这一组命令都放入管道中,一次性的提交到服务器中,服务器处理完成在一次性的返回结果,从而节省了大量的通讯时间。

注意:使用通道的一组命令是不存在因果关系的,因为他们几乎是同时执行,不可能在客户端中做任何的前后因果关系逻辑判断处理。

特点:高内聚低耦合,


优点:

1 通过打包命令,一次性执行,可以节省 连接->发送命令->返回结果 所产生的往返时间,

减少的I/O的调用次数。


缺点:

1.前先缓存起所有命令的处理结果。这样就有一个内存的消耗。

 2 是责任链模式,这个模式的缺点是,每次它对于一个输入都必须从链头开始遍历(参考Http Server处理请求就能明白),这确实存在一定的性能损耗。

 3 不保证原子性,如果要求原子性的,不推荐使用 pipeline



 */

$redisObj = new \Redis();

$redisObj->connect('127.0.0.1', 6379);

$time_start = microtime(true);

$mcKey      = "lpush:normal";

for ($i = 0; $i < 20000; $i++)

{

    $redisObj->lPush($mcKey, $i);

}


$time_end = microtime(true);

$time     = $time_end - $time_start;

echo "逐条写模式耗时: {$time}\n";


// =======================================


$time_start = microtime(true);

$redisObj->multi(Redis::PIPELINE);

unset($time, $time_end, $mcKey);

$mcKey = "lpush:pipeline";

for ($i = 0; $i < 20000; $i++)

{

    $redisObj->lPush($mcKey, $i);

}

$redisObj->exec();


$time_end = microtime(true);

$time     = $time_end - $time_start;

echo "pipeline 模式运行耗时:{$time}\n";

  • 发表于 2021-01-12 18:08
  • 阅读 ( 935 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
plum
plum

1 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章