redis基础超详细 思维导图

    科技2022-07-10  171

    Redis

    先上图:

    简介

    Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。

    它支持多种类型的数据结构,

    如 字符串(strings),

    散列(hashes),

    列表(lists),

    集合(sets),

    有序集合(sorted sets) 与范围查询,

    bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。

    Redis 内置了 复制(replication),

    LRU驱动事件(LRU eviction),

    和不同级别的 磁盘持久化(persistence),

    并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

    key常用命令

    redis-cli -p 6379

    keys
    keys* 匹配数据库中所有的keykeys h?llo 匹配hello ,hallo 等keys h*llo 匹配数据库中的h00000llo 等keys h[ae]llo 匹配数据库中的hallo hello
    exists key

    ​ 判断key 是否存在

    EXPIRE key seconds
    给key 设置生存的时间 当key 过期 他被自动商储在 Redis 中,带有生存时间的 key 被称为『易失的』(volatile)。

    ttl key 查看key 生存时间的剩余时间

    Type

    ​ type key 查看当前key 的类型

    MOVE key db

    将当前数据库的 key 移动到给定的数据库 db 当中。

    如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定 key ,或者 key 不存在于当前数据库,那么 MOVE 没有任何效果。

    因此,也可以利用这一特性,将 MOVE 当作锁(locking)原语(primitive)

    String (字符串)

    append
    append key v

    ​ 在key 的value 后面追加v

    STRLEN key

    ​ 查看key 的长度

    INCR && decr 自增/减

    ​ 将 key 中储存的数字值增一/减一。

    ​ 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR/DECR 操作。

    ​ 如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。

    ​ 本操作的值限制在 64 位(bit)有符号数字表示之内。

    127.0.0.1:6379> set sum 0 OK 127.0.0.1:6379> get sum "0" 127.0.0.1:6379> incr sum (integer) 1 127.0.0.1:6379> get sum "1" 127.0.0.1:6379> incr sum (integer) 2 127.0.0.1:6379> get sum "2" 127.0.0.1:6379> DECR sum (integer) 1 127.0.0.1:6379>
    INCRBY/DECRBY key increment 自增/减

    将 key 所储存的值加上增量/减量 increment 。

    如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。

    如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。

    本操作的值限制在 64 位(bit)有符号数字表示之内。

    GETRANGE key start end 获取

    ​ 返回 key 中字符串值的子字符串,字符串的截取范围由 start 和 end 两个偏移量决定(包 括 start 和 end 在内)

    0 表示第一个 -1 表示最后一个字符, -2 表示倒数第二个 以此类推

    127.0.0.1:6379> set key1 "hello ,hututu" OK 127.0.0.1:6379> GETRANGE key1 0 5 "hello " 127.0.0.1:6379> GETRANGE key1 5 10 " ,hutu" 127.0.0.1:6379> GETRANGE key1 5 -1 " ,hututu" 127.0.0.1:6379>

    SETRANGE key offset value 替换

    用 value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始。

    确保字符串足够长以便将 value 设置在指定的偏移量上,如果给定 key 原来储存的字符串长度比偏移量小(比如字符串只有 5 个字符长,但你设置的 offset 是 10 ),那么原字符和偏移量之间的空白将用零字节(zerobytes, "\x00" )来填充。

    setex &&setnx

    SETEX key seconds value

    将 key 的值设为 value , 并且设置过期时间 如果不存在就创建 如果存在就覆盖她

    setnx ---- 常在分布式锁中使用

    将 key 的值设为 value ,当且仅当 key 不存在。

    若给定的 key 已经存在,则 不做任何动作。

    mset && mget
    127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 OK 127.0.0.1:6379> keys * 1) "k1" 2) "k3" 3) "k2" 127.0.0.1:6379> 127.0.0.1:6379> mget k1 k2 k3 1) "v1" 2) "v2" 3) "v3" 127.0.0.1:6379>

    msetnx(原子性操作) 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uWaJFgFb-1601696142138)(C:\Users\hly\AppData\Roaming\Typora\typora-user-images\image-20201001105032218.png)]

    List

    列表(list)用于存储多个有序的字符串。列表是一种比较灵活的数据结构,可以充当栈和队列的角色,在实际开发上有很多应用场景

    列表的特点:

    列表中的元素是有序的,可以通过索引下标来获取某个元素或者某个范围内的元素列表列表中的元素是可以重复的 lpush mylist a b c 左插入 rpush mylist x y z 右插入 lrange mylist 0 -1 数据集合 lpop mylist 弹出元素 rpop mylist 弹出元素 llen mylist 长度 lrem mylist count value 删除 lindex mylist 2 指定索引的值 lset mylist 2 n 索引设值 //更新操作 ltrim mylist 0 4 删除key ltrim 去除不在区间里面的数据 1 -1 (去小标为一的) LINSERT key BEFORE|AFTER pivot value linsert mylist before "work" H 在mylist 中的work 前插入H linsert mylist before a 插入 linsert mylist after a 插入 rpoplpush list list2 转移列表的数据

    命令 rpoplpush在一个原子时间内,执行以下两个动作:

    将列表 source 中的最后一个元素(尾元素)弹出,并返回 给客户端。将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。

    举个例子,你有两个列表 source 和 destination , source 列表有元素 a, b, c , destination 列表有元素 x, y, z ,执行 RPOPLPUSH source destination 之后, source 列表包含元素 a, b , destination 列表包含元素 c, x, y, z ,并且元素 c 会被返回给客户端。

    如果 source 不存在,值 nil 被返回,并且不执行其他动作。

    如果 source 和 destination 相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况视作列表的旋转(rotation)操作。

    修改

    lset key index newValue 修改指定索引下标的元素

    应用场景

    消息队列

    redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的抢列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性

    列表的使用场景很多,以下是命令组合口诀: lpush + lpop = stack(栈) lpush + rpop = queue(队列) lpush + ltrim = capped collection(有限集合) lpush + brpop = message queue(消息队列)https://www.jianshu.com/p/fa39cc1d9779

    Set

    Hset mymap key value: 增加 如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。 如果域 field 已经存在于哈希表中,旧值将被覆盖。 HsetNx : 同上 但是只有key 不存在生效 HGET mynap key :取出 Hdel :hdel mymap a (a b c ) 删除一个 或多个 HmSET mymap key f value : 一次添加多个元素 Hmget : 同时取出多个key 的值 HgetAll mymap:返回哈希表中,所有的域和值。 Hexists mymap key :查看 mymap 中是否存在key HKEYS mymap 获取mymap中mymap 的所有key Hvalues 获取所有的value Hlen : 获取数量 HINCRBY counter page_view -50 : 减去/增加 步长 HINCRBYFlout : 同上 精度为浮点

    ZST

    127.0.0.1:6379> ZADD SC 23 ZHANG (integer) 1 127.0.0.1:6379> ZADD SC 98 LI (integer) 1 127.0.0.1:6379> ZADD SC 55 WU (integer) 1 127.0.0.1:6379> KEYS * 1) "SC" 2) "sc" 127.0.0.1:6379> ZRANGEBYSCORE SC -inf +inf ( -inf +inf 负/正无穷) 1) "ZHANG" 2) "WU" 3) "LI" 127.0.0.1:6379>

    Zset(有序集合) Zadd : zadd k1 v1 score1 v1 ZRANGEBYSCORE ZRANGEBYSCORE salary -inf +inf :显示整个集合 : 从小到大 ZRANGEBYSCORE salary -inf +inf WITHSCORES : 显示整个有序集及成员的 score 值 ZRANGE SC 0 -1 WITHSCORES 同上

    ZRANGEBYSCORE salary -inf 5000 WITHSCORES # 显示工资 <=5000 的所有成员 ZRANGEBYSCORE salary (5000 400000 # 显示工资大于 5000 小于等于 400000 的成员 ZRANGE:返回有序集 中,指定区间内的成员。 score 值递增(从小到大)来排序。 ZRANGE salary 0 -1 WITHSCORES :显示整个 ZRANGE salary 1 2 WITHSCORES : # 显示有序集下标区间 1 至 2 的成员 ZCOUNT myset min max:获取最大值最小值之间的个数 ZCOUNT salary 2000 5000 # 计算薪水在 2000-5000 之间的人数 ZINCRBY :为有序集 myset 的成员 value 的 score 值加上增量 increment 。 Zrank myset value1:返回有序集 myset中成员 value 的排名 Zrevrank :返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)排序。 Zrem :移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。 ZREMRANGEBYRANK key start stop 移除有序集 中,指定排名(rank)区间内的所有成员。 ZREMRANGEBYSCORE key min max 移除有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。 Zrevrange key start stop : 返回有序集 key 中,指定区间内的成员。 ZREVRANGE salary 0 -1 WITHSCORES # 递减排列 ZREVRANGEBYSCORE :返回有序集 key 中, score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score 值递减(从大到小)的次序排列。 ZREVRANGEBYSCORE salary +inf -inf ZREVRANGEBYSCORE salary 10000 2000 # 逆序排列薪水介于 10000 和 2000 之间的成员 Zscpore myset value : 返回myset value 的score(key) 排序不同

    特殊Geospatial

    特殊类型Geospatial 地理位置 geoadd : 添加地理位置 GEOADD china:city 124.47 31.23 sahnghai GeoPOs 获取地理位置 GEOPOS china:city sahnghai 1) "124.46999877691268921" 2) "31.22999903975783553" geodist : 获取距离 geodist china:city beijing sahnghai km 北京与上海的距离km geoRadius 我附近的人 GeoRadius china:city 110 30 500 km (以110 50 点为中心 半500km 的人) 后面可以加count 限制显示人数 withdist 显示到中心的距离 withcide 显示地位人的相信 geo的底层是zset 可以用zset的命令来操作geo

    Hyperloglog

    简介: redis 2.8.9 更新

    ​ redsi hyperloglog 是基数的统计的算法

    优点: 占用内存的固定 2^64 不同的元素的技术 只要12kb 的内存

    ​ 网页的UV (一个人访问一个网站多次 算一个人)

    ​ 传统的方法: set 保存用户的id 然后 可以统计set 中元素的数量作为标准判断

    ​ 这个方法要保存用户大量的id 麻烦

    (empty array) 127.0.0.1:6379> PFADD key1 a b c d e f g h (integer) 1 127.0.0.1:6379> PFADD key3 e f g h y k m n v (integer) 1 127.0.0.1:6379> PFMERGE mykey key1 key3 OK 127.0.0.1:6379> PFCOUNT mykey (integer) 13 127.0.0.1:6379>

    Bitmap位储存

    统计 用户信息 活跃 1 不活跃 0: 是否登陆 1/0 打开1/0

    两个状态的都可以使用Bitmaps

    都是操作二进制来进行记录 只有0/1 两状态

    0-6 星期一没打开

    getBit sign 6获取星期日的 状态

    bitcount sign: 统计这个周的打卡记录

    事物

    本质: 一组命明的集合 一个事物的所有的命令会被序列化 在事物执行的过程中 会按照顺序进行

    一次性 顺序性 排他性 执行一些命令

    redis 单条命令保证原子性 但是事物不保证原子性

    redis 事物没有隔离级别的概念 只有发起执行命令的时候才会执行 exec

    所有的命令在事物中 并没有直接被执行

    redis 的事物

    开启事物(multi)命令入队(exec)执行事物()

    锁:

    正常执行事物

    127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> get k2 QUEUED 127.0.0.1:6379> exec 1) OK 2) OK 3) OK 4) "v2" 127.0.0.1:6379>

    discard 放弃事物

    127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set m k1 v1 QUEUED 127.0.0.1:6379> set m k2 v2 QUEUED 127.0.0.1:6379> DISCARD OK 127.0.0.1:6379> exec (error) ERR EXEC without MULTI 127.0.0.1:6379>

    编译型异常 代码问题 事物中的命令都不会被执行

    127.0.0.1:6379> MULTI OK 127.0.0.1:6379> set key k1 v1 QUEUED 127.0.0.1:6379> set key k2 v2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> getest k3 # 错误的 (error) ERR unknown command `getest`, with args beginning with: `k3`, 127.0.0.1:6379> set key k4 v4 QUEUED 127.0.0.1:6379> exec (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379>

    运行时间异常 如果事物队列存在语法性的错误 那么在执行命令的时候 其他命令也可以正常执行

    错误的命令抛出异常

    127.0.0.1:6379> MULTI OK 127.0.0.1:6379> incr k1 //错误 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> get k3 QUEUED 127.0.0.1:6379> exec 1) (error) ERR value is not an integer or out of range 2) OK 3) OK 4) "v3"

    watch

    watch 可以当作redis 的乐观锁使用

    watch money

    多线程模拟 事务对钱进行操作 在exec 之前 另外一个线程修改我们的值 这个时候 事物执行一点会失败

    解决: 先解锁:unwatch 在 watch

    Processed: 0.100, SQL: 8