理解 Redis
title: “理解 Redis”
url: “https://wsk1103.github.io/”
tags:
- Redis
- 架构
Redis
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 时,如果请求量过大,那么就会对 后台系统 造成很大的压力,有可能会导致 后台系统 奔溃。
避免:
- 为查询的结果为空也进行缓冲,可以把有效时间设置比平时的 key 短。
- 把所有可能存在的 key 放到一个大的 Bitmap中,查询前,先在BitMap过滤。
缓存雪崩
当 缓存服务器重启期间,或者大量的缓冲在某一个时间段失效,而在这段期间,如果有大量的请求,就会给 后台系统 带来很大的压力。
避免:
- 在缓存失效后,通过加锁或者队列来控制 访问 后台系统 的线程数量
- 使用二级缓存,一级缓存 设置的有效时间较短,二级缓存有效时间较长。
- 不同的key,设置不同的有效时间。
上一篇: Java实训学习之Map
下一篇: redis服务器部署
推荐阅读