缓存、排行榜、消息队列、计数器(文章、视频浏览数根据浏览实时+1,避免频繁的进行IO)
使用单线程架构和I/O多路复用模型。每一条命令从客户端达到服务端不会立刻被执行,所有命令都会进入一个队列,然后逐个被执行
- 纯内存访问
- 非阻塞IO
- 单线程避免了多线程上下文切换产生的消耗
字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)
可以参考:http://www.redis.cn/commands/append.html
几个常用命令解释:
SETEX
:设置key在给定的seconds时间之后超时过期,等效命令(SET、EXPIRE组合)SETNX
(SET if Not exists):如果key不存在,这种情况下等同SET命令。 当key存在时,什么也不做
Redis其将所有数据都存储在了内存中,一旦宕机或者重启,数据就会丢失,所以需要将数据从内存中同步到硬盘中,这一过程就是持久化。 当下次重启时利用之前持久化的文件即可实现数据恢复。
RDB持久化是把当前进程数据生成快照保存到硬盘的过程,代表Redis在某个时间点上的数据快照。触发RDB持久化过程分为手动触发和自动触发。 当符合一定条件时Redis会自动将内存中的所有数据进行快照并存储在硬盘上。进行快照的条件可以由用户在配置文件中自定义, 由两个参数构成:时间和改动的键的个数。当在指定的时间内被更改的键的个数大于指定的数值时就会进行快照。
- 优缺点
- 优点:适用于备份,全量复制等场景。Redis加载RDB恢复数据远远快于AOF的方式。
- 缺点:没办法做到实时持久化/秒级持久化,属于重量级操作,频繁执行成本过高。
以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。主要作用是解决了数据持久化的实时性
重写机制:随着命令不断写入AOF,文件会越来越大,Redis引入AOF重写机制压缩文件体积。(新的文件会去掉浪费空间的冗余命令)
- 手动触发:直接调用
bgrewriteaof
命令。- 自动触发:根据
auto-aof-rewrite-min-size
和auto-aof-rewrite-percentage
参数确定自动触发时机。
缓存可以有效加速应用读写速度(缓存通常都是全内存的(例如:Redis、Memcache
),而
存储层查询或者存储会进行I/O操作(例如MySQL
)),降低后端负载。
- 1、开销大的复杂计算:一些复杂的操作或者计算(例如大量联表操作、一些分组计算),如果不加缓存,不但无法满足高并发量,同时也会给MySQL带来巨大的负担。
- 2、加速请求响应:如果是高并发场景,有些热点数据需要放到缓存当中,防止经常到数据查询进行IO操作,影响性能
缓存中的数据会和数据源中的真实数据有一段时间窗口的不一致,需要利用某些策略进行更新
- 1、LRU/LFU/FIFO算法剔除:缓存使用量超过了预设的最大空间,如何对现有的数据进行剔除
- 2、超时剔除:通过给缓存数据设置过期时间。超时剔除通过给缓存数据设置过期时间。一段时间窗口内(取决于过期时间长短)存在一致性问题
- 3、主动更新:应用方对于数据的一致性要求高,需要在真实数据更新后,立即更新缓存数据
查询一个不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。 导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义
- 缓存空对象:当存储层不命中后,仍然将空对象保留到缓存层中,之后再访问这个数据将会从缓存中获取,这样就保护了后端数据源(可以针对这类数据设置一个较短的过期时间,让其自动剔除)
- 布隆过滤(Bloom Filter):先将存在的
key
用布隆过滤器提前保存起来,做第一层拦截。
是 1970 年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。主要用于判断一个元素是否在一个集合中。
- 原理:当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就知道集合中有没有它了。
由于缓存层承载着大量请求,有效地保护了存储层,但是如果缓存层由于某些原因不能提供服务,于是所有的请 求都会达到存储层,存储层的调用量会暴增,造成存储层也会级联宕机的情况。
高可的基础,解决单点问题。会把数据复制多个副本部署到其他机器。
- 原理
主节点(master)和从节点(slave),每个从节点只能有一个主节点,而主节点可以同时具有多个从节点。 复制的数据流是单向的,只能由主复制到从。
- 读写分离
由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器, 以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时, 自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能。
通过执行 MONITOR
指令,客户端可以将自己变成一个监视器,实时地接收并打印出服务器当前处理的命令请求的相关信息。
每当一个客户端向服务器发送一条命令时,服务器除了会处理这条命令请求之外,还会将关于这条命令的请求信息发送给所有监视器。
- 客户端订阅一个或者多个频道:
SUBSCRIBE channel
- 向某个频道发布消息:
PUBLISH channel "message"
一组操作要么全部执行,要不全部不执行。这组命令置于MULTI
&EXEC
之间。
有些场景需要在事务之前,确保事务中的key没有被其他客户端修改过,才执行事务,否则不执行:使用watch
命令解决。
redis
客户端可以使用Lua
脚本,直接在服务器端原子地执行多个redis
命令。服务器内嵌了一个 Lua
环境。
- 执行 Lua 脚本:
eval
/evalsha