redis简介

为什么要用Redis

NoSQL:

NoSQL是不同于传统的关系数据库的数据库管理系统的统称。其两者最重要的区别是NoSQL不使用SQL作为查询语言。 NoSQL数据存储可以不需要固定的表格模式。NoSQL是基于键值对的,可以想象成表中的主键和值的对应关系。

常见的NoSQL有:redis、memcached、mongodb、guava(loadingCache)

redis的定义:

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多 种类型的数据结构,如 字符串(strings)、散列(hashes)、 列表(lists)、 集合(sets)、 有序集合(sorted sets)等。

作为同款功能的内存缓存产品,redis和memcached各有什么优势:

内存管理机制
Memcached默认使用Slab Allocation机制管理内存,其主要思想是按照预先规定的大小, 将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎 片问题。空闲列表进行判断存储状态,【类似于Java虚拟机对象的分配,空闲列表】

Redis使用现场申请内存的方式来存储数据,并且很少使用free-list等方式来优化内存分配,会在一定程度上存在内存碎片,【CPU内存是连续,类似于Java虚拟机对象的分配,直接内存分配(指针碰撞)】

数据持久化方案
memcached不支持内存数据的持久化操作,所有的数据都以in-memory的形式存储。

redis支持持久化操作。redis提供了两种不同的持久化方法来讲数据存储到硬盘里面, 第一种是rdb形式,一种是aof形式:
rdb:属于全量数据备份,备份的是数据
aof:append only if,增量持久化备份,备份的是指令

缓存数据过期机制
概念:key,设计一个小时之后过期,超过一个小时查数据就会查不到

Memcached 在删除失效主键时也是采用的消极方法,即 Memcached 内部也不会监视主键是否失效,而是在通过 Get 访问主键时才会检查其是否已经失效

Redis 定时、定期等多种缓存失效机制,减少内存泄漏

支持的数据类型
Memcached支持单一数据类型:[k,v]
redis支持五种数据类型:【字符串(strings)、散列(hashes)、 列表(lists)、 集合(sets)、 有序集合(sorted sets)】

redis作为数据库的使用有什么优缺点?

优点:没有Scheme约束,数据结构的变更相对容易,一开始确定数据类型, 抗压能力强,性能极高,10万/qps

缺点:没有索引,没有外键,缺少int/date等基本数据类型,多条件查询需要通过集合内联(sinter,zinterstore) 和连接间接实现开发效率低,可维护性不佳

redis作为缓存的使用,搭配数据库使用的两种方案

1.jedis整合使用方案 set key,value ["11","22"] 第一层在缓存进行查询,如果得到数据则直接返回, 第二层在数据库进行查询,并且刷新缓存,方便下次查询 ["33,"44"]

2.作为mybatis/hibernate二级缓存使用方案,一级缓存:sqlSession,进程缓存,单次链接有效

Redis安装启动

redis4.0安装步骤:
  • 安装wget yum install wget
  • 下载redis安装包 wget http://download.redis.io/releases/redis-4.0.6.tar.gz
  • 解压压缩包 tar -zxvf redis-4.0.6.tar.gz
  • yum install gcc
  • 跳转到redis解压目录下 cd redis-4.0.6
  • 编译安装 make MALLOC=libc
  • cd src ./redis-server
redis三种启动方式以及其中的使用区别

1.直接启动(例如:cd src ./redis-server)
2.通过指定配置文件启动(例如:cd src ./redis-server ../redis.conf)
3.使用redis启动脚本设置开机启动,linux配置开机自启动/etc/init.d
配置步骤:

  • 启动脚本 redis_init_script 位于Redis的 /utils/ 目录下
  • mkdir /etc/redis
  • cp redis.conf /etc/redis/6379.conf
  • 将启动脚本复制到/etc/init.d目录下,本例将启动脚本命名为redisd(通常都以d结尾表示是后台自启动服务)。
    cp redis_init_script /etc/init.d/redisd
  • 设置为开机自启动,直接配置开启自启动 chkconfig redisd on 发现错误: service redisd does not support chkconfig
    解决办法:在启动脚本开头添加如下注释来修改运行级别
    #!/bin/sh # chkconfig: 2345 90 10
  • 设置为开机自启动服务器
chkconfig redisd on
service redisd start 打开服务
service redisd stop 关闭服务

Redis五种数据类型和消息订阅

Key / Value数据类型

String是最常用的一种数据类型,普通的key/value存储都可以归为此类。
常用的命令:

  • set/get
    设置key对应的值为String类型的value
    获取key对应的值

  • mget
    批量获取多个key的值,如果可以不存在则返回nil

  • incr && incrby
    incr对key对应的值进行加加操作,并返回新的值;incrby加指定值

  • decr && decrby
    decr 对key对应的值进行减减操作,并返回新的值;decrby减指定值

  • setnx
    设置key对应的值为String类型的value,如果key已经存在则返回0

  • setex
    设置key对应的值为String类型的value,并设定有效期

  • 其他命令
    getrange:获取key对应value的子字符串
    mset:批量设置多个key的值,如果成功表示所有值都被设置,否则返回0表示没有任何值被设置
    msetnx:同mset,不存在就设置,不会覆盖已有的key
    getset:设置key的值,并返回key旧的值
    append:给指定key的value追加字符串,并返回新字符串的长度

Hash类型
  • Hash是一个String类型的field和value之间的映射表
  • redis的Hash数据类型的key(hash表名称)对应的value实际的内部存储结构为一个HashMap
  • Hash特别适合存储对象
  • 相对于把一个对象的每个属性存储为String类型,将整个对象存储在Hash类型中会占用更少内存。
  • 所存储的成员较少时数据存储为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。
  • 运用场景:如用一个对象来存储用户信息,商品信息,订单信息等等。
  • Hash命令讲解
    hset——设置key对应的HashMap中的field的value
    hget——获取key对应的HashMap中的field的value
    hgetall——获取key对应的HashMap中的所有field的value
    hlen——返回key对应的HashMap中的field的数量
List类型
  • lpush——在key对应的list的头部添加一个元素
  • lrange——获取key对应的list的指定下标范围的元素,-1表示获取所有元素
  • lpop——从key对应的list的尾部删除一个元素,并返回该元素
  • rpush——在key对应的list的尾部添加一个元素
  • rpop——从key对应的list的尾部删除一个元素,并返回该元素
Set类型
  • sadd——在key对应的set中添加一个元素
  • smembers——获取key对应的set的所有元素
  • spop——随机返回并删除key对应的set中的一个元素
  • suion——求给定key对应的set并集
  • sinter——求给定key对应的set交集
SortSet类型

set的基础增加顺序score,再根据score进行排序
实战(用途):通过sortset实现排行榜

  • zadd ——在key对应的zset中添加一个元素
  • zrange——获取key对应的zset中指定范围的元素,-1表示获取所有元素
  • zrem——删除key对应的zset中的一个元素
  • zrangebyscore——返回有序集key中,指定分数范围的元素列表,排行榜中运用
  • zrank——返回key对应的zset中指定member的排名。其中member按score值递增(从小到大); 排名以0为底,也就是说,score值最小的成员排名为0,排行榜中运用
  • set是通过hashmap存储,key对应set的元素,value是空对象 sortset是怎么存储并实现排序的呢,hashmap存储,还加了一层跳跃表 跳跃表:相当于双向链表,在其基础上添加前往比当前元素大的跳转链接
redis消息订阅发布

作用:发布订阅类似于信息管道,用来进行系统之间消息解耦,类似于mq,rabbitmq、rocketmq、kafka、activemq主要有消息发布者和消息订阅者。比如运用于:订单支付成功,会员系统加积分、钱包进行扣钱操作、发货系统(下发商品)

  • PUBLISH 将信息message发送到指定的频道channel。返回收到消息的客户端数量

  • SUBSCRIBE 订阅给指定频道的信息

  • UNSUBSCRIBE 取消订阅指定的频道,如果不指定,则取消订阅所有的频道。

  • redis的消息订阅发布和mq对比?
    redis发布订阅功能比较薄弱但比较轻量级,mq消息持久化,数据可靠性比较差,无后台功能可msgId、msgKey进行查询消息

传统关系型数据库事务与Redis事务

事务概要和事务隔离级别
  • 一个数据库事务通常包含了一个序列的对数据库的读/写操作。它的存在包含有以下两个目的:
    1)为数据库操作序列提供了一个从失败中恢复到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法。
    2)当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰。

  • 事务的ACID四大特性
    原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行
    一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束
    隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行
    持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中

  • 事务隔离机制
    语法:set global transaction isolation level read uncommitted;
    种类:read uncommitted、read committed、repeatable read、serializable

mysql事务隔离机制和MVCC

redis事务隔离机制可重复读讲解(repeatable read)

select @@tx_isolation ; 查看事务类型

  • InnoDB MVCC多版本并发控制
    在每一行数据中额外保存两个隐藏的列:当前行创建时的版本号和删除时的版本号(可能为空,其实还有一列称为回滚指针,用于事务回滚)。这里的版本号并不是实际的时间值,而是系统版本号。每开始新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号, 用来和查询每行记录的版本号进行比较


    MVCC.png
redis事务机制
  • MULTI 与 EXEC命令
    以 MULTI 开始一个事务,然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令

  • DISCARD命令
    DISCARD 命令用于取消一个事务, 它清空客户端的整个事务队列, 然后将客户端从事务状态调整回非事务状态, 最后返回字符串 OK 给客户端, 说明事务已被取消

  • WATCH命令
    WATCH 命令用于在事务开始之前监视任意数量的键: 当调用 EXEC 命令执行事务时, 如果任意一个被监视的键已经被其他客户端修改了, 那么整个事务不再执行, 直接返回失败。


    事务状态.png

    处理事物.png
redis事务ACID
  • 原子性(Atomicity)
    单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。如果一个事务队列中的所有命令都被成功地执行,那么称这个事务执行成功

  • 一致性(Consistency)
    入队错误
    在命令入队的过程中,如果客户端向服务器发送了错误的命令,比如命令的参数数量不对等等, 那么服务器将向客户端返回一个出错信息, 并且将客户端的事务状态设为 REDIS_DIRTY_EXEC 。

执行错误
如果命令在事务执行的过程中发生错误,比如说,对一个不同类型的 key 执行了错误的操作, 那么 Redis 只会将错误包含在事务的结果中, 这不会引起事务中断或整个失败,不会影响已执行事务命令的结果,也不会影响后面要执行的事务命令, 所以它对事务的一致性也没有影响

  • 隔离性(Isolation)
    WATCH 命令用于在事务开始之前监视任意数量的键: 当调用 EXEC 命令执行事务时, 如果任意一个被监视的键已经被其他客户端修改了, 那么整个事务不再执行, 直接返回失败

  • 持久性(Durability)
    因为事务不过是用队列包裹起了一组 Redis 命令,并没有提供任何额外的持久性功能,所以事务的持久性由 Redis 所使用的持久化模式决定

你可能感兴趣的:(redis简介)