八股文五(Redis、Nginx、Docker)

Redis篇

常用术语有哪些

UA   客户ip
PV   浏览量
DAU  日活跃用户量
MAU  月活跃用户量

Redis的基本类型有哪些 *

字符串、List、Hash、Set、ZSet、bitmap(用于位图)、HyperLogLog、GEO(地图)、Stream(消息队列)、Redis位域
-----------
字符串使用场景:(对某文章进行点赞,取消点赞)
INCR [key]  对某key+1  
DECR [key]  对某key-1
-----------
Hash使用场景:(小型购物车,不适合高并发)
创建key:用户id  商品id 数量  例子:该用户的 某个商品id,数量1
-----------
List使用场景:(订阅公众号,公众号发文章会进行推送)
该key:用户id 文章id 文章id2 文章id3
-----------
Set使用场景:
它有这些方法:
添加元素、删除元素、获取全部元素、判断元素是否在集合中、获取集合中个数、从集合中弹出一个元素,并不删除、从集合中弹出一个元素,并删除
集合运算:差集 A集合-B集合、交集、并集
场景1:微信抽奖 - 从集合中弹出一个元素,并删除
场景2:朋友圈看自己的点赞数 - key集合:点赞用户1 点赞用户2 点赞用户3
场景3:求共同好友 - 两个集合求并集
-----------
Zset使用场景:(定义商品的排行榜)
创建key  商品id 銷量  商品id2 銷量2 (每个商品的销量排序)

Redis除了做缓存,还可以用来做什么

GEO地图、ZSet适合做排行榜、分布式事务、消息队列(Stream流)、基数统计(HyperLogLog)

缓存预热、缓存雪崩、缓存穿透、缓存击穿是什么 *

缓存预热:程序上线后,将一些mysql的数据,加载到缓存中,避免上线后,客户大量访问mysql,造成服务器压力;
缓存雪崩:可能是Redis服务挂了或者Redis中的key大量同时失效
解决:Redis部署集群、或者哨兵模式、Redis中的key过期时间分散过期处理、增加本地缓存(ehcache)+Redis缓存、服务降级、限流;
缓存穿透:就是客户端查询大量不存在的数据,大量的请求会造成服务器压力;
解决:先查询Redis,Redis中没有话话,查询Mysql,mysql如果没有,把没有的值更新到Redis中,下次查询直接走Redis,不会到Mysql层;	如果有恶心攻击也会有问题,需要使用过滤器进行过滤,比如:布隆过滤器Guava,进行白名单过滤。
缓存击穿:大量请求的过程中,其中一个key过期,造成大量查询数据库,压力过大,一般这种情况都是热点;
解决:key设置永不过期、在查询到过程,使用双重检测,只有一条请求查询数据库,其他都在自选等待、
使用差异失效时间,有2块缓存,A缓存和B缓存,更新B缓存再更新A缓存,查询先查A缓存,没有再查B缓存。

如何保证缓存和数据库的一致性 *

缓存同步策略:
1 设置过期时间段key,到期后,会查询最新数据库同步到缓存中。
2 同步双写,缓存和数据强一致,数据一致性得到保障,缺点:大量查询命中缓存会很低。
3 异步通知,监控数据库,一旦数据库的数据发生改变,同步到缓存中,如Canal

过程会产生的问题:
就是当key失效,大量的请求查询数据,此时判断有没有缓存,都会判断没有缓存,会大量查询数据库,造成数据库压力
解决:采用双检加锁策略
更新或者删除操作,对缓存进行延迟双删:
先删除缓存key,更新数据库,再删除缓存到key
延迟双删的目的:A线程查询(查询缓存,如果缓存不存在,查询数据库),B删除更新(先删除缓存)
然后,修改操作,先更新数据库后删除缓存
肯能存在更新失败,可以采用延时删除。但由于读比写快,发生这一情况概率较小。
但是无论哪种策略,都可能存在删除失败的问题,解决方案是用中间件canal订阅binlog日志提取需要删除的key,然后另写一段非业务代码去获取key并尝试删除,若删除失败就把删除失败的key发送到消息队列,然后进行删除重试

什么是布隆过滤器

它是一个bit数组,然后多次hash,用来判断集合中是否存在该元素。
底层利用hash函数,2个对象hash值相等,两个对象可能是一样的,hash值不相等肯定不是同一个对象。
优点:存储空间小,快读判断该元素存不存在
缺点:因为它底层是利用hash,初始数组是固定的,不容易扩容或者删除元素,如整体结构变化,需要重构数组。

Redis为什么快 *

1 因为Redis是基于内存的数据库,操作内存速到更快,像Mysql数据最终存在磁盘中,从磁盘读取,而Redis是直接从内存读取
2 Redis是单线程,这样就也解决了并发线程安全问题,单线程的好处,避免了CPU频繁切换上下文,它的单线程也是工作命令的单线程
3 Redis的数据接口,都是基于键值对形式,根据key立马找到对应的value
4 还有IO多路复用,这个跟Nginx一样,它使用一个线程去处理多个输入、输出流,避免多线程的CPU上下文切换
就是Redis的瓶颈不是CPU,而是内存

IO多路复用是什么

它是用一个线程进行监听多个输入、输出流,谁有数据去处理谁,它并不是为每个输入、输出流创建独立的线程,去处理任务,一个线程可以监听多个描述符(socket)。
例子:老师收学生们的作业
同步阻塞情况:老师收A学生作业、再收B学生作业,如果C学生不交作业,会阻塞,D学生就等待
同步非阻塞情况:老师收A学生作业、再收B学生作业,如果C学生不交作业,进行跳过,收D学生的作业,缺点:如果每个学生都不交,老师走一圈白走
select/poll:老师收作业,学生会举手,老师会问每个学生有没有做完,做完进行收,没有做完不处理,缺点:老师需要询问一遍
epoll:学生举手,谁举手老师去收谁的作业

什么是Redis持久化

就是将Redis里的数据存到磁盘中,进行持久化操作

Redis有哪几种持久化方式 *

AOF:它是以操作日志的方式记录,
优点:数据丢失概率小,适合做紧急恢复数据,缺点:恢复数据慢、数据大小大于RDB
RDB:它是制定时间间隔,将数据进行备份,也就是快照,会生成rdb后缀的文件,也是默认的方式
优点:比AOF快,适合大规模数据恢复,缺点:并不是实时的,会存在数据丢失
RDB - AOF混合持久化
rdb做存量,aof做当量;

Redis有哪几种淘汰策略 *

默认的内存是没有限制,默认的策略是不删除,生产环境内存是物理内存的4分之3,避免OOM
淘汰策略有8种
1 不删除(默认)
2 随机删除key
3 随机删除设置过期的key
4 马上删除过期的key
5 对所有的key进行LRU算法进行删除(推荐,默认优先删除不经常使用的key)
6 对设置过期的key进行LRU算法进行删除
7 对所有的key进行LFU算法进行删除
8 对设置过期的key进行LFU算法进行删除
...
对过期的key删除,一般我会使用惰性删除+定期删除
马上删除(马上进行删除,占CPU)
惰性删除(什么时候访问该key,什么时候判断是否过期,是否要删除,占内存)
定期删除(定期抽查进行删除,会存在漏删)

如果一个键是过期的,它到了过期时间,是马上从内存删除吗

不是马上,默认情况使用定期删除,这样对CPU比较友好

什么是LRU算法,LFU算法

LRU:就是最长时间没有被使用的(最长时间)
LFU:就是一段时间内,使用次数最少的(最少的次)

实现LRU算法

/**
 * lru 算法
 */
public class Lru<K,V> extends LinkedHashMap<K,V> {

    // 坑位
    private int capacity;

    public Lru(int capacity) {
        // true 代表,如果重复会刷新,会在队列最右端,最后一个出, 如果是false,保持不变
        super(capacity, 0.75f, true);
        this.capacity = capacity;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return super.size() > capacity;
    }

    public static void main(String[] args) {
        Lru l = new Lru(3);
        l.put(1, "aa");
        l.put(2, "bb");
        l.put(3, "cc");
        System.out.println(l.keySet()); //[1, 2, 3]
        l.put(4, "dd");
        l.put(5, "ee");
        l.put(5, "ee");
        System.out.println(l.keySet()); //[3, 4, 5]
        l.put(6, "ff");
        System.out.println(l.keySet()); //[4, 5, 6]
        l.put(5, "ee");
        l.put(5, "ee");
        System.out.println(l.keySet()); //[4, 6, 5]
        l.put(7, "gg");
        System.out.println(l.keySet()); //[6, 5, 7]
    }

Redis 集群方案应该怎么做 *

1.哨兵模式:
一般哨兵至少需要3台机器(1台主机,2台从机)如果有主机挂了,会重新选举出新的主机
注意事项:需要配置主从复制、缺点:就是重新选举的时候,会存在丢数据
2.集群配置
一般需要3台主机,3台从机,一个客户端请求会根据槽位定位算法,得出去访问哪台Redis上
(根据哈希槽分区,将一些数据存在不同的Redis主机上,方便扩容)

什么情况会导致集群不可用

例:A、B、C Redis主机,其中B主机挂了,B主机会少一些槽点,某些请求访问不到Redis数据,
默认情况,集群不完整,是不会对外进行访问,可以通过配置文件改。

MySQL里有2000w 数据,redis中只存20w的数据,如何保证 redis 中的数据都是热点数据

可以使用Redis的淘汰策略,不经常使用带key,优先删除掉。

使用过Redis分布式锁么,它是怎么实现的 *

redis中有setnx 它就是分布式锁,它的底层思想是,判断key键值是否存在,不存在给一个定值,如果存在,不执行任何操作,返回1(成功),0(失败)
这个可以在中小项目中使用,这里是有缺陷的
比如:
1 没有加过期时间,如果服务A加锁,后服务挂了,锁一致保持,其他线程肯定进不来,(加过期时间可解决,并且只能删除自己的锁,其它线程删除不了)
2 还有问题,因为加锁和删除,2个指令不是原子性命令,所以需要lua脚本,来保证原子性
3 还有问题,比如我们本地锁,Lock、synchronized他们都是可重入锁,Redis的setnx肯定不支持可重入的概念,需要改成(加锁,解锁需要原子性,可重入锁、看门狗机制,自动续期)可以使用Redisson解决,也可以解决Redis集群模式造成锁丢失

Redis 哈希槽的概念

它是一个数组,它增加了一层哈希槽,一个集群有16384个槽,这些槽会分配给集群中的所有主节点

Redis 集群会有写操作丢失吗?

会丢失,因为Redis 并不能保证数据的强一致性,并且数据复制是异步复制
例子:A、B、C主机,B挂了,此时,C主机有写操作,然后重新选举进行分槽,此时C主机挂了,刚才C主机刚才写操作会丢。

Redis 中的管道有什么用

管道是一次性将多条指令发送服务端,适合做批量的操作

怎么理解 Redis 事务

Redis的单线程,一个命令执行完再执行下一个命令,所以具有原子性,不用担心,我更改一个值,同时间有其他线程也更改了值。
然后它的事务,就是相当于序列化,变成一组命令,当一组命令执行完,代表该事务完成。(保证那么这组命令都成功,或者都失败,不会一部分成功,一部分失败)
但Redis没有回滚,只能保证成功或者失败

常用的 Redis 优化手段有哪些

1 合理利用Redis的数据结构进行存数据,将string类型控制在10kb、hash、list、set、zset个数不超过5000
2 限制 Redis 内存大小,避免出现OOM,使用适当的淘汰策略
3 不要与CPU密集型应用部署在一起
4 避免大量数据同时失效
5 生产环境禁止使用 keys 命令,避免查询大key
  当key很庞大的时候,进行使用key * 命令,使用其他命令,如游标
6 有删除操作,使用异步删除的方式,避免阻塞主线程,配置文件可以配置,为非阻塞删除

Nginx篇

什么是Nginx

它是高性能的反向代理Web服务器,可以实现动静分离、负载均衡、web缓存、节省宽带:支持GZIP压缩,可以添加浏览器本地缓存
优点:它稳定性好,很少宕机、并发能力强(官网检测可支持5万个并发连接数)

为什么Nginx性能这么高 *

1 异步非阻塞
它跟Redis一样,使用I/O多路复用,它分为一个主进程,多个工作进程,每个工作进程可以处理多个请求,每进来一个请求,会有一个worker进程去处理,属于网络io密集型。异步非阻塞事件处理机制:运用了epoll模型,可处理2-3万并发连接数;
用一个线程进行监听,谁有请求,就处理谁的回调方法,这样也避免了多线程直接上下文切换。
之前,客户端和服务端进行连接,一个连接就是一个socket,会创建一个线程,客户端请求,然后该线程处理,处理完返回给该客户端,Apache就是这样多线程,进行分配线程。
它是用一个线程进行监听多个输入、输出流,谁有数据去处理谁,它并不是为每个输入、输出流创建独立的线程,去处理任务,一个线程可以监听多个描述符(socket)。
例子:老师收学生们的作业
同步阻塞情况:老师收A学生作业、再收B学生作业,如果C学生不交作业,会阻塞,D学生就等待
同步非阻塞情况:老师收A学生作业、再收B学生作业,如果C学生不交作业,进行跳过,收D学生的作业,缺点:如果每个学生都不交,老师走一圈白走
select/poll:老师收作业,学生会举手,老师会问每个学生有没有做完,做完进行收,没有做完不处理,缺点:老师需要询问一遍
epoll:学生举手,谁举手老师去收谁的作业

什么是正向代理和反向代理

正向代理:客户端1发送请求给服务端1,中间没有中介接入
反向代理:客户端1发送请求给Nginx,Nginx内部根据一些规则,发送给服务端1
优点:多一层,也更加安全

location的作用是什么

是根据用户请求的url来执行不同的应用,匹配对应的location模块。
例:
    #优先级1,精确匹配,根路径
    location =/ {
    	return 400;
    }

    #优先级2,以某个字符串开头,以av开头的,优先匹配这里,区分大小写
    location ^~ /av {
       root /data/av/;
    }

    #优先级3,区分大小写的正则匹配,匹配/media*****路径
    location ~ /media {
          alias /data/static/;
    }

为什么要做动静分离

Nginx是当下最热的Web容器,一般前端静态资源都放在Nginx储存,静态的请求静态文件,动态请求后端服务地址。Nginx还可以对一些静态文件进行压缩传输。
之前用户请求 - Nginx - 后端服务器,(返回前端静态文件,现在只有动态会这么走)
现在用户请求 - Nginx (返回前端静态文件)

Nginx负载均衡的算法有哪些

默认是轮询、权重(权重越大访问概率越大)、ip_hash(IP绑定)、url_hash(对所有的url进行hash得出结构分配服务)、least_conn (最小连接数)

Nginx配置高可用性怎么配置

如果生产环境只有一台Nginx,当它挂了,整个服务都不能访问了,需要搭建集群配置
在小项目中,可以一台Nginx转发到多台Nginx机器上,Nginx挂掉概率很小
在大项目中,我们准备2台Nginx,分别安装keepalived服务,进行配置对应的keepalived.conf配置文件,其中一台配置主机,另一台就是备机
我们还需要写一个shell脚本,Nginx服务与keepalived进行绑定。
在keepalived这边,它提供一个虚拟IP(VIP),2台Nginx有真实的IP地址,当其中Nginx挂掉,会在shell脚本这里逻辑,一般都是尝试重启,如果失败,会杀掉当前keepalived的进程,另一台的keepalived,它的把当前的(VIP)切换到当前的Nginx的主机ip上,备机就上位,如果有多台Nginx,会根据keepalived的配置文件配置的选举概率选中其中一台。

Docker篇

什么是 Docker 容器

容器是基于镜像创建的运行实例,如:mysql容器、Redis容器

什么是 DockerFile

Dockerfile 是用来构建Docker镜像文件,是由一条条构建镜像所需的指令构成的脚本。

虚拟化和容器化有什么区别

虚拟化::是一个物理服务器上运行多个操作系统,如VM
容器化: 是提供了一个独立的环境来运行我们的应用程序

Docker虚悬镜像是什么?

仓库名和标签都是空的镜像,就是虚悬镜像,我们需要删除掉。

Dockerfile 中的RUN和CMD的区别:

CMD:可以有多个CMD,但只有最后一个会生效,相当于是在docker run时运行
RUN:可以执行shell的脚本,相当于在docker build时运行,例子:RUN yum -y install vim
<think>嗯,用户想了解运维工程师的八股文,也就是面试中常见的问题和知识点。首先,我需要确定运维工程师的核心领域,比如基础概念、网络、操作系统、数据库、中间件、监控、自动化、云计算、安全、故障处理等。然后分门别类整理常见问题,确保覆盖全面。 基础部分可能包括运维职责、DevOps、CI/CD的区别,还有Linux常用命令,比如进程管理、日志查看、权限设置。网络方面,TCP/IP模型、三次握手、四次挥手,以及HTTP和HTTPS的区别都是常问的。还有防火墙配置,比如iptables和firewalld,可能需要解释它们的区别和使用场景。 操作系统方面,用户可能想知道进程和线程的区别,内存管理,比如虚拟内存和Swap空间,以及文件系统相关的问题,比如inode的作用。Shell脚本也是重点,比如如何编写备份脚本或处理文本数据。 数据库部分,SQL优化、备份恢复、主从复制和分库分表策略都是常见问题。中间件如Nginx和Tomcat的配置优化,负载均衡算法也需要涵盖。 监控工具如Zabbix、Prometheus,以及日志分析工具ELK栈,可能需要解释它们的原理和使用方法。自动化方面,Ansible、SaltStack、Jenkins的用法,还有容器技术如Docker和Kubernetes的基础知识,包括核心组件和网络模型。 云计算部分,AWS、阿里云等常见服务的运维操作,比如ECS、VPC、S3,以及IaC工具Terraform。安全方面,防火墙策略、漏洞扫描、DDoS防护措施,以及HTTPS的配置步骤。 故障处理需要实际案例,比如服务器崩溃或数据库响应慢的诊断流程。软技能如沟通和压力应对也可能被问到。 在整理这些内容时,要确保每个知识点简明扼要,重点突出。可能还需要注意最近的技术趋势,比如云原生和微服务,以及运维工程师向SRE角色的转变。另外,要提醒用户结合项目经验准备,用实际例子展示能力。最后,保持结构清晰,分点说明,方便用户理解和复习。</think>以下为运维工程师面试常见知识点("八股文")的体系化整理,内容覆盖基础概念与高频问题,供参考学习: --- ### 一、基础概念篇 1. **运维核心职责** - 保障系统稳定性(SLA 99.9%/99.99%)、自动化部署、监控告警、容量规划、故障恢复等 - DevOps核心思想:开发与运维协同,CI/CD流水线实现快速交付 2. **Linux基础** - 常用命令: ```bash ps aux | grep nginx # 查看进程 netstat -tunlp # 查看端口占用 lsof -i :8080 # 定位端口进程 ``` - 日志分析:`grep "ERROR" /var/log/app.log | awk '{print $3}' | sort | uniq -c` - 权限管理:`chmod 755 script.sh`(rwx权限计算) --- ### 二、网络与协议篇 1. **TCP/IP模型** - 三次握手过程:SYN → SYN-ACK → ACK - 四次挥手:FIN → ACK → FIN → ACK(TIME_WAIT状态作用) - **HTTP vs HTTPS**:SSL/TLS加密层、端口80 vs 443、证书机制 2. **防火墙与安全组** - iptables四表链:`iptables -A INPUT -p tcp --dport 22 -j ACCEPT` - 云平台安全组配置(如AWS Security Group、阿里云ECS安全组) --- ### 三、操作系统篇 1. **进程与线程** - 进程间通信方式:管道、信号、共享内存、Socket - 内存管理:虚拟内存机制、Swap空间设置原则 2. **文件系统** - inode结构:存储文件元数据(权限、时间戳、数据块指针) - 磁盘I/O优化:`noatime`挂载选项、RAID级别选择(RAID 0/1/5/10) --- ### 四、数据库篇 1. **MySQL高频问题** - 索引优化:B+树结构、最左前缀原则、覆盖索引 - 主从复制原理:binlog格式(ROW/STATEMENT)、半同步复制 - 慢查询分析:`EXPLAIN`执行计划、`slow_query_log`配置 2. **Redis核心知识点** - 持久化机制:RDB快照 vs AOF日志 - 缓存穿透/雪崩解决方案:布隆过滤器、随机过期时间 --- ### 、监控与自动化篇 1. **监控体系** - 分层监控:硬件层(Zabbix)、应用层(Prometheus+Granfana)、日志层(ELK) - 关键指标:CPU利用率、磁盘IOPS、网络丢包率、JVM GC时间 2. **自动化工具** - Ansible核心概念:Inventory文件、Playbook YAML语法 - 示例任务:批量部署Nginx ```yaml - hosts: webservers tasks: - name: Install nginx apt: name=nginx state=present ``` --- ### 六、云计算与容器篇 1. **Docker核心** - 镜像分层原理、Dockerfile最佳实践(多阶段构建) - 网络模式:bridge/host/none的区别 2. **Kubernetes架构** - 核心组件:API Server、etcd、kubelet、Controller Manager - Service类型:ClusterIP、NodePort、LoadBalancer --- ### 七、故障排查思路 1. **通用方法论** - 定位流程:监控指标 → 日志分析 → 复现验证 → 修复验证 - 经典案例: - CPU飙高:`top → pidstat -p <PID> 1 3 → jstack` - 磁盘满:`df -h → du -sh * → lsof | grep deleted` --- ### 八、趋势与进阶方向 1. **云原生技术栈** - Service Mesh(Istio)、Serverless架构(AWS Lambda) 2. **SRE(站点可靠性工程)** - 错误预算(Error Budget)、SLI/SLO定义 --- **建议学习路径**: 1. 夯实Linux/网络基础 → 2. 掌握1-2种监控/自动化工具 → 3. 深入理解至少一个公有云平台 → 4. 参与实际故障演练 注:面试时需结合项目经验,用`STAR法则`(情境-任务-行动-结果)描述实际问题解决过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值