Redis特性

  1. 速度快
    1. 10w ops,数据存在内存中,使用5w行C语言编写,单线程
      1. 数据存储在内存中
      2. 使用C语言实现
      3. 单线程模型
  2. 持久化
    1. 断电不丢失数据,所有数据保存在内存中,对数据库的更新将异步的保存在磁盘上
  3. 多种数据结构
    1. String,Hash,Linked List,Set,Sorted Sets
    2. 字符串,KeyValue,Linked Lists,Sets,Sorted Sets
    3. BitMaps位图,HyperLogLog超小内存唯一计数,GEO地理信息定位
  4. 支持多种编程语言
    1. java,php,python,Ruby,Lua,node,c#
  5. 功能丰富
    1. 发布订阅,简单事务,Lua脚本,pipeline
  6. 简单
    1. 不依赖外部库,单线程模型
  7. 主从复制
    1. 从服务器同步复制到主服务器
  8. 高可用,分布式

典型应用场景

  1. 缓存系统
  2. 计数器
    1. 转发数,评论数
  3. 消息队列系统
  4. 排行榜
  5. 社交网络
  6. 实时系统

一. 通用命令

  1. keys [pattern] O(n) 遍历key 一般不在生产环境使用
  2. dbsize O(1) 计算key的总数
  3. exists key O(1) 检查key是否存在
  4. del key...] O(1) 删除指定的key
  5. expire key seconds O(1) key在seconds秒后过期
    2. ttl key 查看key剩余过期时间, >=0代表还没有过期。-1代表key存在,并且没有过期时间。-2代表key已经过期
    3. persist key 去掉key的过期时间
  6. type key O(1) 返回key的类型
    1. string、hash、list、set、zset有序集合、none不存在的key

二、数据结构和内部编码

image-20200318134110489

三、单线程架构

  1. 纯内存,非阻塞IO,避免线程切换和竞态消耗
  2. 一次只运行一条命令、拒绝长(慢)命令、其实不是单线程

各种类型

  1. 字符串类型 ,最大512MB o(1)

    1. 缓存、计数器、分布式锁...
    2. set key value,get key,del key
    3. incr key,自增1,如果key不存在,自增后get(key)=1
    4. decr key,自减1,如果key不存在,自减后get(key)=-1
    5. incrby key k,自增k,如果key不存在,自增后get(key)=k
    6. decrby key k,自减k,如果key不存在,自减后get(key)=-k

    1. set key value,不管key是否存在都设置
    2. setnx key value,key不存在才设置
    3. set key value xx,key存在才设置,可理解成update

    1. mget key1 key2 key3...,批量获取key,原子操作
      1. n次get = n次网络时间 + n次命令时间
      2. n次mget = 1次网络时间 + n次命令时间 可节省网络时间
    2. mset key1 value1 key2 value2 key3 value 3...,批量设置key-value

    1. getset key newvalue,set key newvalue并返回旧的value
    2. append key value,将value追加到旧的value
    3. strlen key,返回字符串的长度(注意中文)

    1. incrbyfloat key 3.5,为key对应的值增加3.5
    2. getrange key start end,获取字符串指定下标所有的值
    3. setrange key index value,设置指定下标所有对应的值
  2. 哈希类型 O(1)

    1. hget key field,获取hash key对应的field的value
    2. hset key field value,设置hash key对应的field的value
    3. hdel key field,删除hash key对应的field的value

    1. hexists key field,判断hash key是否有field
    2. hlen key,获取hash key field的数量

    1. hmget key field1 field2 field3 ...fieldN,批量获取hash key的一批field对应的值
    2. hmset key field1 value1 field2 value2...fieldN valueN,批量设置hash key的一批field value

    1. hgetall key,返回hash key对应所有的field和value
    2. hvals key,返回hash key对应所有field的value
    3. hkeys key,返回hash key对应所有field

    1. hsetnx key field value,设置hash key对应的value(如果field已经存在则失败)
    2. hincrby key field intCounter,hash key对应的field的value自增intCounter
    3. hincrbyfloat key field folatCounter,hincrby浮点数版
  3. 列表类型 list

    key elements push pop

    有序、可以重复、左右两边插入弹出

    1. rpush key value1 value2...valueN,从列表的右端插入(1-N个)值
    2. lpush key value1 value2...valueN,从列表的右端插入(1-N个)值
    3. linsert key before|after value NewValue,在list指定的值前|后插入newValue

    1. lpop key,从列表左边弹出(删除)一个item
    2. rpop key,从列表右边弹出(删除)一个item
    3. lrem key count value,根据count值,从列表中删除所有value相等的项
      1. count>0,从左到右,删除最多count个value相等的项
      2. count<0,从右到左,删除最多Math.abs(coiount)个value相等的项
      3. count=0,删除所有value相等的项
    4. ltrim key start end,按照索引范围修剪(保留)列表

    1. lrange key start end(包含end),获取列表指定索引范围所有item
    2. lindex key index,获取列表指定索引的item
    3. llen key,获取列表的长度
    4. lset key index newValue,设置列表指定索引值为newValue

    1. blpop key timeout,lpop阻塞版本,timeout阻塞超时时间,itmeout=0位永远不阻塞
    2. brpop key timeout,rpop阻塞版本,
  4. 集合类型

    key value

    无序、无重复元素、集合间操作 ,element

    1. sadd key element,向集合key添加element,如果element已经存在,则添加失败,element可以为多个
    2. srem key element,将集合key中的element移除掉

    1. scard key,计算集合大小

    2. sismember key element,判断element是否在集合中

    3. srandmenber key count,从集合中随机挑选count个元素

    4. spop key,从集合中随机弹出(删除)一个元素

    5. smembers key,获取集合所有元素

      smember 特点:无序、小心使用


    1. sdiff key1 key2,差集
    2. sinter key1 key2,交集
    3. sunion key1 key2,并集
    4. sdiff|sinter|sunion + store destkey,将差集、交集、并集的结果保存在destkey中

    微博的共同关注

  5. 有序集合类型

    key score value

    有序,无重复元素,element + score

    1. zadd key score element,添加score和element,可以是多对o(logN)
    2. zrem key element,删除元素,可以是多个
    3. zscore key element,返回元素的分数score
    4. zincrby key increScore element,增加或减少(负数)元素的分数(increScore )
    5. zcard key,返回元素的总个数

    1. zrange key start end [withscores],返回指定排名索引范围内的升序元素[分值],o(log(n)+m)
    2. zrangebyscore kley minScore maxScore [withscores],返回指定分数范围的升序元素(分值)o(log(n)+m)
    3. zcount key minScore maxScore,返回指定分数范围内的个数o(log(n)+m)
    4. zremrangebyrank key start end,删除指定排名索引范围内的升序元素o(log(n)+m)
    5. zremrangebyscore key minScore maxScore,删除指定分数范围内的升序元素

    --

    1. zrevrank zrevrange zrevrangebyscore zinterstore zunionstore

    排行榜

慢查询

  1. 生命周期
    image-20200321014639155

    1. 慢查询发生在第三阶段(执行命令)
    2. 客户端超时不一定是慢查询,但慢查询是客户端超时的一个可能因素
  2. 两个配置

    1. slowlog-max-len
      1. 先进先出
      2. 固定长度
      3. 保存在内存中
    2. slowlog-log-slower-than
      1. 慢查询阈yu值(单位:微秒)
      2. slowlog-log-slower-than = 0,记录所有命令
      3. slowlog-log-slower-than < 0,不记录任何命令
    3. 默认值
      1. config get slowlog-max-len = 128
      2. config get slowlog-log-slower-than = 10000
    4. 修改配置文件重启
    5. 动态配置
      1. config set slowlog-max-len 1000
      2. config set slowlog-log-slower-than 1000
  3. 慢查询命令

    1. slowlog get [n],获取慢查询队列(n条数)
    2. slowlog len,获取慢查询队列长度
    3. slowlog reset,清空慢查询队列
  4. 运维经验

    1. slowlog-max-len不要设置过大,默认10ms,通常设置1ms
    2. slowlog-log-slower-than不要设置过小,默认128,通常设置1000左右
    3. 理解命令生命周期
    4. 定期持久化慢查询

pipline 流水线

  1. 1次pipline(n条命令)= 1次网络时间 + n次命令时间(将多条命令打包,节省网络时间)
  2. 两个注意点
    1. redis的命令时间是微秒级别的
    2. pipline每次条数要控制(网络瓶颈)
  3. 与原生M操作对比
    • M操作是原子操作,pipline是非原子操作(M操作是一个命令,pipline会拆分成多个命令执行)
  4. 使用建议
    1. 注意每次pipline携带数量
    2. pipline每次只能作用在一个redis节点上
    3. M操作与pipline区别

发布订阅

  1. 角色

    1. 发布者publisher、订阅者subscriber、频道channel
  2. 模型

    image-20200321021856466

  3. API

    1. publish channel message,发布命令
    2. subscribe [channel],订阅一个或多个
    3. unsubscribe [channel],取消一个或多个订阅

    1. psubscribe [pattern...],订阅模式
    2. punsubscribe [pattern...],退订指定的模式
    3. pubsub channels,列出至少有一个订阅者的频道
    4. pubsub numsub [channel...],列出给定频道的订阅者数量
    5. pubsub numpat,列出被订阅模式的数量
  4. 消息队列和发布订阅的区别

    • 消息队列对于消息订阅者是的模型
    • 发布订阅对于订阅者是都收到

Bitmap 位图

  1. 命令
    1. setbit key offset value #给位图指定索引设置值
    2. getbit key offset #获取位图指定索引的值
    3. bitcount key [start end] #获取位图指定范围(start到end,单位为字节,如果不指定就是获取全部)位值为1的个数
    4. bittop op destkey key [key...] #做多个Bitmap的and交集、or并集、not非、xor异或操作并将结果保存在destkey中
    5. bitpos key targetBit [start] [end] #计算位图指定范围(start到end,单位为字节,如果不指定就是获取全部)第一个偏移量对应的值等于targetBIt的位置

HyperLogLog

极小的空间完成独立数量统计,本质还是字符串

  1. pfadd key element [element...] #向hyperloglog添加元素,已存在的不会重复添加
  2. pfcount key [key...] #计算hyperloglog的独立总数
  3. pfmerge destkey sourcekey [sourcekey...] #合并多个hyperloglog

使用经验(缺点)

  1. 是否能容忍错误(错误率:0.81%)
  2. 是否需要单条数据

GEO

地理信息定位:存储经纬度,计算两地距离,范围计算等

  1. API
    1. get key longitude latitude member [longitude latitude member] #添加地址位置信息
      1. geoadd cities:locations 116.28 39.55 beijing
    2. geopos key member [member..] #获取地理位置信息 geopos cities:locations beijing
    3. geodist key member1 menber2 [unit] #获取两个地理位置的距离
      1. unit:m(mi)、km(千米)、mi(英里)、ft(尺)
    4. georadius #获取指定范围内的地理位置信息集合(参数太复杂)
  2. type geokey = zset,删除使用zset相关命令

持久化

  • 什么是持久化

    redis所有数据在内存中,持久化是对数据的更新异步的保存到磁盘上

  • 持久化方式

    • 快照 MySql Dump、Redis RDB、MS SQL 备份
    • 写日志 MySql BinLog、Hbase HLog、Redis AOF
  1. RDB

    将Redis中的数据以创建快照的方式保存到RDB文件中,RDB文件启动载入Redis内存中

    耗时、耗性能、不可控、丢失数据、全量复制

    1. 触发机制
      1. save #同步,会阻塞客户端命令,如果存在老的RDB文件,会被新的替换,不消耗额外内存o(n)
      2. bgsave #异步,不会阻塞客户端命令(阻塞发生在fork),执行fork()函数增加一个子进程在后台执行,消耗额外内存
      3. 自动 #通过配置,满足任意一个条件,创建bgsave子进程生成RDB文件
        1. save time count,dbfilename dump.rdb #time秒 count次命令
  2. AOF

    1. 三种AOF方式

      • always 写命令刷新到缓冲区,每条命令fsync到硬盘
        • 不丢失数据,IO开销大
      • everysec 写命令刷新到缓冲区,每秒把缓冲区fsync到硬盘
        • 每秒一次fsync,丢一秒数据
      • no 写命令刷新到缓冲区,操作系统决定fsync
        • 不用管,不可控
    2. AOF重写

      • 过期的,没用的,重复的,以及一些可优化的命令

      • 减少磁盘的占用量,加速恢复速度

      1. AOF的实现方式
        1. bgrewriteaof命令 ,fork子进程,异步执行
        2. AOF重写配置
          1. auto-afo-rewrite-min-size AOF文件重写需要的尺寸,AOF文件增长到多大的时候开始重写
          2. auto-aof-rewrite-percentage AOF文件增长率,AOF文件达到最大重写尺寸后,进行了重写,下次需达到的重写条件
        3. 统计项
          1. aof_current_size AOF当前尺寸(单位:字节)
          2. aof_base_size AOF上次启动和重写的尺寸(单位:字节)