[笔记] [redis] redis命令总结

[笔记] [redis] redis命令总结

安装

# 修改docker源
"registry-mirrors": [
        "https://docker.mirrors.ustc.edu.cn",
        "https://registry.docker-cn.com",
        "http://hub-mirror.c.163.com",
        "https://mirror.ccs.tencentyun.com"
    ]

# 安装redis
docker pull redis:latest
# 检查镜像
docker images
# 运行容器
docker run -itd --name redis-test -p 6379:6379 redis
docker exec -it 容器id /bin/bash
# 在Windows系统上顺带安装redis, 为了使用redis-cli

redis key

对于key来说,我们应该拥有哪些属性和接口呢?首先是过期属性,在计算时间时,因为使用的是system_clock,在测量时间间隔时可能会修改时钟,比如通过网络与另一个时钟同步、转换到夏令时等。因此如果两个redis实例时钟不同步,则在过期时间的精度上会不准确。

对于expire属性来说,我们需要这些接口:

  • 设置过期时间:对于时间可分为两种抽象:时间间隔和时间点
expire key integer           # 设置key在integer秒后过期
pexpire key integer          # 以毫秒为单位
expireat key unix_timepoint  #设置key在unix_timepoint时过期
pexpireat key unix_timepoint #以毫秒为单位
persist key                  #不过期
ttl key                      # 判断还有多久过期
pttl                         # 毫秒为单位
  • redis支持多种数据类型,可以通过key来判断我们存储的类型是什么 type key
  • 删除key del key
  • 判断是否存在exists key
  • 序列化和反序列化
dump key #序列化
restore key ttl serialized-value [replace]
  • 重命名key
rename key new_key
# assert key != new_key
# if (exists new_name then overlap)
  • 查询匹配的键 keys pattern

redis的过期删除策略(ToDo)

redis数据类型

  • string
    • List
  • hash
  • Set
  • Sorted Set

string

  • 二进制安全(jpg/序列化后的对象等)
  • value不能大于512MB

string支持二进制、整数、浮点数操作:
对于二进制,有以下接口:

  • 以二进制形式读取字符串,计算位为1的个数:bitcount key start end,[start, end]内bit=1的个数
  • 位运算 setbitgetbitbitfieldgetrange
# SETBIT key offset value # 配合bitcount可以快速计算1的个数
# GETBIT key offset
# BITOP operation destkey key [key ...] #可能需要and/or/not/xor等操作
# BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]
# type: u8/u16/u32/u64/i8/i16/i32/i64
# offset: #0 => first
# value: 使用与type相对应的值即可, 不确实是否支持二进制输入.

# getrange key start end

对于整数,有以下接口:

  • decr key
  • decrby key value
  • incr key
  • incrby key value

对于浮点数,有以下接口:

  • incrbyfloat key value

位图的使用(引用自[2])

  • 统计每日活跃用户
    redis.setbit(login:yyyy-mm-dd, user_id, 1),为了统计月活,即对一个月所有天数求并集。bitop or dest login:yyyy-mm-01 login:yyyy-mm-02 ....,同时我们可以为对每日、每周、每月的数据进行缓存以优化计算。

reference

list

list为链表型数据结构,随机读取&插入的复杂度为O(n),

lpush key value # 左端插入元素,返回list长度
rpush key value # 同lpush
lpop key
rpop key
lpushx/rpushx key value # 逻辑和lpush/rpush相似,不同点在于lpushx/rpush仅在key存在时才执行

# 谨慎使用,复杂度为O(n),特殊情况见注释
LINDEX key index        # 下标访问
LSET key index value   # 下标访问, 如果访问的是头/尾元素则复杂度为O(1)
LINSERT key BEFORE|AFTER pivot value
LREM key count value    # 从存于 key 的列表里移除前 count 次出现的值为 value 的元素,count的正负值决定从头开始还是从末尾开始

redis的list可以用于模拟双端队列,为此也提供了一系列阻塞式操作,如blpop/brpop,见引用[1],提供该接口的一个目的是解决这类问题:在生产者消费者模型中,如果链表为空,那么消费者执行rpop时返回null,此时消费者不得不等待一段时间并且重试rpop

BLPOP key [key ...] timeout
BRPOP key [key ...] timeout
reference

Hash

可以理解为将hashmap搬入redis。Hash非常适用于表现对象类型的数据。用Hash中的field对应对象的field即可。如果存在嵌套类型,其中的一个解决方案是:使用redis json(注:或许存在其他解决方案)。

优点:

  • 存储经过序列化后的数据
  • 随机访问性能强于list
HSET key field value
HMSET key field value [field value ...]
HGET key field
HMGET key field [field ...]
HDEL key field [field ...]
HEXISTS key field
hincrby key field value  # 与field对应的值能转为整型
hincrbyfloat field value # 能转float
hlen key			     # 计算有多少个field


# 以下3个命令谨慎使用,因为复杂度为O(n),可转换为HSCAN进行游标式遍历
HGETALL key
HKEYS key                # 获取所有的field
HVALS key                # 获取所有的值
使用scan命令(ToDo)

Set

Set是无序的,不可重复的String集合。

SADD key member [member ...]    # 向set中添加member
SISMEMBER key member            # 查询member是否是set中的member
SREM key member [member ...]    # 删除set中的member,返回值=删除的个数
SCARD key                       # 返回member个数
SRANDMEMBER key [count]         # 随机地返回count个member
SPOP key [count]                # 随机移除并返回count个member
SMOVE source destination member # 将指定的member从source移动到destination

以下为复杂度较高的指令:

SMEMBERS key                    # 返回指定set中的所有member,复杂度O(n)
SUNION key [key ...]            # 计算多个Set的并集并返回
SUNIONSTORE destination key [key ...] # 计算多个Set的并集并将结果存储至destination
SDIFF key [key ...]             # 计算多个Set的差集并返回
SDIFFSTORE destination key [key ...]  # 计算多个Set的差集并将结果存储至destination

可以考虑使用sscan指令获取所有的member,对于union和diff运算,可以在客户端上进行计算。

Sorted Set

有序的不可重复的Set。

ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
# 这里的附加选项其实要解决的问题是:当我们添加key时,如果key存在如何处理,如果key不存在如何处理,以及是否根据上述条件对全局做一个约束
# XX => 仅更新存在的成员,不添加新成员
# NX => 不更新存在的成员,仅添加新成员
# ...

ZREM key member [member ...] # 可删除多个成员
ZCOUNT key min max           # 返回score∈[min, max]的成员个数 O(log(n))
ZCARD key                    # 返回Set中成员的个数
ZSCORE key member            # 返回成员的score
ZRANGE key start stop [WITHSCORES]    # 升序,返回key [+scores]
ZREVRANGE key start stop [WITHSCORES] # 降序,返回key
ZINCRBY key increment member          # 对指定member的score增加increment,increment可以为负数

复杂度较高的指令:

ZRANGE key start stop [WITHSCORES]    # 升序排序,返回指定范围的member
ZREVRANGE key start stop [WITHSCORES] # 降序排序,返回指定范围的member

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] # 升序,返回score∈[min, max]的member
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] # 降序,返回score∈[min, max]的member

应尽量避免[0, -1][-inf, inf]这样的范围指定,尽量使用zscan指令进行游标式遍历。

redis的数据持久化

redis的持久化包括RDB和AOF两个方案。其中:

  • RDB: 能够在指定的时间间隔能对你的数据进行快照存储
  • 记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大

如果只把redis当作缓存使用,可以不进行持久化。
也可以同时开启RDB和AOF,redis在重启时优先加载AOF,因为通常情况下AOF的数据集比RDB更加完整。

RDB优点

  • RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集.
  • RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复.
  • RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能.
  • 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些.

RDB缺点

  • 如果你希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合你.虽然你可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),是Redis要完整的保存整个数据集是一个比较繁重的工作,你通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,你可能会丢失几分钟的数据.
  • RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度.

AOF 优点

  • 使用AOF 会让你的Redis更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync.使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据.
  • AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也也可使用redis-check-aof工具修复这些问题.
  • Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
  • AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

AOF 缺点

  • 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
  • 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。

定时生成RDB快照易于备份,且恢复速度比AOF快。

如何生成RDB快照:

save 60 1000 # 60s内有1000个键被改动

如何开启AOF功能:
配置文件添加:appendonly yes

redis如何实现RDB和AOF?

RDB实现方式

  • 父进程调用fork
  • 子进程将内存数据写入临时RDB文件,此时并不会影响父进程的写入(利用写时复制原理)
  • 子进程完成对临时文件的写入,使用系统调用rename原子地替换原来的RDB文件,并删除原有的RDB文件。

AOF实现方式(version≥7.0)

  • 父进程调用fork
  • 子进程开始在临时文件中写入基础的AOF(这里完成了AOF重建,其实就是根据当前的内存状态生成AOF文件)
  • 父进程将新的更新写入新的AOF文件,如果子进程重写AOF失败,此时旧的AOF和父进程此时新的AOF就是完整的数据集,并将其持久化
  • 当子进程完成基础AOF的重写后,向父进程发信号,父进程收到信号后则使用子进程新建的基础AOF文件+新AOF生成临时的AOF文件
  • 使用rename替换原有AOF文件,持久化生效,并清理基础文件和未使用的增量文件。

reference

redis的一些常见应用

string

  • session cache
  • 购物车数据
  • 队列处理流量,消息,数据收集

list

Set

  • 数据分析,如集合操作等
  • IP访问量统计
  • 文本过滤=>关键词过滤

Sorted Set

Hash

redis主从配置

master其实可以什么都不做,slave则需要指定master的ip和port,如果master设置了密码,则需要添加masterauth masterpassword。

slaveof ip port
cluster-enable no
masterauth masterpassword

待阅读

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值