zoukankan      html  css  js  c++  java
  • redis基础知识

    redis基础知识

         Redis有9种基本数据类型,大部分盆友最熟悉的有这5种:string、hash、list、set、zset。其实,除此之外,经常用到的还有:bitmap、hyperloglog、geohash、stream

         下面来整理下各个数据类型的概念和基本用法。

    一、 普通数据类型(5种)

         Redis支持5种最基本的数据类型:string(字符串),hash(哈希),list(列表),set(集合)及 zset (sorted set:有序集合)。

         1、String

         1)String是简单的 key-value 键值对,value 可以是字符串,也可以是数字

         相关命令:

         SET key value

         GET key

         MSET

         MGET

         INCR

         INCRBY

         DECR

         DECRBY

         DEL

         EXPIRE

         TTL

          

        补充:为什么incr/decr具有原子性

        答:Redis的操作之所以是原子性的,是因为Redis是单线程的线程,是操作系统最小的执行单元,在单线程程序中,任务是要一个一个地做,必须做完一个任务后才会去做另一个任务

        2、List(列表)

        Redis列表是简单的字符串列表

        相关命令:

        LPUSH key value1 [value2]

        LPUSHX key value  将一个值插入到已存在的列表头部,列表不存在时操作无效

        LLEN

        LRANGE

        LPOP key

        LREM key count value

        LTRIM key start stop

        RPOP

        RPUSH

        RPUSHX

        BLPOP

        BRPOP

        BRPOPLPUSH LIST1 ANOTHER_LIST TIMEOUT 

        说明: BRPOPLPUSH: 从列表中取出最后一个元素,并插入到另外一个列表的头部; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。这个过程具有原子性。

        

        3、Hash(字典)

        相关命令:

        HSET

        HMSET

        HLEN

        HKEYS

        HGET

        HINCRBY

        HGETALL

        HSCAN

        

        4、Set(集合)

        Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

        相关命令:

        SADD

        SMEMBERS

        SCARD

        SRANDMEMBER  KEY [count]

        SINTER

        SISMEMBER

        SREM

        

        5、Sorted Set(有序集合)

        Redis有序集合类似Redis集合,不同的是增加了一个功能,即集合是有序的。一个有序集合的每个成员带有分数,用于进行排序。有序集合的成员是唯一的,但分数(score)却可以重复。

        相关命令:

        ZADD key score1 member1 [score2 member2]   注意:score 值可以是整数值或双精度浮点数

        ZCARD

        ZCOUNT key min max

        ZINCRBY

        ZRANGE

        ZRANGEBYSCORE

        ZREVRANGE

        ZRANK

        

        关于zrank的使用,需要注意:

        1)  返回有序集中指定成员的排名(索引下表)。

        2)  其中有序集成员按分数值递增(从小到大)顺序排列

        3)  如果需要依据分值从高到低来排列,需要使用zrevrank

         

        二、高级数据结构(3种)

         Redis中3种高级数据结构分别是HyperLogLog、bitmap、GEO

         1、HyperLogLog

         Redis 在 2.8.9 版本添加了 HyperLogLog 结构,它是用来做基数统计的算法。

         相关命令:
         PFADD key element [element...]
         PFCOUNT
         PFMERGE

         

        说明:

        1)HyperLogLog的计数统计是有一定的误差的,误差最大在1%以下

        2)Redis中每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

        3)因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素

        4)什么是基数?

        比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

        5)pfadd命令并不会一次性分配12k内存,而是随着基数的增加而逐渐增加内存分配;而pfmerge操作则会将sourcekey合并后存储在12k大小的key中,这由hyperloglog合并操作的原理(两个hyperloglog合并时需要单独比较每个桶的值)可以很容易理解。

        6)Redis 对 HyperLogLog 的存储进行了优化,在计数比较小时,它的存储空间采用稀疏矩阵存储,空间占用很小,仅仅在计数慢慢变大,稀疏矩阵占用空间渐渐超过了阈值时才会一次性转变成稠密矩阵,才会占用 12k 的空间。 

    应用场景

        a.   统计注册 IP 数

        b.   统计每日访问 IP 数

        c.   统计页面实时 UV 数

        d.   统计在线用户数

        e.   统计用户每天搜索不同词条的个数

    说明:

        a.  基数不大,数据量不大就用不上,会有点大材小用浪费空间

        b.  有局限性,就是只能统计基数数量,而没办法去知道具体的内容是什么

        c.   和bitmap相比,属于两种特定统计情况,简单来说,HyperLogLog 去重比 bitmap 方便很多

         一般可以将bitmap和hyperloglog配合使用,bitmap标识哪些用户活跃,hyperloglog计数

         2、bitmap 位图(大数据处理)

         bitmap是什么?

         通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间。

         说明:

         1) BIT位图不是实际的数据类型,而是在String类型上定义的一组面向位的操作。而String类型的key是二进制格式的,所以任意二进制格式的数据都可以作为key。Redis中是以8位二进制的方式存储。

         2) Redis从2.2.0版本开始新增了setbit,getbit,bitcount等几个bitmap相关命令。虽然是新命令,但是并没有新增新的数据类型,因为setbit等命令只不过是在set上的扩展

         常用命令:

          1)setbit

          SETBIT key offset value:给第offset位设置成value。当 key 不存在时,自动生成一个新的字符串值。

          

         注意:每次SETBIT完毕之后,有一个(integer) 0或者(integer)1的返回值,这个是在你进行SETBIT 之前,该offset位的比特值。

          2)getbit

          GETBIT命令: getbit key offset,获取指定offset下标的二进制,返回0或者1。当offset超过下标时,一直返回0。

          注意:offset是从左往右计数的,也就是从高位往低位。当超过位数时,结果是0。

           

         3)bitcount

          统计字符串被设置为1的bit数。

         BITCOUNT key [start end]  

         

         不指定start和end的情况下,bitcount会对整个该key对应的value字符串进行行计数。

         注意:

         1)统计指定key位置为1的数量(区间统计不建议使用,bitcount用的是byte来计算位数,其他setbit和getbit用的是bit

         2)bitCount虽然提供了start和end参数,但是这个说的是字节的位置,而不是对应"位"的位置。而redis中一个汉字占3个字节,一个英文字符占1个字节

         3)如果要指定区间,用bitcount并不是太合适,因为它的start或者end指的是第几个字节,不太好确定。不过,我们可以通过get把value取出来自己解析,一般情况下,这个value不会太大。

         比如下面这段代码:

     1 <?php
     2 // 字符串(中文)转化为二进制
     3 function StrToBin($str){
     4     $arr = preg_split('/(?<!^)(?!$)/u', $str);
     5     foreach($arr as &$v){
     6         $temp = unpack('H*', $v);
     7         $v = base_convert($temp[1], 16, 2);
     8         while($v<8)$v='0'.$v;
     9         unset($temp);
    10     }
    11     return join('',$arr);
    12 }
    13 
    14 
    15 $bin=StrToBin('中文');
    16 echo $bin;
    17 echo PHP_EOL;
    18 echo substr_count($bin,'1');
    19 
    20 // 输出结果
    21 // 111001001011100010101101111001101001011010000111
    22 // 26

        使用场景:用户签到

         4)bitop

          使用时间作为cacheKey,然后用户ID为offset,如果当日活跃过就设置为1
          那么我该如果计算某几天/月/年的活跃用户呢(暂且约定,统计时间内只有有一天在线就称为活跃),有请下一个redis的命令

          BITOP operation destkey key [key ...]
         说明:

          1)对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。

          2)BITOP 命令支持 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种参数

          3)操作的时候,最短的那个字符串,转换二进制,位数不足的就在后面用0填充,直到与最长的字符串长度相等

          4)操作的结果,返回的是最长的那个字符串的长度

         

        使用场景:统计活跃用户

         3、GEO

         自Redis 3.2开始,Redis基于geohash和有序集合提供了地理位置相关功能。

          Redis Geo命令实现
          Redis将地理位置的52位GeoHash值作为有序集合的score,将地理位置存放在有序集合中进行保存。

          后续按位置搜索时,依据GeoHash的特性搜索当前方块与环绕当前方块的8个方块来搜索目标位置集合。Redis中接受的有效的精度范围为-180到180度,有效维度范围为-85.05112878到 85.05112878度(靠近南北极的一小块地方是无法生成索引的)。

          实现方式:
          Redis内部使用有序集合来保存key,每一个member的score大小为一个52位的Geohash值(double类型精度为52位)。
          实际上Redis内部实现的时候就是将GEOADD命令转换成ZADD命令来实现的。(这也解释了为什么没有专门的georem命令,地理位置信息是通过使用ZREM命令来删除成员。)

         常用命令:

         1) GEOADD key longitude latitude member [longitude latitude member ...]

         2) GEOPOS

         3) GEODIST key member1 member2 [m|km|ft|mi]    用于返回两个给定位置之间的距离,默认单位:m(米)

         4)GEORADIUS   以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

         说明:

         WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。

         WITHCOORD: 将位置元素的经度和维度也一并返回。

         WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。

         COUNT 限定返回的记录数。

         ASC: 查找结果根据距离从近到远排序。

         DESC: 查找结果根据从远到近排序。

         5)GEORADIUSBYMEMBER :和GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的, 而不是使用经度和纬度来决定中心点。

         6)GEOHASH

         用于获取一个或多个位置元素的 geohash 值

          实现方式:

         Redis在内部生成有序集合成员score时的geohash值与标准的算法略有差异(Redis内部使用-85,85作为维度范围,标准使用-90,90)。

         这个命令返回的是标准值,与 https://en.wikipedia.org/wiki/Geohash 中标准算法和http://geohash.co/网站的计算结果一致。

     

     三、Stream

         这是Redis5.0引入的全新数据结构,用一句话概括Stream就是Redis实现的内存版kafka。

         Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。

         简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。

         消息队列相关命令:

    XADD key ID field value [field value ...]    说明: ID 指的是消息 id,我们使用 * 表示由 redis 生成,可以自定义,但是要自己保证递增性。

    XTRIM

    XDEL

    XLEN

    XRANGE

    XREVRANGE

    XREAD

    消费者组相关命令:

    XGROUP CREATE

    XREADGROUP GROUP

    XACK

    XGROUP SETID

    XGROUP DELCONSUMER

    XGROUP DESTROY

    XPENDING

    XCLAIM

    XINFO

    XINFO GROUPS

    XINFO STREAM

     参考链接:

     https://developer.aliyun.com/article/62844

     https://segmentfault.com/a/1190000008188655

  • 相关阅读:
    生产者消费者模式 (在已有线程下不断生产不断消费)
    Spring boot Spring cloud 框架搭建
    个人见解
    加入博客园!
    sqlserver 工具
    slqserver 拆分函数
    sqlserver 自定义函数与存储过程的区别
    sqlserver row_number() over() 理解
    C# Newtonsoft.Json JObject移除属性
    PropertyInfo 简单用法
  • 原文地址:https://www.cnblogs.com/hld123/p/14654305.html
Copyright © 2011-2022 走看看