redis笔记


Redis笔记


准备

概念

  • 字典结构的存储服务器
  • 多个字典,对应关系型数据库的不同database
  • 单线程

命令

  • 启动、结束

    redis-server #启动redis
    redid-cli shutdown #关闭Redis
    redis-cli #Redis命令行工具
  • 全局命令

    dbsize #获取redis中全部key的数量
    keys * #获取全部key
    ping 
    echo
    config set #设置Redis配置信息
    config get * #获取Redis配置信息
    select 1 #选择第一个数据库,Redis默认有16个,集群默认使用第一个(0号数据库)且只有一个

    入门

String

  • 定义
    • 最大512M
  • 命令
    • 取值赋值
      set
      Mset
      get
      Mget
  • 增加整数
    incr
    incrBy
    incrByFloat
    decr
    decrBy
  • 位操作
    getBit
    setBit
    bitCount
    bitOp
    bitPos
  • 其他
    exists
    del
    strLen
    append(追加)

List

  • 定义

    • 字符串列表
    • 基于双向链表
    • 有序、不唯一
    • 最多2^32 -1 头尾时间复杂度是O(1)
  • 应用

    • 新鲜事
    • 日志
    • 队列
  • 命令

    • 取值赋值
      • 两端增加
        LPUSH key ele[eles...]
        rpush
      • 两端弹出
        LPOP key [count]
        rpop
      • 根据索引
        LINDEX key index(获取索引处值)
        LSET key index ele(修改索引处值)
        RpopLpush source target(转移元素)
  • 片段

    • 获取片段
      lrange 0 -1(索引从0开始、正数从左边,负数从右边)
    • 保留片段
      • trim 0 -1
  • 删除指定值
    LREM key count value

      - count > 0
          - 从左边开始删除count个value
      - count < 0
          - 从右边开始删除count的绝对值个value
      - count = 0
          - 删除全部的value
    
  • 其他

    • llen

Set

  • 定义
    • 基于值为空的hash表
    • 无序、唯一
    • 最多2^32 -1
    • 时间复杂度是O(1)
      • 因为hash
  • 命令
    • 取值赋值
      sadd
      srem
      smembers
      SrandMember key count
      count > 0 获取不重复的元素 count < 0 可能获取重复的元素
      spop
      随机移除
    • 集合计算
      • 差集
        sdiff
        sdiffstore
      • 交集
        sinter
        sinterstore
      • 并集
        sunion
        sunionstore
    • 其他
      sismember(是否存在)
      scard(数量)

ZSet

  • 定义

    • 基于哈希表和跳跃表
    • 有序、唯一
    • 关联一个分数权值,按从大到小排序
    • 和List相比
        • 都是有序的
        • 都可以获取片段
        • List基于链表,中级数据获取慢,ZSet获取每个位置都一样
        • List不能调整某个元素的位置,ZSet可以(通过调整分数)
        • ZSet更费内存
  • 命令

    • 取值赋值
      zadd
      zRem(删除一个或多个)
      zRemRangeByRank key starts stop(按照排名范围删除)
      zRemRangeByScore key starts stop(按照分数范围删除)

    • 获取片段

      • ZRANGE key min max [withscores]
        根据排名返回[min,max]之间的元素 分数相同按字典顺序 从小到大
      • ZrevRANGE key min max [withscores]
        根据排名返回[min,max]之间的元素 从大到小
      • zRangeByScore key min max limit offset count 根据分数返回[min,max]之间的元素,支持偏移 从小到大
      • zRevRangeByScore key min max limit offset count 根据分数返回[min,max]之间的元素,支持偏移 从大到小
    • 参数

      • 负无穷(-inf)
      • 正无穷(inf)
      • 不包含(()
    • 分数
      zadd key score member(修改分数)
      zscore key member(获取分数)
      zIncrBy key increment member(修改分数)
      increment > 0 增加 increment < 0 减少

    • 集合计算

      • 差集
        zDiff
        zDiffStore
      • 交集
        zInterStore
      • 并集
        zUnionStore
    • 其他

      • sismember(是否存在)
      • zRank(获取元素排名、分数最小为 0)
      • zRevRank(获取元素排名、分数最大为 0)
      • 数量
        • zCard
        • zCount(获取指定范围的元素数量)
        • zLexCount

Hash

  • 定义
    • 最多2^32 -1
  • 命令(针对字段)
    • 取值赋值
      hset
      Mhset
      hget
      Mhget
      hgetAll
      hsetNX
      存在不执行操作 不存在= hset
      hexists
      hdel
    • 增加整数
      hincrby
    • 只获取key、value
      hkeys
      hvals
    • 其他
      hlen

自定义类型

进阶

事务

  • 好处
    • 保证原子性
    • 保证顺序性
  • 错误处理
    • 语法错误
      • 全部不执行
    • 运行错误
      • 正确的执行,错误的不执行
  • 命令
    multi
    exec
    watch
    unWatch

过期时间

  • 命令
    • 设置过期时间
      • expire key second
      • pExpire key milliSecond
      • expireAt key timestap
      • pExpireAt key millisecond-timestap
    • 清除过期时间
      • persist
      • set
      • getset
    • ttl
      • 【Time To Live】生存时间
      • -1永不过期
      • -2键不存在
  • 缓存系统
    • key过期时间不好确定
      • 时间长-浪费内存
      • 时间短-命中率低
    • 设置最大内存
    • 内存淘汰策略
      • LRU
        • 【List Recently Used】最近最少使用
          • 随机取maxmemory-samples个,删除最少使用的
      • volatile-LRU
        • 使用LRU删除设置了ttl的键
      • allkeys-LRU
        • 使用LRU删除全部键
      • volatile-random
        • 随机删除设置了ttl的键
      • allkeys-random
        • 随机删除全部键
      • volatile-TTL
        • 删除ttl最近的一个键
          • 随机取maxmemory-samples个,删除ttl最近的
      • noEviction
        • 不删除键,只返回错误

排序

  • sort
    • alpha
      • 默认转为double类型来排序
    • desc
      • 倒序
    • limit
      • 返回指定个数
    • by
      • SORT tag:ruby:posts BY post:*->time
      • 使用tag:ruby:posts的值替换 *,获取对应hash的time值进行排序
    • get
      • get # 返回元素本身的值
    • store
      • 保存后的键类型为List
      • 通常结合 expire 缓存
  • 性能优化
    • 时间复杂度
      • O(n + mlog(m))
      • n为需要排序的元素个数
      • m为需要返回的元素个数
    • n尽可能小
    • m尽可能小
    • 大数据量排序,记得缓存

消息通知

  • 消息队列
    • 生产者
      • 把消息存入队列
    • 消费者
      • 从队列中获取消息消费
    • 好处
      • 解耦合
      • 降覆载
    • 队列
      • 普通队列
        • Lpush
        • Rpop
      • 优先级队列
        • bRpop key [key...] timeout
          • 优先监控key1,如果没有返回后面的key2,key3中的值,如意有先返回key1中的值
          • 如果没有值会阻塞timeou时间,0表示一直阻塞
    • 发布\订阅
      • publish
      • subscribe
        • unSubscribe
      • pSubscribe
        • pUnSubscribe
          • 按照规则订阅
          • 取消订阅是正则表达式必须完全匹配

管道

  • 批量执行相互不依赖的命令

节省空间

  • 精简键名和键值
  • 内部编码优化
    • String
      • REDIS_ENCODING_RAW
        • rwa
      • REDIS_ENCODING_INT
        • int
    • List
      • REDIS_ENCODING_ZIPLIST
        • zipList
      • REDIS_ENCODING_LINKEDLIST
        • linkedList
    • Set
      • REDIS_ENCODING_HT
        • hashTable
      • REDIS_ENCODING_INTSET
        • intSet
    • ZSet
      • REDIS_ENCODING_SKIPLIST
        • skipList
      • REDIS_ENCODING_ZIPLIST
        • zipList
    • Hash
      • REDIS_ENCODING_EMBSTR
        • embStr
      • REDIS_ENCODING_HT
        • hashTable

持久化

RDB

  • 符合条件时,将内存中的全部快照到硬盘
    • 根据配置规则自动快照
      • 每当M时间修改了大于N个键时快照
        • save 900 1
        • 900s内修改了大于1个键时快照
    • 执行SAVE、BGSAVE命令
      • SAVE会阻塞所有来自客户端的请求
      • BGSAVE异步进行快照
        • 通过lastSave查看上次快照时间
    • 执行FLUSHALL命令
      • 依赖于自动快照条件
        • 只要自动快照条件不为空,flushall就会快照
    • 执行复制(replication)时
      • 没有定义自动快照条件也会快照
  • 原理
    • 从当前进程(父进程)fork一份到子进程
    • 父进程继续接受命令,子进程开始保存到磁盘的临时文件
    • 子进程写完后,替换上次生成的dump.rdb文件
    • 新的.rdb文件保存的是执行fork命令是的数据
  • 如果异常退出,会丢失最后一次快照之后修改的数据

AOF(append only file)

  • 将redis执行的每一条命令保存到硬盘
  • 为了避免冗余,满足一定条件会自动重写AOF文件
    • 自动重写
      • auto-aof-rewrite-percentage
        • 达到之前AOF文件的百分之多少重写
      • auto-aof-rewrite-min-size
        • 允许重写的最小AOF文件大小
    • 手动重写
      • bgRemWriteAOF
  • 需要跳过系统的磁盘缓存机制,写入AOF后主动从磁盘缓存同步硬盘
    • appendFSync
      • always
        • 每次写入都同步
      • everySec
        • 每秒执行一次同步
      • no
        • 不跳过
  • 区别
  • AOF载入速度慢
    • 重新执行AOF中保存的命令

集群

复制

  • 主数据库
  • 从数据库
    • 一般是只读的
    • 从数据库也可以有从数据库
  • 乐观复制
    • 需要一定时间内主从不一致
    • 原理(复制初始化)
      • 从数据库启动,向主数据库发送sync同步请求
      • 主数据库接收到sync请求后,执行RDB持久化操作,同时缓存快照期间的命令
        • 快照完成后,发送给从数据库
      • 从数据库接收后,载入快照,执行收到的缓存的命令
    • 优点
      • 读写分离
        • 主数据库写
        • 从数据库读
      • 持久化
        • 主数据库关闭持久化
        • 从数据库来持久化
        • 故障
          • 主数据库故障
            • 提升从数据库为主数据库
            • 重启数据库,并设置为从数据库
            • 禁止自动重启
              • 因为主数据库没有开启持久化,会清空全部数据,然后导致从数据库数据也清空
          • 从数据库故障
            • 自动同步主数据库数据
    • 缺点
      • 即使关闭主数据库的RDB快照,执行【复制初始化】依然会生成RDB文件
        • 主数据下次启动会读取RDB文件,因为复制时间不确定,所以数据不确定
        • 硬盘性能瓶颈
  • 无硬盘复制
    • 不持久化读写硬盘,之间通过网络发送个从数据库
  • 增量复制
    • 断线重连
    • 原理
      • 基础
        • 从数据库保存主数据的run ID
        • 复制同步阶段,主数据库把每一个传给从数据的命令保存到一个【积压队列】,同时记录命令偏移范围
        • 复制同步阶段,从数据库接收命令时,保存命令偏移量
      • 实现
        • 从数据发送同步请求命令
          • PSync 主数据ID 命令偏移量
        • 主数据库判断ID是否一致
        • 主数据库判断命令偏移量是否在【积压队列】
          • 在,增量复制
          • 不在,全量复制

哨兵

  • 独立的进程
    • 监控主从数据库是否正常运行
    • 主数据出现故障,自动将从数据库提升为主数据库
    • 监控其他哨兵
    • 和数据库建立两个连接
      • 一个订阅数据库的哨兵频道
      • 一个用来发送命令
    • 和哨兵建立一个连接
      • 发送PING命令
  • 操作
    • 每 10s 向主从数据库发送INFO信息
      • 第一次,解析INFO,获取当前数据库信息
      • 之后,向已知的数据库发送INFO,解析IFNO,更新数据库信息
    • 每 2s 向从数据库哨兵频道发送自身信息
      • 与其他哨兵同分享信息
    • 每 1s 向主从数据库和其他哨兵发送PING信息
      • 判断是否下线
  • 工作
    • 判断下线
      • 主观下线
        • 一个哨兵发现了主数据库下线
          • 向其他哨兵发送请求是否发现主数据库下线
      • 客观下线
        • 超过quorum的哨兵发现主数据库下线
    • 选举领头哨兵
      • Raft算法
        • 第一个发现下线的哨兵A要求其他哨兵选自己为领头哨兵
        • 其他哨兵如果没有选过其他哨兵,则选A为领头哨兵
        • 如果有半数并且> quorum的哨兵选择A,则A成为领头哨兵
        • 如果没有选成功,等待一个随机时间重新选
    • 选取主数据库
      • 选择优先级最高的
      • 同优先级选择命令偏移量最大的
      • 优先级、命令偏移量一样,选择ID最小的
  • 部署
    • 每个节点设置一个哨兵
    • 设置quorum = N /2 +1
      • N为哨兵数量

集群

  • 默认使用 0号数据库,且不能切换

  目录