redis介绍

redis介绍

redis 是开源的,基于内存的数据存储系统,可以用作数据库、缓存和消息中间件。
redis支持多种数据存储结构,包括string, hashes, lists, sets, sorted sets。
通过复制、持久化和数据分片等特性,可以很方便地将redis扩展成一个能够包好数百GB、每秒处理上百万次请求的系统。

持久化

对于基于内存存储的数据库,一个很重要的问题是,服务器关闭时,数据的安全性问题。redis有两种持久化方案,保证了数据的安全性。

  1. RDB
    RDB是一种按照指定时间周期定期保存redis数据镜像到一个单文件中的持久化方式。
    非常适用于用作容灾备份,因为RDB文件可以传输至不同地方备份,且服务器能够很快地从RDB文件中恢复数据。
    但是RDB方式不适用于对数据丢失方案容忍度很低的场景,因为按周期备份数据镜像,尽管周期可以设置得很短,但是仍然有丢失数据的风险。

  2. AOF
    该方式能够以AOF文件的方式,保存每次对redis的数据修改。AOF文件是一个只允许追加的log文件,所以没有查找带来的性能消耗。当文件过大时,redis能够自动重新AOF文件(合并部分同类操作INCR A 1, INCR A 1 --> INCR A 2).

redis的基本数据结构简介

1. string

redis介绍_第1张图片
image

redis的string可以存储以下三种类型的值:

  • 字节串(byte string)
  • 整数
  • 浮点数

当执行set key value命令时,redis检测到value值可以转化为整数或者浮点数,会更改其数据类型,使其支持对整数和浮点数的特殊操作,如自增和自减INCR, INCRBY等操作,redis的强大之处还在于其支持对字符串的截取和二进制为操作。

命令 行为
GET 获取存储在给定间中的值
SET 设置存储在给定键中的值
DEL 删除
APPEND 在指定键末尾追加
INCR 增加1(对于int类型)

2. list

redis介绍_第2张图片
image

Redis的列表允许用户从序列的==两端==推入或者弹出元素、获取元素,执行各种常见的列表操作,如获取子列表。

3. set

redis介绍_第3张图片
image

集合以==无序==的方式来存储多个各不相同的元素,用户可以快速地对集合执行添加元素、移除元素以及检查一个元素是否存在于集合里的操作。
并且可以对多个set进行差集、交集、并集计算。

4. hash

redis介绍_第4张图片
image

散列可以让用户将多个键值对存储到一个Redis键里面。从功能上来说,Redis为散列值提供了一些和字符串值相同的特性,使得散列非常适用于将一些相关的数据存储在一起。我们可以把这种数据聚集看作是关系==数据库中的行==,或者==文档存储中的文档==。

5. sort set

redis介绍_第5张图片
image

有序集合存储着==成员与分值之间的映射==,并且提供了分值处理命令,以及根据分值大小有序地获取(fetch)或扫描(scan)成员和分值的命令。

6. 发布&订阅

订阅者(listener)订阅频道(channel),发送者(sender)想频道发送二进制字符串消息。每当有消息发送至指定频道时,频道的所有订阅者都会收到消息。

命令 行为
SUBSCRIBE SUBSCRIBE channel [channel ...] ——订阅给定的一个或多个频道
UNSUBSCRIBE UNSUBSCRIBE [channel [channel ...]]——退订给定的一个或多个频道,如果未指定频道,则退订所以频道
publis PUBLISH channel message ——向给定频道发送消息
PSUBSCRIBE PSUBSCRIBE pattern [pattern ...] ——订阅与给定模式想匹配的所有频道
PUNSUBSCRIBE PUNSUBSCRIBE [pattern ...]——退订给定模式

事务

MULTI, EXEC, DISCARD & WATCH作为redis事务的基本命令,允许原子性地执行一组redis操作。

  • 保证所有事务内的命令将会串行顺序执行,保证不会在事务的执行过程中被其他客户端打断。不同于关系型数据库的事务概念,redis保证会在执行完毕上一个事务的所有命令后才会处理其他客户端的命令。
  • 事务内的命令全部执行或一个都不执行。
> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1
  • 事务运行中出错
    • 在执行EXEC调用前出错,如语法错误、out of memmeroy错误。如果命令入队是返回QUEUED,则入队成功;否则入队失败,客户端会停止并取消该事务。
    • 执行EXEC调用后出错,如对string类型的键调用了list类型的操作。==对于此类错误,redis并未进行特殊处理,即使事务中某些命令产生了此类错误,事务中的其他命令仍会继续执行下去。此特性有别于传统关系型数据库的事务概念。== 简而言之,redis不支持事务回滚。
MULTI
+OK
SET a 3
abc
+QUEUED
LPOP a
+QUEUED
INCR a
EXEC
*3
+OK
-ERR Operation against a key holding the wrong kind of value
(integer) 4

为什么redis不支持事务回滚

redis命令只会因为语法错误而失败,在事务命令入队时就能检查到该错误;或者错误运用了键的命令。这就是说,失败的命令是有编程错误造成的,这些错误应该在开发过程中被发现,不应该出现在生产环境中。
因此不需要支持回滚,是redis内部保持了简单和快速高效。

PS: 使用事务主要是为了:移除竞争条件。从事务的特性我们知道,redis的事务能够保证事务内的所有命令在不被其他客户端打断的情况下顺序执行。

redis没有实现传统关系型数据库的select ... for update的悲观锁

悲观锁加锁会造成客户端竞争条件的长时间等待,所以为了尽可能减少客户端等待时间,redis未实现for update的悲观锁机制。
而是通过watch命令,检测某值是否被抢先修改,并在发生时给客户端返回错误。该机制类似于关系型数据库中根据版本号实现的乐观锁机制。

通过配置主从复制来提升redis的读性能

redis复制

复制可以让其他服务器拥有一个不断更新的数据副本,扩展系统的读请求处理能力。
从服务器连接住服务器时的步骤

步骤序列 主服务器操作 从服务器操作
1 等待命令进入 连接主服务器,发送SYNC同步命令
2 开始I执行BGSAVE,备份数据副本,在此期间使用缓冲区记录BGSAVE之后执行的所以命令 根据配置选项决定是继续使用现有数据(if has)来处理客户端的命令请求,还是想发送请求的客户端返回错误
3 BGSAVE执行完毕,想从服务器发送快照文件,并在发送期间继续使用缓冲区记录被执行的命令 丢弃所有旧数据(if has),开始载入主服务器发来的快照
4 快照文件发送完毕,开始想从服务器发送存储在缓冲区里面的写命令 完成对快照文件的解释,开始正常接受命令请求
5 缓冲区存储的写命令发送完毕,此后每执行一个写命令,就行从服务器发送相同的写命令 执行主服务器发来的所有存储在缓冲区的写命令;此后,接收并执行主服务器传来的每个写命令

从服务器在进行同步是,会清空自身原本数据。

redis不支持主主复制

当多个从服务器尝试链接同一个主服务器的时候:

  1. 当上表步骤3尚未执行时,所有服务器都会接受到相同的快照文件和相同的缓冲区写命令
  2. 当步骤3正在执行或者已经执行完毕,新连接的从服务器会重新执行一遍步骤1-5

主从链

redis可以组成如下图所示的主从链。
因为redis的复制会占用主服务器的网络和其他开销,如果一个主服务器需要同步太多的从服务器时,可能会造成主服务器不可用,所以可以组成如下所示的主从链树状结构,用以在提升整体读性能的前提下,减轻主服务器的同步开销。

redis介绍_第6张图片
image.png

redis集群

参考资料
https://redis.io/
http://redisdoc.com
《Redis实战》

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