Redis知识总结

Redis

一、五大数据类型

  • String字符串类型
  • Hash哈希表类型
  • List列表
  • Set集合
  • Sorted Set有序集合

1、Redis通用操作

  • exists:判断key是否存在

    exists name 存在返回数字,不存在返回0

  • expire:设置key的过期时间,单位秒

    expire name 10; 成功返回1,失败返回0

  • ttl:查看key的剩余过期时间

    ttl name; 返回剩余的时间,如果不过期返回-1,过期返回-2

  • del:根据key删除键值对

    del name; 返回被删除key的数量

  • keys:查看当前redis中的key数据

    keys *

  • flushall:清空数据库中所有数据

2、String字符串

  • set:设置指定key的值

    set name “zijian”

  • get:获取指定key的值

    get name

  • setnx:当key不存在时新增

    setnx name “lisi”

  • setex:设置key的存活时间,无论是否存在指定的key都能新增,存在则覆盖。

    setex name 10 “zhangsan”

  • incr/dect:让value递增/递减

    incr age;

3、Hash表

注意:下方的key表示是在名为key中的hash表中

  • hset:给key中filed设置值

    kset key username “zhangsan”

  • hget:获取key中某个filed的值

    kget key username;

  • hmset:给key中多个filed设置值

    hmset key username “lisi” age 22

  • hmget:一次获取key中多个field的值

    hmget key username age

  • hkeys:获取key中所有的field的值

    hkeys key

  • hvals:获取key中所有value的值

    hvals key

  • hgetall:获取所有field和value

    hgetall key

  • hdel:删除key中任意个field

    hdel key username age

4、List列表

  • rpush:向列表末尾插入一个或多个值。可以重复

    rpush username “zhangsan” “lisi”

  • lrange:返回列表中指定区间内的值。-1代表末尾

    lrange username 0 -1

  • lpush:将一个或多个值插入到列表前面

    lpush username “wangwu”

  • llen:获取列表长度

    llen username

  • lrem:删除列表中元素

    lrem username 1 “zhangsan”;正数表示从左往右删除的数量。负数表示从由往左删除的数量。

5、Set集合

  • sadd:向集合中添加内容。不能重复

    sadd setage 22 23 24

  • scard:返回集合元素数量

    scard setage

  • smembers:查看集合中元素内容

    smembers setage

  • srem:删除集合中的元素

    srem setage 22

  • spop:随机取出count个集合中的元素

    spop setage 1

6、Sorted Set有序集合

注意:有序集合中每个value都有一个score,根据这个进行排序

  • zadd:向有序集合中添加数据

    zadd zage 1 22 3 24 2 23

  • zrange:返回区间内容

    zrange zage 0 3

  • zrem:删除集合内容

    zrem zage 22

二、三种特殊的数据类型

1. geospatial(地理位置)

  • geoadd:添加地理位置

    • 有效的经度从-180到180度。
    • 有效的纬度从-85.05112878度到85.05112878度。
    • 当坐标位置超出上述指定范围时,该命令会发生一个致命的错误。
    127.0.0.1:6379[2]> geoadd china:city 116.40 39.90 beijing
    (integer) 1
    127.0.0.1:6379[2]> geoadd china:city 121.47 31.23 shanghai
    (integer) 1
    127.0.0.1:6379[2]> geoadd china:city 106.50 29.53 chongqing
    (integer) 1
    127.0.0.1:6379[2]> geoadd china:city 114.05 22.52 shengzhen
    (integer) 1
    
  • geodist:返回两个给定位置之间的距离

    127.0.0.1:6379[2]> geodist china:city beijing shanghai
    "1067378.7564"
    127.0.0.1:6379[2]> geodist china:city beijing shengzhen
    "1945788.0901"
    
    127.0.0.1:6379[2]> geodist china:city beijing shengzhen km #查看北京到上海的直线距离单位是千米
    "1945.7881"
    127.0.0.1:6379[2]> geodist china:city beijing shanghai km
    "1067.3788"
    
  • georadius:以给定的经纬度为中心, 找出某一半径内的元素

    127.0.0.1:6379[2]> georadius china:city 110 30 1000 km #查找经纬度为中心,找出1000公里内的城市
    1) "chongqing"
    2) "shengzhen"
    127.0.0.1:6379[2]> georadius china:city 110 30 500 km
    1) "chongqing"
    
    127.0.0.1:6379[2]> georadius china:city 110 30 500 km withcoord#查找经纬度为中心,找出500公里内的城市并附带经纬度
    1) 1) "chongqing"
       2) 1) "106.49999767541885376"
          2) "29.52999957900659211"
    127.0.0.1:6379[2]> georadius china:city 110 30 500 km withdist#查找经纬度为中心,找出500公里内的城市并附带直线距离
    1) 1) "chongqing"
       2) "341.9374"
    
    127.0.0.1:6379[2]> georadius china:city 110 30 1000 km withdist count 1 #刷选出指定的城市
    1) 1) "chongqing"
       2) "341.9374"
    127.0.0.1:6379[2]> georadius china:city 110 30 1000 km withdist count 2
    1) 1) "chongqing"
       2) "341.9374"
    2) 1) "shengzhen"
       2) "924.6408
    
  • geo底层实现原理就是Zset,可以使用zset命令来操作geo

    127.0.0.1:6379[2]> zrange china:city 0 -1 #查看地图中的全部元素
    1) "chongqing"
    2) "shengzhen"
    3) "shanghai"
    4) "beijing"
    127.0.0.1:6379[2]> zrem china:city beijing#删除地图中指定的元素
    (integer) 1
    127.0.0.1:6379[2]> zrange china:city 0 -1
    1) "chongqing"
    2) "shengzhen"
    3) "shanghai"
    

2.hyperloglog

  • 什么是基数:

    • 比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。
    127.0.0.1:6379[2]> pfadd mykey a b c d e f g h i j #创建一组元素
    (integer) 1
    127.0.0.1:6379[2]> pfcount mykey #统计mykey元素的基数数量
    (integer) 10
    127.0.0.1:6379[2]> pfadd mykey2 i j l m n o p q r s
    (integer) 1
    127.0.0.1:6379[2]> pfcount mykey2 #创建第二组元素
    (integer) 10
    127.0.0.1:6379[2]> pfmerge mykey3 mykey mykey2 #合并两组的元素,并集
    OK
    127.0.0.1:6379[2]> pfcount mykey3
    (integer) 18
    

3.bitmap

  • 统计用户信息,例如打卡,或者登陆的活跃状态;只要是两个状态的都可以使用Bitmap.
使用Bitmap记录周一到周五的打卡记录,统计打卡天数
127.0.0.1:6379[2]> setbit sign 0 1
(integer) 0
127.0.0.1:6379[2]> setbit sign 1 1
(integer) 0
127.0.0.1:6379[2]> setbit sign 2 0
(integer) 0
127.0.0.1:6379[2]> setbit sign 3 0
(integer) 0
127.0.0.1:6379[2]> setbit sign 4 0
(integer) 0
127.0.0.1:6379[2]> setbit sign 5 1
(integer) 0

127.0.0.1:6379[2]> getbit sign 2 #查看是否打卡
(integer) 0
127.0.0.1:6379[2]> getbit sign 1
(integer) 1

127.0.0.1:6379[2]> bitcount sign#统计这周打卡记录
(integer) 3

三、Redis持久化策略

  • redis是内存数据库,如果不将内存中的数据状态保存到磁盘中,那么一旦服务器进程退出,服务器中的数据库状态也会消失,所以redis提供了持久化功能。
  • redis提供了两个持久化方案:RDB持久化和AOF持久化,一个是快照的方式,一个是类似日志追加的方式。

1.RDB持久化策略

  • 通过快照的方式,在指定的时间间隔内将内存中的数据集快照写入磁盘。在创建快照之后,用户可以备份该快照,可以将快照复制到其它服务器以创建相同数据的服务器副本,或者在重启服务器后恢复数据。RDB是Redis默认的持久化方式。
  • RDB持久化会生成RDB文件,该文件是一个压缩过的二进制文件,可以通过该文件还原快照时的数据库状态。RDB文件默认为当前工作目录下的dump.rdb。当redis重启后会自动加载dump.rdb文件中内容到内存中。

触发快照的时机:

  • 执行save(同步)和bgsave(异步)命令

  • 配置文件设置save 规则,自动间隔性执行bgsave命令

  • 主从复制时,从库全量复制同步主库数据,主库会执行bgsave

  • 执行flushall命令清空服务器数据

  • 执行shutdown命令关闭Redis时,会执行save命令

save和bgsave命令区别:

  • save命令会阻塞Redis服务器进程,服务器进程在RDB文件创建完成之前是不能处理任何的命令请求。

  • bgsave命令会fork一个子进程,然后该子进程会负责创建RDB文件,而服务器进程会继续处理命令请求。

优点:

  • rdb文件是一个紧凑文件,直接使用rdb文件就可以还原数据。
  • 数据保存会由一个子进程进行保存,不影响父进程。
  • 恢复数据的效率要高于AOF的方式。

缺点:

  • 在两个保存点之间的时间时,Redis如果关闭了,会导致数据的丢失。
  • 使用bgsave保存数据时,每次都需要fork子进程,在数据量比较大时会比较耗费性能。

2.AOF持久化方式

注意:AOF默认是关闭的,需要在配置文件中开启AOF,Redis支持RDB和AOF同时生效,若同时存在,AOF的优先级高于RDB

  • 开启后,每执行一条更改Redis数据的命令,都会把该命令追加到AOF文件中,这会降低Redis性能。

AOF实现步骤:

  • 命令追加(append)、文件写入(write)、文件同步(sync)

命令追加:

  • 开启AOF持久化功能后,服务器每执行一个写命令,都会把该命令以协议格式先追加到aof_buf缓存区的末尾,而不是直接写入文件,避免每次有命令都直接写入硬盘,减少硬盘IO次数。

AOF重写(rewrite):

  • 随着时间的推移,Redis执行的写命令会越来越多,AOF文件也会越来越大,过大的AOF文件可能会对Redis服务器造成影响,而且会加大还原时间。

  • AOF重写的目的就是减少AOF文件的体积,不过值得注意的是:AOF文件重写并不需要对现有的AOF文件进行任何读取、分享和写入操作,而是通过读取服务器当前的数据库状态来实现的。

  • 文件重写可以分为手动触发和自动触发,手动触发执行bgrewriteaof命令,该命令的执行跟bgsave触发快照时类似的,都是先fork一个子进程做具体的工作。

    127.0.0.1:6379> bgrewriteaof
    Background append only file rewriting started
    

AOF优点:

  • 相对于RDB方式更加能保证数据的安全性。

AOF缺点:

  • 对于相同的数据集,AOF文件体积要大于RDB文件,数据恢复也会比较慢。

如何选择RDB和AOF:

  • 如果是数据不那么敏感,且可以从其他地方重新生成补回的,那么可以关闭持久化。
  • 如果是数据比较重要,不想再从其他地方获取,且可以承受数分钟的数据丢失,比如缓存等,那么可以只使用RDB。
  • 如果是用做内存数据库,要使用Redis的持久化,建议是RDB和AOF都开启,或者定期执行bgsave做快照备份,RDB方式更适合做数据的备份,AOF可以保证数据的不丢失

四、数据恢复

  • 如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据。
  • 如果是redis进程所在机器挂掉,那么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复,如果AOF文件破损,那么用redis-check-aof fix命令修复。
  • 如果没有AOF文件,会去加载RDB文件。
  • 如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复。

五、事务

  • 事务是一个单独的隔离操作(Redis事务的本质):事务中的所有命令都会序列化按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断(排他性)。
  • Redis单条命令式保存原子性的,但是事务不保证原子性。
  • Redis事务没有隔离级别的概念。
  • 一个事务从开始到执行会经历以下三个阶段:
    • 开始事务。multi
    • 命令入队。
    • 执行事务。exec

六、Redis缓存

  • 缓存穿透:

    查询缓存和DB都不存在的数据。

    解决方式:

    • 利用互斥锁,缓存失效时,失去获得锁,得到锁,再去请求数据库。没得到锁则休眠一段时间重试。
    • 采用异步更新策略,无论key是否取到值都返回,value中加入一个缓存失效时间。
    • 使用布隆过滤器。
  • 缓存击穿:

    高并发情况下,某个热门的key突然过期,导致大量的请求在redis中未找到缓存数据,进而全部去访问DB数据库,引起DB压力瞬间变大。

    解决方式:

    • 保证热点数据永不过期,再加一个互斥保证缓存单线程写。
  • 缓存雪崩:

    如果大量的缓存在一段时间内集中过期,这是就会出现大量的缓存击穿,所有请求都落在DB上,引起DB压力过大,导致DB宕机。

    解决方式:

    • 给缓存一个失效时间,避免集体失效。
  • 缓存预热:

    系统上线后,将相关的缓存数据直接加载缓存系统。

  • 缓存降级:

    当访问量剧增,服务出现问题(响应忙或不响应),仍需要保证服务还是可用的,系统可根据一些关键数据进行自动降级。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值