为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪offer怀里抱!
这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。
本份面试集锦涵盖了
- 174 道运维工程师面试题
- 128道k8s面试题
- 108道shell脚本面试题
- 200道Linux面试题
- 51道docker面试题
- 35道Jenkis面试题
- 78道MongoDB面试题
- 17道ansible面试题
- 60道dubbo面试题
- 53道kafka面试
- 18道mysql面试题
- 40道nginx面试题
- 77道redis面试题
- 28道zookeeper
总计 1000+ 道面试题, 内容 又全含金量又高
- 174道运维工程师面试题
1、什么是运维?
2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?
3、现在给你三百台服务器,你怎么对他们进行管理?
4、简述raid0 raid1raid5二种工作模式的工作原理及特点
5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?
6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?
7、Tomcat和Resin有什么区别,工作中你怎么选择?
8、什么是中间件?什么是jdk?
9、讲述一下Tomcat8005、8009、8080三个端口的含义?
10、什么叫CDN?
11、什么叫网站灰度发布?
12、简述DNS进行域名解析的过程?
13、RabbitMQ是什么东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
事务日志文件默认存储在dataDir
目录下,因为每次事务请求都是一次磁盘IO操作,事务日志的写入性能直接影响了ZooKeeper
对事务请求的吞吐,为了更高的吞吐和低延迟,建议单独为事务日志配置一个目录dataLogDir
,以免受其他操作影响。
dataLogDir
下会先生成一个子目录version2
,2表示ZooKeeper
日志格式的版本号,同一版本的日志可以互相迁移恢复数据。version2
下才是事务日志文件。
2、文件大小和后缀名
事务日志的文件有两个特点:
-
文件大小出奇一致:都是
67108880KB
,即64MB
。 -
文件名后缀是一串看似有些规律的数字,而且随着修改时间推移呈递增状态。
(1)磁盘空间预分配
文件大小都是64MB
,是因为日志文件的磁盘空间预分配。
事务日志不断追加写入文件的操作会触发底层磁盘IO为文件开辟新的磁盘块,即磁盘Seek,为了避免频繁的文件大小增长带来的磁盘Seek开销,ZooKeeper
在创建事务日志文件时就向操作系统预分配了一块比较大的磁盘块,保证了单一事务日志文件所占用的磁盘块是连续的,以此提升事务的写入性能。默认是64MB
,空闲部分用空字符(\0
)填充。
如果后续检测到文件空间不足4KB
,将扩容再次预分配64MB
,直到创建新的事务日志文件。
(2)ZXID作为后缀名
文件名后面的一串数字是事务ID:ZXID
,并且是写入事务日志文件的第一条事务ZXID
。前面讲了,ZXID
高32位是当前Leader
任期编号,低32位是事务计数器,比如 log.1400000001
、log.1400000003
,都是Leader
任期编号为20时产生的事务日志文件。
3、事务日志可视化
事务日志文件中存放的是二进制格式的数据,不能用vim、cat等工具直接打开,需要用apache-zookeeper-3.7.0
提供的脚本bin/zkTxnLogToolkit.sh
打开:
bin/zkTxnLogToolkit.sh logs/zoo-1/version-2/log.1400000003
一行就是一个事务记录,每行从左到右依次是操作时间、客户端session
ID、CXID
(客户端操作序列号)、ZXID
、操作类型(做了什么),如果操作类型是 createSession
,后面的30000就是session
的超时时间。
4、相关配置项
跟事务日志有关的配置除了dataLogDir
外,还有 preAllocSize
。
(1)dataLogDir
zoo.cfg
中默认没有显式配置dataLogDir
,事务日志和快照日志共享dataDir
。但是强烈建议,单独为事务日志指定dataLogDir
。
事务日志记录对磁盘性能要求极高,为了保证数据一致性,ZooKeeper
在返回客户端请求响应前,必须将本次请求对应的事务日志写入到磁盘中。因此,事务日志写入性能直接决定了ZooKeeper
在处理事务请求时的吞吐。
针对同一块磁盘的其他并发读写操作(如ZooKeeper
运行时日志输出和操作系统自身的读写等),尤其是数据快照操作,会极大影响事务日志的写性能。因此尽量给事务日志的输出配置一个单独的磁盘或是挂载点,极大提高ZooKeeper
整体性能。
(2)preAllocSize
java 系统属性: ZooKeeper.preAllocSize
,从字面意思就可以看出,preAllocSize
是用来配置事务日志文件预先分配文件大小的参数。默认65536
,单位KB
,即64MB
。
5、什么时候创建新日志文件
在进行事务日志写入前,ZooKeeper
会判断是否正在关联一个可写的事务日志文件,如果有则继续追加到该文件中,如果没有就需要创建新的日志文件并关联上。
什么时候ZooKeeper
没有关联上一个可写的事务日志文件呢?有两种情况:
-
ZooKeeper
停止会导致之前关联的事务日志文件断开,重启后第一次事务日志写入,需要创建新的日志文件。 -
上一个事务日志文件写满了(达到阈值,触发了快照之后),需要创建新的日志文件。
需要注意ZooKeeper
服务不要频繁重启,否则会产生很多日志文件,并且有些文件还没有写满,非常浪费磁盘空间。
快照日志是将ZooKeeper
服务器上某个时刻的全量内存数据,写入到指定磁盘文件中。可以这样理解,快照日志文件是存量数据,事务日志文件是增量数据,二者加起来就是最大限度的全量数据。
1、文件存储
和事务日志类似,快照日志存放在dataDir
子目录version2
中,文件名为snapshot.ZXID
,不需要像事务日志文件一样预分配空间。
需要强调快照文件名后缀 ZXID
是触发快照的瞬间,提交的最后一个事务ID。如果是事务ZXID5
触发快照,那么快照文件名就是snapshot.ZXID5
,快照之后的下一个事务的ID是ZXID6
,新的事务日志名就是log.ZXID6
。
在数据恢复阶段,ZooKeeper
可以根据快照文件名后缀ZXID
,确定增量事务日志的起点文件。
2、快照日志可视化
快照日志内容同样也是二进制格式的,需要用 apache-zookeeper-3.7.0
提供的脚本bin/zkSnapShotToolkit.sh
打开:
bin/zkSnapShotToolkit.sh data/zoo-1/version-2/snapshot.1300000000 |less
快照日志记录每个节点的元信息,每个节点从上到下依次为:
-
cZxid
,创建这个节点时的事务ID。 -
ctime
,创建节点时间。 -
mZxid,
最后修改节点的事务ID。 -
mtime,
最后修改节点时间。 -
pZxid,
,该节点最后更新子节点列表的事务ID。 -
cversion
,该节点子节点列表更新版本号,即子节点列表修改次数(不是子节点的值修改)。 -
dataVersion
,节点数据版本号。 -
aclVersion
,节点访问控制列表版本号。 -
ephemeralOwner
,如果为临时节点,则为节点拥有者的sessionID
,如果不是临时节点则为0。 -
dataLength,
,节点数据长度。
3、相关配置
快照日志相关的配置,除了dataLog
,还有snapCount
、autopurge.snapRetainCount
和autopurge.purgeInterval
。
(1)snapCount
java 系统属性: ZooKeeper.snapCount
,默认100,000,表示每写100,000次事务日志,触发一次快照,并滚动事务日志,即切换新的事务日志文件。
但是,实际情况,快照是一个比较好性能的操作。为了防止集群中的所有机器同时触发快照操作,当事务日志中的事务数量达到运行时[ snapCount/2 + 1,snapCount ]
范围内生成的随机值时,该ZooKeeper
服务器就触发一次快照。
(2)日志清理
每一个快照日志文件都是zk集群某个时刻的全量数据快照,理论上只需要最新的一个快照日志文件及其后面的事务日志即可,所以定时清理一些不需要的日志文件以节省磁盘内存资源。
日志的清理跟autopurge.snapRetainCount
和autopurge.purgeInterval
有关。
-
autoburge.snapretaincount
表示保留多少个快照日志文件,如果启动日志清理功能,zk会保留autoburge.snapretaincount
个最近的快照日志文件和dataDir
和dataLogDir
中相应的事务日志文件,并删除其余的。autopurge.snapRetainCount
默认为3,最小也是3。 -
autopurge.purgeInterval
,清理任务触发的小时数时间间隔。设置为正整数(1及以上) ,以启用自动清洗。默认为0不启动。
4、什么时候触发数据快照
触发快照即生成新的快照日志文件有两种情况,事务日志写入数量达到阈值snapCount
和新Leader
同步数据。
(1)事务日志写入数量达到阈值snapCount
每进行一次事务日志记录之后,ZooKeeper
都会判断当前是否需要进行数据快照。前面也说过,理论上进行snapCount
次事务操作后就会触发一次数据快照,但是考虑到数据快照对zk集群的整体性能影响,需要尽量避免所有机器同时进行数据快照。
所以采用过半随机策略,某个ZooKeeper
服务器的事务次数在[ snapCount/2 + 1,snapCount ]
范围内生成的随机值时,触发数据快照。
满足快照条件后,ZooKeeper
先进行事务日志文件的切换,即创建新的事务日志文件,然后再异步进行数据快照操作,尽量不影响正常流程。
(2)新Leader同步数据
运行中的ZooKeeper
集群,如果发生Leader重新选举,新Leader所在机器会检查最近一次快照之后是否有事务日志产生,有就对最近的一次事务之前的全量数据做一次数据快照。
ZooKeeper
服务器启动期间,需要进行数据初始化工作,就是将磁盘中的日志文件加载到ZooKeeper
服务器内存中,主要包括两个过程:从快照日志文件中加载快照数据和根据事务日志进行数据修正。
1、加载并解析快照日志文件
每一个快照日志文件都保存了某个时刻ZooKeeper
服务器全量数据,所以可以加载解析快照日志,先生成一棵DataTree
。
(1)加载最新快照文件
在 ZooKeeper
服务器运行期间,磁盘上会产生一些快照文件。更新时间最晚的那个文件包含了最新的全量数据,那么是否只需要这个最新的快照文件就可以了呢?
在 ZooKeeper
的实现中,会获取最新的至多100个快照文件(如果磁盘上存在不到100个快照文件,那么就获取所有快照文件)。这至多100个快照文件并不是全部都要加载和解析,而是先逐个进行数据正确性校验,校验通过就解析这个文件了,正常解析成功,就不会再向后加载检查。
这样做的目的就是防止某些快照文件损坏,最大力度恢复数据。
(2)解析快照文件
每个快照文件都是内存数据序列化到磁盘的二进制文件,因此需要对其进行反序列化,生成 DataTree
对象。
(3)获取最新ZXID(zxid_for_snap)
最新的快照文件解析成功后,根据该文件名解析出一个最新的ZXID
(zxid_for_snap
),即发生快照最后一次提交事务的ZXID
,找到这个ZXID
有什么用呢?
可以根据这个ZXID
找到快照之后对应的增量事务日志文件,进行数据修正。
2、事务日志进行数据修正
只通过快照日志无法完全恢复数据,还需要根据事务日志进行增量数据修正。
(1)获取zxid_for_snap之后提交的事务
快照日志文件处理完后,可以得到一个zxid_for_snap
,扫描加载文件名后缀大于zxid_for_snap
的事务日志文件,获取在zxid_for_snap
之后提交的所有事务。
(2)数据修正
逐个对zxid_for_snap
之后的事务进行内存同步,修复DataTree
数据。如果该ZooKeeper
服务器是Leader
,
在数据修正的过程中,每当有一个事务同步到内存数据库,就将这一事务记录转换成提议,保存到事务提议缓存队列中,为后续数据同步做准备。
(3)获取最新ZXID校验epoch
epoch
字面意思是纪元、时代,在ZooKeeper
中,epoch
表示当前Leader
任期。每次选举出一个新Leader
后,epoch
在原来基础上加1。
ZooKeeper
集群在运行期间,服务间相互通信都会带上这个epoch
,以确保彼此在同一个Leader
任期内。
待所有的事务日志对数据修正后,获取一个最大的ZXID
,即上次服务器正常运行时最后提交的事务ID。
从最大ZXID
的高32位解析出该事务处理的Leader任期epoch
,同时从磁盘的dataDir/version2
目录下currentEpoch
和acceptedEpoch
文件中读取出最新的epoch
值,进行校验。
3、数据同步
ZooKeeper
服务器重启后,做完日志文件的加载和数据初始化,整个集群完成Leader
选举或者本身就有Leader
,此时,Learner
服务器(Follower
或者Observer
)需要向Leader
服务器进行注册,注册完成后,就进入数据同步阶段,即Leader
服务器上的事务和Learner
服务器的事务做对比,同步或者回滚。
(1)Learner 向 Leader 发送 ACKEPOCH
在注册Learner
最后阶段,Learner
向 Leader
发送一个 ACKEPOCH
数据包,Leader
从这个数据包中解析出该Learner
的 currentEpoch
和 lastZxid
。
(2)Leader 初始化 peerLastZxid、minCommittedLog、maxCommittedLog
在开始数据同步之前,Leader
服务器首先从内存数据库中提取出事务请求对应的提议缓存队列,并完成以下三个ZXID
的初始化:
-
peerLastZxid
,将从Learner
获取的lastZxid
赋值给peerLastZxid
。 -
minCommittedLog
,Leader
服务器提议缓存队列committedLog
中的最小ZXID
。 -
maxCommittedLog
,Leader
服务器提议缓存队列committedLog
中的最大ZXID
。
通过 peerLastZxid
和 minCommittedLog
、maxCommittedLog
比较,有四种数据同步的方式:直接差异化同步(DIFF
)、先回滚再差异化同步(TRUNC+DIFF
)、仅回滚同步(TRUNC
)、全量同步(SNAP
)。
(3.1)直接差异化同步(DIFF)
minCommittedLog < peerLastZxid < maxCommittedLog
(peerLastZxid, maxCommittedLog]
范围内的事务是Learner
没有的,所以只需要Leader
把这个范围内的事务提议发送给这个Learner
同步即可。具体流程如下:
-
Leader
先向这个Learner
发送一个DIFF
指令,用于通知Learner
进入差异化数据同步阶段,Leader
也将把这些差异事务提议同步给自己。 -
对于每条差异事务提议,
Leader
会发送两个数据包给Learner
,分别是PROPOSAL
内容数据包和COMMIT
指令数据包。 -
Leader
发完所有的差异事务提议后,还会发送一个NEWLEADER
指令,用于通知Learner
,已经将所有差异事务提议都同步给自己了。 -
Learner
收到NEWLEADER
指令后,回复一个ACK
消息给Leader
,表明自己已经完成差异化事务的同步。 -
Leader
在接收到来自这个Learner
的ACK
消息后,就认为这个Learner
已经完成了数据同步,同时进入过半等待阶段,即Leader
会和其他Learner
服务器进行上述同样的数据同步流程。 -
直到集群中有过半的
Learner
机器响应了Leader
这个ACK
消息,此时Leader
向所有已经完成数据同步的Learner
发送一个UPTODATE
指令,用来通知Learner
已经完成了数据同步,同时集群中已经有过半机器完成了数据同步。此时集群已经具备了对外服务的能力。 -
Learner
在接收到这个来自Leader
的UPTODATE
指令后,会终止数据同步流程,然后向Leader再次反馈一个ACK
消息。
很明显差异化同步过程和运行时的Leader
与Follower
事务提交一样,都用了两阶段提交。
(3.2)先回滚再差异化同步(TRUNC+DIFF)
minCommittedLog < peerLastZxid < maxCommittedLog
上述直接差异化同步场景存在一种罕见,但是确实存在的特殊场景,peerLastZxid
依然在 minCommittedLog
和 maxCommittedLog
之间,但是peerLastZxid
和minCommittedLog
是同一任期,maxCommittedLog
是另一个任期。
为什么会出现这样的情况?这一定是发生过Leader重选!假设有 A、B、C 三台机器:
-
某一时刻B是Leader服务器,此时的Leader_Epoch为5,同时当前已经被集群中绝大部分机器都提交的
ZXID
包括:0x500000001
和0x500000002
。 -
此时,Leader 正在处理
ZXID: 0x500000003
,并且已经将该事务写入到了 Leader本地事务日志文件,但是还没来得及把该事务提议广播给Follower
,Leader
服务器挂了。所有Follower
上最后一次事务提交还是0x500000002
。 -
还有两台机器,进行
Leader
选举,假设A成为新Leader
,Leader_Epoch+1变更为6。 -
A和C继续对外提供服务,又提交了一个事务
0x600000001
,此时,A的事务提议缓存队列中minCommittedLog
为0x500000001
,maxCommittedLog
为0x600000001
。 -
此时,B 重启,开始数据同步,B最后一次提交事务
peerLastZxid
为0x500000003
,peerLastZxid
在minCommittedLog
和maxCommittedLog
之间,却和现在的Leader
不在同一个任期。 -
对于这个特殊场景,现任Leader没有事务
0x500000003
,B 就使用先回滚再差异化同步(TRUNC+DIFF)的方式。 -
当
Leader
服务器发现某个Learner
包含了一条自己没有的事务记录,那么就在数据同步时让该Learner
进行事务回滚,回滚到Leader
服务器上存在的,同时也是最接近于peerLastZxid
的ZXID
。 -
B先回滚到
ZXID
为0x500000002
的事务记录,然后再进行差异化同步。
(3.3)仅回滚同步(TRUNC)
peerLastZxid > maxCommittedLog
Leader
要求 Learner
回滚到 ZXID
值为 maxCommitedLog
对应的事务操作。
(3.4)全量同步(SNAP)
发生全量同步主要原因是 Leader
服务器上的提议缓存队列不能直接用于和 Learner
进行数据同步,所以只能进行全量同步。
有两种情况,Leader
服务器上的提议缓存队列不可用:
-
peerLastZxid
小于minCommittedLog
。 -
Leader
服务器上的提议缓存队列为空。
所谓全量同步就是 Leader
服务器将本机上的全量内存数据都同步给 Learner
。
1、为什么需要快照日志
通过对事务日志和快照日志基本概念的了解,知道事务日志存的是增量数据,快照日志存的是某个时刻的全量数据,二者合二为一就是最大限度的全量数据。
又通过对ZooKeeper
启动时数据初始化和同步的了解,快照日志可以初步恢复出一个DataTree
,事务日志只是对这棵DataTree
做数据修正。如果没有快照日志都是事务日志,那么数据恢复的过程将非常耗时好性能,每条事务需要重新写入内存数据库,肯定是没有用快照日志反序列化生成一个DataTree
来的快。
2、数据备份策略
理论上,只需要备份最新的一个快照日志文件及其之后产生的事务日志文件即可,但是防止日志文件损坏,可以全量备份,开启了日志清理任务之后,至多保留3个快照文件,也不会很多。
为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪offer怀里抱!
这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。
本份面试集锦涵盖了
- 174 道运维工程师面试题
- 128道k8s面试题
- 108道shell脚本面试题
- 200道Linux面试题
- 51道docker面试题
- 35道Jenkis面试题
- 78道MongoDB面试题
- 17道ansible面试题
- 60道dubbo面试题
- 53道kafka面试
- 18道mysql面试题
- 40道nginx面试题
- 77道redis面试题
- 28道zookeeper
总计 1000+ 道面试题, 内容 又全含金量又高
- 174道运维工程师面试题
1、什么是运维?
2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?
3、现在给你三百台服务器,你怎么对他们进行管理?
4、简述raid0 raid1raid5二种工作模式的工作原理及特点
5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?
6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?
7、Tomcat和Resin有什么区别,工作中你怎么选择?
8、什么是中间件?什么是jdk?
9、讲述一下Tomcat8005、8009、8080三个端口的含义?
10、什么叫CDN?
11、什么叫网站灰度发布?
12、简述DNS进行域名解析的过程?
13、RabbitMQ是什么东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
对他们进行管理?
4、简述raid0 raid1raid5二种工作模式的工作原理及特点
5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?
6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?
7、Tomcat和Resin有什么区别,工作中你怎么选择?
8、什么是中间件?什么是jdk?
9、讲述一下Tomcat8005、8009、8080三个端口的含义?
10、什么叫CDN?
11、什么叫网站灰度发布?
12、简述DNS进行域名解析的过程?
13、RabbitMQ是什么东西?
14、讲一下Keepalived的工作原理?
15、讲述一下LVS三种模式的工作过程?
16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?
17、如何重置mysql root密码?
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!