Redis基础知识

2023-04-01 16:13
1855
0

Redis作为一个高性能的键值对存储系统,越来越得到贴近实际生产环境的应用。本文将从Redis的安装、单机、集群以及缓存穿透四个方向来介绍Redis。

一、安装
Redis的安装方式有多种,这里介绍两种常用的方式。

1、源码安装
a) 下载redis.tar.gz文件,并解压缩。

b) 进入解压后的目录,执行make命令编译Redis。

c) 编译完成后,运行make install命令将Redis安装到系统目录。

d) 安装成功后,进入Redis目录中的bin目录下,执行redis-server命令就可以启动Redis服务了。

2、使用包管理器安装
对于早期版本的Linux发行版,如CentOS 6,可以使用yum安装Redis。对于较新的发行版,如CentOS 7和Ubuntu 18.04 LTS,则需要使用包管理器apt-get。

二、单机Redis
单机Redis指的是将Redis安装在一台单独的机器上,作为一个独立的Redis节点。这种方式实现简单,配置容易,只需要开发者提供一个Redis节点的地址就可以。

1、Redis配置
在单机Redis中,需要正确配置Redis的初始化参数。

a) 配置缓存大小(maxmemory):为了防止Redis消耗过多的内存,需要限定Redis分配的最大内存。可以通过修改Redis配置文件中的maxmemory值来实现。这个值可以设置为Redis宿主机可用内存的50%,让Redis有充足的空间来存储数据。

b) 设定数据过期时间:除了限定Redis分配的最大内存外,还需要考虑Redis宿主机的磁盘容量。Redis允许设置key的过期时间,可以使用expire命令来设定某一个key的过期时间,过期后Redis会自动删除该key。

c) 配置持久化方式:Redis支持RDB(Redis Database)和AOF(Append-Only File)两种持久化方式。对于不需要高可靠性的业务场景,通常使用RDB方式;对于需要高可靠性的业务场景,则使用AOF方式。AOF方式可以将所有的写操作以追加方式写入文件中,文件可以通过分布式方式实现主从复制,从而实现高可靠性。

2、缓存应用
Redis单机模式的使用场景比较广泛,通常用于解决全局性数据访问的问题。例如在商品详情页中展示主数据,对于全站访问量较小、更新频率较低的商品数据,可以直接使用Redis进行缓存,以加速显示速度。

三、Redis集群
Redis集群是Redis的一种多节点方案,主要为解决单机Redis容量过小、性能瓶颈等问题。针对这些问题,Redis提供了自己的解决方案,可以通过集群方式来实现Redis的横向扩展。

1、集群搭建
集群搭建需要考虑多节点之间的同步问题、读写分离问题以及故障切换问题等。

a) 集群模式:Redis提供多种集群模式,常见的有主从模式、哨兵模式和集群模式。推荐使用基于Redis官方推出的Redis集群模式,实现高可用、可扩展的Redis服务。

b) 集群节点:Redis集群可以由多个节点组成,一个Redis节点可以拥有多个从节点。在集群中,可以根据节点状态进行读写分离和负载均衡。

c) 集群切换:Redis集群故障切换的方式通常有手动切换和自动切换。手动切换需要管理员介入并手动执行;自动切换则需要Redis集群中的哨兵节点处理,监视Redis集群的状态,发现节点异常就进行自动切换。

2、集群应用
Redis集群可以有效解决大规模网站的缓存问题。例如,在一个电商网站中,可以使用Redis集群存储用户信息、商品信息等常用数据,以达到快速存取和清理缓存的效果。

四、缓存穿透
缓存穿透是指查询一个不存在的key,由于缓存中不包含该key所对应的value值,导致对数据库中进行查询,增加数据库负载,影响服务性能。

1、缓存穿透原因
缓存穿透的原因有二:

a) 恶意攻击:攻击者可能会手动构造查询请求,查询缓存中不存在的key,以达到消耗数据库资源、攻击系统的目的。

b) 系统异常:代码异常等问题可能会导致缓存中不存在的key被访问,发生缓存穿透。

2、解决方案
为避免发生缓存穿透,需要采取一定的措施,例如:

a) 过滤掉无效的请求:常用的过滤方式是使用Bloom Filter算法,可以在较小的空间内处理大量的key,用于判断某个key是否存在,可以有效地减少查询数据库的次数。

b) 缓存空值:将不存在的key以null值存入Redis缓存中,可以避免对数据库进行查询,减小系统的压力。

c) 增加二级缓存:将热点数据存储在二级缓存中,可以有效减少对后端数据库的查询次数,降低系统的压力。

在实际应用中,结合业务场景进行选择,可以避免Redis缓存穿透的问题。

五、关于持久化

Redis作为一个内存数据库,仅仅通过内存存储数据时容易出现数据丢失的问题。因此,Redis自带两种持久化方式,分别是RDB和AOF。本篇文章将从两种持久化方式的介绍、使用场景和常见问题等方面进行详细介绍和探讨。

A、RDB持久化
1、RDB持久化介绍
RDB持久化是Redis默认的持久化方式,它通过快照(snapshot)的方式定期将Redis中的数据持久化到磁盘上。

通过定时的dump操作,Redis将内存快照保存到磁盘上的RDB文件中,然后根据设定的策略将RDB文件备份或迁移至其他存储介质中,以保证Redis持久化后的数据安全性。

2、RDB持久化使用场景
RDB持久化适用于对数据的实时性要求不高的场景,例如系统的全量备份和灾难恢复等。此外,RDB持久化还常常被用来实现读写分离,因为RDB持久化可以将数据集压缩到一个文件里,并支持后续操作的压缩和加密操作,这样就可以将文件集中存储在单一服务器上,并让从服务器执行相应的读取操作。

3、RDB持久化常见问题

a) 持久化过程中出现问题
如中途意外掉电等意外事件导致数据保存不完整。通常可以将半持久化完成的RDB数据放到备份磁盘上,并尝试重新进行备份恢复过程。

b) Redis宕机恢复失败
对于一些业务数据量比较大的Redis数据库,如果宕机后恢复不彻底,可能会导致丢失大量的业务数据,这对于业务来说影响会是非常严重的。因此,在进行数据迁移时,需要谨慎对待,建立完整的数据备份、灾难恢复计划,以提高Redis运行安全性。

B、AOF持久化
1、AOF持久化介绍
AOF持久化是通过一个追加写入的日志文件(Append Only File)来记录Redis服务器每个写入操作所引发的数据变化,在Redis重新启动时,会重新执行AOF文件中的写操作以恢复数据集的内容。

2、AOF持久化使用场景
AOF持久化适用于对数据的实时性要求较高场景,例如缓存变化频繁、对数据实时性要求较高的业务场景下。同时,AOF持久化的可靠性较高,因此,对于对数据稳定性和可恢复性要求高的业务场景来说,AOF持久化是首选方案。

3、AOF持久化常见问题

a) AOF日志文件过大
如果Redis的日志文件过大,会导致重启Redis时加载日志文件较为缓慢,解决方法是定期进行AOF日志文件压缩或是将日志文件迁移到大硬盘或是更快的存储介质中。

b) AOF增量持久化过程中中断
AOF持久化过程中意外中断导致日志文件未正确关闭,可能会导致AOF日志被无法恢复,此时需要执行redis-check-aof命令来检测AOF文件错误,并手动修复。

六、热Key问题

热key问题是Redis中常见的性能瓶颈之一,指的是Redis中某些key的访问频率特别高,导致该key对应的操作(读/写)成为系统瓶颈。解决热key问题的方法主要有以下几种:

1.增加Redis实例
通过增加Redis实例的数量,可以将热key分散到不同的实例中,从而降低单个实例的负载。尤其是在集群中,不同实例的CPU、内存、网络带宽等资源都是独立的,可以更好地处理高并发情况。

2.使用缓存预热和缓存淘汰
在系统刚启动时,通过缓存预热将可能的热key提前加载到缓存中,从而减少系统在运行时的压力。同时也可以通过缓存淘汰机制来清除不常用的热key,从而释放内存资源,提高系统的性能。

3.使用一致性哈希算法
一致性哈希算法是常用的缓存集群分片策略,它对key进行哈希计算,将哈希值映射到一个虚拟的环形空间中,根据哈希值在环上的位置,将相邻若干个位置最近的几个Redis节点来分配key。这样可以使热key分散到不同的节点,以分摊单个节点的压力,达到负载均衡的效果。

4.使用Redis Cluster
Redis Cluster是官方提供的分布式集群方案,将数据分布到不同的节点,多个节点间相互备份数据。每个节点只提供部分slot的服务,根据hash slot分配key到不同的节点,使不同的节点负责不同的部分数据,从而减少单个节点的负载。

5.使用Redis Sentinel
Redis Sentinel是Redis官方提供的高可用方案,主要可以监控Redis节点的状态,当某个节点宕机时可以自动进行故障切换。对于热key问题,可以通过Redis Sentinel监控系统的状态,当某个节点负载过高时,可以自动进行故障转移,将负载分摊到其他可用的节点上。

七、分布式锁

Redis分布式锁是一种基于Redis的实现方式,主要实现方式是通过Redis的原子性操作和Lua脚本实现。

实现过程如下:

1.使用SETNX(SET if Not eXists)命令,在Redis中创建一个key,并设置key的值为唯一标识符(如UUID)。

2.如果SETNX命令返回1,即设置成功,就说明该进程获得了锁,可以继续执行业务逻辑;如果返回0,就说明该进程未获得锁,需要等待一段时间再次尝试获取锁。

3.当获取锁的进程执行完业务逻辑,需要释放锁,可以使用DEL命令从Redis中删除key,从而释放锁。

需要注意的是,在Redis中实现分布式锁时,需要考虑如下几个问题:

1.锁的超时时间

为了避免锁被永久占用,需要设置锁的超时时间,在一定时间后无论进程是否执行完业务逻辑都要释放锁。

2.锁的可重入性

如果在同一个进程中,某段代码递归地获取锁,需要保证能够正常释放锁。

3.死锁问题

如果只使用超时时间来避免死锁,可能会出现多个进程同时获取锁的情况,因此需要在代码实现中考虑如何避免死锁。

4.分布式环境下的一致性

需要保证在分布式环境下锁的一致性,即只有一个进程可以获得锁,其他进程都需要等待。可以通过Redis的Lua脚本实现多个操作的原子性,确保不会出现竞争条件。

全部评论