Redis 基础

简要概述 Redis

Redis使用的是C语言开发,不同于传统数据库,Redis 的数据是在内存中的,可以叫它内存数据库。基于内存,所以读写非常快,一般用作服务中做缓存。
Redis 还可以实现分布式锁: (后续文章会具体实现)

  • 单节点借用 setexlua 表达式实现
  • 集群下使用官方的 RedLock
  • 成熟的组件 Redisson

Redis还可以实现队列,使用 list 数据结构, lpush lpop 等 api。
Redis 还支持事务 、持久化、Lua 脚本、多种集群方案

为什么选型 Redis 而不是 Memcached

首先要了解他们的共同点和区别点。
共同点:

  • 都是基于内存的数据库,一般用作缓存
  • 都有过期策略
  • 性能好

区别点

  • 数据结构不同,Redis 数据结构更丰富,Memcached 只有简单的k/v。(Redis有k/v、list、set、zset、hash
  • 存储机制不同,Redis 有持久化功能(RDB+AOF,并且有灾备恢复功能),Memcached 只基于内存
  • 网络模型不同,Redis 是单线程的多路 IO 复用模型(Redis 6.0 引入了多线程 IO ),Memcached 是多线程,非阻塞 IO 复用的网络模型
  • 过期策略不同,Redis 是惰性删除+定期删除,Memcached 只有惰性删除

简述Redis的数据结构

string(k/v)

常用命令:

set,get,strlen,exists,decr,incr,setex

应用场景:

  • 简单的存储一个 key,一个 value
  • incr 和 decr 作计数器
list

双向链表的实现,可参考 LinkedList 理解。
常用命令:

rpush,lpop,lpush,rpop,lrange,llen

应用场景:

  • rpush 和 lpop 实现FIFO消息队列
hash

参考 HashMap 理解,hash 是一个 string 类型的 field 和 value 的映射表,特别适合用于存储对象。
常用命令:

hset,hmset,hexists,hget,hgetall,hkeys,hvals

应用场景:

  • 存储对象
set

参考 HashSet 理解,这里set也是一个无序不重复集合。
常用命令:

sadd,spop,smembers,sismember,scard,sinterstore,sunion

应用场景:

  • 去重存储数据
  • 取集合的交集、并集等
zset(sorted set)

与 set 结构类似,但是多了一个 score 分数,可以按照 score 分数进行排序,有点类似于 TreeSet。

zadd,zcard,zscore,zrange,zrevrange,zrem

应用场景:

  • 对数据进行排序存储
  • 直播系统里面的礼物排行榜,弹幕消息

Redis 单线程模型,为何性能高?

Redis 基于 Reactor 模式来设计开发了自己的一套高效的事件处理模型。对应的是 Redis 中的文件事件处理器(file event handler),由于文件事件处理器(file event handler)是单线程方式运行的,所以我们一般都说 Redis 是单线程模型。
Redis 通过 IO 多路复用程序 监听客户端的连接,也就是一个个 socket,这样的优势就是 I/O 多路复用技术的使用让 Redis 不需要额外创建多余的线程来监听客户端的大量连接,降低了资源的消耗(所以性能很高)。
文件事件处理器(file event handler)主要是包含 4 个部分:

  • 多个 socket(客户端连接)
  • IO 多路复用程序(支持多个客户端连接的关键)
  • 文件事件分派器(将 socket 关联到相应的事件处理器)
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)
    《Redis设计与实现:12章》

Redis 缓存过期删除策略

缓存过期的意义:

  • 及时释放资源,缓解内存的消耗
  • 业务意义(比如短信验证码放到 Redis ,一分钟过期时间)

过期策略:

  • 定期删除:每隔一段时间抽取一批 key 执行删除过期的操作(会消耗 CPU 资源,但 Redis 会基于一些策略降低频次,减少对 CPU 的占用)
  • 惰性删除:获取 key 的时候,判断一下是否过期,这样对 CPU 很友好,但是可能会存在很多失效数据,占用内存

定期删除对内存友好,惰性删除对 CPU 友好,Redis 采用的是两种相结合的策略。

Redis 如何判断数据过期的?

Redis 数据库在数据库服务器中使用了 redisDb 数据结构

typedef struct redisDb {
     dict *dict;     /* 键空间 key space */
     dict *expires;    /* 过期字典 */
		......
} redisDb;

转自 javaguide.cn
转自 javaguide.cn

Redis 通过一个叫做过期字典(可以看作是 hash 表)来保存数据过期的时间。过期字典的键指向 Redis 数据库中的某个 key(键),过期字典的值是一个 long long 类型的整数,这个整数保存了 key 所指向的数据库键的过期时间(毫秒精度的 UNIX时间戳)。

Redis 内存淘汰机制

  1. volatile-lru:从已设置过期(volatile)的 key 中,淘汰最少使用的(LRU)
  2. volatile-ttl:从已设置过期(volatile)的 key 中,淘汰将要过期的(TTL)
  3. volatile-random:从已设置过期(volatile)的 key 中,随机淘汰(random)
  4. allkeys-lru:从所有(allkeys)的 key 中,淘汰最少使用的(LRU)
  5. allkeys-random:从所有(allkeys)的 key 中,随机淘汰(random)
  6. no-eviction:不淘汰数据,新增数据将报错

Redis 持久化

两种持久化数据的方式:

  1. RDB(快照 snapshotting)
  2. AOF(追加文件 append-only file)
RDB(快照 snapshotting)

Redis 通过创建快照,存储 Redis 某一时刻数据的副本。
RDB 是 Redis 默认的持久化的方式。

save 900 1           #在900(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

save 300 10          #在300(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

save 60 10000        #在60(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。

转自 javaguide.cn
AOF(追加文件 append-only file)

每执行一条会更改 Redis 中的数据的命令,Redis 就会将该命令写入到内存缓存 server.aof_buf 中,然后再根据 appendfsync 配置来决定何时将其同步到硬盘中的 AOF 文件。
在 Redis 的配置文件中存在三种不同的 AOF 持久化方式,它们分别是:

appendfsync always    #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度
appendfsync everysec  #每秒钟同步一次,显示地将多个写命令同步到硬盘
appendfsync no        #让操作系统决定何时进行同步

一般考虑使用 appendfsync everysec 策略,如果发生崩溃,可能丢失这 1s 的数据。

选择哪一种持久化方式?
  • RDB 持久化方式能够在指定的时间间隔能对你的数据进行快照存储
  • AOF 持久化方式记录每次对服务器写的操作
Redis 4.0 提出混合持久化(RDB + AOF)

内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作。也就是将 RDB 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值