redis由Antirez开发出来的: ?? ?在redis还未出来的时候,我们所有的查询操作都是通过直接对mysql查询,设计之初数据较少还好,后来因为互联网的发展它容纳的数据也越来越多,用户请求也随之暴涨,而每一个用户对数据的请求的也成了直接对mysql的读写,这样势必会在大批次请求时出现数据库雪崩的情况,这也就是我们说的,数据库雪崩的时候没有一片雪花是无辜的; ?? ?后来redis创始人发现数据库的一大半请求也都是基本的读写操作,尤其是其中很大一部分就是重复的查询,浪费了很多时间去进行磁盘的I/O(读写);于是他就开始琢磨是不是可以学习CPU给数据库也加一个缓存的功能,于是redis就诞生了; ?? ?redis:应用程序在mysql查询到的数据都要在redis登记(存储)一下,后边在需要用的时候就直接从redis读取,如果redis没有这个数据再从mysql查询,redis支持的数据结构有:string、hash、list、set、sortedset、bitmap等等;redis是一个内存数据库, 所有数据基本上都存在于内存当中, 会定时以追加或者快照的方式刷新到硬盘中. 由于redis是一个内存数据库, 所以读取写入的速度是非常快的, 所以经常被用来做数据, 页面等的缓存。有了redis的加入mysql的压力就减轻了不少了。
缓存过期 && 缓存淘汰: ?? ?redis将数据存储到内存当中确实是一个好点子,但是随着数据的刷新和增加,慢慢的就发现了一个问题;它所缓存的的数据都是在内存当中,可就算是服务器也不能这么无节制的的存储下去...于是redis就想到一个办法,那就是在存储数据的时候将数据设置一个时间,在时间到了之后就将它从redis中删去及时腾出空间,然后将这个设置时间的权限交给程序们,超时时间是有了,那怎么去删除数据呢? ?? ?最简单来说就是让redis每过一定时间扫描内部数据,然后揪出过期的数据将他给删除掉,可是很快redis就考虑到了,如果有很大的数据量的话每扫描一遍可能就要花费不少时间,可能还会影响到存储数据,于是redis就将数据信息进行一定时间的随机扫描,被随机到的数据如果发现过期就会被删除掉。可是很快我们就发现,由于每次随机的数据可能会和存储的数据不成正比,有些数据就会幸免于难,这样势必会造成一部分过期数据因为幸运未被扫描到然后每次删除也没有他,那他就会长期占用资源。
于是redis在原来定期删除的基础上,又加了一招:
那些原来逃脱redis随机选择算法的键值,一旦遇到查询请求,被redis发现已经超期了,那redis就绝不客气,立即删除。
这种方式因为是被动式触发的,不查询就不会发生,所以也叫惰性删除!
可是,还是有部分键值,既逃脱了我的随机选择算法,又一直没有被查询,导致它们一直逍遥法外!而于此同时,redis可以使用的内存空间却越来越少。
而且就算退一步讲,redis能够把过期的数据都删除掉,那万一过期时间设置的很长,还没等到redis去清理,内存就吃满了,一样要吃枣药丸,所以redis还得想个办法。
redis苦思良久,终于憋出了个大招:内存淘汰策略,这一次我要彻底解决问题!
redis提供了8种策略供应用程序选择,用于redis遇到内存不足时该如何决策:
-
noeviction:返回错误,不会删除任何键值 -
allkeys-lru:使用LRU算法删除最近最少使用的键值 -
volatile-lru:使用LRU算法从设置了过期时间的键集合中删除最近最少使用的键值 -
allkeys-random:从所有key随机删除 -
volatile-random:从设置了过期时间的键的集合中随机删除 -
volatile-ttl:从设置了过期时间的键中删除剩余时间最短的键 -
volatile-lfu:从配置了过期时间的键中删除使用频率最少的键 -
allkeys-lfu:从所有键中删除使用频率最少的键
? ? 我们在不同的应用场景使用不同的策略组合搭配就可以解决问题啦; ?
|