美文网首页
中间件系列1 Redis

中间件系列1 Redis

作者: 莫小归 | 来源:发表于2019-03-06 16:07 被阅读0次

    参考《Java EE 互联网轻量级框架整合开发》相关章节

    一.Redis概述

    1.适用场景
    • 传统关系型数据库无法满足高并发场景(如商品抢购、主页瞬间大量访问)的需要
    • Redis适用于缓存场景,现实场景中读操作远多于写操作,80%的读取集中在20%的数据
    • Redis适用于高速读/写场景,将高速读/写的数据缓存到Redis,满足一定条件后再写入数据库
    2.Redis性能优势
    • 基于ANSI C语言编写,接近于汇编语言的机器语言,运行速度快
    • 基于内存的读/写,比磁盘IO快
    • 数据库结构比较简单(只有6种数据类型),规则较少
    3.NoSQL与传统数据库
    • NoSQL使用内存存储数据,传统数据库使用磁盘
    • NoSQL数据结构比较简单,功能有限,不如传统数据库的SQL语句强大
    • NoSQL基于内存,持久化能力受外部条件影响,不如基于磁盘的传统数据库
    • NoSQL数据完整性、事务能力、安全性、可靠性及可扩展性都远不及传统数据库
    • NoSQL短期内难以取代传统数据库,但能够作为提高互联网应用性能的辅助工具

    二.Redis数据结构和常用命令

    1.字符串
    • Redis最基本的数据结构,以键值对的形式存储于Redis内部,Redis通过键查找值
    • Redis字符串基本命令
    命令 说明 备注
    set key value 设置键值对
    get key 通过键获取值
    del key 通过键删除键值对 返回删除的键值对个数
    strlen key 求key指向字符串的长度 返回长度
    getset key value 修改原key对应的值,并返回原值 若原值为空则返回空
    getrange key start end 获取子串 返回(start,end)截取的字符串
    append key value 将新value加入到key指向的value末尾 返回拼接后value的长度
    • 如果字符串是数字(整数或浮点数),Redis还能支持简单的加减运算
    命令 说明 备注
    incr key 原字段加1 限整数
    incrby key increment 原字段加整数(increment) 限整数
    decr key 原字段减1 限整数
    decrby key decrement 原字段减整数(decrement) 限整数
    incrbyfloat key increment 原字段加浮点数(increment) 整数或浮点数
    2.哈希
    • Redis中hash是一个String类型的field和value的映射表,一个哈希里有许多键值对,适合存储对象
    • Redis哈希常用命令
    命令 说明 备注
    hdel key field1 [field2...] 删除hash结构中的某字段 可同时删除多个字段
    hexists key field 判断hash结构中是否存在field字段 存在返回1,否则返回0
    hgetall key 获取hash结构中所有键值
    hincrby key field increment hash结构的指定字段加上一个整数 要求该字段本身为整数字符串
    hincrby float key field increment hash结构的指定字段加上一个浮点数 要求该字段本身为数字型字符串
    hkeys key 返回hash中所有键
    hvals key 返回hash中所有值
    hlen key 返回hash中键值对的数量
    hmget key field1 [field2 ...] 返回hash中指定键的值,可以是多个键 依次返回值
    hmset key field1 value1 [field2 value2 ...] hash设置多个键值对
    hset key field value hash设置单个键值对
    hsetnx key field vaule 当hash结构中不存在对应的键,才设置值
    3.链表(linked-list)
    • Redis链表底层是双向链表
    • 便于增删但不便于查询
    • 因为是双向链表结构,所以Redis链表命令分为左操作和右操作两种,常见链表命令如下
    命令 说明 备注
    lpush key node1 [node2...] 把node1加到链表最左边
    rpush key node1 [node2...] 把node1加到链表最右边
    lindex key index 读取下标为index的节点 返回节点字符串
    llen key 求链表的长度 返回链表节点数
    lpop key 删除左边第一个节点,并将其返回
    rpop key 删除右边第一个节点,并将其返回
    insert key before/after pivot node 在节点pivot的前/后插入node节点 如果list不存在,则报错;如果没有值为pivot的节点,将插入失败返回-1
    lpushx list node 如果存在key为list的链表,则从左边插入节点node 如果list不存在,则失败
    rpushx list node 如果存在key为list的链表,则从右边插入节点node 如果list不存在,则失败
    Irange list start end 获取链表list从start下标到end下标的节点值 包含start和end下标
    lrem list count value 如果count为0,则删除所有值等于value的节点;若count不为0,则从左到右删除不大于count绝对值数目值为value的节点
    lset key index node 设置列表下标为index的节点的值为node
    ltrim key start stop 修剪链表,只保留从start到stop区间的节点 包含start和end下标
    • 上述命令未对Redis的链表加锁,在多个Redis客户端同时操作同一链表时将造成并发数据安全和一致性问题,Redis提供链表的阻塞命令以保障链表操作的安全性
    命令 说明 备注
    blpop key timeout 移出并获取链表的第一个元素,如果链表没有元素会阻塞链表直到等待超时或发现可弹出元素为止 相对于lpop命令线程安全
    brpop key timeout 移出并获取链表的最后一个元素,如果链表没有元素会阻塞链表直到等待超时或发现可弹出元素为止 相对于rpop命令线程安全
    rpoplpush key src dest 将原链表最右边一个元素移除,并插入目标链表最左边 不能设置超时时间
    brpoplpush key src dest timeout 将原链表最右边一个元素移除,并插入目标链表最左边,可以设置超时时间
    4.集合
    • Redis集合是一个哈希表结构,插入、删除和查找的复杂度都是O(1)
    • 集合是无序、不可重复的,集合的每一个元素都是String数据结构类型
    • Redis集合可对两个或多个集合求交集、差集和并集,常用命令如下
    命令 说明 备注
    sadd key member1 [member2 member3 ...] 给集合key增加成员 可以同时增加多个
    srem key member1 [member2 ...] 移除集合key的元素
    scard key 统计集合key的成员数
    sdiff key1 [key2] 找出两个集合的差集 参数如果只有一个集合,则返回这个集合的所有元素
    sdiffstore des key1 [key2] 找出两个集合的差集,并保存在集合des中
    sinter key1 [key2] 求集合key1和集合key2的交集 参数如果只有一个集合,则返回这个集合的所有元素
    sinterstore des key1 key2 求集合key1和集合key2的交集并保存到des
    sismember key member 判断member是否为集合key的成员 是返回1,否返回0
    smembers key 返回集合key的所有成员 数据量大时需考虑迭代遍历
    smove src des member 将成员member从集合src迁移到集合des
    spop key 随机弹出集合key的一个元素
    srandmember key[count] 随机返回集合key的一个或多个元素 count为整数,不填默认为1,负数取绝对值,count大于集合元素总数时返回整个集合
    sunion key1 [key2] 求集合key1和集合key2的并集
    sunionstore des key1 key2 求并集并将结果保存到键为des的集合
    5.有序集合
    • Redis有序集合和集合类似,通过哈希表实现,添加、删除、查找的时间复杂度均为O(1)
    • 区别在于每个元素除了值之外,还多一个分数,Redis根据分数进行排序
    命令 说明 备注
    zadd key score1 value1 [score2 value2 ...] 给有序集合key增加成员 如果不存在有序集合key,则自动创建
    zcard key 统计有序集合key的成员数
    zcount key min max 根据分数返回对应的成员列表 分数在最小值min与最大值max间
    zincrby key increment member 给有序集合成员值为member的分数增加increment
    zinterstore desKey numkeys key1 [key2 key3 ...] 求多个有序集合的交集并存入desKey
    zlexcount key min max 求有序集合key成员值在min和max的范围集合
    zrange key start stop [withscores] 按照分值的大小从小到大返回成员,start和stop参数可截取某一段返回,若输入可选项withscores则连同分数一起返回
    zrank key member 按从小到大求有序集合的排行
    zrangebylex key min max [limit offset count] 根据值的大小,从小到大排序,min和max为最小/最大值,Redis求出范围集合后根据偏移量offset和限定返回数count返回对应的成员
    zrangebyscore key min max [withscore] [limit offset count] 根据分数的大小,从小到大排序,min和max为最小/最大值,Redis求出范围集合后根据偏移量offset和限定返回数count返回对应的成员
    zremrangebyscore key start stop 根据分数区间进行删除
    zremrangebyrank key start stop 按照分数排行从小到大的顺序删除
    zremrangebylex key min max 按照值得分布进行删除
    zrevrange key start stop [withscores] 从大到小按分数排序,参数参照zrange
    zrevrangebyscore key max min [withscores] 从大到小按分数排序,参数参见zrangebyscore
    zrevrank key member 按从大到小顺序求元素的排行
    zscore key member 返回成员的分数值
    zunionstore desKey numKeys key1 [key2 key3 key4...] 求多个有序集合的并集 numKeys是有序集合的个数
    6.基数(HyperLogLog)
    • 基数并不存储元素,存储元素需要较大内存空间
    • 基数用于给某个有重复元素的数据集合评估需要的空间单元数(即数据集合中不重复的元素数量)

    三. Redis事务

    1.概述
    • 在多个客户端同时向Redis系统发送命令的时候,同一个数据同时可能被不同线程操纵,产生并发下的数据一致性问题
    • Redis通过事务解决并发场景的数据安全问题,事务使用Multi-Exec命令组合
      1)事务是一个被隔离的操作,事务中的方法都会被Redis进行序列化并按顺序执行,事务在执行过程中不会被其他客户端发出的命令所打断
      2)事务是一个原子性操作,要么全部执行,要么全部不执行
    2.事务过程
    • Redis事务将经历3个过程
      1)开启事务
      2)命令进入队列
      3)执行事务

    • 事务命令

    命令 说明 备注
    multi 开启事务,之后的命令进入队列,但不会立刻执行
    watch key1 [key2...] 监听某些键,当被监听的键在事务执行前被修改,则事务将被回滚 乐观锁机制
    unwatch key1 [key2...] 取消监听的键
    exec 执行事务,但如果被监听的键发生改变,则执行回滚 执行事务队列存储的命令前,Redis会检测被监听的键值对有没有发生变化
    discard 回滚事务 回滚后的事务不能再提交
    • 事务执行流程示例
    时刻 客户端1 客户端2 说明
    T1 set key1 value1 客户端1:返回OK
    T2 watch key1 客户端1:监控key1
    T3 multi 客户端1:开启事务
    T4 set key2 value2 客户端1:事务命令入列
    T5 - set key1 value1 客户端2:修改key1的值
    T6 exec - 客户端1:执行事务,执行前检测到key1的值被其他命令修改过,所以将进行回滚
    3.流水线(pipelined)
    • Redis通过事务提供队列,作为一个可以批量执行任务的队列,但使用事务会检测对应的锁和序列化命令,存在系统开销
    • Redis提供流水线技术,用来在没有任何附加条件的场景下使用队列批量执行一系列的命令,从而提高系统性能
    • 应用场景
      1)Redis执行读/写速度非常快,系统的瓶颈往往是网络通信的延时
      2)使用Redis的流水线(本质是一种通信协议),可以有效提高性能
      3)使用流水线产生的返回对象,可能占用服务器上较多的内存空间,导致OOM异常
    4.发布订阅
    • 场景
      使用银行卡消费时,银行通过微信、短信或邮件通知用户该笔交易信息
    • 观察者模式
      1)记账系统是消息源,收到交易指令,成功记账后,就会发布消息
      2)要有消息渠道,记账系统通过消息渠道向订阅者发布消息
      3)要有订阅者(微信、短信、邮件等系统)订阅消息渠道的消息

    四. 超时命令——Redis内存回收

    1. Redis键值对的超时
    • 超时命令
    命令 说明 备注
    persist key 持久化key,取消超时时间
    ttl key 查看key的超时时间 以秒计算,-1代表没有超时时间,-2代表不存在key或key已超时
    expire key seconds 设置超时时间戳 以秒为单位
    expireat key timestamp 设置超时时间点 用unix时间戳确定
    pptl key milliseconds 查看key的超时时间戳 以毫秒为单位
    pexpire key 设置键值超时的时间 以毫秒为单位
    pexpireat key stamptimes 设置超时时间点 以毫秒为单位的unix时间戳
    • Redis的key超时不会被自动回收,而是被标识为已经超时
      1)好处:避免因很大的键值对超时的回收造成卡顿
      2)坏处:被标记为超时而未回收的键值对会占用空间
    2. Redis回收机制
    • 定时回收:在某个确定的时间统一回收超时的键值对
      1)可以完全回收超时的键值对
      2)一次性回收的键值对较多时,Redis会停顿影响业务,故定时回收一般在没有业务发生的时刻触发
    • 惰性回收:再次执行访问(get命令)超时的键时回收该键
      1)优点是可以指定回收超时的键值对
      2)缺点是通过get命令指定回收,需要额外执行get操作

    相关文章

      网友评论

          本文标题:中间件系列1 Redis

          本文链接:https://www.haomeiwen.com/subject/eeqtpqtx.html