欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

理解 Redis

程序员文章站 2022-07-05 20:36:50
...

title: “理解 Redis”

url: “https://wsk1103.github.io/

tags:

  • Redis
  • 架构

Redis

官网:http://www.redis.cn/

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

Redis 支持的数据类型

字符串类型

String

set key value
get key

String 是最基本的类型,可以存储任何数据,一个键最大能存储 512M

散列类型

hash

hset key field value
hget key field 

散列类型的键值也是一种字典结构,存储了字段 field 和字段值的映射,但字段值只能是字符串,不支持其他数据类型,也就是说不能嵌套。

一个hash键可以包含最多2^32 - 1 个字段。

hash类型适合存储对象:使用对象类别和ID构成键名,使用字段表示对象的属性,而字段值表示存储的属性值。就类似Java中 bean 。key对于 bean 名,fiel 对应变量, value 对应变量的值。

列表类型

list(双向)

lpush key value [value...]
rpush key value [value...]
lpop key
rpop key

list 存储一个有序的字符串列表,常用的操作是向列表两端添加元素或者获得列表的某一个片段。

列表内部是基于 双向链表 实现,所以向列表两端添加元素的时间复杂度为 O(1)。

适用场景:获取最新的数据;或者记录日志,可以保证新加入的速度不受已经存在的日志数量的影响,等很少访问中间元素的应用。

集合类型

set

sadd key member [member...]
srem key member [member...]

在集合中,每个元素是不同的,并且没有顺序,一个set键最多可以存储 2^32 - 1 个字符串。

集合和列表的区别

set list
存储内容 最多 2^32 - 1 个字符串 最多 2^32 - 1 个字符串
有序性
唯一性

有序集合

zset

zadd key score member [score member...]

时间复杂度 O(log N)

zset 是在set 和 list 的基础上,为每个 key 增加一个 score(分数),通过 score 进行排序。

Redis 持久化

RDB

Redis DataBase
核心函数是rdbSave(生成RDB文件)和rdbLoad(从文件加载到内容)。

graph LR
内存中的数据-(rdbSave)->磁盘的RDB文件
磁盘的RDB文件-(rdbLoad)->内存中的数据

AOF

append-only file

graph LR
服务器-(flushAppendOnlyFile)->磁盘的AOF文件

每当执行服务器的任务,或者函数 flushAppendOnlyFile 被调用时,就会触发:
aof写入/保存
write:将aof_buf中的缓冲写入AOF文件中。
save:调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。

比较:

  • AOF 文件比 RDB 文件更新频繁,优先级比较高。
  • AOF 比 RDB 更安全,但是也更大。
  • RDB 的性能比 AOF 好。
  • 如果配置了这2种方式的持久化,优先使用 AOF 。

Redis 分布式锁

使用 setnx 命令来争抢锁,当抢到之后,使用 expire 来为锁加一个过期时间。

缓存穿透

查询的时候,是根据 key 去查询的,如果不存在该 key 对应 value 时,就会去后台系统(例如数据库)查询。当一些请求重复查询不存在的 key 时,如果请求量过大,那么就会对 后台系统 造成很大的压力,有可能会导致 后台系统 奔溃。

避免:

  1. 为查询的结果为空也进行缓冲,可以把有效时间设置比平时的 key 短。
  2. 把所有可能存在的 key 放到一个大的 Bitmap中,查询前,先在BitMap过滤。

缓存雪崩

当 缓存服务器重启期间,或者大量的缓冲在某一个时间段失效,而在这段期间,如果有大量的请求,就会给 后台系统 带来很大的压力。

避免:

  1. 在缓存失效后,通过加锁或者队列来控制 访问 后台系统 的线程数量
  2. 使用二级缓存,一级缓存 设置的有效时间较短,二级缓存有效时间较长。
  3. 不同的key,设置不同的有效时间。