Redis的全拼是Remote Dictionary Server,即远程字典服务
Redis用ANSI C语言编写,完全免费且源代码公开
Redis是一种键值对形式的数据库,而非象MySQL或Oracle这样的关系型数据库
Redis是一个内存型数据库,但也可以借助日志被持久化
Redis提供多种编程语言的API
Redis适用于:
缓存:在Redis中缓存查询结果,减轻MySQL的压力,提高系统性能
排行榜:Redis提供SortSet,即有序集合
用于统计在线人数、访问量、播放量等数据的,计数器或限速器:Redis提供原子化的自增操作
好友关系:Redis提供交、并、差等集合操作,便于实现找到共同好友,发现共同爱好之类的功能
消息队列:Redis提供订阅发布模式
Session:将Session保存在Redis中,无论用户从哪台服务器登录,都能访问Session中的登录信息
Redis不适用于:
数据访问频率很低:访问频率很低数据不必放在Redis里,浪费宝贵的内存资源
数据量很大:数据量太大会增加成本
缓存从数据查询出的数据
支持订阅发布的消息队列
实现分布式锁
实现数据持久化
实现事务机制
字符串:一般情况下,键都是字符串类型,任何形式的值,无论它是XML、JSON、数值、图片,甚或音视频等,都可以被处理为字符串
散列表:不存放键本身,而是将值保存在以键的哈希值作为下标的散列表中,不适合做复杂查询
列表:列表可用于实现缓存或队列,天然满足生产者——消费者模式对同步性的要求
集合:集合中的元素是唯一且无序的,可对单个集合执行增删改查,也可对多个集合求交并补
有序集合:有序集合中的元素是唯一且有序的,元素的顺序取决于人为设置的分值
数据都存放在内存中,却大部分操作都在内存中完成
数据结构简单,对数据的操作也简单
只有一个线程,避免了因上下文切换导致的系统开销,也不存在多线程场景下的竞态和锁问题
借助多路I/O复用模型和非阻塞I/O,解决多用户问题
假设要查询一个数据,缓存中没有,然后查询数据库,数据库中也没有。下次再查这个数据,还是先查缓存再查数据库。对于这种数据库中不存在的数据,每次都要查数据库,缓存并没有起到拦截作用,这就叫缓存穿透
为了避免缓存穿透,可以在查询数据库失败后,于缓存中用一个特殊的标记标识出该键的值不存在。以后在缓存中获知该值不存在,就不必再查询数据库了。这种不存在的值在缓存中的过期时间可以设得短一些,一方面及时释放键值对占用的内存空间,另一方面降低了缓存与存储发生不一致的风险
另一种方法是设置一个布隆过滤器,所有存在的数据都被哈希到布隆过滤器中,而不存在的数据则会被布隆过滤器拦截,从而减轻了数据库的查询压力
缓存中的数据在一小段时间内集中过期失效,导致短时间内的大量查询请求被提交给数据库,这就叫缓存雪崩
避免缓存雪崩的方法有下面几种:
缓存失效后,通过加锁或排队,限制访问数据库的线程数
在缓存数据的同时,为过期时间附加一个随机因数,避免同时过期失效
在数据失效前手动重加载缓存,同时设置不同的过期时间,让缓存失效的时间点尽量均匀分布
一个过期时间较短的原始缓存,一个过期时间较长的拷贝缓存,原始缓存失效时可从拷贝缓存中读取
只要设置了合理的过期时间,就可以令缓存中的数据与数据库中的数据保持一致。因为只要缓存中的数据过期了,就会被删除,迫使下次读取该数据时,必须查询数据库同时写入缓存,二者自然一致
在一个缓存中的数据过期前,其在数据库中的副本被更改了,这时二者会存在短暂的不一致
在对数据库执行增删改操作的事务中,加入同步更新缓存的操作,保证二者在任何时候都是一致的
RDB:按照一定的周期策略,将内存中的数据,以快照的形式,保存到磁盘上的二进制文件中
AOF:每收到一条执行写操作的命令,即将该命令追加到文件末尾,执行该文件中的命令,即可重建数据库
两种持久化方式的对比
AOF比RDB的实时性更好,数据更加安全,通常作为首选方案
RDB比AOF的性能更优越,但安全性略差,通常作为备用方案
Redis工作在单线程模式下,通过队列将并发访问变成串行访问
同时访问Redis服务器的多个客户机,并不存在竞争关系
Redis使用setnx命令实现分布式锁
一个分布式锁在任一时间只能被一个进程占有,直至其被del命令释放,才能被其它等待锁的进程占有
作为内存数据库,当内存空间不足时,为了保证命中率,Redis会因循一套可配置的淘汰策略,淘汰一些数据
no-enviction:不淘汰任何数据,默认策略
volatile-lru:淘汰最近最少使用的,已设置过期时间的数据
volatile-ttl:淘汰即将过期的,已设置过期时间的数据
volatile-random:淘汰随机选择的,已设置过期时间的数据
allkeys-lru:淘汰最近最少使⽤的数据
allkeys-random:淘汰随机选择的数据
主服务器不做持久化,从服务器以RDB方式备份,每秒一次
主从服务器最好位于同一个局域网内,以保证主从复制的速度和稳定性
主从服务器的拓扑结构不要呈图状,单向链表结构为宜,如:主服务器