1.什么是redis
redis是一个开源的、高性能的、基于键值对的缓存和存储系统,通过提供多种键值数据类型来适应不同场景下的缓存和储存需求。
2.储存的结构类型
Strings、Lists、Sets、Sorted Set 、hashes
3.为什么要使用redis
1.速度快。因为redis是存在内存之中的,也是以键值对的形式存在,所以来说查找很快。
2.支持事务。
3.数据类型比Memcached丰富。
4.丰富的特性。例如缓存、消息,可以设置时间,过期自动删除。
4.为什么redis是单线程的?Memcached是多线程的?
redis是利用队列的技术将redis的并发访问改变为串行访问。
5.redis比Memcached有哪些优势
1.redis拥有更多的数据类型
2.redis的速度比Memcached更快(1.redis是完全基于内存,绝大部分操作是纯粹的内存操作;2.采用的是多路复用IO;3.采用队列技术将多线程转变为单线程,避免了不必要的上下文切换和竞态条件;4.数据结构比较简单)
3.redis可以持久化数据
6.redis和memcached的区别?
1.支持的数据类型不一样
2.redis并不是所有的数据都存在内存之中
3.redis使用的是单线程模型,数据是按照顺序提交;而Memcached则是使用CAS保证数据一致性
4.单个value的最大限制是1GB,不像 memcached只能保存1MB的数据
7.MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?
了解缓存策略:
先设置最大缓存maxmemory,然后使用回收策略算法
voltile-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)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据
方法:1.然后给数据设置相同的过期时间,当redis的缓存每命中一次,就给命中的缓存增加一定ttl(过期时间)(根据具体情况来设定, 比如10分钟).一段时间后, 热数据的ttl都会较大, 不会自动失效, 而冷数据基本上过了设定的ttl就马上失效了。2.设置最大缓存,当内存到了之后就使用volatile-ttl回收策略。
8.redis的持久化
RDB持久化:某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文上次件替换持久化的文件,达到数据恢复。
两种创建方式:SAVE和BGSAVE,其中前者会阻塞进程,而后者则是创建子线程来生成.RDB文件。当.RDB文件保存在硬盘中被redis服务器启动发现的时候就自动加载该文件。
注:在AOF持久化功能开启的时候,服务器会优先使用AOF文件;只有在AOF持久化功能关闭的时候,服务器才使用RDB文件来还原数据库状态。
dirty计数器和lastsave属性,一个记录的是从上次bgsave之后数据库修改的次数,另外一个是上次保存的时间。
AOF持久化:是指所有的命令行记录以redis命令请求协议的格式(完全持久化存储)保存为aof文件。
AOF持久化功能的实现可以分为三个部分:命令追加(append)、文件写入、文件同步
AOF文件的同步操作是:处理文件事件,接收命令请求和发送命令回复->处理命令请求时可能会有新内容被追加到aof_buf缓冲区中->处理时间事件->考虑是否要将缓冲区内容写入和保存到AOF文件之中。
各自的优缺点:
RDB好处:1.方便备份;2.恢复速度比较快;3.可以让redis保持高性能,因为redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可。
RDB不足:1.一旦发生意外,数据丢失比较多;2.文件较大的时候,可能造成阻塞
AOF好处:1.对数据更加友好;2.因为是采用redis协议的格式保存,所有更加让人读懂;3.AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
AOF不足:1.文件更大;2.数据恢复比较慢;
9.redis过期键
过期键的判定:1.检查给定键是否存在于过期字典:如果存在,那么取得过期时间;2.检查当前UNIX时间戳是否大于键的过期时间:如果是的话,那么键已经过期;否则的话,没过期。
过期键的删除策略:
1.定时删除:在设置键的过期时间的同时,创建一个定时器(timer). 让定时器在键的过期时间来临时,立即执行对键的删除操作。
该策略是对内存最友好的:通过定时器,可以保证过期键会尽可能快的被删除,释放占用的内存。但是,当过期键比较多的情况下,可能会占用CPU很多时间。
2.惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
该策略是对CPU时间最友好的,因为在不使用的时候就不会去检查它。与之相反,他是对内存不友好的。当数据比较多的时候,可以看作是一种内存泄漏。
3.定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。
该策略等于是前面两种的一种综合,它的难点是:确定删除操作的时长和频率。操作才频繁就变为定时删除;操作执行太少,就变为了惰性删除。
而redis则采用的是惰性删除和定期删除两种策略。
10.redis事务
redis是通过MULTI、EXEC、WATCH等命令来实现事务功能。事务的阶段一般是:事务开始、命令入队、事务执行。
MULTI命令的开始则标志着事务的开始,当服务器处于事务状态的时候,如果客户端发送的是MULTI、EXEC、WATCH、DISCARD命令,那么立刻执行,反之,则加入到事务队列里面。
事务队列:每个redis客户端都有自己的事务状态,这个事务状态保存在客户端状态的matate属性里面,而事务状态又包含一个事务队列,以及一个已入队命令的计数器(事务队列的长度)。
当一个处于事务状态的客户端向服务器发送EXEC命令的时候,服务器立刻开始遍历这个客户端的事务队列,而后将执行结果返回给客户端。
WHTCH命令的实现:该命令是一个乐观锁,在执行EXEC命令之前监视任意数量的数据库键,如果在EXEC执行期间,发生了键值的修改,那么服务器就拒绝执行此任务,向客户端返回执行失败的回复。怎么判断是否修改呢?通过REDIS_DIRTY_CAS来判断,如果改变,那么就是修改过,如果没有改变,那么就是没有修改过。
redis的ACID与数据库的一致,见MYSQL总结部分。
11.redis集群