redis常用功能和概念的使用笔记及与memcache对比分析
当下redis和memcache是最常用的缓存使用系统,项目中如何选择redis和memcache?redis和memcache各有什么特点和不同?
一、redis为什么快?
- redis采用了多路复用io阻塞机制(linux内核的epoll机制,主分支是不支持windows的)
- 数据结构化繁为简,操作节省时间
- 运行在内存中
- 参考文档
二、 redis与memcache的对比
- 定位不同
- redis的定位是内存数据库,数据更安全,它有数据的持久化,可恢复数据,内存不足时会使用虚拟内存,
- memcache的定位是内存缓存系统,只能使用内存,无持久化,数据不可恢复
- 数据结构不同
- redis支持stringhashlistsetzset等多种数据类型
- memcache仅支持简单key-value,数据类型单一
- 数据大小
- redis存储小数据(<100k)时效率高于memcache, 但最大可支持450M的数据
- memcache存储(>100k)的数据时比redis效率更高,可存储图片、视频,但最大数据1M,
- 并发处理不同
- redis存取内存是单线程的,保证数据一致性。多核系统可以起多个redis的进程来利用
- memcache是多线程,可以充分利用多cup的性能
- 分布式方式不同
- redis是服务器端做分片的,把数据分片到16348个槽点上,最多可以设置16348个节点
- memcache的分布式是由客户端来做的,在客户端来处理,把数据存储到不同的节点上
- 高可用性不同
- redis是可以做主从复制的,主服务器挂了,快速切换到从服务器,可以确保数据的安全和高可用性
- memcache没有自带的主从复制功能,需要第三方工具实现主从,效率相对较低
- 复杂数据处理能力
- redis自带数据处理功能,内部函数丰富,可以有效减少数据存取的次数
- memcache无数据处理能力
- 过期策略不同
- redis可以通过expire来调整过期时间
- memcache只能在set的时候设置过期时间
- 总结
- 单纯的使用k-v做缓存,建议使用memcache,效率更高,估计只有大公司才有这种需求和条件
- 缓存的同时,还需要更多数据类型、数据处理、高可用方面,当然是redis
- 对于中小公司来讲当然首先redis,功能全,安全,效率也不低
- 参考文档
三 redis的持久化方式
- RDB持久化(Redis DataBase 快照式)
- RDB其实就是把数据以快照的形式保存在磁盘上,是redis默认的持久化方式
- 提供了三种持久化触发机制:save、bgsave、自动化。
- save命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止
- bgsave命令执行时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。是主要的内部触发机制
- 自动触发是配置文件来设置的,redis.conf 中 “save m n” 就触发bgsave.不需要持久化,那么你可以注释掉所有的 save
- stop-writes-on-bgsave-error :默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。
- rdbcompression ;默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。
- rdbchecksum :默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,
但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。 - dbfilename :设置快照的文件名,默认是 dump.rdb
- dir:设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。
- RDB的优势
- RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
- 生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
- DB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
- RDB的劣势
- 存在部分数据丢失可能。持久化时,是由子进程来操作的,父进程如果数据变化了,数据可能丢失
- AOF持久化(Append Only File日志式)
- redis会将每一个收到的写命令都通过write函数追加到文件中。通俗的理解就是日志记录。
- 持久化文件会变的越来越大。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。
将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写。 - AOF也有三种触发机制:alwayseverysec
o
- always:同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差当数据完整性比较好(慢,安全)
- everysec:出厂默认推荐,每秒异步记录一次(默认值)
- no:不同步
- 配置重写触发机制,当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。一般都设置为3G,64M太小了。
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
- AOF的优势
- 数据的完整性和一致性更高
- AOF的劣势
- 因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。
- 开启AOF后消耗系统资源,损耗一部分效率
- redis持久化的流程
- 客户端向服务端发送写操作(数据在客户端的内存中)。
- 数据库服务端接收到写请求的数据(数据在服务端的内存中)。
- 服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)。
- 操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)。
- 磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)。
- redis故障情况分析
- Redis数据库发生故障,只要在上面的第三步执行完毕,那么就可以持久化保存,剩下的两步由操作系统替我们完成。
- 操作系统发生故障,必须上面5步都完成才可以。才需要RDB或AOF的来恢复数据
- 总结
- 若只打算用Redis 做缓存,可以关闭持久化。
- 若打算使用Redis 的持久化。建议RDB和AOF都开启。其实RDB更适合做数据的备份,留一后手。AOF出问题了,还有RDB。
- 一般使用默认的RDB做持久化就好了
- 参考文档
四、缓存穿透,缓存雪崩以及缓存击穿
- 缓存穿透:
- 就是客户持续向服务器发起对不存在服务器中数据的请求。客户先在Redis中查询,查询不到后去数据库中查询。
- 解决办法:
- 接口层增加校验,对传参进行个校验,比如说我们的id是从1开始的,那么id<=0的直接拦截;
- 缓存中取不到的数据,在数据库中也没有取到,这时可以将key-value对写为key-null,这样可以防止攻击用户反复用同一个id暴力攻击
- 缓存击穿:
- 就是一个很热门的数据,突然失效,大量请求到服务器数据库中
- 解决办法:
- 重要的热点数据不设置过期时间,
- 定时执行相关任务更新数据及过期时间
- 缓存雪崩:
- 就是大量数据同一时间失效。
- 解决办法
- 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生
- 如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中