内存读写是比在磁盘快很多的,Redis 基于内存存储实现的数据库,相对于数据存在磁盘的 MySQL 数据库,省去磁盘 I/O的消耗。
而使用数据持久化的情况下,Redis会将数据同时保存在内存和磁盘中。
Redis提供了两种持久化方式:RDB(Redis Database)和AOF(Append Only File)。
MySQL 的索引使用的是B+树,而redis则是由多种数据结构和内部编码
在Redis中,每种数据结构的底层实现数据结构如下:
字符串(String):字符串数据结构是简单的动态字符串(SDS),它是一个包含了字符数组和长度信息的结构体。如C语言中字符串会遇到’\0’会结束,SDS标志字符串结束的是len属性。它是对C语言中的字符串的一种封装,而SDS提供了更多的功能和优势。
简单动态字符串具有以下特点:
哈希表(Hash):哈希表的底层实现是字典(Dictionary)。字典是一种用于存储键值对的散列表,采用了哈希算法来实现高效的查找和插入操作。
列表(List):列表的底层实现是双向链表(Doubly Linked List)。双向链表是一种每个节点都包含前后指针的数据结构,可以在常数时间内进行节点的插入、删除、访问等操作。
集合(Set):集合的底层实现有两种:一种是基于哈希表的实现,另一种是基于有序集合的实现。具体使用哪种实现方式取决于集合的大小和元素类型。
有序集合(Sorted Set):有序集合的底层实现是跳跃表(Skip List)和哈希表的组合。跳跃表是一种有序的、快速查询的数据结构,可以按照分数进行有序存储和查询。跳表的特色:
Redis 支持多种数据数据类型,每种基本类型,可能对多种数据结构。什么时候,使用什么样数据结构,使用什么样编码,是 redis 设计者总结优化的结果。
I/O多路复用(IO Multiplexing)是一种同时监视多个I/O流的机制,它允许单个线程同时处理多个I/O操作,提高系统的并发性能。通过使用I/O多路复用,可以避免单线程在处理阻塞式I/O时出现的等待时间,从而提高系统的效率。
在Redis中,I/O多路复用是用来处理客户端连接和网络通信的关键机制。Redis服务器在启动时会创建一个I/O多路复用的事件循环(Event Loop),它负责监听和处理客户端的请求和网络事件。
具体表现在以下几个方面:
内存数据库系统,但它也提供了一种虚拟内存机制,允许将数据持久化到磁盘而不仅仅存储在内存中。
虚拟内存机制允许Redis将部分数据从内存中移动到磁盘上,以便处理大于物理内存的数据集。这对于处理大型数据集的情况非常有用,但需要谨慎使用,因为虚拟内存可能导致性能下降。以下是一些关于Redis虚拟内存的关键要点:
虚拟内存配置:Redis的虚拟内存可以通过配置文件中的vm-enabled
参数启用或禁用。默认情况下,虚拟内存是禁用的。
虚拟内存限制:你可以配置Redis的虚拟内存限制,即vm-max-memory
参数,来指定Redis可以使用的虚拟内存的最大大小。当达到这个限制时,Redis会将一些不常用的数据移到磁盘上,以腾出更多的内存。
数据分页:Redis的虚拟内存将数据分为不同的页(pages),每个页的大小由vm-page-size
参数定义。这些页存储在磁盘上,根据数据的访问频率进行移动。
数据置换策略:Redis使用一种称为"页置换"的策略来决定哪些数据会被移动到磁盘上。常见的策略包括LRU(最近最少使用)和LFU(最不常使用)。
警告和性能影响:使用虚拟内存时,需要注意性能问题。频繁的数据移动和磁盘访问可能会导致性能下降。Redis会在达到一定的内存使用阈值时发出警告,以提醒你。
数据持久化:与传统的Redis内存数据库不同,虚拟内存Redis在磁盘上存储数据,因此不需要单独的持久化选项。数据将在Redis服务器重新启动时从磁盘加载到内存中。
内存机制的实现原理可以简要概括如下:
数据分页:Redis将数据分成固定大小的页面(pages),每个页面的大小由vm-page-size
参数定义。这些页面存储在磁盘上,并根据需要进行加载和卸载。
内存映射:Redis使用内存映射(memory mapping)技术来管理虚拟内存。它会将磁盘上的页面映射到进程的地址空间中,这使得可以像访问内存一样访问磁盘上的数据。
页置换策略:Redis使用一种页面置换策略来决定哪些数据页应该从内存中移动到磁盘上,以便腾出内存空间。常见的策略包括LRU(最近最少使用)和LFU(最不常使用),可以通过配置文件中的vm-max-policy
参数进行选择。
内存管理:Redis会维护一个内存使用情况的统计信息,以了解哪些数据页需要被置换到磁盘上。当内存使用接近虚拟内存限制时,Redis会启动虚拟内存机制,将一些不常用的页面移动到磁盘上,以释放内存。
持久化:虚拟内存中的数据页也会被持久化到磁盘上,以便在Redis服务器重新启动时能够恢复数据。这是通过Redis的RDB快照机制来完成的。
需要注意的是,虚拟内存机制在Redis中并不是主要的工作模式,而是一种辅助的机制,用于处理大型数据集。在实践中,虚拟内存通常需要谨慎配置,以避免性能下降。通常情况下,更好的方法是根据实际需求适当地分片数据,或者使用更大的物理内存来容纳数据集,以获得更好的性能。虚拟内存通常用于处理数据集过大,无法完全加载到内存的特殊情况。