Redis基础知识

Redis简介

Redis基于ANSI C语言编写开发,是一个开源的高性能内存数据存储系统,以键值对的形式存储数据,并支持多种数据结构,如字符串、哈希表、列表、集合和有序集合等。

Redis具有低延迟、高吞吐量的特点,适用于对响应时间要求较高的场景。它支持数据持久化,通过快照和日志机制确保数据的安全性。由于其出色的性能和灵活性,Redis成为了众多开发者和企业的首选之一。

Redis特点

1.读写速度快:Redis数据库是基于内存读写的,整个数据库的数据都被加载到内存中进行操作或处理,它会定期通过异步操作把数据写入磁盘进行保存,从而保证了数据库的容错性,避免在计算机断电时,存储在内存中的数据丢失。Redis每秒可以处理超过十万次读写操作,被称为非关系数据库中读写速度最快的数据库。

2.支持多种数据结构:Redis为用户提供了字符串、散列、列表、集合、有序集合、位图、地理坐标等一系列数据结构,每种数据结构都适用于解决特定的问题。用户还可以通过事务、Lua脚本、模块等特性,扩展数据结构的功能,甚至可以从零实现自己专属的数据结构。通过这些数据结构和特性,Redis能够确保用户可以使用适合的工具去解决问题。

3.支持事务:Redis支持事务操作,可以将多个命令打包成一个原子性操作,要么全执行成功,要么全部失败回滚。这使得开发者能够保证一系列命令的一致性,对于复杂的数据操作非常有用。

4.发布订阅:Redis支持发布订阅模式,允许客户端订阅一个或多个频道,当有消息发布到这些频道时,订阅者会接收到相应的消息。这使得Redis可以作为消息队列或实时消息处理系统使用。

5.高可用和分布式:Redis 支持主从复制、哨兵和集群等功能,可以构建高可用和分布式的 Redis 架构。主从复制可以实现数据的热备份和读写分离,哨兵可以监控 Redis 的健康状态并进行自动故障转移,集群可以将数据分布在多个节点上,提高性能和扩展性。

6.脚本支持:Redis支持使用Lua脚本在服务端执行一些复杂的原子性操作,减少网络传输开销并提高性能。

Redis应用场景

1.缓存:缓存是Redis最常见的应用场景,因为缓存操作是指把数据存储在内存而不是磁盘上,而访问内存远比访问磁盘的速度要快得多,所以用户可以通过把需要快速访问的数据存储在Redis中来提升应用程序的速度。

2.构建队列系统:目前队列系统的应用十分广泛,很多互联网电商网站均使用Redis数据库中的List实现队列。常见的应用场景有电商网站的秒杀、抢购等。

3.排行榜:Redis数据库使用有序集合按照应用的得分进行排序,从而得到TopN。常见的应用场景有热搜榜、游戏排行榜等。

4.实时的反垃圾系统:实时的反垃圾系统通常是基于关键词的,因此使用Redis存储关键词,并利用Redis的高性能,为监控系统提供稳定及精确的实时监控功能。常见的应用场景有邮件系统,评论系统等。

5.过期数据自动清理:Redis针对数据都可以设置过期时间(可以精确到毫秒),过期的数据会自动清理,从而提高开发效率。常见的应用场景有短信验证码,具有时间性的商品展示等。

6.计数器应用:Redis 支持原子操作,并且线程安全,诸如统计点击数等应用使用Redis可以避免并发问题,从而保证统计结果不会出错。常见的应用场景有网站访问统计,广告点击数的统计等。

Redis基本数据结构

1.字符串(String):String是Redis中最基本也是最简单的数据结构,其值是二进制安全的,值的数据类型可以为数字、文本、图片、视频或者序列化的对线等,值的最大长度不能超过512MB。

2.列表(List):List是由若干个字符串元素组成的集合,并且每个字符串元素都是按照插入顺序进行排序的。列表可以理解为多个字符串组成的一个集合对象,并按照链表的插入顺序进行排序。可以在列表的两端进行快速的元素插入和删除操作,还支持通过索引范围获取子列表、修剪列表等操作。

3.集合(Set):由不重复且无序的字符串元素组成的。与List最主要的区别是:List可以有重复值但是Set当中所有的字符串都是唯一的;List读写操作是要从两端开始,而Set的读写操作都是针对任意的位置的。Set支持支持求交集、并集、差集等操作。

4.哈希(Hash):Hash可以存储多个键值对之间的映射,属于无序的一种数据集合。Hash可以包含多个字段和对应的值,字段和值之间是一一对应的关系。

5.有序集合(Sorted Sets):Sorted Sets和Set类似,不同的是Set是无序的,Sorted Sets是有序的。Sorted Sets当中的每个元素都会关联一个score属性,可以基于scroe属性对元素排序,底层的实现是一个跳表(SkipList)加hash表。

Redis持久化

Redis提供了两种持久化方式,分别是RDB持久化和AOF持久化。

ROB

RDB持久化是 Redis的一种快照持久化方式。它将 Redis在某个时间点上的数据保存到磁盘上,以生成一个压缩过的二进制文件(ROB文件),其中包含了 Redis数据库的快照,包含了Redis在某个时间点上的所有数据。

RDB文件在 Redis服务器启动和关闭时自动生成和载入,也可以通过SAVE和BGSAVE命令手动触发保存。

当需要恢复数据时,Redis会读取RDB文件,并根据文件中的内容来还原数据库。

RDB持久化的优点是备份恢复数据速度快,适合用于备份和灾难恢复。缺点是如果在Redis发生故障时,最后一次持久化的数据可能会丢失。

AOF

AOF持久化是Redis的一种日志式持久化方式。它将Redis所有的写命令记录到一个只读文件(AOF文件)中,以确保数据的完整性和实时性。

Redis通过设置 appendonly yes来启用AOF持久化。可以设置appendfsync配置选项来指定AOF文件同步到磁盘的策略,例如always、everysec和no等。always表示每个写命令都立即同步到磁盘,最慢但最安全;everysec表示每秒同步一次,可能会丢失一秒钟的写命令;no则由操作系统决定何时将数据刷新到磁盘。

当Redis需要恢复数据时,它会读取AOF文件,并重新执行文件中保存的写操作,来还原数据库。

AOF持久化的优点是可以保证更高的数据安全性,因为它记录的是每个写操作,即使Redis在持久化时发生故障,也可以通过AOF文件来还原数据。缺点是相比于RDB持久化,AOF持久化的性能较低。

Redis缓存机制

缓存穿透

缓存穿透是指恶意请求或者查询不存在的数据,导致缓存无法命中,每次请求都会直接访问数据库,从而导致数据库压力过大的情况。

通常来说,当一个请求需要查询某个数据时,首先会尝试从缓存中获取数据,如果缓存中存在该数据,则直接返回给用户。如果缓存中不存在该数据,则需要去数据库中查询,并将查询结果存入缓存中,以便下次请求时可以直接使用。然而,当恶意请求或者查询不存在的数据时,由于数据库中也没有该数据,缓存也无法命中,这就导致每次请求都会直接访问数据库。如果请求量很大,就会给数据库造成严重的压力,甚至可能导致数据库崩溃。

一般采取以下方法解决缓存穿透问题:

1.布隆过滤器:布隆过滤器是一种高效的数据结构,它可以快速判断某个元素是否存在于集合中。可以将所有可能存在的数据哈希到一个足够大的位数组中,当查询时先通过布隆过滤器判断是否可能存在,如果不存在则可以直接拒绝访问,避免了对数据库的查询操作。

2.空值缓存:对于查询不存在的数据,可以将其对应的缓存值设置为空值,这样下次再来查询相同的数据时就可以从缓存中获取到空值,而不需要直接访问数据库。可以设置一个较短的过期时间,避免长时间占用缓存空间。

3.热点数据预加载:对于一些热门的数据,在系统启动时可以提前将其加载到缓存中,避免在运行时遇到缓存穿透问题。

4.异步更新缓存:当发现某个数据不存在于缓存中时,可以通过异步任务去数据库中查询并更新缓存,而不是阻塞请求等待缓存更新完成。

缓存雪崩

缓存雪崩是指在某个时间段内,缓存中大量的数据同时失效或者被清空,导致大量请求直接访问数据库,从而造成数据库负载骤增,甚至引发数据库崩溃的情况。

通常情况下,为了提高系统性能和响应速度,我们会将数据缓存在缓存中,当有请求需要查询这些数据时,会首先尝试从缓存中获取。如果缓存中存在对应的数据,则可以直接返回给用户,避免了频繁访问数据库。但是,当缓存中大量数据同时失效或者被清空时,所有的请求都无法从缓存中获取数据,只能直接访问数据库,从而导致数据库负载急剧增加。大量请求直接访问数据库,数据库负载骤增,导致数据库性能下降,影响整体系统的响应速度和性能,甚至会导致数据库崩溃或无法正常提供服务。

一般采取以下方法解决缓存雪崩问题:

1.缓存失效时间随机化:对于大量数据同时失效的情况,可以将缓存的失效时间进行随机设置,避免大量缓存同时失效而引发雪崩效应。

2.数据预热:在系统启动或者低峰期,提前将常用的数据加载到缓存中,避免在高峰期出现大量缓存失效导致的雪崩问题。

3.限流熔断:当检测到缓存失效后,可以采取限流或者熔断等措施,控制请求的并发量,避免对数据库造成过大的压力。

4.高可用架构设计:采用多级缓存、分布式缓存等方式,将缓存分散到不同的节点或者服务器上,提高系统的可用性,降低单点故障的风险。

缓存更新策略

缓存更新策略是指在数据发生变化时如何及时更新缓存,以保证缓存中的数据与源数据的一致性。不同的应用场景和需求可能需要选择不同的缓存更新策略。

以下是常见的缓存更新策略:

1.Cache-Aside(旁路缓存)策略:在读取数据时,先从缓存中查询,如果缓存中不存在,则从数据库中读取,并将读取到的数据放入缓存中。当更新数据时,直接更新数据库,然后将缓存中对应的数据移除或者标记为失效,下次读取时再重新加载到缓存中。这种策略适用于读多写少的场景,对于数据的一致性要求相对较低。

2.Write-Through(写透)策略:在更新数据时,先更新数据库,然后再更新缓存。即每次写操作都会先更新数据库,然后再更新缓存。这样可以保证数据的一致性,但可能会增加写操作的延迟。

3.Write-Behind(写后策略)策略:在更新数据时,只更新缓存,而不立即更新数据库。缓存会维护一个队列,将更新操作异步批量地写入数据库。这样可以降低写操作的延迟,并提高写操作的吞吐量。但是在发生故障或者宕机时可能会导致数据丢失。

4.Read-Through(读透)策略:在读取数据时,先从缓存中查询,如果缓存中不存在,则从数据库中读取,并将读取到的数据放入缓存中。不同于Cache-Aside策略,这里在读取时会直接从数据库加载数据到缓存中,而不是等待下次读取时再加载。这样可以保证缓存中始终存在最新的数据,但可能增加读操作的延迟。

5.Refresh(刷新)策略:定期刷新缓存中的数据,避免数据过期。可以设置一个定时任务或者使用触发器,在规定的时间间隔内定期更新缓存中的数据,以保持缓存和数据库中数据的一致性。

缓存失效处理

缓存失效处理是指在缓存中的数据或对象过期或无效时,如何及时地将其从缓存中清除或更新。缓存失效处理是保证系统数据一致性和正确性的重要手段,可以避免因为缓存数据不一致导致的错误结果。

以下是常见的缓存失效处理:

1.定时失效:缓存数据通常有一个过期时间,一旦过期时间到了,缓存数据就会自动失效。过期时间可以在缓存中设置,根据业务需求来决定。当缓存数据过期时,需要从数据库或其他可靠数据源读取最新数据,并重新写入到缓存中。

2.手动失效:程序可以通过某些手段,比如调用缓存API中提供的invalidate(key)方法,来主动清除缓存中的数据。这种方式可以根据业务逻辑主动地清除缓存,比如当用户修改了某个数据时,需要清除该数据的缓存。

3.事件失效:当缓存中的数据发生变化时,需要及时更新缓存,否则会导致缓存数据不一致。被动失效通常是通过使用缓存框架提供的监听器来实现。当缓存中的数据发生变化时,监听器会自动触发,并将缓存中的数据更新或删除。

4.LRU(最近最少使用)失效:LRU失效是指当缓存中的数据量达到一定阈值时,会按照最近最少使用的原则,清理掉一些很长时间没有使用的缓存数据。这种方式可以有效地利用缓存空间,但可能会导致一些数据被提前失效。

5.LFU(最不常用)失效:LFU失效是指当缓存中的数据量达到一定阈值时,会按照最不常使用的原则,清理掉一些很少使用的缓存数据。这种方式可以保留一些经常使用的数据,但可能会导致一些数据被过早地清理。

Redis过期策略

Redis的过期策略是指在Redis中对于设置了过期时间的键的过期处理方式。当一个键设定了过期时间后,在过期时间到达后,这个键会被自动删除,这就是过期策略的核心。

定时过期

定时过期是指在设置数据或对象的过期时间时,指定一个具体的时间点或时间间隔,当时间到达或超过设定的过期时间时,数据或对象将被自动删除或标记为过期。这种过期策略可以精确地控制数据的生存时间,并在指定的时间点执行过期操作。该策略可以立即清除过期的数据,对内存很友好,但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。

惰性过期

当一个数据项被访问时,系统会先检查该数据项是否过期,如果已经过期,则在访问时将其删除。这种方式避免了定期轮询整个数据集合的开销,只有在需要访问数据时才会执行过期检查和清理操作,从而减少了系统的负载。

惰性过期在实现上比较简单,但可能会导致一些过期数据长时间未被清理,造成存储空间的浪费。因此,在使用惰性过期时,通常需要权衡数据的访问频率和过期清理的效率,确保过期数据能够及时得到清理,同时避免频繁的过期检查对系统性能造成影响。

定期过期

定期过期是指通过周期性地检查过期键,并删除已经过期的键来实现过期管理。定期过期会在一定时间间隔内,反复扫描数据库或缓存中的数据,并删除已过期的数据。这种过期策略是基于轮询机制,需要系统定期进行扫描和清理操作。

Redis发布订阅

Redis的发布订阅是一种消息传递模式,用于在多个客户端之间传递消息。在Redis中,发布者通过向指定的频道发送消息,所有已订阅该频道的订阅者都会接收到这条消息。可以将Redis的发布订阅看作是一种广播机制,发布者是广播发射器,订阅者是广播接收器。

Redis的发布订阅机制是异步的,发布者和订阅者之间没有直接的通信通道。发布者只是将消息发送到指定的频道,而订阅者则从Redis服务器接收到消息。因此,发布者无法得知哪些客户端订阅了消息,也无法确定消息是否被成功接收。

Redis的发布订阅机制不保证消息的可靠性。即使订阅者在消息发布时已经订阅了频道,也可能因为网络故障或其他原因未能接收到消息。因此,在实际应用中需要根据具体需求和场景来选择合适的消息传递方式,例如使用Redis的持久化机制或者消息队列等技术来保证消息的可靠性和一致性。

Redis架构模式

单机架构

在单机架构中,Redis运行在单个节点上。它将所有的数据存储在内存中,并使用持久化机制将数据写入磁盘,以便在重启后能够恢复数据。客户端可以直接连接到该节点进行读写操作。单机架构适用于小规模应用场景,具有快速的读写能力和简单的部署。

主从架构

主从复制架构包括一个主节点(Master)和多个从节点(Slaves)。主节点负责处理所有的写操作,并将写操作的日志传播给从节点。从节点通过复制主节点的数据来实现数据的同步。从节点可以用作读服务,提供读取请求的负载均衡和扩展性。主从复制架构提高了系统的可伸缩性和可用性。

哨兵架构

哨兵架构是Redis的高可用解决方案之一。它由多个哨兵进程组成,负责监控 Redis 的主从节点状态。哨兵会定期检查节点是否正常运行,当主节点出现故障或不可用时,哨兵会自动将一个从节点升级为新的主节点,并将其他从节点重新配置为新的从节点。这种方式实现了主节点的故障转移和自动切换,确保系统的高可用性。

集群模式

集群模式是Redis官方提供的分布式解决方案。它将数据分片存储在多个节点上,并使用哈希槽(Hash Slot)算法进行数据分配。每个节点负责管理一部分数据和哈希槽。集群模式提供了自动数据分片和故障转移机制,能够在节点故障或增加时自动进行数据迁移和重新分配,保证系统的可伸缩性和高可用性。

Redis的优缺点

优点:

1.Redis读写速度非常快。它采用了高效的数据结构和算法,能够在微秒级别完成大量的操作。

2.Redis提供简单的键值对操作,提供了简洁、直观的命令行接口和易于使用的API,易于上手和使用。

3.Redis能够实现分布式存储和自动数据分片,支持大规模数据存储和高扩展性。

缺点:

1.Redis的数据存储在内存中,可能会导致较高的内存消耗,特别是在存储大量数据时需要考虑内存成本。

2.Redis不支持像传统关系型数据库那样的复杂查询操作,只适合于简单的键值查找和部分数据处理操作。

3.Redis受到单机内存容量的限制,无法像传统数据库那样存储海量数据。

你可能感兴趣的:(数据库,redis)