`
student_lp
  • 浏览: 437293 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

一、redis持久化

    redis是基于内存的数据库,内存数据库有个严重的弊端;突然宕机或者断电时,内存的数据不会保存。为了解决这个问题,redis提供了两种持久化方式:内存快照(Snapshotting)和日志追加(Append-only file)。

1、内存快照

    内存快照方式是将内存中的数据以快照方式写入二进制文件中,默认文件名为dump.rdb。

    redis每隔一段时间进行一次内存快照操作,客户端使用save或者bgsave命令告诉redis要做一次内存快照操作。save命令在主线程中保存内存快照,redis由单线程处理所有请求,执行save命令可能阻塞其他客户端请求,从而导致不能快速响应请求,所以不建议不要使用save命令。另外要注意,内存快照每次都把内存数据完整的写入硬盘,而不是只写入增量数据。所以如果数据量大,写入操作比较频繁,从而严重影响性能。

    与内存快照相关的配置选项如下:save <seconds> <changes>。该配置表示经过seconds秒或者数据更改changes次进行一次内存快照操作。

2、日志追加

    日志追加(aof)方式是把增加、修改数据的命令通过write函数追加到文件尾部(默认是appendonly.aof)。redis重启时读取appendonly.aof文件中的所有命令并且执行,从而把数据写入内存中。

    另外操作系统内核的I/O接口可能存在缓存,所以日志追加方式不可能立即写入文件中,这样就有可能丢失部分数据。幸运的是redis提供了解决方法,通过修改配置文件告诉redis应该在什么时候使用fsync函数强制操作系统把缓存吸入磁盘。有以下三种方法:

  • appendonly yes   #启动日志追加持久化方式(yes|no)
  • #appendfsync always   #每次收到增加或者修改命令就立刻强制写入磁盘
  • appendfync everysec    #每秒强制写入磁盘一次
  • #appendfsync no          #是否写入磁盘完全依赖操作系统

   日志追加方式有效降低数据丢失的风险,同时也带来另一个问题,即持久化文件不断膨胀。为了压缩日志文件,redis提供了bgrewriteaof命令。当redis收到此命令,就使用类似内存快照方式将内存的数据以命令的方式保存到临时文件中,最后替换原来的日志文件。

二、虚拟内存

    redis的数据保存在内存中,可能出现物理内存不足的情况。物理内存不足时,redis使用“虚拟内存”(VM)解决该问题。

    VM是redis2.0新增功能。之前,redis把数据库中所有数据存放在内存中。随着redis的不断运行,使用的内存会越来越大,最终导致内存不足的情况。redis的VM与操作系统的VM相似,把很少访问的value保存到磁盘中。与此同时,redis把value对应的key都放在内存中,为了能够让redis快速定位被换出的value所在磁盘位置,从而将其导入内存中。

1、redis自己设计VM的原因

  • 操作系统VM是基于页的概念,比如linux系统中每个页是4kB,而redis大多数对象远小于4KB,一页上可能有多个redis对象。另外redis的集合对象类型如list、Set可能存在于多个页上。故redis自己实现可达到控制转入粒度。
  • redis将交换到磁盘的对象压缩,保存到磁盘的对象可以去除指针和对象元数据信息。一般压缩后的对象比内存中的对象小10倍,这样redis的VM比操作系统的VM少做很多I/O操作。

2、配置文件信息

    要使用VM,在配置文件中开启相关的配置项:

#开启VM功能
vm-enabled yes
#交换出来的value保存的文件路径/tmp/redis.swap
vm-swap-file /tmp/redis.swap
#redis使用的最大内存上限,超过上限后redis开始交换value到磁盘文件中
vm-max-memory  268435456
#设置每个页面的大小为32个字节
vm-page-size 32
#最多在文件中使用多少页面,swap文件的大小等于vm-page-size * vm-pages
vm-pages  134217728
#用于执行value对象换入换出的工作线程数量。0表示不使用工作线程
vm-max-threads 4

    redis的vm只把value交换到磁盘中,而key依然存储在内存中,目的是让开启vm的redis和完全使用内存的redis性能基本保持一致。如果由于太多key而造成内存不足的问题,redis的vm并不能解决。

    和操作系统一样,redis也按照页(page)交换对象。一页只能保存一个对象,但是一个对象可以保存在多个页中。

    当redis使用的内存没有超过设置的vm-max-memory之前,不把任何value交换到磁盘中;当超过最大内存限制后,redis根据以下算法寻找一个对象交换到磁盘中:swappability=age*log(size_in_memory);其中age代表这个对象距离上一次被访问的时间,size_in_memory是这个对象在内存中占用的空间大小。redis采取这个策略是把那些很少访问,而且占据内存又比较大的对象交换到磁盘中,但是第二个因素所占的权重更低,所以在公式中取log值。因为交换大对象时,需要占用更多的I/O和CPU资源。

    应该根据自己的应用设置vm-page-size,设置太大浪费磁盘空间,设置太小造成SWAP文件出现过多碎片。

    vm-max-threads表示用于交换任务的工作线程数量,建议不要将vm-max-threads设置为0,设置为0时交换过程在主线程进行,从而阻塞其他用户。但也不建议设置的越大越好,因为太多的工作线程会导致操作系统使用更多时间来切换线程,从而降低效率。推荐把vm-max-threads设置为服务器的CPU核心数。

3、对象在swap中的存储

    swap文件中采用rdb文件的存储格式。swap文件被分割成固定数量的页,每页占用固定数量的字节空间。在redis.conf中根据自己业务需求配置一下两个参数:

    ①vm-page-size设置每页的大小,默认值为32.

    ②vm-pages设置能够使用的页数,默认值为134217728.

    redis在内存中保存一个bitmap以映射这些页是否被占用,每bit代表对应磁盘空间的页是否被使用。内存中保存这样一份映射表极大增强了redis性能,同时,对内存的使用有非常少。

三、redis内存淘汰

    redis是一个内存数据库,当内存不足时,redis有两种处理方式:①启用虚拟内存:将vm-enabled配置项设置为yes; ②启用内存淘汰:将maxmemory配置项设置为一个大于0的整数。

    当redis使用的内存数大于可使用的最大内存数时,进行内存淘汰。redis的淘汰算法较丰富,主要有3种:①随机淘汰算法,从数据库中随机删除一个key;②LRU淘汰算法,从数据库中删除一个最近最少访问的key;③TTL淘汰算法,从数据库中删除一个最快过期的key。通过maxmemory-policy配置项指定使用的淘汰算法。

四、对象引用计数器

    设想当一个客户端调用get获取一个较大的key时(不能通过一次网络I/O把数据传输完毕),另一个客户端调用del命令删除此key,如果此时没有对key进行任何保护,get操作就有可能导致内存错误(因为del操作已经把key从内存删除,而get操作还在进行,这样get操作就会访问到非法内存地址)。

    为了解决这个问题,redis使用对象引用计数器。原理是:给对象添加一个引用计数器,每当有地方引用它时,计数器值就加1,当引用失效时,计数器值就减1.当引用计数器为0时,redis便把此对象从内存中删除。

    这样当get操作尚未完成时,del命令不能够删除数据。等待get操作完成后,redis就把key的引用计数器减1.当所有的get操作完成后,此key的引用计数器将变为0,此时,redis就把这个key从内存中删除。

五、自动关闭超时连接

    redis有自动关闭超时连接的功能,当有一个客户端连接在一定时间内不进行任何操作时,redis自动关闭它。因为redis只能处理有限的客户端连接,这个功能有效防止一些用户恶意占用连接。

    开启这个功能在配置文件中把timeout设置为大于0的参数,redis根据客户端最后一次操作时间,判断是否超过timeout配置时间,如果超过timeout配置时间,redis就关闭此连接。

六、清除过期数据

    redis为每个存储的数据设置一个过期时间,当到达这个设置的过期时间后,redis便会把过期的数据从内存中删除。为了提高效率,redis使用一个HashTable存储数据的过期时间,把数据的key与过期时间相关联,这样就可以通过key来检查数据的过期时间了。

    redis并不会每时每刻去检查数据是否过期,因为这样效率太低。redis清除过期数据分两个阶段进行:第一个阶段在定时器中进行,在redis定时器中,每隔100毫秒进行一次清理过期数据的操作;第二个阶段在用户获取数据时进行,当用户使用get、hget命令获取数据时,redis会判断数据是否过期,如果过期,就从内存中删除。

分享到:
评论

相关推荐

    redis基础认识与使用

    综上所述,Redis以其丰富的数据结构和高效的性能,广泛应用于缓存、计数、排行榜、发布/订阅系统等多个领域。学习和掌握Redis的基本概念和使用,对于提升应用性能和解决复杂问题具有重要意义。提供的参考资料可帮助...

    redis-6.0.8.zip

    Redis是一款高性能的键值对数据库,常用于缓存、消息队列等场景。"redis-6.0.8.zip"是Redis的6.0.8版本安装包,它包含了运行Redis服务器所需的所有文件。让我们深入了解一下Redis的核心特性、安装过程以及如何在不同...

    Redis应用场景--Redis作者谈Redis应用场景

    Redis的强大之处在于其灵活多样的数据结构以及高效的命令执行能力,这使得它能够在多种应用场景中发挥重要作用。无论是用于实时系统开发还是构建高效的缓存系统,Redis都展现出了巨大的潜力。通过本文的介绍,相信...

    redis使用场景及数据结构.docx

    Redis 是一款非常流行的开源内存数据库系统,因其高性能和灵活性而被广泛应用于多种场景之中。以下是一些常见的使用场景: 1. **缓存**: - **本地缓存**:通过在本地存储频繁访问的数据,可以显著提高应用性能。 ...

    redis实战的英文原版

    - **第1章: 认识Redis (Getting to know Redis)** - **主要内容**: - Redis简介: Redis是一款高性能的键值存储系统,支持多种数据结构如字符串、列表、集合等。 - Redis的特点: 高性能、低延迟、支持主从复制、...

    Redis深度历险:核心原理和应用实践【TALKDATA推荐】1

    书中提到,Redis不仅可以作为缓存系统,还可以用于消息队列、计数器、分布式锁等多种功能,这为读者提供了对Redis功能的广泛认识。 接下来,小册内容范围的介绍明确了本书将详细讲解Redis的基础数据结构,包括安装...

    redis入门手册(中文)

    Redis,全称Remote Dictionary Server,是一款高性能的键值存储系统,常被用于数据库、缓存和消息中间件的角色。作为一款开源的、基于内存的数据结构存储系统,它支持数据的持久化,可以将内存中的数据定期保存到...

    第2章 Redis快速入门 试看.zip

    Redis(Remote Dictionary Server)是一个开源的、基于内存的数据结构存储系统,支持数据持久化,可作为数据库、缓存和消息代理使用。它提供了多种数据结构,如字符串、哈希、列表、集合和有序集合,使得在处理特定...

    Redis快速入门ppt(1)

    2. 熟悉 Redis 的常用五种数据结构 3. 熟悉 Redis 的常用命令 4. 熟练使用 Jedis 或 SpringDataRedis 客户端 Redis 是一种功能丰富、性能高的 NoSQL 数据库,广泛应用于缓存、消息队列、数据存储等领域。本课程旨在...

    spring redis集成

    随着数据存储技术的发展,Redis作为一款高性能的键值存储系统,被广泛应用于缓存、消息队列等多个场景。Spring为开发者提供了一种便捷的方式来集成Redis,使得在Spring应用中操作Redis变得更加简单和高效。本文将...

    Redis入门及集群环境搭建

    2. **认识 Redis** Redis 是一个用 ANSI C 编写的、面向 Posix 系统的持久化键值数据库,它以网络接口进行通信。Redis 可以视为内存数据库,因为它主要在内存中处理数据,以实现高速读写性能。然而,Redis 也支持将...

    redis入门指栏

    通过以上介绍,你应该对Redis有了初步的认识。在实际应用中,还需要结合具体需求选择合适的数据结构,合理利用Redis的特性来优化系统的性能。随着对Redis的深入学习,你会发现它在很多场景下都能发挥重要作用。祝你...

    Redis-x64-3.2.100.msi

    由于其在内存中运行的特点,使得Redis在数据处理速度方面具有显著优势,适用于实时性要求高的场景,例如缓存、消息队列、实时数据分析等领域。 ### Windows环境下Redis的安装与配置 #### 1. 下载与安装 本次提到的...

    Redis in Action.

    Redis是一种开源的内存数据结构存储系统,它通常用作数据库、缓存和消息代理。它支持多种类型的数据结构,如字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)、位图...

    redis实战 黄健宏 完整得

    其特点是数据结构丰富,支持多种数据类型,如字符串、哈希、列表、集合、有序集合等,且具有高速读写性能。 本书首先介绍了Redis的基础知识,包括安装配置、基本命令以及数据类型,让读者对Redis有一个全面的认识。...

    Redis入门学习必备教程

    Redis的数据结构是其核心特性之一。字符串是最基础的数据类型,可以用来存储简单的文本或数字。哈希允许存储键值对的集合,适合表示对象。列表支持元素的有序插入和删除,常用于实现消息队列。集合是不重复元素的...

    Redis入门指南

    2. **数据结构支持**:Redis支持更多类型的数据结构,如列表、集合等,而关系型数据库主要支持表格形式的数据存储。 3. **事务支持**:虽然两者都支持事务,但Redis的事务更为简单,主要用于保证一系列操作的顺序...

    Redis的40道面试题.docx

    Redis 的主要特点是其高速性能,支持数据持久化,能够将内存中的数据保存到磁盘,以便在系统重启后继续使用。此外,Redis 提供了多种数据结构,如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)和...

    ThinkPHP3.2框架操作Redis的方法分析

    在ThinkPHP3.2的目录结构中,Redis缓存文件通常位于\ThinkPHP\Library\Think\Cache\Driver路径下。尽管ThinkPHP3.2已提供了与Redis的集成方式,但其功能主要限定于基本的缓存操作。 如果需要对Redis进行更深层次的...

Global site tag (gtag.js) - Google Analytics