1、概述
redis是Remote Dictionary Service的简称,也是远程字典服务。
redis是内存型数据库,KV型数据库,数据结构数据库。通过key操作value,value支持多种类型string、list、hash、set、zset等。
2、安装启动
安装
bash
下载源码:比如redis-7.0.15
cd redis
make
make install
# 默认安装在/usr/local/bin
# redis-server 是服务端程序
# redis-cli 是客户端程序
启动redis
配置文件redis.conf在源码目录有,可以拷贝到自定义目录,启动时指定目录即可,默认使用端口6379。
bash
# 启动redis
redis-server
# 使用配置文件启动redis
redis-server ./redis-data/redis.conf
启动客户端,redis-cli是redis提供的客户端命令行工具,可以通过命令操作redis数据库了
bash
# 服务器和客户端在一个机器上
redis-cli
# -h 指定要连接redis节点的ip地址
# -p 指定要连接redis节点的端口,默认6379
# -a 指定redis的访问密码
redis-cli -h 127.0.0.1 -p 6379 -a XXXX
3、数据类型及其存储方式
string:是一个安全的二进制字符串,安全是指以长度区分字符串
list:插入有序的,双端列表
hash:对顺序不关注,field是唯一的
set:对顺序不关注,里面的值都是唯一的
zset:对顺序是关注的,里面的值是唯一的,根据member来确定唯一,根据score来确定有序。
3.0、key的设计
对于单个功能的单个key,使用有意义的名字
SET key value
对于相同功能的多个key,使用有意义字段并用冒号分隔,推荐冒号分隔(当然也可以使用其他分隔符),因为很多开源项目或工具使用冒号分隔的,是大家约定俗成的规定。
SET role:10001 '{["name"]:"张三",["sex"]:"male",["age"]:30}'
3.1、string字符串
扩容机制:字符串长度小于1M时,加倍扩容;超过1M时,每次只多扩1M,字符串最大长度512M
基础命令
# 设置key的value值
SET key val
# 获取key的value
GET key
# 执行原子加一的操作(value必须整数,否则会报错)
INCR key
# 执行原子加一个整数的操作(value必须整数,否则会报错)
INCRBY key increment
# 执行原子减一的操作
DECR key
# 执行原子减一个整数的操作
DECRBY key decrement
# 如果key不存在,这种情况下等同SET命令,当key存在时,什么也不做,只有当key不存在时,才设置成功
SETNX key value
# 删除key val键值对
DEL key
# 设置或清空key的value(字符串)在offset处的bit值
# 动态字符串 能够节约内存
SETBIT key offset value
# 返回key对应的string在offset处的bit值
GETBIT key offset
# 统计字符串被设置为1的bit数
BITCOUNT key
应用场景举例:
场景1:对象存储
将某些json字符串,保存到redis,前提条件json字符串极少修改,如果要经常修改可考虑hash数据结构。
SET role:10001 '{["name"]:"张三",["sex"]:"male",["age"]:30}'
SET role:10002 '{["name"]:"李四",["sex"]:"male",["age"]:30}'
# 极少修改,对象属性字段很少改变的时候
GET role:10001
场景2:累加器
# 统计阅读数 累加1
incr reads
# 累计加100
incrby reads 100
场景3:位运算
# 月签到功能 10001 用户id 202106 2021年6月份的签到 6月份的第1天
setbit sign:10001:202106 1 1
# 计算 2021年6月份 的签到情况
bitcount sign:10001:202106
# 获取 2021年6月份 第二天的签到情况 1 已签到 0 没有签到
getbit sign:10001:202106 2
自测
3.2、list双端列表
双向列表实现,列表首尾操作(删除和增加)时间复杂度o(1),查找中间元素时间复杂度为o(n)
基础命令
# 从队列的左侧入队一个或多个元素
LPUSH key value [value ...]
# 从队列的左侧弹出一个元素
LPOP key
# 从队列的右侧入队一个或多个元素
RPUSH key value [value ...]
# 从队列右侧弹出一个元素
RPOP key
# 返回从队列的start 和 end之间的元素, 0, 1, 2, 负索引
LRANGE key start end
# 从存于key的列表里移除前 count 次出现的值为value的元素
# list没有去重功能
LREM key count value
# 它是RPOP的阻塞版本,因为这个命令会在给定list无法弹出任何元素的时候,阻塞连接
BRPOP key timeout # 超时时间 + 延时队列
BRPOP命令:拥有移出并获取list右边最后一个元素,如果列表中没有元素,则卡住命令知道等到超时或发现可弹出元素为止。比如:A机器调用brpop等待弹出元素,B机器调用lpush插入数据,此时A机器brpop会弹出对应元素。
应用场景举例:
场景1:获取固定窗口记录
# 在某些业务场景下,需要获取固定数量的记录;比如获取最近50条记录;这些记录需要按照插入的先
后顺序返回;
lpush says '第一条评论'
lpush says '第二条评论'
lpush says '第三条评论'
lpush says '第四条评论'
lpush says '第五条评论'
lpush says '第六条评论'
lpush says '第七条评论'
# 裁剪最近5条记录 战绩 近50条
ltrim says 0 4
lrange says 0 -1
自测:
3.3、hash
散列表,在很多高级语言当中包含这种数据结构,C++unordered_map通过key快速索引value。
基础命令
bash
# 获取key对应hash中的 field对应的值
HGET key field
# 设置key对应hash中的封field对应的值
HSET key field
# 设置多个hash键值对
HMSET key field1 value1 field2 value2 ... fieldn valuen
# 获取多个field的值
HMGET key field1 field2 ... fieldn
# 给key对应hash中的field对应的值加一个整数值
HINCRBY key field increment
# 获取key对应的hash有多少个键值对
HLEN key
# 删除key对应的hash的键值对,该键位field
HDEL key field
# 获取key的所有字段
HGETALL key
应用场景举例:
场景1:购物车
bash
# 将用户id作为 key
# 商品id作为 field
# 商品数量作为 value
# 注意:这些物品是按照我们添加顺序来显示的;
# 添加商品:
hmset MyCart:10001 40001 1 cost 5099 desc "戴尔笔记本14-3400"
lpush MyItem:10001 40001
# 增加数量:
hincrby MyCart:10001 40001 1
hincrby MyCart:10001 40001 -1 // 减少数量1
# 显示所有物品数量:
hlen MyCart:10001
# 删除商品:
hdel MyCart:10001 40001
lrem MyItem:10001 1 40001
# 获取所有物品:
lrange MyItem:10001
# 40001 40002 40003
hget MyCart:10001 40001
hget MyCart:10001 40002
hget MyCart:10001 40003
自测
3.4、set集合
集合,用来存储唯一性字段,不要求有序。集合可以用来计算交集、并集等业务场景。
基础命令
bash
# 添加一个或多个指定的member元素到集合的key中
SADD key member [member ...]
# 计算集合元素个数
SCARD key
# SMEMBERS key 返回集合中的member
SMEMBERS key
# 返回成员member 是否是存储的集合key的成员
SISMEMBER key member
# 随机返回key集合中的一个或多个元素,不删除这些元素
SRANDMEMBER key [count]
# 从存储在key的集合中移除并返回一个或多个随机元素
SPOP key [count]
# 返回一个集合与给定集合 差集的元素
SDIFF key [key ...]
# 返回一个集合与给定集合的交集
SINTER key [key ...]
# 返回给定的多个集合的并集的所有成员
SUNION key [key ...]
应用场景举例
场景1:抽奖
bash
# 添加抽奖用户
sadd Award:1 10001 10002 10003 10004 10005 10006
sadd Award:1 10009
# 查看所有抽奖用户
smembers Award:1
# 抽取多名幸运用户
srandmember Award:1 10
场景2:共同关注
bash
sadd follow:A aa bb cc dd ee
sadd follow:C aa 22 cc 11 ee
sinter follow:A follow:C
场景3:推荐好友
bash
sadd follow:A aa bb cc dd ee
sadd follow:C aa 22 cc 11 ee
sdiff follow:A follow:C
自测:
3.5、zset
有序集合,用来实现排行榜,它是一个有序唯一。
基础命令
bash
# 添加到键为key有序集合(sorted set)里面
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
# 从键为key有序集合中删除 member 的键值对
ZREM key member [member ...]
# 返回有序集key中,成员member的score值
ZSCORE key member
# 为有序集key的成员member的score值加上增量increment
ZINCRBY key increment member
# 返回key的有序集元素个数
ZCARD key
# 返回有序集key中成员member的排名
ZRANK key member
# 返回存储在有序集合key中的指定范围的元素 order by id limit 1,100
ZRANGE key start stop [WITHSCORES]
# 返回有序集key中,指定区间内的成员(逆序)
ZREVRANGE key start stop [WITHSCORES]
应用场景举例
bash
# 点击新闻:
zincrby hot:20230612 1 10001
zincrby hot:20230612 1 10002
zincrby hot:20230612 1 10003
zincrby hot:20230612 1 10004
zincrby hot:20230612 1 10005
zincrby hot:20230612 1 10006
zincrby hot:20230612 1 10007
zincrby hot:20230612 1 10008
zincrby hot:20230612 1 10009
zincrby hot:20230612 1 10010
# 获取排行榜:
zrevrange hot:20230612 0 9 withscores
自测
4、总结
通常是组合使用的方式,实现业务需求,比如:hash + list组合等方式。