基础命令
server:
- 启动server:redis-server
- 指定启动端口:redis-server --port 端口号
- 指定配置文件启动:redis-server ../redis.conf (这样可以在conf里面修改端口、缓存等)
client:
- 启动client:redis-cli
- 指定启动端口:redis-cli -p 端口号
- 指定地址:redis-cli -h 地址(127.0.0.1)
- 关闭客户端:exit
- 关闭redis:redis-cli shutdown(服务端也会关闭)
- 系统信息:info
- 选中保存的数据库:select + 数据库编号:(redis.conf中)
# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT <dbid> where
# dbid is a number between 0 and 'databases'-1
databases 16
默认是使用下标为0的数据库,选择范围是0-15,该命令适用于区分开发环境
- 清除当前数据库:flushdb
- 清除所有数据库: flushall
- 测试链接情况:ping(正常返回pong)
- 查看当前数据库数量:dbsize
左侧是redis服务端启动成功,右边是redis客户端连接成功。
键命令
- 查看所有键:
keys *
- 查看键值对过期时间:
ttl +键(-1永久的key,-2过期的key)
- 查看储存类型:
type+键
- 重命名:
rename +原键名+新键名
- 设置键值对过期时间:
expire +键 +时间(秒)
- 删除 key:
del+key
String类型命令:
- 添加string类型数据:
set +键 +值
- 添加多个String类型数据:
mset +键+值 +键 +值 +键 +值...
- 获取多个String类型数据:
mget+键+键+键...
- 是否存在该键值对:
exists + 键
- 添加string类型数据并设置过期时间:
setex+键+时间(秒)+值
- 查看String类型值:
get + 键
- 添加新的键值对(避免再次添加):
setnx +键 +值(`与set命令不同,set时键值对存在会重新给值赋值。setnx 如果键值对存在则添加失败,所以该命令只能添加新的键值对`。可配合expire指令用与实现分布式锁)
- 查看长度:
strlen+键
- 将存储的数值类型数据
+1
:
**incr+键**(`如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作`),**-1是decr**
- 指定键并增加指定数量:
incrby+键+增加的值(decrby+键+减少的值)
- 追加字符串到末尾:
append+键 +值
- 设置并返回返回旧的value值(具有原子性),key之前不存在返回nil:
getset+key+value
hash类型命令:
- 添加hash单个数据:
hset +名称(name)+键名+值
- 添加多个数据:
hset +名称(name)+键名+值...
- 获取多个数据:
hmget+名称(name)+键+键+键...
- 获取指定单个数据:
hget+名称(name)+键+键+键...
- 是否存在该键值对:
hexists + 键
- 获取所有值:
hgetall+ 键
- 获取所有键:
hkeys+ 键
- 获取所有值:
hvals+ 键
- 获取size:
hlen+ 键
- 获取所有值:
hvals+ 键
list类型命令:
- 新建数据:
lpush 名称+ 元素...(`元素的排列是从后到前开始插入`)
- 设置指定下标的元素:
lset+名称+下标+ 元素
- 获取指定下标的元素:
lindex+名称+下标
- size:llen 名称
- 获取指定范围的值:
lrange 名称 +起下标+止下标()
- 移除第一个下标:
lpop+名称
- 移除最后一个下标:
rpop+名称
set类型命令:
- 添加set集合(
有则添加没重复的值,无则新建
):
sadd+名称+ 元素 + 元素...
- 获取集合的成员数:
scard+名称
- 查看元素成员:
smember+名称
- 查看两个set中差集:
sdiff+名称1+名称2
- 查看两个set中交集:
sinter+名称1+名称2
- 查看两个set中并集:
sunsion+名称1+名称2
- 返回集合中的随机数:
srandmember + 名称+返回个数
- 是否是集合中的元素:
sismember+名称+ 元素
- 移除:
srem+名称+ 元素 + 元素...
- 移除一个随机元素并返回:
spop+名称
sortedset有序集合类型命令
- 新建:
zadd+名称+分数(排序用,int)+元素+分数(排序用,int)+ key +...
- 获取集合的成员数:
zcard+名称
- 获取指定key的数值:
zscore+名称+ 元素
- 获取指定数值之间的数量:
zcount+名称+起值+止值(0 200)
- 获取指定数值之间的数量和分数:
zcount+名称+起值+止值(0 200)+withscores
- 获取元素的下标:
zrank+名称+ 元素
- 增加分数并返回增加后的值(原值+增加的值):
zincrby+名称+分数+ 元素
从海量key里查询出某一固定前缀都key
留意细节
- 摸清数据规模,即问清楚边界
1.使用keys指令对线上业务的影响
keys pattern:查找所有符合给定模式patten的key
- keys指令一次性返回所有匹配的key
- 键的数量过大会使服务卡顿
2.使用scan避免keys指令的问题
SCAN cursor[MATCH pattern][COUNT count]
- 基于游标的迭代器,需要基于上一次的游标延续之前的迭代过程
- 以0作为游标开始一次新的迭代,知道命令返回游标0完成一次遍历
- 不保证每次执行都返回某个给定数量的元素,支持模糊查询
- 一次返回的数量不可控,只能大概率符合count参数
如何通过redis实现分布式锁
分布式锁需要解决的问题
- 互斥性
- 安全性
- 死锁
- 容错
1.使用setnx +键 +值:作用在上方的基础命令中有介绍
- 时间复杂读:O(1)
- 返回值:设置成功返回1,失败返回0
2.解决setnx长期有效的问题
expire+key+time
- 设置key的生存时间,当key过期时(生存时间为0),会被自动删除
- 缺点:原子性得不到满足(存在还没有执行到expire指令时程序挂掉的风险)
3.redis6.2后可将上述两步合并起来
set+key+value+seconds+milliseconds+nx|xx
- seconds:秒
- milliseconds:毫秒
- nx:只有键不存在时,才对键进行设置操作
- xx:只有键存在时,才对键进行设置操作
- set操作成功完成时,返回ok,否则返回nil
大量的key同时过期的注意事项
集中过期,由于清除大量的key很耗时,会出现短暂的卡顿现象
- 解决方案:在设置key的过期时间为一个随机值
如何使用redis做异步队列
使用list作为队列,rpush生产消息,lpop消费消息
- 缺点:lpop没有等待队列里有值就直接消费
- 弥补:可以通过在应用层引入sleep机制去调用lpop重试
blpop+key+time:阻塞知道队列有消息或者超时
优化:针对上一步的弥补,不用使用弥补中的sleep机制
- 缺点:只能提供一个消费者消费
优化:针对上一步的缺点
pub/sub:主题订阅者模式
- 发送者publish发送消息,订阅者subscribe接收消息
- 订阅者可以订阅任意数量的频道
- 缺点:消息的发布时无状态的,无法保证可达
pipeline
- pipeline和linux管道类似
- redis基于请求/响应模式,单个请求处理需要一一应答,所有使用pipeline来批量执行指令,节省多次io往返的时间
- 有顺序依赖的指令建议分批发送
redis的同步机制
全同步过程
- slave发送sync命令到master
- master启动一个后台进程,将redis中的数据快照保存到文件中
- master将保存数据快照期间接收到的写命令缓存起来
- master完成写文件操作后,将该文件发送给slave
- 使用新的AOF文件替换掉旧的AOF文件
- Master将这期间收集的增量写命令发送给slave端
增量同步过程
- master接收到用户的操作指令,判断是否需要传播到slave
- 将操作纪律追加到AOF文件
- 将操作传播到其他Slave:1.对齐主从库 2.往响应缓存写入指令
- 将缓存中的数据发送给slave
sentinel
解决主从同步master宕机后的主从切换问题:
- 监控:检查主从服务器是否运行正常
- 提醒:通过API向管理员或者其他应用程序发送故障通知
- 自动故障切换:主从切换
redis集群
- 通过
一致性哈希算法
:对2^32取模,将哈希空间组织成虚拟的圆环,服务器分布在圆环上,key通过hash算法计算出在圆环中的位置然后按顺时针找到最近的服务器 - 通过虚拟节点来解决服务器分布不均造成的
数据倾斜
问题。
网友评论