redis总结
redis
1. 含义:
- 基于内存的高性能key-value数据库
2. 安装
docker run -d --name redis -p 6379:6379 redis:2.8
3. 鉴权登录
修改redis.conf配置文件,然后重启服务
requirepass 123 指定密码123
4. 工具使用
redis-server
: 用于启动redis服务端redis-cli
: redis 客户端, 使用命令redis-cli -h 127.0.0.1 -p 6379
连接redis服务器redis-check-dump
: redis dump数据文件的修复工具,导入失败,用于修复导入文件redis-check-aof
: redis aof日志文件修复工具,重启服务失败时,用于修复日志文件redis-sentinel
: 用于实现redis集群高可用(自动切换master和服务发现)redis-benchmark
: redis性能检测工具
5. 基本数据类型键操作命令
6. 订阅发布
7. 事务
- redis事务不支持回滚;
- redis事务是伪原子性的,要不全部执行,要不全部不执行,事务中可能会执行失败,但是Redis事务不会回滚,而是继续会执行余下的命令.redis事务一旦开始,除非服务停止,否则不会回滚。
8. 性能优化
- 读写分离: redis支持主从模式。redis的Master会将数据同步到slave,而slave不会将数据同步到master。Slave启动时会连接master来同步数据。因此Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。
- slave开启AOF备份数据,而非master。 Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,推荐为某个Slave开启AOF备份数据,策略为每秒同步一次。
- redis主从在同一个局域网内: Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内
9. redis的优点
- 操作都是原子性,所谓原子性就是对数据的更改要么全部执行,要不全部不执行。
- 订阅发布模式
- 可设置缓存过期时间
- 单线程,事件驱动,IO多路复用,利用redis队列技术并将访问变为串行访问,消除了传统数据库串行控制的开销
- redis速度快,因为数据存在内存中
- redis支持丰富的数据类型
- redis可持久化,
- 缓存以支持高并发
- 支持事务,所有的命令要么都被一起处理,要么全都没有被处理。如果在事务中可能会执行失败,但是Redis事务不会回滚,而是继续会执行余下的命令。如果操作执行一半中断后,重启服务后会Redis在重新启动时会检测这种情况,并报错,然后退出。使用 redis-check-aof工具可以检查AOF,并移除那不完整的事务,使服务可以再次启动
10. redis相关问题
- 可扩展性,所以出现了codis(redis+zookeeper)
- 缓存预热: 系统上线后,将相关的缓存数据直接加载到缓存系统。这样避免用户请求的时候,再去加载相关的数据
- 缓存雪崩问题: 缓存雪崩是指在某一个时间段,缓存集中过期失效,所有请求都去查询数据库,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。如果是单个缓存出现这样的问题一般问题不大,数据库能扛得住这个压力,如果必须单个点可以在缓存过期前重新set缓存,或者直接设置一个超长缓存或永久缓存;但如果某台redis服务器挂掉,则会出现严重的缓存雪崩问题, 只能做好监控,然后快速的添加机器恢复缓存数据。
- 缓存击穿问题: 缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。解决的办法就是:如果查询数据库也为空,直接设置一个默认值存放到缓存,再次查询就直接返回空了,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。
- 缓存的并发竞争问题: 主要是并发写问题, 即假设有某个key = "price", value值为10,现在想把value值进行+10操作。正常逻辑下,就是先把数据key为price的值读回来,加上10,再把值给设置回去。如果只有一个连接的情况下,这种方式没有问题,可以工作得很好,但如果有两个连接时,两个连接同时想对price进行+10操作,就可能会出现问题了。这种问题比较通用的解决方法是事务。
- redis机器master之间一致性问题(扩容缩容如何保持master一致性
- redis分布式锁:事务中实现;
11. redis为什么那么快
- 在内存中操作
- 单线程,避免了频繁的上下文切换;
- 非阻塞I/O多路复用: 很多个网络I/O复用一个或少量的线程(TCP连接)来处理这些连接
12. redis的key回收策略
-
redis的key回收机制:redis采用的是定期删除+惰性删除策略。如果采用定时删除,则会耗CPU;故采用定期删除+惰性删除策略。
- 惰性淘汰机制: 在进行get或setnx等操作时,先检查key是否过期,若过期,删除key,然后执行相应操作; 若没过期,直接执行相应操作;
- 定期删除:是主动删除机制, redis每隔一段时间随机取一部分key进行过期判断,如果过期则删除;服务端定时的去检查失效的缓存,如果失效则进行相应的操作。【redis基于事件驱动的,一类是IO事件,一类是定时事件】
-
redis的key回收过程: 无论是惰性淘汰机制还是定期删除机制,都是先从expires中查找key的过期时间,如果不存在说明对应key没有设置过期时间,直接返回,如果是slave机器,则直接返回,因为Redis为了保证数据一致性且实现简单,将缓存失效的主动权交给Master机器,slave机器没有权限将key失效。如果当前是Master机器,且key过期,则master会做两件重要的事情:1)将删除命令写入AOF文件。2)通知Slave当前key失效,可以删除了。master从本地的字典中将key对于的值删除;
-
redis的key回收方式
配置文件里redis.conf
的maxmemory_policy:noeviction
用以设置缓存到期后的数据淘汰机制,默认为noeviction- volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
- volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
- allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
- noeviction(驱逐):禁止驱逐数据
13. redis的两种数据持久化方案
redis允许采用RDB和AOF两种方案提供了将数据定期自动持久化至硬盘的能力,两者的区别在于RDB同步的是数据,AOF同步的是操作。
1. RDB
-
说明: Redis会定期保存数据快照至一个rbd文件中,并在启动时自动加载rdb文件,恢复之前保存的数据
-
配置
# 时间策略 save 900 1 # 如果900s内有1条写入命令,就触发产生一次快照,进行一次备份; save 300 10 save 60 10000 # save "" # 如果设置成""则禁用RDB # 当备份进程出错时,主进程就停止接受新的写入操作,是为了保护持久化的数据一致性 stop-writes-on-bgsave-error yes # 是否压缩 rdbcompression yes # 导入时是否检查 rdbchecksum yes # 文件名 dbfilename dump.rdb # 文件会被写到dir里 dir
-
优点
- 对性能影响最小。如前文所述,Redis在保存RDB快照时会fork出子进程进行,几乎不影响Redis处理客户端请求的效率。
- 每次快照会生成一个完整的数据快照文件,所以可以辅以其他手段保存多个时间点的快照
- 使用RDB文件进行数据恢复比使用AOF要快很多。
-
缺点
- 快照是定期生成的,所以在Redis crash时或多或少会丢失一部分数据
- 如果数据集非常大且CPU不够强(比如单核CPU),Redis在fork子进程时可能会消耗相对较长的时间,影响Redis对外提供服务的能力。
2. AOF
-
说明: AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新
-
# 开启AOF模式 appendonly: yes # AOF文件名 appendfilename "appendonly.aof" # 三种文件同步策略, no,不设置同步策略,由系统决定; everysec,后台线程每秒同步一次; always:每写入一条日志同步一次,数据安全性最高,速度最慢; appendfsync everysec # AOF自动重写机制 # 在重写阶段是否允许同步 no-appendfsync-on-rewrite no # redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小比基础大小大制定的百分比, 或者如果现在的大小比基础大小大制定的百分比,是上次rewrite后大小的一倍且文件大于64M时触发。默认64M。 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # redis在恢复时,会忽略最后一条可能存在问题的指令 aof-load-truncated yes
-
优点
- 同步所有写操作,安全性高
-
缺点
- 相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb
3. redis的导入导出
- 使用redis-dump
- aof导入方式
redis.conf
里配置appendonly yes
,- cp appendonly.aof 到redis的数据库目录也就是配置文件里面的dir关键字
- 重启服务
- rdb导入方式
redis.conf
里配置appendonly no
,- cp dump.rdb 到redis的数据库目录也就是配置文件里面的dir关键字
- 重启服务
14. redis和mencache相比的优缺点
- memcache所有的值均是简单的字符串,redis支持更为丰富的数据类型;
- redis速度比memcached快很多
- redis可以持久化
- redis最大可以达到1GB,而memcache只有1MB
- redis原生支持集群模式
- redis 只使用单核,而 memcached 可以使用多核,所以平均每一个核上 redis 在存储小数据时比 memcached 性能更高。而在 100k 以上的数据中,memcached 性能要高于 redis,虽然 redis 最近也在存储大数据的性能上进行优化,但是比起 memcached,还是稍有逊色。
15. redis应用场景
- 会话缓存(session)
- 数据或页面缓存
- 队列(list)
- 订阅发布模式(subscribe)
- 排行榜(有序集合,zadd,zrange)
- 计数器(字符串 + incr)