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
  • 阅读 ( 178 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
plum
plum

1 篇文章

作家榜 »

  1. Pack 1132 文章
  2. 轩辕小不懂 394 文章
  3. 小编-青青 120 文章
  4. Cara 33 文章
  5. 文双 25 文章
  6. 小威 23 文章
  7. 吉洪叶 21 文章
  8. 五福 12 文章