《玩转Redis》系列文章 by zxiaofan主要讲述Redis的基础及中高级应用,穿插企业实战案例。本文是《玩转Redis》系列第【2】篇,最新系列文章请前往 公众号 “zxiaofan”(点我点我)查看,或 百度搜索 “玩转Redis zxiaofan”(点我点我)即可。

  最新思维导图原图可联系公众号【zxiaofan】后台获取。
Redis-最新思维导图原图

  本文更适合用于复习总结,阅读》实战》阅读 更有效果哟,主要包含以下内容:

  • String(字符串);
  • List(列表);
  • Set(集合);
  • Hash(散列);

  后续会介绍其他高级数据结构:

  • Sorted Set(有序集合);
  • Bitmap(位图);
  • HyperLogLog;
  • Streams(流);

文章思路:

  • 数据结构应用场景及注意事项;
  • 数据结构各命令对比分析;

异常统一说明:
error(out of range)导图简写@EOOR;
负数偏移量表示倒数第几,导图简写@LBN(last but number);


1、String

1.1、String应用场景及注意事项

1.1.1、String应用场景

  String可以说是Redis中最常见的数据结构,没有之一。
  String结构可存储字符串或者各种类型的二进制数据

  • 分布式锁;
  • 计数器;
  • 分布式全局唯一ID;

1.1.2、String注意事项

  String底层结构是动态字符串,可修改指定位置数据,通过预分配冗余空间减少内存的频繁分配,实际分配的空间capacity一般要高于实际字符串长度len。当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次只会多扩1M的空间。字符串最大长度为512M(512 1024 1024个字符)。
  数字及浮点数在Redis中以字符串形式存储。

// 如何证明 String最大长度是512M;
// 512M=512*1024*1024;
127.0.0.1:6379> setrange ran 536870911 a
(integer) 536870912
127.0.0.1:6379> strlen ran
(integer) 536870912
127.0.0.1:6379> append ran a
(error) ERR string exceeds maximum allowed size (512MB)

1.2、String各命令对比分析

  String命令支持以下操作类型:单一操作、批量操作、字符操作、位操作、计数操作。

1.2.1、String单元素操作

【核心命令】:SET、SETNX、SETEX、PSETEX、GET、GETSET、APPEND、STRLEN;

注意:

  • 【SET】:Redis2.6.12 版本支持设置value值时,同时设置过期时间,此操作为原子操作;
  • 【PSETEX】:Redis2.6.0 版本支持,可将过期时间精确到毫秒;

【Redis-String单元素操作】命令简述:

命令功能参数
SET设置value值,支持选项key value [expiration EX seconds/PX milliseconds] [NX/XX]
SETNXkey不存在才允许设置key value
SETEX设置value及过期时间(秒)key seconds value
PSETEX设置value及过期时间(毫秒)key milliseconds value
GET查询指定keykey
GETSET查询返回旧值设置新值key value
APPENDvalue追加字符串key value
STRLEN查询value长度key

【Redis-String单元素操作】命令详细对比分析如下:

Redis-String单元素操作

1.2.2、String批量操作

【核心命令】:MSET、MGET;

注意:

  • MGET、MSET是Redis命令中的Boss,因为执行这两个命令是绝不会失败的。
  • 【MSET】操作具有原子性,不存在部分key更新成功而部分key更新失败的情况;
  • 【MGET】如果value不是String类型,将返回nil;

【Redis-String批量操作】命令简述:

命令功能参数
MSET批量设置key value [key value ...]
MGET批量查询key [key ...]

【Redis-String批量操作】命令详细对比分析如下:

Redis-String批量操作

1.2.3、String指定范围处理

【核心命令】:SETRANGE、GETRANGE;

注意:

  • 【SETRANGE、GETRANGE】 在操作对象较小时,时间复杂度近似看成O(1);
  • 【SETRANGE】在特定情况下会造成服务器阻塞(value不存在或很小 偏移量offset很大),具体阻塞时长与服务器有关;

【Redis-String指定范围处理】命令简述:

命令功能参数
SETRANGE设置指定偏移量位置的字符key offset value
GETRANGE查询指定区间字符串key start end【@LBN;offset大于len将自动以len为准】

【Redis-String指定范围处理】命令详细对比分析如下:

Redis-String指定范围处理

1.2.4、String递增操作

【核心命令】:INCR/DECR、INCRBY/DECRBY、INCRBYFLOAT;

注意:

  • String结构能存储数字?因为数字在Redis中是以字符串形式保存的;
  • 【INCR/DECR】 支持加减1;
  • 【INCRBY/DECRBY】 支持 加减指定整数,参数支持负数;
  • 【INCRBYFLOAT】 支持 加减指定浮点数,参数支持负数;
  • 递增命令时间负责度都是O(1);

【Redis-String递增操作】命令简述:

命令功能参数
INCR/DECR递增/1递减1key
INCRBY/DECRBY递增n/递减nkey increment(支持负数)
INCRBYFLOAT递增浮点值key increment(支持负数)

【Redis-String递增操作】命令详细对比分析如下:

Redis-String递增操作

1.2.5、String位操作

【核心命令】:SETBIT、BITOP、GETBIT、BITCOUNT、BITFIELD、BITPOS;

注意:

  • 【BITOP】支持逻辑操作,且AND、或OR、异或XOR、非NOT;
  • 由于按位存储非常节省空间,位操作特别适合于对连续的海量数据做标记。比如贴吧签到,标记每天是否签到,1天1标识位,则10年=10*365bit=456byte。

【Redis-String位操作】命令简述:

命令功能参数
SETBIT指定偏移量bit位置设置值key offset value【0=< offset< 2^32】
BITOP对一个或多个key执行逻辑操作,并将结果保存到destkeyoperation destkey key [key ...]【AND, OR, XOR, NOT】
GETBIT查询指定偏移位置的bit值key offset
BITCOUNT统计指定区间bit为1的数量key [start end]【@LBN】
BITFIELD操作多字节位域key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP/SAT/FAIL]
BITPOS查询指定区间第一个被设置成1的bit位的位置key bit [start] [end]【@LBN】

【Redis-String位操作】命令详细对比分析如下:

Redis-String位操作


2、List

2.1、List应用场景及注意事项

2.1.1、List应用场景

  • List可用于构建队列(右进左出/先进先出)、栈(右进右出/先进后出);
  • 存储相关数据,比如文章的相关文章ID,可用于文章推荐;
  • 高级使用:quicklist快速链表;

2.1.2、List注意事项

  • 元素是String,按插入顺序排序;
  • 插入、弹出快,O(1);
  • 索引慢(查询),O(n);
  • List查询操作类似Java链表的get(int index),需要对链表遍历,性能随index的增大而降低;
  • lindex的index可为负数,-1表示倒数第一个元素,-2倒数第二个;
  • List的index参数存在越界问题;

-List的start、stop参数不存在越界问题;

  • 列表弹出最后一个元素后,结构自动被删除,内存被回收;
  • List左头右尾(记忆:我国自古就有左为尊的说法,左才是头);

2.2、List各命令对比分析

概述:

  • List命令支持以下操作类型:新增元素、弹出元素、处理指定位置元素。
  • List主命令L开头(左侧处理)、右侧处理目录R开头、阻塞命令B开头;
  • List的超时timeout为0表示无限阻塞;

2.2.1、List新增元素

【核心命令】:LPUSH、RPUSH、LPUSHX、RPUSHX、RPOPLPUSH、BRPOPLPUSH;

注意:

  • 【LPUSH / RPUSH】 支持批量添加元素;
  • 【RPOPLPUSH】 拆分成2个命令理解:RPOP(src) LPUSH(dest);
  • 【RPOPLPUSH】可作为安全队列:ListA取出消息放入“处理中的ListB”,处理完毕移除ListB;外挂监控ListB的超时情况;

【Redis-List新增元素操作】命令简述:

命令功能参数
LPUSH / RPUSH(批量)添加元素key value [value ...]
LPUSHX / RPUSHX向已存在的list中添加单个元素key value
RPOPLPUSH弹出source尾压入dest头部source destination
BRPOPLPUSH阻塞式弹出source压入destsource destination timeout

【Redis-List新增元素操作】命令详细对比分析如下:

Redis-List新增元素操作

2.2.2、List弹出元素

【核心命令】:LPOP、RPOP、BLPOP、BRPOP;

注意:

  • 【BLPOP】为LPOP的阻塞版本,0表示无限阻塞;
  • 弹出元素操作时间复杂度都是O(1);

【Redis-List弹出元素操作】命令简述:

命令功能参数
LPOP / RPOP弹出元素key
BLPOP / BRPOP阻塞式弹出元素key [key ...] timeout

【Redis-List弹出元素操作】命令详细对比分析如下:

Redis-List弹出元素操作

2.2.3、List处理指定位置元素

【核心命令】:LSET、LINDEX、LRANGE、LTRIM、LREM;

注意:

  • 【ltrim】支持保留区间内的值,可实现定长链表;
  • 【LRANGE、LTRIM】不会越界;
  • List处理指定位置相关命令时间复杂度可记为O(N);

【Redis-List处理指定位置元素】命令简述:

命令功能参数
LSET指定位置设置元素key index value
LINDEX查询指定位置元素key index
LRANGE查询指定区间元素key start stop
LTRIM保留指定区间元素key start stop
LREM移除前/后count次的value元素key count value

【Redis-List处理指定位置元素】命令详细对比分析如下:

Redis-List处理指定位置元素


3、Set

3.1、Set应用场景及注意事项

3.1.1、Set应用场景

  • 类似Java的HashSet,键值无序唯一,可用于去重;
  • Set支持交集运算,可用于查找QQ共同好友;

3.1.2、Set注意事项

  • Set支持集合运算(差集、交集、并集);
  • Set底层实现相当于特殊字典,value都是NULL;
  • 集合最后一个元素移除后,结构自动删除,内存被回收;

3.2、Set各命令对比分析

概述:

  • Set命令支持以下操作类型:集合运算、增删移动及统计;
  • Set命令都是S开头;

3.2.1、Set增删移动及统计

【核心命令】:SADD(增)、SCADD(数量统计)、SISMEMBER(存在)、SMEMBERS(所有元素)、SREM(移除)、SMOVE(移动);

注意:

  • Redis2.4 ,SADD、SREM支持批量添加元素;
  • 【SMEMBERS】将返回Set中所有元素,慎用,请使用SSCAN代替;
  • 【SRANDMEMBER】返回count个随机元素,支持count为负;SPOP返回并移除count个随机元素,不支持count为负(越界异常);

【Redis-Set增删移动及统计】命令简述

命令功能参数
SADD(批量)添加元素到Set中key member [member ...]
SCARD统计Set中元素数量key
SISMEMBER判断指定元素是否存在于Set中key member
SMEMBERS返回Set中的所有元素key
SMOVE移动Set的指定元素到另一个集合source destination member
SRANDMEMBER返回Set中count个随机元素key [count]
SPOP移除并返回Set中count个随机元素key [count]
SREM移除Set中指定的元素key member [member ...]
SSCAN迭代Setkey cursor [MATCH pattern] [COUNT count]

【Redis-Set增删移动及统计】命令详细对比分析如下:

Redis-Set增删移动及统计

3.2.2、Set集合运算(差集、交集、并集)

【核心命令】:差集SDIFF/SDIFFSTORE、交集SINTER/SINTERSTORE、并集SUNION/SUNIONSTORE;

注意:

  • 主命令加STORE表示将对应的结果存入指定目标Set中;
  • 对于“STORE”命令,如果destkey已存在,destkey的值将会被覆盖;
  • 交集的时间复杂度是(N*M),差集/并集的时间复杂度是O(N);

【Redis-Set集合运算】命令简述

命令功能参数
SDIFF【差集】返回在第一个set中但不在其他set中的元素集合key [key ...]
SDIFFSTORE【差集】将SDIFF结果存入destinationdestination key [key ...]
SINTER【交集】返回(多个)set集合的交集key [key ...]
SINTERSTORE【交集】将多个set集合的交集存入destdestination key [key ...]
SUNION【并集】返回多个set的并集key [key ...]
SUNIONSTORE【并集】将多个set集合的并集存入destdestination key [key ...]

【Redis-Set集合运算】命令详细对比分析如下:

Redis-Set集合运算


4、Hash

4.1、Hash应用场景及注意事项

4.1.1、Hash应用场景

  • 记录一个对象的多个属性,如员工的姓名/生日/职级,文章的点赞数/阅读数/收藏数;

4.1.2、Hash注意事项

  • 类似Java的HashMap,数组 链表,结构是<rediskey , <hashkey1, hashvalue1>>;
  • 字典key、value都只能是字符串(数字在redis里面是以 sds 字符串形式存在);
  • 使用渐进式rehash策略:高性能,不堵塞服务;而HashMap的rehash是一次性hash,很耗时;
  • 【优点】支持按需存取指定字段;
  • 【缺点】hash结构存储消耗高于单个字符串;

4.2、Hash各命令对比分析

概述:

  • Hash命令支持以下操作类型:新增、查询、统计、修改、删除(增删改查及统计);

4.2.1、Hash新增、查询元素

【核心命令】:HSET、HSETNX、HMSET;HGET、HMGET、HGETALL;

注意:

  • 【HSET】field存在则覆盖;HSETNX:field不存在才赋值;
  • 【HMSET、HMGET】支持批量操作;

【Redis-Hash新增、查询元素】命令简述

命令功能参数
HSET设置hash中指定字段的值key field value
HSETNXfield不存在才设置hash中指定field的值key field value
HMSET批量设置hash值key field value [field value ...]
HGET查询hash中指定字段的值key field
HMGET批量查询指定field的valuekey field [field ...]
HGETALL查询所有field-value列表key

【Redis-Hash新增、查询元素】命令详细对比分析如下:

Redis-Hash新增、查询元素

4.2.2、Hash统计、修改、删除

【核心命令】:HKEYS、HVALS、HLEN;HDEL、HEXISTS、HSTRLEN;HINCRBY、HINCRBYFLOAT;HSCAN;

注意:

  • 支持查询Hash中所有field、所有value;
  • 【HVALS】不是HVALUES;
  • 【HINCRBY】支持增加Hash中指定field的值(点赞数/阅读数/收藏数);

【Redis-Hash统计、修改、删除】命令简述

命令功能参数
HKEYS查询所有field列表key
HVALS查询所有value列表key
HLEN查询hash的field数量key
HDEL移除hash中指定field字段key field [field ...]
HEXISTS判断hash中是否存在指定fieldkey field
HSTRLEN查询hash中filed关联的value字符串的长度key field
HINCRBY增加hash中指定field的值key field increment
HINCRBYFLOAT增加hash中指定field的值key field increment
HSCAN基于游标迭代hasheskey cursor [MATCH pattern] [COUNT count]

【Redis-Hash统计、修改、删除】命令详细对比分析如下:

Redis-Hash统计、修改、删除

5、后记

  《玩转Redis-Redis基础数据结构及核心命令》至此结束,后续将继续分享Redis其他数据结构及核心命令。


公众号搜索zxiaofan】【点我】查阅最新系列文章。

Life is all about choices!

将来的你一定会感激现在拼命的自己!


zxiaofan
0 声望0 粉丝

学习,思考,沉淀,成长。