Redis核心数据结构应用场景与高性能原理刨析

  • 一、Redis的数据结构
  • 1、String
  • 1.1、单值缓存
  • 1.2、对象缓存
  • 1.3、分布式锁
  • 1.4、计数器
  • 2、Hash
  • 3、List
  • 4、Set
  • 5、ZSet
  • 二、Redis高性能原理
  • 1、Redis是单线程的吗?
  • 2、Redis单线程快的原因
  • 3、Redis单线程能够处理那么多的并发客户端连接的原因
  • 三、Redis的范围查找
  • 1、keys *
  • 2、scan渐进式遍历键


一、Redis的数据结构

Redis一共有5种数据结构,分别是String(字符串)、Hash(哈希)、List(链表)、Set(集合)、ZSet(有序集合)

1、String

1.1、单值缓存

(1)set key value:设置key的值

(2)get key:获取指定key的值

Redission的核心功能 redis核心原理与实战_redis

1.2、对象缓存

将对象式的value抽象成一个JSON格式,然后进行缓存

(1)单个操作

set key value:设置key的值

get key:获取指定key的值

Redission的核心功能 redis核心原理与实战_Redis_02


(2)批量操作

mset key1 value1 key2 value2

mget key1 key2

Redission的核心功能 redis核心原理与实战_单线程_03

1.3、分布式锁

命令

含义

setnx product:100 true

获取当前key的锁,返回1代表取锁成功

setnx product:100 true

获取当前key的锁,返回0代表取锁失败

del product:100

删除当前key

set product:100 true ex 10 nx

设置超时时间,默认为秒

1.4、计数器

命令

含义

incr key

给当前key值的积分加1

get key

获取当前key值的积分

Redission的核心功能 redis核心原理与实战_Redission的核心功能_04

指定增量计数器:incrby key 数值–>给对应的key加上某值

2、Hash

(1)常用操作

命令

含义

HSET key field value

存储一个哈希表key的键值

HSETNX key field value

存储一个不存在的哈希表key的键值

HMSET key field value [field value …]

在一个哈希表key中存储多个键值对

HGET key field

获取哈希表key对应的field键值

HMGET key field [field …]

批量获取哈希表key中多个field键值

HDEL key field [field …]

删除哈希表key中的field键值

HLEN key

返回哈希表key中field的数量

HGETALL key

返回哈希表key中所有的键值

HINCRBY key field increment

为哈希表key中field键的值加上增量increment

(2)对象缓存

命令

含义

hmset user {userid}:name lele {userid}:balance 100

设置hash对象

hmget user {userid}:name lele {userid}:balance 100

获取hash对象

Redission的核心功能 redis核心原理与实战_redis_05


(3)优点

①同类数据归类整合储存,方便数据管理。

②相比string操作消耗内存与cpu更小

③相比string存储更节省空间

(4)缺点

①过期功能不能使用在field上,只能使用在key上

②redis集群架构下不适合大规模使用

3、List

(1)常用操作

命令

含义

LPUSH key value [value …]

将一个或多个值value插入到key列表的表头(最左边)

RPUSH key value [value …]

将一个或多个值value插入到key列表的表尾(最右边)

LPOP key

移除并返回key列表的头元素

RPOP key

移除并返回key列表的尾元素

LRANGE key start stop

返回列表key中指定区间内的元素,区间以偏移量start和stop指定

BLPOP key [key …] timeout

从key列表表头弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待

BRPOP key [key …] timeout

从key列表表尾弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待

(2)应用场景
作为分布式数据结构
①栈Stack=LPUSH+LPOP;
②队列Queue=LPUSH+RPOP ;
③阻塞队列MQ=LPUSH+BRPOP;

4、Set

(1)常用操作

命令

含义

SADD key member [member …]

往集合key中存入元素,元素存在则忽略,若key不存在则新建

SREM key member [member …]

从集合key中删除元素

SMEMBERS key

获取集合key中所有元素

SCARD key

获取集合key的元素个数

SISMEMBER key member

判断member元素是否存在于集合key中

SRANDMEMBER key [count]

从集合key中选出count个元素,元素不从key中删除

SPOP key [count]

从集合key中选出count个元素,元素从key中删除

(2)运算操作

命令

含义

SINTER key [key …]

交集运算

SINTERSTORE destination key [key …]

将交集结果存入新集合destination中

SUNION key [key …]

并集运算

SUNIONSTORE destination key [key …]

将并集结果存入新集合destination中

SDIFF key [key …]

差集运算

SDIFFSTORE destination key [key …]

SDIFFSTORE destination key [key …]

(3)案例

me关注的人:{A1,A2,A4,A6,A8}
A1关注的人:{A2,A3,A4}
A2关注的人:{A1,A4,A5,A6}
A3关注的人:{A6,A7,A8}
A4关注的人:{A2,A5}
me和A2的共同关注:{A1,A4,A6}

如图所示:

Redission的核心功能 redis核心原理与实战_Redis_06

5、ZSet

(1)常用操作

命令

含义

ZADD key score member [[score member]…]

往有序集合key中加入带分值元素

ZREM key member [member …]

从有序集合key中删除元素

ZSCORE key member

返回有序集合key中元素member的分值

ZINCRBY key increment member

为有序集合key中元素member的分值加上increment

ZCARD key

返回有序集合key中元素个数

ZRANGE key start stop [WITHSCORES]

正序获取有序集合key从start下标到stop下标的元素

ZREVRANGE key start stop [WITHSCORES]

倒序获取有序集合key从start下标到stop下标的元素

(2)ZSet集合操作

命令

含义

ZUNIONSTORE destkey numkeys key [key …]

并集计算

ZINTERSTORE destkey numkeys key [key …]

交集计算

二、Redis高性能原理

1、Redis是单线程的吗?

其实严格意义上来说,Redis不是单线程的,比如Redis的持久化、异步删除、集群数据这些都是由额外的线程来完成的。
我们平时说的Redis单线程其实是是指从其它端发送给Redis的IO操作都是由一个线程来完成的,外部访问Redis时,Redis会将这些命令排好序,然后一个一个执行。

2、Redis单线程快的原因

(1)其所有数据都是存放在内存中,所有运算都是内存级别的运算
(2)单线程避免了多线程的上下文切换
(3)IO多路复用

因此,对于耗时指令、可能导致Redis卡顿;导致其他用户请求无法得到处理。

3、Redis单线程能够处理那么多的并发客户端连接的原因

Redis的IO多路复用:Redis利用epoll来实现IO多路复用、将连接信息和时间放到队列中、一次放到文件事件分派器、事件分派器将事件发给事件处理器

与网络通信的NIO相关:

Redission的核心功能 redis核心原理与实战_redis_07

三、Redis的范围查找

1、keys *

(1)优点是简单,初学者拿来即用。(但通常运维大神会在redis服务端禁用该命令),

(2)缺点是可能会直接导致redis服务宕机。**由于redis服务是单线程工作,每一条到达的指令都是串行执行,而Keys 命令会全量遍历缓存中的所有key,直到结束,如果redis中的key数量太多、所需要的时间就很长,**此刻请求redis服务的其它指令都将被阻塞,后台服务可能会因为超时而报错;

Redission的核心功能 redis核心原理与实战_Redission的核心功能_08

2、scan渐进式遍历键

SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]

(1)cursor:游标;默认为0;

(2)pattern: 需要进行模糊查询的字符串;与keys的pattern相同;可省略;

(3)count:返回多少条符合的key; 可省略

(4)Type: 模糊查询返回的key的类型;可为StringHash,List,Set,

(5)Zset:可省略。

Redission的核心功能 redis核心原理与实战_redis_09


第 一次遍历时,cursor 值为 0,然后将返回结果中第一个整数值作为下一次遍历的 cursor。一直遍历 到返回的 cursor 值为 0 时结束。

注意:但是scan并非完美无瑕, 如果在scan的过程中如果有键的变化(增加、 删除、 修改) ,那 么遍历效果可能会碰到如下问题: 新增的键可能没有遍历到, 遍历出了重复的键等情况, 也就是说 scan并不能保证完整的遍历出来所有的键, 这些是我们在开发时需要考虑的。