博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[面试] 找实习面试时问到的跟项目、分布式和数据库有关的问题
阅读量:2342 次
发布时间:2019-05-10

本文共 5653 字,大约阅读时间需要 18 分钟。

kubernetes:

kubernetes的体系结构,master上的三大进程和作用,node上的三大进程和作用;

服务发现和负载均衡,任务调度都怎么实现的;

k8s网络模型:

Flannel:

数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。

Flannel通过Etcd服务维护了一张节点间的路由表,详细记录了各节点子网网段 。

源主机的flanneld服务将原本的数据内容(TCP数据)UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一样的由docker0路由到达目标容器。

原始数据是在起始节点的Flannel服务上进行UDP封装的,投递到目的节点后就被另一端的Flannel服务还原成了原始的数据包,两边的Docker服务都感觉不到这个过程的存在。

openvswitch:

实现了虚拟交换机,可以把虚拟网卡和虚拟交换机的端口连接,这样一个交换机下的多个网卡网络就打通了,类似Linux Bridge的功能。在此之上,OVS很重要的一点就是支持OpenFlow,这是一种可编程的流量控制语言,可以方便我们以编程的方式对流量进行控制,例如转发,拒绝,更改包信息,NAT,QoS 等等。此外OVS还支持多种网络流量监控的协议,方便我们可视化监控并跟踪整个虚拟网络的流量情况。

但是,OVS只是一个单机软件,它并没有集群的信息,自己无法了解整个集群的虚拟网络状况,也就无法只通过自己来构建集群规模的虚拟网络。这就好比是单机的Docker,而OVN就相当于是OVS的Kubernetes,它提供了一个集中式的OVS控制器。这样可以从集群角度对整个网络设施进行编排。

OVS方案与基于三层交换机方案对比,各有什么优缺点?

OVS最大的优点在于可编程,灵活性比较好。虚拟网络不用手动插网线,而且有OpenFlow加持,可以实现一些普通交换机无法实现的流量控制。物理交换机的主要有点就是性能好,而且比较稳定,不容易出问题。


分布式锁:

1. 基于数据库的表级锁

3. 数据库的排它锁-行级锁

4. Redis的RedLock算法:

每个单机上的锁是通过添加一条有过期时间的记录(key要锁的资源-value线程的唯一标识)来维护的,分布式的RedLock要获取超过一半的master节点上的单机锁,如果失败就再去所有master上删除记录。为了防止删了别的线程创建的记录,需要先根据value判断这个记录是不是自己创建的。

5. Zookeeper:

每个客户端对某个方法加锁时,在zookeeper上的与该方法对应的指定节点的目录下,生成一个唯一的瞬时有序节点。 判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。 当释放锁的时候,只需将这个瞬时节点删除即可。同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。

来看下Zookeeper能不能解决前面提到的问题。

锁无法释放?使用Zookeeper可以有效的解决锁无法释放的问题,因为在创建锁的时候,客户端会在ZK中创建一个临时节点,一旦客户端获取到锁之后突然挂掉(Session连接断开),那么这个临时节点就会自动删除掉。其他客户端就可以再次获得锁。

非阻塞锁?使用Zookeeper可以实现阻塞的锁,客户端可以通过在ZK中创建顺序节点,并且在节点上绑定监听器,一旦节点有变化,Zookeeper会通知客户端,客户端可以检查自己创建的节点是不是当前所有节点中序号最小的,如果是,那么自己就获取到锁,便可以执行业务逻辑了。

不可重入?使用Zookeeper也可以有效的解决不可重入的问题,客户端在创建节点的时候,把当前客户端的主机信息和线程信息直接写入到节点中,下次想要获取锁的时候和当前最小的节点中的数据比对一下就可以了。如果和自己的信息一样,那么自己直接获取到锁,如果不一样就再创建一个临时的顺序节点,参与排队。

单点问题?使用Zookeeper可以有效的解决单点问题,ZK是集群部署的,只要集群中有半数以上的机器存活,就可以对外提供服务。


分布式一致性:

1. 两阶段提交

2. 三阶段提交

3. 可靠事务投递

4. 业务补偿

5. Try-Confirm-Cancel补偿

6. paxos算法:

paxos 基于消息传递并具有高度容错性;

paxos 算法的核心是,分布式系统如何就某个状态(提案)达成一致;
paxos 算法假设不存在“拜占庭将军问题”;
paxos 算法中的角色:proposer、acceptor、learner

  • proposer:发送提案;
  • acceptor:裁决提案;只能批准一个提案;过半批准原则;
  • learner:学习提案;

1) prepare 阶段(生成提案)

proposer 提出编号为Mn 的提案,向acceptor 集合发送prepare 请求;

acceptor 反馈;
保证不再接收编号小于Mn 的提案;
返回已经批准的,编号最大的提案的Value;
若Mn 小于已经批准的最大编号,则忽略Mn;(优化)  
proposer 收到过半响应,则发送accept 请求(Mn,Vn)给acceptor 集合;Vn 是接收回的最大编号提案的Value;若无Value 可选(acceptor 都未接收提案),Vn 可为任意值;

2)accept 阶段(批准提案)

acceptor 接收到accept 请求之后,只要Mn 不小于已接受提案最大的编号,则批准提案;

3)learner 获取提案(学习策略)

一旦提案被批准(过半),则发送给所有learner;

提案批准,则发送给一个learner,该learner再发送给其他learner;
提案批准,则发送给一个learner集合,该learner集合再发送给其他learner;算法

7. zab 协议

ZAB 协议是为分布式协调服务(Zookeeper)专门设计的一种支持故障恢复的原子广播协议。

1)只允许有一个主进程(leader)接收事务请求并处理。

2)当leader 接收到请求之后,将事务请求转化为事务提议(proposal) 并将该proposal 分别入队 (leader 会为每个follower 分别创建一个响应队列用来保证事务提交的顺序)。

3)每个事务proposal 有一个递增的全局唯一的ID,事务ID(ZXID)

4)leader 通过响应队列将proposal 分发到其他节点之后,等待反馈;follower 接收到proposal 之后写入本地日志,返回 ack;

5)leader 收到一半以上follower 的反馈之后,会向其他节点 发送commit,同时提交事务。

故障恢复:

  • 保证已经在leader 机器上提交的事务最终被所有机器提交
  • 丢弃只在leader 机器上被提出的事务

为保证以上两点:

  • Leader选举:选择ZXID 最大的节点作为Leader。
  • 数据同步:leader 为每个follower 创建一个队列,将没有被各个follower 提交的事务proposal填入各个队列,并分发给follower。follower 事务同步以后,leader会将它加入到真正可用follower 列表中。

Zookeeper

zookeeper 为分布式应用提供了一个高效可靠的分布式协调服务;

实现依赖于ZAB 协议,实现了一种主备模式的架构来保持集群的数据一致性;
zookeeper 可以帮助分布式应用以一个共享的树形的命名空间实现协调;
zookeeper 将数据全部存储在内存中并且集群中任意一台机器都可以响应客户端读操作,因此它更适合用以读操作为主的场景;
zookeeper 集群节点有三种角色:leader、follower、observer。
leader:通过选举产生的集群领导者;提供读写服务;
follower:提供读服务;参与leader 选举和写操作“过半写成功”策略;
observer:提供读服务;不影响集群写性能的前提下提升集群的读性能;
zookeeper 集群节点总数为奇数;
zookeeper 数据节点类型:持久节点(只能采用删除操作清除该节点)、临时节点(其生命周期取决于session 是否失效)、顺序节点(子节点顺序表,节点名有数字后缀) ;
zookeeper 每个节点都有 Stat 结构(数据节点的所有状态信息)
最重要的功能:watcher;
开源客户端:zkclient、curator;


接口的幂等性

  • 查询、删除一般情况下是幂等的;

  • 唯一索引防止重复数据插入;

  • token机制,防止页面重复提交;

  • 悲观锁——获取数据的时候加锁获取;

  • 乐观锁——乐观锁只是在更新数据那一刻锁表,其他时间不锁表,效率更高。比较版本号或者其他状态条件;

  • 分布式锁;

  • select + insert——并发不高的后台系统;

  • 状态机幂等——有限状态机,这时候,如果状态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论上是不能够变更的,这样的话,保证了有限状态机的幂等;

对外提供接口的api如何保证幂等。

如银联提供的付款接口:需要接入商户提交付款请求时附带:source来源,seq序列号 。source+seq在数据库里面做唯一索引,防止多次付款(并发时,只能处理一个请求) 。重点:对外提供接口为了支持幂等调用,接口有两个字段必须传,一个是来源source,一个是来源方序列号seq,这个两个字段在提供方系统里面做联合唯一索引,这样当第三方调用时,先在本方系统里面查询一下,是否已经处理过,返回相应处理结果;没有处理过,进行相应处理,返回结果。注意,为了幂等友好,一定要先查询一下,是否处理过该笔业务,不查询直接插入业务系统,会报错,但实际已经处理了。


MySQL数据库调优:

  1. 可以用 mysqlslowdump 来分析慢查询日志

  2. 针对占用资源最严重的sql进一步的分析Explain该命令是查看查询优化器如何决定执行查询的主要方法,这个功能有局限性,只是一个近似结果,有时它是一个很好的近似,有时可能相差甚远。但它的输出是可以获取的最准确信息,值得仔细学习。

  3. MySQL profile:分析SQL执行带来的开销是优化SQL的重要手段。在MySQL数据库中,可以通过配置profiling参数来启用SQL剖析。该参数开启后,后续执行的SQL语句都将记录其资源开销,诸如IO,上下文切换,CPU,Memory等等。

SQL优化方法:

  • 改变 SQL 执行计划:明确了优化目标之后,我们需要确定达到我们目标的方法。对于 SQL 语句来说,达到上述2个目标的方法其实只有一个,那就是改变 SQL 的执行计划,让他尽量“少走弯路”,尽量通过各种“捷径”来找到我们需要的数据,以达到 “减少 IO 次数” 和 “降低 CPU 计算” 的目标。

  • 尽量少 join:MySQL 的优势在于简单,但这在某些方面其实也是其劣势。MySQL 优化器效率高,但是由于其统计信息的量有限,优化器工作过程出现偏差的可能性也就更多。对于复杂的多表 Join,一方面由于其优化器受限,再者在 Join 这方面所下的功夫还不够,所以性能表现离 Oracle 等关系型数据库前辈还是有一定距离。但如果是简单的单表查询,这一差距就会极小甚至在有些场景下要优于这些数据库前辈。

  • 尽量少排序:排序操作会消耗较多的 CPU 资源,所以减少排序可以在缓存命中率高等 IO 能力足够的场景下会较大影响 SQL 的响应时间。

    对于MySQL来说,减少排序有多种办法,比如:
      通过利用索引来排序的方式进行优化
      减少参与排序的记录条数
      非必要不对数据进行排序

  • 尽量避免select *:Select * 一般都会造成全表扫描,显示所有列,select 需要的字段即可。

  • 尽量用 join 代替子查询:虽然 Join 性能并不佳,但是和 MySQL 的子查询比起来还是有非常大的性能优势。MySQL 的子查询执行计划一直存在较大的问题,虽然这个问题已经存在多年,但是到目前已经发布的所有稳定版本中都普遍存在,一直没有太大改善。虽然官方也在很早就承认这一问题,并且承诺尽快解决,但是至少到目前为止我们还没有看到哪一个版本较好的解决了这一问题。

  • 尽量用 union all 代替 union::union 和 union all 的差异主要是前者需要将两个(或者多个)结果集合并后再进行唯一性过滤操作,这就会涉及到排序,增加大量的 CPU 运算,加大资源消耗及延迟。所以当我们可以确认不可能出现重复结果集或者不在乎重复结果集的时候,尽量使用 union all 而不是 union。

  • 禁用外键

SQL优化的基本原则:

  • 避免大sql:一个SQL只能在一个cpu上运行高并发环境中,大SQL容易影响性能问题可能一个大SQL把数据库搞死

  • 拆分SQL:保持事物的短小精悍,即开即用,用完即关,无关操作踢出事务,减少资源占用,保持一致性的前提下,拆分事务

  • 避免大批量更新:避开高峰,白天限制速度,加sleep

  • 避免类型转换

  • 避免取过量数据,建议使用limit

  • 避免在SQL 语句中进行数学运算、函数计算、逻辑判断等操作

  • 避免OR:同一字段,推荐in;不同字段,推荐union

  • 优先优化高并发的 SQL,而不是执行频率低某些“大”SQL;从全局出发优化,而不是片面调整

  • 尽可能对每一条运行在数据库中的SQL进行explain。

转载地址:http://jmkvb.baihongyu.com/

你可能感兴趣的文章
管理webpack中的jQuery插件依赖项
查看>>
删除可能不存在的文件的大多数pythonic方式
查看>>
如何在Eclipse中为Java文本编辑器更改字体大小?
查看>>
我们应该@Override接口的方法实现吗?
查看>>
ng-repeat定义次数而不是重复数组?
查看>>
选择语句以查找某些字段的重复项
查看>>
引导程序中“col-md-4”,“col-xs-1”,“col-lg-2”中数字的含义
查看>>
JavaScript ES6类中的私有属性
查看>>
List vs tuple,何时使用? [重复]
查看>>
默认情况下,如何以管理员身份运行Visual Studio?
查看>>
通过varargs参数可能导致堆污染
查看>>
Git学习笔记1 神奇的git stash
查看>>
Unable to locate package错误解决办法
查看>>
关于service中添加Transaction注解后,service无法注入bean
查看>>
linux shell 自定义函数(定义、返回值、变量作用域)介绍
查看>>
写自己的ASP.NET MVC框架(上)
查看>>
C++和C在linux下编程和与在WINDOWS下有什么区别
查看>>
CSS 的优先级机制[总结]
查看>>
linux shell 数组建立及使用技巧
查看>>
IEnumerator 协程 全称协同程序
查看>>