Redis 系列笔记:
第一篇:Redis 基础命令
第二篇:Redis 常见应用场景
第三篇:Redis Cluster集群搭建
第四篇:Redis 主从及哨兵搭建
第五篇:Redis 主从及集群
第六篇:Redis 持久化
第七篇:Redis 分布式锁
第八篇:Redis 底层数据存储结构
第九篇:Redis 面试常问问题
文章目录
前言
redis复习笔记,记录不同数据类型的常用命令,以及一些踩坑场景。本文命令是参考redis中文网,对一些命令进行归纳整理,具体的使用详情还请参考官网。
一、key相关命令
keys pattern # 所有符合给定模式 pattern, 例: keys hello*
keys * # 查看所有键(遍历所有的键,它的时间复杂度 O(n),一般生产环境是禁止使用的)
dbsize # 返回当前数据库中的键总数(直接获取 Redis 内置的键总数变量,时间复杂度是 O(1))
exists key_name # 检查键是否存在
expire key_name seconds # 设置 key 的过期时间(秒),过期删除
expireat key_name 时间戳 # 设置 key 的过期时间(时间戳),过期删除
pexpireat key_name 时间戳 # 设置 key 的过期时间(毫秒级时间戳),过期删除,已毫秒技。key 过期后将不再可用。
ttl key_name # 查看还剩多久过期
pttl key_name # 以毫秒为单位返回 key 的剩余过期时间。
persist key_name # 移除给定 key 的过期时间,使得 key 永不过期。
dump key_name # 用于序列化给定 key ,并返回被序列化的值
rename old_key new_key # key 重命名
renamenx old_key new_key # 新的 key 不存在时修改 key 的名称,存在不变
move key_name database # 移动 key 到指定数据库( database 默认16个:0~15)
type key # 查看 key 的数据结构类型
object encoding key # 查看缓存数据编码类型
randomkey # 从当前数据库中随机返回一个 key
del key_name [key_name...] # 无论值是什么数据结构类型,del 命令都可以将其删除
踩坑:
1.禁止使用 KEYS/FLUSHALL/FLUSHDB 命令,会阻塞主线程,影响线上业务
- SCAN 替换 KEYS
- 4.0+版本可使用 FLUSHALL/FLUSHDB ASYNC,清空数据的操作放在后台线程执行
2.对于 bigkey 删除要慎重,可能会导致堵塞,分批删除或者线上压力小的时候删除
3.使用 randomkey 命令时,当存在大量已过期,但还未被清理的 key,master【删除过期key】上耗时变长影响性能, slave【不会删除过期key】上执行可能会造成整个 Redis 实例卡死!, redis5.0 才被修复,设置最大重试次数,slave 最多只会在哈希表中寻找 100 次
二、string类型命令
set key_name [ex seconds ] # 设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。
- ex seconds:为键设置秒级过期时间。
- px milliseconds:为键设置毫秒级过期时间。
- nx:键必须不存在,才可以设置成功,用于添加。
- xx:与nx相反,键必须存在,才可以设置成功,用于更新。
get key_name # 获取指定 key 的值。
mset key1 value1 key2 value2 .. # 同时设置一个或多个 key-value 对。
mget key1 key2 .. # 返回所有(一个或多个)给定 key 的值。
getset key_name value # 用于设置指定 key 的值,并返回 key 旧的值。
setnx key_name # key 不存在时,为 key 设置指定的值。
msetnx key1 value1 key2 value2 .. # 用于所有给定 key 都不存在时,同时设置一个或多个 key-value 对。【MSET 是原子性操作】
setex key_name timeout value # 指定的 key 设置值及其过期时间。如果 key 已经存在, SETEX 命令将会替换旧的值。
psetex key1 milliseconds value1 # 以毫秒为单位设置 key 的生存时间。
strlen key_name # 获取指定 key 所储存的字符串值的长度。
incr key_name # 将 key 中储存的数字值增一。
Incrby key_name number # 将 key 中储存的数字加上指定的增量值。
Incrbyfloat key_name number # 为 key 中所储存的值加上指定的浮点数增量值。
decr key_name # 将 key 中储存的数字值减一。如果值不能表示为数字,那么返回一个错误。
decrby key_name number # 将 key 所储存的值减去指定的减量值。
setrange key_name offset value # 用指定的字符串覆盖给定 key 所储存的字符串值,覆盖的位置从偏移量 offset 开始。
append key_name new_value # 为指定的 key 追加值。
getrange key_name start end # 获取存储在指定 key 中字符串的子字符串。字符串的截取范围由 start 和 end 两个偏移量决定
getbit key_name offset value # 对 key 所储存的字符串值,获取指定偏移量上的位(bit)【 value 只能是0或1】。
setbit key_name offset # 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
踩坑:
1.在使用 getbit 命令时,如果这个 key 不存在,或者 key 的内存使用很小,此时你要操作的 offset 非常大,那么 Redis 就需要分配「更大的内存空间」,这个操作耗时就会变长,影响性能。这种类型的 key,也是典型的 bigkey,除了分配内存影响性能之外,在删除它时,耗时同样也会变长。
三、hash类型命令
hexists key_name field # 查看哈希表的指定字段是否存在。
hset key_name field value # 为哈希表中的字段赋值 。
hget key_name field # 返回哈希表中指定字段的值。
hmset key_name field1 value1 field2 value2 .. # 同时将多个 field-value (字段-值)对设置到哈希表中。
hmget key_name field1 field2 .. # 返回哈希表中,一个或多个给定字段的值。
hgetall key_name # 返回哈希表中,所有的字段和值。
hsetnx key_name field value # 为哈希表中不存在的的字段赋值 。
hdel key_name # 删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。
hlen key_name # 获取哈希表中字段的数量。
hvals key_name # 返回哈希表所有字段的值。
hkeys key_name # 获取哈希表中的所有字段名。
hincrby key_name field number # 为哈希表中的字段值加上指定增量值。
hncrbyfloat key_name field number # 为哈希表中的字段值加上指定浮点数增量值。
四、list类型命令
lpush key_name value1 value2 .. # 将一个或多个值插入到列表头部。
lpop key_name # 移除并返回列表的第一个元素。
rpush key_name value1 value2 .. # 将一个或多个值插入到列表的尾部(最右边)。
rpop key_name # 移除并返回列表的最后一个元素。
lpushx key_name value1 value2 .. # 将一个或多个值插入到已存在的列表头部,列表不存在时操作无效。
rpushx key_name value1 value2 .. # 将一个或多个值插入到已存在的列表尾部(最右边)。如果列表不存在,操作无效
blpop list1 list2 .. timeout # 移出并获取列表的第一个元素(左边第一个), 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
brpop list1 list2 .. timeout # 移出并获取列表的最一个元素(右边第一个), 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
rpoplpush source_key_name destination_key_name # 移除列表的最后一个元素,并将该元素添加到另一个列表并返回。
brpoplpush source_key_name destination_key_name # 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它;
lindex key_name index # 通过索引获取列表中的元素。
lset key_name index value # 通过索引来设置元素的值。
lrange key_name start end # 返回列表中指定区间内的元素
llen key_name # 返回列表的长度。
ltrim key_name start stop # 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
lrem key_name count value # 根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素。
- count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 。
- count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值。
- count = 0 : 移除表中所有与 VALUE 相等的值。
linsert key_name before|after existing_value new_value # 在列表的元素前或者后插入元素。
五、set类型命令
sadd key_name value1 value2 .. # 将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略。
spop key_name # 移除并返回集合中的一个随机元素。
srandmember key_name [count] # 返回集合中的一个随机元素。
- 如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合。
- 如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值
smembers key_name value # 返回集合中的所有的成员。 不存在的集合 key 被视为空集合。
srem key_name member1 member2 .. # 用于移除集合中的一个或多个成员元素,不存在的成员元素会被忽略。
smove source destination member # 将指定成员 member 元素从 source 集合移动到 destination 集合。
scard key_name # 返回集合中元素的数量。
sismember key_name value # 判断成员元素是否是集合的成员。
sscan key [MATCH pattern] [COUNT count] # 用于迭代集合键中的元素。
sunion key1 key2 .. # 返回给定集合的并集。不存在的集合 key 被视为空集。
sunionstore destination_key key1 key2 .. # 将给定集合的并集存储在指定的集合 destination 中。
sinter key1 key2 .. # 返回给定所有给定集合的交集。 不存在的集合 key 被视为空集。 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
sinterstore destination_key key1 key2 .. # 将给定集合之间的交集存储在指定的集合中。如果指定的集合已经存在,则将其覆盖。
sdiff first_key other_key1 other_key2 .. # 返回给定集合之间的差集。不存在的集合 key 将视为空集。
sdiffstore destination_key key1 key2 .. # 可用版本 # 将给定集合之间的差集存储在指定的集合中。如果指定的集合 key 已存在,则会被覆盖。
六、zset类型命令
zadd key_name score1 value1 score2 value2 .. # 用于将一个或多个成员元素及其分数值加入到有序集当中。
zrem key_name member # 移除有序集中的一个或多个成员,不存在的成员将被忽略。
zscore key_name member # 返回有序集中,成员的分数值。
zcard key_name # 计算集合中元素的数量。
zcount key_name min max # 用于计算有序集合中指定分数区间的成员数量。
zlexcount key_name min max # 在计算有序集合中指定字典区间内成员数量。
zincrby key_name increment member # 对有序集合中指定成员的分数加上增量 increment
zscan key_name cursor [MATCH pattern] [COUNT count] # 用于迭代有序集合中的元素(包括元素成员和元素分值)
zrank key_name member # 返回有序集中指定成员的排名。其中有序集成员按分数值递增(从小到大)顺序排列。
zrevrank key_name member # 返回有序集中成员的排名。其中有序集成员按分数值递减(从大到小)排序。
zrangebylex key_name min max [LIMIT offset count] # 通过字典区间返回有序集合的成员。
zrange key_name start stop [WITHSCORES] # 返回有序集中,指定区间内的成员【其中成员的位置按分数值递增(从小到大)来排序。】。
zrevrange key_name start stop [WITHSCORES] # 返回有序集中,指定区间内的成员【其中成员的位置按分数值递减(从大到小)来排列。】。
zrangebyscore key_name min max [WITHSCORES] [LIMIT offset count] # 返回有序集合中指定分数区间的成员列表。有序集成员按分数值递增(从小到大)次序排列。
zrevrangebyscore key_name max min [WITHSCORES] [LIMIT offset count] # 返回有序集中指定分数区间内的所有的成员。有序集成员按分数值递减(从大到小)的次序排列。
zremrangebyrank key_name start stop # 移除有序集中,指定排名(rank)区间内的所有成员。
zremrangebyscore key_name min max # 移除有序集中,指定分数(score)区间内的所有成员。
zremrangebylex key_name min max # 用于移除有序集合中给定的字典区间的所有成员。
zunionstore destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] # 命令计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination 【默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和 】。
zinterstore destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] # 计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 【默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和 】。
七、Redis 发布订阅命令
publish channel message # 将信息发送到指定的频道。
pubsub <subcommand> [argument [argument ...]] # 查看订阅与发布系统状态,它由数个不同格式的子命令组成。
subscribe channel [channel ...] # 订阅给定的一个或多个频道的信息。
unsubscribe channel [channel ...] # 退订给定的一个或多个频道的信息。
psubscribe pattern [pattern ...] # 订阅一个或多个符合给定模式的频道。
punsubscribe [pattern [pattern ...]] # 退订所有给定模式的频道。
八、Redis 连接命令
echo message # 用于打印给定的字符串。
select index # 切换到指定的数据库,数据库索引号 index 用数字值指定,以 0 作为起始索引值。
ping # 使用客户端向 Redis 服务器发送一个 PING ,如果服务器运作正常的话,会返回一个 PONG 。
quit # 关闭与当前客户端与redis服务的连接。
auth password # 检测给定的密码和配置文件中的密码是否相符。
九、Redis 服务器命令
Info # 以一种易于理解和阅读的格式,返回关于 Redis 服务器的各种信息和统计数值。
dbsize # 返回当前数据库的 key 的数量。
time # 返回当前服务器时间。
command # 返回所有的Redis命令的详细信息,以数组形式展示。
command Info command-name [command-name ...] # 获取 redis 命令的描述信息。
command getkeys # 获取所有 key。
command count # 统计 redis 命令的个数。
showlog subcommand [argument] # 管理 redis 的慢日志。记录查询执行时间的日志系统。
flushdb # 清空当前数据库中的所有 key。
flushall # 清空整个 Redis 服务器的数据(删除所有数据库的所有 key )。
config set parameter value # 修改 redis 配置参数,无需重启。须执行config rewrite才会同步到配置文件中,否则重启失效
config get parameter # 获取 redis 服务的配置参数。
config resetstat # 重置 INFO 命令中的某些统计数据
config rewrite # 对启动 Redis 服务器时所指定的 redis.conf 配置文件进行改写.config set 后执行
role # 查看主从实例所属的角色,角色有master, slave, sentinel。
slaveof host port # 将当前服务器转变为指定服务器的从属服务器(slave server)。
slaveof no one # 使得这个从属服务器关闭复制功能,并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃。
sync # 用于(全量)同步主从服务器。
psync # 用于(全量和增量)同步主从服务器。为了解决旧版本中断线情况下SYNC进行全量复制(同步)的低效问题,在Redis 2.8之后使用PSYNC命令代替SYNC命令执行复制同步操作,PSYNC具备了数据全量重同步 和 部分重同步模式。
save # 执行一个同步保存操作,将当前 Redis 实例的所有数据快照(snapshot)以 RDB 文件的形式保存到硬盘。
bgsave # 在后台异步保存当前数据库的数据到磁盘。
bgrewriteaof # 异步执行一个 AOF(AppendOnly File) 文件重写操作。重写会创建一个当前 AOF 文件的体积优化版本。
lastsave # 返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示。
client slots # 获取集群节点的映射数组。
client kill ip:port # 关闭客户端连接。
client list # 获取连接到服务器的客户端连接列表
client setname connection-name # 指定当前连接的名称。
client getname # 获取连接的名称。返回 CLIENT SETNAME 命令为连接设置的名字。 因为新创建的连接默认是没有名字的, 对于没有名字的连接, CLIENT GETNAME 返回空白回复。
client pause timeout # 阻塞客户端命令一段时间(以毫秒计)。
shutdown [NOSAVE] [SAVE] # 异步保存数据到硬盘,并关闭服务器
debug object key_name # 是一个调试命令,它不应被客户端所使用。
debug segfault # 执行一个非法的内存访问从而让 Redis 崩溃,仅在开发时用于 BUG 调试。
monitor # 实时打印出 Redis 服务器接收到的命令,调试用。
十、Redis 脚本命令
script kill # 用于杀死当前正在运行的 Lua 脚本,当且仅当这个脚本没有执行过任何写操作时,这个命令才生效。
script load "script" # 用于将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本。
script exists sha1 # 用于校验指定的脚本是否已经被保存在缓存当中。
script flush # 清除所有 Lua 脚本缓存。
eval script numkeys key [key ...] arg [arg ...] # 使用 Lua 解释器执行脚本。
evalsha sha1 numkeys key [key ...] arg [arg ...] # 根据给定的 sha1 校验码,执行缓存在服务器中的脚本。
十一、Redis 事务命令
exec # 执行所有事务块内的命令。
watch # 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断
discard # 取消事务,放弃执行事务块内的所有命令。
unwatch # 取消 WATCH 命令对所有 key 的监视。
multi # 标记一个事务块的开始。
十二、其他类型命令
1、geospatial地理位置
应用场景:应用于地理位置计算
geoadd key_name longitude latitude member [longitude latitude member ...] # 存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。
geopos key_name member [member ...] # 从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil。
geohash key member [member ...] # 获取一个或多个位置元素的 geohash 值。
geodist key_name member1 member2 [m|km|ft|mi] # 返回两个给定位置之间的距离。
georadius key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] # 以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
georadiusbymember key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] # 和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 georadiusbymember 的中心点是由给定的位置元素决定的, 而不是使用经度和纬度来决定中心点。
实际上geospatial底层是通过zset实现的,可以通过zset命令来进行删除等操作
2、hyperloglog
应用场景:基数统计
例如:对于 Google 主页面而言,同一个账户可能会访问 Google 主页面多次。于是,在诸多的访问流水中,如何计算出 Google 主页面每天被多少个不同的账户访问过就是一个重要的问题。那么对于 Google 这种访问量巨大的网页而言,其实统计出有十亿 的访问量或者十亿零十万的访问量其实是没有太多的区别的,因此,在这种业务场景下,为了节省成本,其实可以只计算出一个大概的值,而没有必要计算出精准的值。
对于上面的场景,可以使用HashMap、BitMap和HyperLogLog来解决。对于这三种解决方案,这边做下对比:
- HashMap:算法简单,统计精度高,对于少量数据建议使用,但是对于大量的数据会占用很大内存空间;
- BitMap:位图算法,具体内容可以参考我的这篇文章,统计精度高,虽然内存占用要比HashMap少,但是对于大量数据还是会占用较大内存;
- HyperLogLog:存在一定误差,占用内存少,稳定占用 12k 左右内存,可以统计 2^64 个元素,对于上面举例的应用场景,建议使用。
说明:基数不大,数据量不大就用不上,会有点大材小用浪费空间有局限性,就是只能统计基数数量,而没办法去知道具体的
内容是什么,和bitmap相比,属于两种特定统计情况,简单来说,HyperLogLog 去重比 bitmap 方便很多,一般可以bitmap和hyperloglog配合使用,bitmap标识哪些用户活跃,hyperloglog计数
pfadd key element [element ...] # 添加指定元素到 HyperLogLog 中。
pfcount key [key ...] # 返回给定 HyperLogLog 的基数估算值。
pfmerge destkey sourcekey [sourcekey ...] # 将多个 HyperLogLog 合并为一个 HyperLogLog
3、bitmaps
应用场景:
- 用户签到
很多网站都提供了签到功能,并且需要展示最近一个月的签到情况,这种情况可以使用 BitMap 来实现。
根据日期 offset = (今天是一年中的第几天) % (今年的天数),key = 年份:用户id。
如果需要将用户的详细签到信息入库的话,可以考虑使用一个一步线程来完成。- 统计活跃用户(用户登陆情况)
使用日期作为 key,然后用户 id 为 offset,如果当日活跃过就设置为1。具体怎么样才算活跃这个标准大家可以自己指定。
假如 20201009 活跃用户情况是: [1,0,1,1,0]
20201010 活跃用户情况是 :[ 1,1,0,1,0 ]
统计连续两天活跃的用户总数:
bitop and dest1 20201009 20201010
dest1 中值为1的offset,就是连续两天活跃用户的ID
bitcount dest1
统计20201009 ~ 20201010 活跃过的用户:
bitop or dest2 20201009 20201010
- 统计用户是否在线
如果需要提供一个查询当前用户是否在线的接口,也可以考虑使用 BitMap 。即节约空间效率又高,只需要一个 key,然后用户 id 为 offset,如果在线就设置为 1,不在线就设置为 0。- 实现布隆过滤器
getbit key_name offset value # 对 key 所储存的字符串值,获取指定偏移量上的位(bit)【 value 只能是0或1】。
setbit key_name offset # 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
bitcount key [start] [end] # 计算给定字符串中,被设置为 1 的比特位的数量。一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。
bitop operation destkey key [key ...] # 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。
总结
以上就是redis命令相关的内容,本文仅仅简单介绍了基础命令的使用,对于命令的参数并未全部写出,具体用法还请参考手册。
参考链接:
Redis之HyperLogLog底层原理与使用场景、
bitmaps