简介

非关系型(NoSQL)内存键值数据库,可以存储键和五种不同类型的值之间的映射。
的类型只能为字符串,支持五种数据类型:字符串、列表、集合、散列表、有序集合。

数据类型

string

  1. 常用命令: set,get,strlen,exists,decr,incr,setex
  2. 应用场景: 一般常用在需要计数的场景,比如用户的访问次数、热点文章的点赞转发数量等等
//普通字符串的基本操作:
127.0.0.1:6379> set key value #设置 key-value 类型的值
OK
127.0.0.1:6379> get key # 根据 key 获得对应的 value
"value"
127.0.0.1:6379> exists key  # 判断某个 key 是否存在
(integer) 1
127.0.0.1:6379> strlen key # 返回 key 所储存的字符串值的长度。
(integer) 5
127.0.0.1:6379> del key # 删除某个 key 对应的值
(integer) 1
127.0.0.1:6379> get key
(nil)

//批量设置 
127.0.0.1:6379> mset key1 value1 key2 value2 # 批量设置 key-value 类型的值
OK
127.0.0.1:6379> mget key1 key2 # 批量获取多个 key 对应的 value
1) "value1"
2) "value2"

//计数器
127.0.0.1:6379> set number 1
OK
127.0.0.1:6379> incr number # 将 key 中储存的数字值增一
(integer) 2
127.0.0.1:6379> get number
"2"
127.0.0.1:6379> decr number # 将 key 中储存的数字值减一
(integer) 1
127.0.0.1:6379> get number
"1"

set k v [EX] [PX] [NX|XX]

  • EX:key在多少秒后过期
  • PX:key在多少毫秒后过期
  • NX:当key不存在的时候,才创建key,效果等同与setnx
  • XX:当key存在的时候,覆盖key

list

  1. 常用命令: rpush,lpop,lpush,rpop,lrange,llen
  2. 应用场景: 发布与订阅或者说消息队列、慢查询、微信文章订阅公众号
> rpush list-key item
(integer) 1
> rpush list-key item2
(integer) 2
> rpush list-key item
(integer) 3

> lrange list-key 0 -1	# 查看列表中的所有元素,-1表示倒数第一
1) "item"
2) "item2"
3) "item"

> lindex list-key 1
"item2"

> lpop list-key	#将list的尾部(最左边)元素取出
"item"

> lrange list-key 0 -1	# 查看列表中的所有元素,-1表示倒数第一
1) "item2"
2) "item"

set(无序)

  1. 常用命令: sadd,spop,smembers,sismember,scard,sinterstore,sunion
  2. 应用场景: 微信抽奖小程序、朋友圈点赞、微博好友关注社交关系(set交并集运算)
> sadd set-key item	# 添加元素进去
(integer) 1
> sadd set-key item2
(integer) 1
> sadd set-key item3
(integer) 1
> sadd set-key item	# 不允许有重复元素
(integer) 0

> smembers set-key	# 查看 set 中所有的元素
1) "item"
2) "item2"
3) "item3"

> sismember set-key item4 #检查某个元素是否存在set中,只能接收单个元素
(integer) 0
> sismember set-key item
(integer) 1

hash

  1. 常用命令: hset,hmset,hexists,hget,hgetall,hkeys,hvals
  2. 应用场景: 系统中对象数据的存储(早期购物车)

Map<string,Map<Object,Object>>

127.0.0.1:6379> hmset userInfoKey name "guide" description "dev" age "24"
OK
127.0.0.1:6379> hexists userInfoKey name # 查看 key 对应的 value中指定的字段是否存在。
(integer) 1
127.0.0.1:6379> hget userInfoKey name # 获取存储在哈希表中指定字段的值。
"guide"
127.0.0.1:6379> hget userInfoKey age
"24"
127.0.0.1:6379> hgetall userInfoKey # 获取在哈希表中指定 key 的所有字段和值
1) "name"
2) "guide"
3) "description"
4) "dev"
5) "age"
6) "24"
127.0.0.1:6379> hkeys userInfoKey # 获取 key 列表
1) "name"
2) "description"
3) "age"
127.0.0.1:6379> hvals userInfoKey # 获取 value 列表
1) "guide"
2) "dev"
3) "24"
127.0.0.1:6379> hset userInfoKey name "GuideGeGe" # 修改某个字段对应的值
127.0.0.1:6379> hget userInfoKey name
"GuideGeGe"

zset

  1. 介绍: 和 set 相比,sorted set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,还可以通过 score 的范围来获取元素的列表。
  2. 常用命令: zadd,zcard,zscore,zrange,zrevrange,zrem
  3. **应用场景:**销量榜、热搜榜
127.0.0.1:6379> zadd myZset 3.0 value1 # 添加元素到 sorted set 中 3.0 为权重
(integer) 1
127.0.0.1:6379> zadd myZset 2.0 value2 1.0 value3 # 一次添加多个元素
(integer) 2
127.0.0.1:6379> zcard myZset # 查看 sorted set 中的元素数量
(integer) 3
127.0.0.1:6379> zscore myZset value1 # 查看某个 value 的权重
"3"
127.0.0.1:6379> zrange  myZset 0 -1 # 顺序输出某个范围区间的元素,0 -1 表示输出所有元素
1) "value3"
2) "value2"
3) "value1"
127.0.0.1:6379> zrange  myZset 0 1 # 顺序输出某个范围区间的元素,0 为 start  1 为 stop
1) "value3"
2) "value2"
127.0.0.1:6379> zrevrange  myZset 0 1 # 逆序输出某个范围区间的元素,0 为 start  1 为 stop
1) "value1"
2) "value2"

内存淘汰机制

常用的过期数据的删除策略:

  1. 惰性删除 :只会在取出 key 的时候才对数据进行过期检查。这样对 CPU 最友好,但是可能会造成太多过期 key 没有被删除**
  2. 定期删除 : 每隔一段时间抽取一批 key 执行删除过期 key 操作。并且,Redis 底层会通过限制删除操作执行的时长和频率来减少删除操作对 CPU 时间的影响。

数据淘汰策略:

  1. volatile-lru(least recently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

  4. allkeys-lru(least recently used):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)

  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

  6. no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。

使用场景

1. 缓存

2. 分布式锁

3. 消息队列

Q.E.D.