Redis是一个key-value型的数据库(相比较之下,MySQL是关联数据库),也就是说,一个key对应一个value,这是保证高效的手段之一。另外,Redis的全部数据在使用时都存放在内存中。2021Java面试宝典mysql
这包含了两层含义:面试
单台Redis能存放多少数据,取决于其内存的大小(假设全部内存都给Redis用)。若是须要存放更多数据,能够增长内存或作集群。redis
可是,不会直接对磁盘进行读写。这种持久化,通常是用于在服务器重启时,先把数据持久化,重启后再从磁盘中读取到内存。spring
Redis支持五种数据结构,分别是String,List,Hash,Set,Zset。即字符串,列表,哈希,集合,有序集合。sql
String是Redis最基本的类型,一个key对应一个value。数据库
通常状况下,大部分的内容均可以经过序列化后,再存在到Redis中,好比图片或对象等。每一个key对就的value存储的内容最大为512M。数组
Hash即哈希表,即key-value对集合。缓存
是否是很奇怪?Redis的数据自己不就是key-value型的吗?其实不奇怪。咱们这里在说数据结构的时候,单指的是key-value中的value。也就是说,value是一个key-value对集合。想象一下这种数据结构,特别适合存储对象。而且,Redis支持像数据库中update同样,单独修改对象的某个属性。服务器
List即列表。数据结构
value是一个字符串的列表。也就是说,一个value能够存放多个字符串,能够按照顺序,添加到头或尾。它就是一个双向链表。很适合作如朋友圈动态列表或消息队列等。
Set即集合。
它的value和列表的value同样,也是一个字符串列表,只是Set是无序的,而且,value中的元素是不重复的。和Java中的Set差很少,它的基础原理也是基于Hash实现的,因此添加、删除、查找等的效率等都很快。Redis还为Set提供了多个集合操做的API,如交集、并集、差集等。能够利用来作统计,有多少个共同好友等。
Zset即有序集合。
它在Set的基础上,给value中的每一个字符串关联了一个score属性,即得分。Zset经过计算得分,将字符串进行从小到大的排序。字符串的得分能够相同。Zset的排序是在插入时直接就作好的。能够用来作排行榜等。
热点数据(常常会被查询,可是不常常被修改或者删除的数据),首选是使用redis缓存,毕竟强大到冒泡的QPS和极强的稳定性不是全部相似工具都有的,并且相比于memcached还提供了丰富的数据类型可使用,另外,内存中的数据也提供了AOF和RDB等持久化机制能够选择,要冷、热的仍是忽冷忽热的均可选。
结合具体应用须要注意一下:不少人用spring的AOP来构建redis缓存的自动生产和清除,过程通常以下:step1-> Select 数据库前查询redis,有的话使用redis数据,放弃select 数据库,没有就select 数据库,而后将数据插入redis; srep2-> update或者delete数据库钱,查询redis是否存在该数据,存在的话先删除redis中数据,而后再update或者delete数据库中的数据。 这种操做,若是并发量很小的状况下基本没问题,可是高并发的状况请注意下面场景:
为了update先删掉了redis中的该数据,这时候另外一个线程执行查询,发现redis中没有,瞬间执行了查询SQL,而且插入到redis中一条数据,回到刚才那个update语句,这个悲催的线程压根不知道刚才那个该死的select线程犯了一个弥天大错!因而这个redis中的错误数据就永远的存在了下去,直到下一个update或者delete。
诸如统计点击数等应用。因为单线程,能够避免并发问题,保证不会出错,并且100%毫秒级性能。
至关于消息系统,与ActiveMQ,RocketMQ等工具相似,可是以为简单用一下还行,若是对于数据一致性要求高的话仍是用RocketMQ等专业系统。
因为redis把数据添加到队列是返回添加元素在队列的第几位,因此能够作判断用户是第几个访问这种业务。队列不只能够把并发请求变成串行,而且还能够作队列或者栈使用。
用于数据量上亿的场景下,例如几亿用户系统的签到,去重登陆次数统计,某用户是否在线状态等等。腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,能怎么作?
千万别说给每一个用户创建一个key,而后挨个记(你能够算一下须要的内存会很恐怖,并且这种相似的需求不少。这里要用到位操做——使用setbit、getbit、bitcount命令。原理是:
redis内构建一个足够长的数组,每一个数组元素只能是0和1两个值,而后这个数组的下标index用来表示用户id(必须是数字哈),那么很显然,这个几亿长的大数组就能经过下标和元素值(0和1)来构建一个记忆系统。
例如新闻列表页面的最新的新闻列表,若是总数量很大的状况下,尽可能不要使用select a from A limit 10这种low货,尝试redis的 LPUSH命令构建List,一个个顺序都塞进去就能够啦。不过万一内存清掉了咋办?也简单,查询不到存储key的话,用mysql查询而且初始化一个List到redis中就行了。2021Java面试宝典