我们都知道redis是一种缓存数据库,支持事务,持久化(可写入硬盘),LUA脚本,LRU驱动事件,集群
高性能:体现在访问数据是在内存中进行访问,内存访问速度比硬盘的访问速度高3个数量级左右
高并发:因为访问内存的速度很快,所以单位时间能够承受的并发请求数也是 访问硬盘(传统数据库)无法达到的
redis和memcached是分布式缓存,这不同于java中自带的map或者guava实现的本地缓存,虽然map和guava轻量且快速,但是在多主机的集群下面,每个主机(也就是实例)都要各自保存一份缓存数据,且各自的不具有一致性,git上面要求一致性,而redis和memcached是分布式的,各实例公用一份缓存数据,具有一致性。
redis内部使用文件事件处理器file event handler,这个处理器是单线程的,所以redis是单线程的模型。用IO多路复用机制,同时监听多个socket(因为是网络连接)
redis和memcached
- redis支持更丰富的数据类型(string,hash,list,set,zset),相应的操作都可以去菜鸟教程看,而memcached支持简单的数据类型string
- redis支持数据持久化,重启的时候可以加载进行使用,类似于电脑的睡眠,会把内存中的数据先放入硬盘,解除睡眠的时候在放回内存,而memcached只能把数据放在内存
- redis支持cluster模式,支持集群,而memcached没有原生的集群模式
- memcached是多线程,非阻塞IO复用的
String:set,get(就是字符串)
Hash:hget,hset(hash很适合用于存储对象,一个对象可以当成一个字典)-->key:{field1:value1,field2:value2}
List:lpush,rpush,lrange(list实现的是一个双向链表,所以可以反向查找和遍历)
Set:sadd,smembers,spop(set可以过滤重复数据,但是没有顺序,可以用交集,共同喜好)
Sorted Set:zadd,zrange(也可以去重,但是增加了权重参数score,按照score进行排序)
设置过期时间:set key的时候可以设置一个expire,过期了就有两种删除方式
定期删除和惰性删除
- 定期删除:redis默认是每隔100ms就随机抽取一些过期了的key
- 惰性删除:惰性删除就是说定期删除会有许多过期key没有被删除,这些的话就用惰性删除,除非系统去查一下那个key,才会被删除掉,否则还停留在内存中
- 但是惰性删除可能会导致的一种情况是大量过期key没有被删除,而且没有及时去查这个key,那么内存就会严重浪费
缓存
redis是一种缓存数据库,既然是缓存,那么数据就必须是数据库数据的子集,类似的原理还有磁盘缓存,高速缓存
还有就是缓存存在的意义就是加快访问速度,所以要把尽可能多的热点数据放到缓存中,这就涉及到redis的数据淘汰策略
6种数据淘汰策略:前三种是设置了过期时间的,后三种是内存不足的时候,不一定要设置了expiretime
- volatile-LRU:从已经设置过期时间的key中淘汰最近最少未使用的数据
- volatile-TTL:淘汰将要过期的数据
- volatile-RANDOM:随机选取数据淘汰
- allkeys-LRU:内存不足时将最近最久未使用的数据淘汰
- allkeys-RANDOM:随机选取数据淘汰
- no-eviction:不允许淘汰,已经失去了缓存的意义
数据持久化--快照--RDB和只追加文件--AOF
怎么做到redis服务宕了之后重启数据可以进行恢复?--如果数据只能保存在内存中那是无法实现数据恢复的
- 快照:是redis默认的持久化方式,快照是某个时间点上数据的副本,可以在redis.conf配置文件有一些配置,意思是每xx秒内有xx个key改变就进行保存快照
- AOF:实时性更好,通过appendonly yes启动,没执行一条更改redis数据的命令,redis就会将该命令写入AOF文件,默认保存的文件名是appendonly.aof。有三种级别,第二种较好,第一种影响性能,第三种影响数据
- appendfsync always:每次有数据修改
- appendfsync everysec:每秒钟同步一次
- appendfsync no:让操作系统决定何时进行同步
redis事务
支持事务,但是事务不满足ACID四原则
缓存雪崩
缓存同一时间大面积的不命中,所以请求回到数据库中,造成数据库崩掉
缓存穿透
故意访问缓存中不存在的数据导致大量访问数据库