1. 为什么使用redis
1)基于内存;
2)单线程减少上下文切换,同时保证原子性;
3)IO多路复用;
4)高级数据结构(如 SDS、Hash以及跳表等)。
分布式缓存和本地缓存区别
本地缓存:
- 访问速度快,但无法进行大数据存储
- 集群的数据更新问题:本地缓存只支持被该应用进程访问,一般无法被其他应用进程访问,需要同步更新不同部署节点的本地缓存的数据来保证数据一致性,复杂度较高且容易出错,如基于 Redis 的发布订阅机制来同步更新各个部署节点。
- 数据随应用进程的重启而丢失
分布式缓存: - 支持大数据量存储,不受应用进程重启影响
- 数据集中存储,保证数据一致性
- 数据读写分离,高性能,高可用
- 数据跨网络传输,性能低于本地缓存
redis和Memcached的区别
- Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
- Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
- Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;
redis常用数据结构,底层实现和使用场景
ziplist:压缩列表(ziplist) 是 Redis 为了节省内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构。
- String:int、SDS
计数器,存储Json对象 - List:ziplist,linkedlist
消息队列,最新列表 - Set:intset,hashtable
好友、关注、粉丝、感兴趣的人集合 - Hash:ziplist,hashtable
购物车,存储对象 - zset:ziplist,skiplist
排行榜,还可以用来存储学生的成绩
redis过期淘汰策略
定时,定期,惰性,Redis 采用了惰性删除+定期删除
redis持久化机制
RDB,AOF
对比:
- RDB 全量备份,非常适合用于进行备份和灾难恢复
- 生成 RDB 文件时支持异步处理,主进程不需要进行任何磁盘IO操作
- RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
- AOF 可以更好的保护数据不丢失,一般 AOF 隔 1 秒通过一个后台线程执行一次 fsync 操作
- AOF 日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复
redis事务
事务三大指令multi、exec、discard
开启事务,执行事务,取消事务
组队时错误(回滚)和执行命令时错误(不回滚)
redis就是通过CAS(check and set)实现乐观锁,通过watch指令监听一个或者多个key值,当用户提交修改key值的事务时,会检查监听的key是否发生变化。若没有发生变化,则提交成功。
如何理解redis的事务与ACID
- 原子性: redis设计者认为他们是支持原子性的,因为原子性的概念是:所有指令要么全部执行,要么全部不执行。而非一起成功或者失败。
- 一致性: redis事务保证命令失败(组队时出错)的情况下可以回滚,确保了一致性。
- 隔离性: redis是基于单线程的,所以执行指令时不会被其他客户端打断,保证了隔离性。
- 持久性: 持久性的定义为事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。),考虑到性能问题,redis无论rdb还是aof都是异步持久化,所以并不能保证持久性。
缓存击穿,缓存雪崩和缓存穿透,以及解决方法
缓存击穿:(热key问题),当缓存中某个热点数据过期了,在该热点数据重新载入缓存之前,有大量的查询请求穿过缓存,直接查询数据库。这种情况会导致数据库压力瞬间骤增,造成大量请求阻塞,甚至直接挂掉。
- 设置热点数据永不过期
- 使用分布式锁,保证同一时刻只能有一个查询请求重新加载热点数据到缓存中
缓存雪崩:大量key同时过期,Redis 缓存实例发生故障宕机。 - 均匀过期:给热点数据设置不同的过期时间,给每个key的失效时间加一个随机值;
- 设置热点数据永不过期:不设置失效时间,有更新的话,需要更新缓存;
- 服务降级:指服务针对不同的数据采用不同的处理方式:
– 业务访问的是非核心数据,直接返回预定义信息、空值或者报错;
– 业务访问核心数据,则允许访问缓存,如果缓存缺失,可以读取数据库。 - 实现服务熔断或者请求限流机制
- 事前预防:构建 Redis 缓存高可靠集群
缓存穿透:指用户要访问的数据既不在缓存中也不在数据库中 - 接口层增加校验:用户鉴权、参数校验(请求参数是否合法、请求字段是否不存在等等);
- 缓存空值/缺省值:发生缓存穿透时,我们可以在Redis中缓存一个空值或者缺省值(例如,库存缺省值为0),这样就避免了把大量请求发送给数据库处理,保持了数据库的正常运行。这种方法会存在两个问题:
如果有大量的Key穿透,缓存空对象会占用宝贵的内存空间。针对这种情况可以给空对象设置过期时间。
设置过期时间之后,可能会有缓存与数据库不一致的情况。 - 布隆过滤器:快速判断数据是否存在,避免从数据库中查询数据是否存在,减轻数据库压力。由位数组和一系列 hash 函数构成。当使用布隆过滤器添加 key 时,会使用不同的 hash 函数对 key 存储的元素值进行哈希计算,从而会得到多个哈希值。
如何保证缓存和数据库的数据一致性
延迟双删
删除缓存重试机制(mq)
五种IO模型的区别
- 阻塞IO模型
- 非阻塞IO模型:轮询
- IO多路复用模型:进程受阻于select调用
- 信号驱动模型:进程不阻
- 异步IO模型:全程不阻塞,数据由内核复制
IO多路复用机制(select、poll、epoll的区别)
- select 所能监视的文件描述符的数量有限制
- select和poll,采用轮询方式检测就绪事件,epoll采用回调方式
- poll,epoll无最大文件描述符数量的限制。
Redis 有哪些内存淘汰机制
- noenvication:不淘汰,内存不足时,新写入报错
- volatile-lru:在设置了过期时间的,最少使用
- volatile-randon:在设置了过期时间的,随机
- volatile-ttl:在设置了过期时间的,即将要过期的
- volatile-lfu:在设置了过期时间的,使用频率最低
- all-lru:所有的,最少使用
- all-random:所有的,随机
- all-lfu:所有的,使用频率最低
redis集群
- 主从
Redis 的主从结构一主一从,一主多从或级联结构,复制类型可以根据是否是全量而分为全量同步和增量同步。 - 哨兵
哨兵主要用于管理多个 Redis 服务器,主要有以下三个任务:监控、提醒以及故障转移。
在主从复制实现之后,如果想对 master 进行监控,Redis 提供了一种哨兵机制,哨兵的含义就是监控 Redis 系统的运行状态,通过投票机制,从 slave 中选举出新的 master 以保证集群正常运行。
还可以启用多个哨兵进行监控以保证集群足够稳健,这种情况下,哨兵不仅监控主从服务,哨兵之间也会相互监控。 - cluster
其实现原理就是一致性 Hash
hash slot 算法寻址算法