1、分布式系统是用来解决集中式架构的性能瓶颈问题,其核心是可扩展性,其特点包括:不出现单点故障、无状态等。依照 CAP 理论,分布式系统只能在 CP 和 AP 之间做取舍。
2、Base 理论是在 CAP 理论上发展的,是 CAP 理论的实际应用,即在分区和副本存在的前提下,通过一定的系统设计方案,放弃强一致性,实现基本可用,比如 NoSQL 系统、微服务架构等。Base 理论主要包括三个部分,即基本可用(Basically Available)、软状态(Soft State)和最终一致性(Eventually Consistent)。最终一致性模型又包括因果一致性和会话一致性等。因果一致性 指的是要求有因果关系的操作顺序得到保证,非因果关系的操作顺序则无所谓;会话一致性 指的是将系统数据的访问过程框定在一个会话之中,约定了系统能保证在同一个有效的会话中实现“读己之所写”的一致性。
3、系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到,用户读到某一操作对系统数据的更新需要一段时间,我们称这段时间为“不一致性窗口”。
4、分布式系统的三驾马车分别是基于 RPC 的服务调用、基于 MQ 的事件驱动以及基于 Data Sync 的数据共享。
5、Zookeeper 是通过 Zab(Zookeeper Atomic Broadcast,Zookeeper 原子广播协议)协议来保证分布式事务的最终一致性。Zxid 是 Zab 协议的一个事务编号,Zxid 是一个 64 位的数字,低 32 位是一个简单的单调递增计数器,针对客户端每一个事务请求,计数器 +1;高 32 位则代表 Leader 周期年代的编号。Zab 的具体流程可以拆分为消息广播、崩溃恢复和数据同步三个过程。
6、 pow(Proof of Work,工作量证明)被认为是经过验证最安全的拜占庭解决机制。
7、 异步化在分布式系统设计中随处可见,基于消息队列的最终一致性就是一种异步事务机制,在具体实现上主要有本地消息表和第三方可靠消息队列等。
8、 二阶段提交协议
9、三阶段提交协议
10、MySQL 的 XA 事务提交过程,以 redolog、binlog 日志提交为例,整体过程是先写 redo log,再写 binlog,并以 binlog 写成功为事务提交成功的标志。
11、TCC 分布式事务和 2PC/XA 两阶段提交的区别
- 2PC/XA 是数据库或者存储资源层面的事务,实现的是强一致性,在两阶段提交的整个过程中,一直会持有数据库的锁。
- TCC 关注业务层的正确提交和回滚,在 Try 阶段不涉及加锁,是业务层的分布式事务,关注最终一致性,不会一直持有各个业务资源的锁。
12、Redlock 算法是在单 Redis 节点基础上引入的高可用模式,Redlock 基于 N 个完全独立的 Redis 节点,一般是大于 3 的奇数个(通常情况下 N 可以设置为 5),可以基本保证集群内各个节点不会同时出现宕机。在 Redis 官方推荐的 Java 客户端 Redisson 中,内置了对 RedLock 的实现。
13、分布式系统怎么保证消息队列的时序性?先讨论下为什么会产生时序性的问题,首先分布式系统缺乏全局时钟,不同的机器使用各自的本地时钟,由于服务器存在时间偏斜等问题;其次,生产者集群的发送时序无法保证,消息的分发过程也导致消费者集群中不同消费实例的顺序难以全局统一;最后,消息重传也有可能导致顺序发生不一致。
Kafka 保证消息在 Partition 内的顺序,对于需要确保顺序的消息,发送到同一个 Partition 中就可以。单分区的情况下可以天然满足消息有序性,如果是多分区,则可以通过制定的分发策略,将同一类消息分发到同一个 Partition 中。
RocketMQ 对有序消息的保证和 Kafka 类似,RocketMQ 保证消息在同一个 Queue 中的顺序性,也就是可以满足队列的先进先出原则。
除了消息队列自身的顺序消费机制,我们可以合理地对消息进行改造,从业务上实现有序的目的。比如:在每次写入消息时,可以考虑添加一个单调递增的序列 ID,在消费端进行消费时,缓存最大的序列 ID,只消费超过当前最大的序列 ID 的消息。这个方案和分布式算法中的 Paxos 很像,虽然无法实现绝对的有序,但是可以保证每次只处理最新的数据,避免一些业务上的不一致问题。
14、分布式系统怎么保证消息队列的幂等性?RPC 或者 MQ 的重试都有可能出现幂等性问题。解决方式上可以通过考虑 “中间件” + “业务”来处理。中间件比如设置 kafka 的语义:At most once、At least once、Exactly once ;业务上通过数据库唯一索引、分布式锁等方式解决。
15、系统稳定性指标包括:服务器指标、系统运行指标、服务运用时指标、基础组件指标。
16、常见的服务器监控指标:
17、常见的系统运行指标:
18、常见的基础组件指标:
19、常见的监控组件:
- OpenFalcon:小米开源的一款企业级应用监控组件,是第一个国内开发的大型开源监控系统;
- Nagios:支持更丰富的监控设备,包括各类网络设备和服务器;对不同的操作系统都可以进行良好的兼容;对各类交换机、路由器等都有很好的支持;
- Zabbix:基于 Server-Client 架构,可以实现各种网络设备、服务器等状态的监控;数据存储可以根据业务情况,使用不同的实现,比如 MySQL、Oracle 等;Zabbix 的 Server 使用 C 语言实现,可视化界面基于 PHP 实现;
- CAT:Central Application Tracking 早期是大众点评内部的监控组件,2014 年开源,基于 Java 开发;对各类分布式服务中间件、数据库代理层、缓存和消息队列都有很好的支持;可以为业务开发提供各个系统的性能指标、健康状况,并且还可以进行实时报警;
20、监控处理制度:
21、引入 API 网关,可以高效的实现微服务集群的输出,节约后端服务开发成本,减少上线风险,并为服务熔断、灰度发布、线上测试等提供方案;
22、API 网关在微服务架构中是用来整合各个不同模块的微服务,统一协调业务;API 网关封装了系统内部架构,为每个客户端提供了一个定制的 API;从面向对象设计的角度看,它与外观模式(Facade Pattern)类似;
23、服务注册与发现是保证当服务上下线发生变更时,服务消费者和服务提供者能够保持正常通信;消费者不需要知道具体服务提供者的真实物理地址就可以进行调用,也不需知道具体有多少个服务者可用;服务提供者只需要注册到注册中心,就可以对外提供服务;
24、日志的采集和存储有很多开源的工具可以选择,一般会使用 离线+实时 的方式去存储日志,主要是分布式日志采集的方式,典型的解决方案如 Flume 结合 Kafka 等 MQ,日志存储到 HBase 等存储中;
25、在实际业务中,链路跟踪系统会有一个采样器配置,不会监控全部的链路。作为非业务组件,应当尽可能少侵入或者无侵入其他业务系统并且尽量少的占用系统资源;
26、Diamond:
27、Disconf:
28、NoSQL 数据库可以从以下几个角度进行分类:K-V 数据库,比如 redis;文档型数据库,比如 mongoDB;列存储数据库,比如 Hbase;图数据库,比如 GraphDB、Neo;
29、分库分表中间件实现:
- ShardingSphere:前身是当当开源的 Sharding-JDBC,已经加入 Apache 基金会,ShardingSphere 额外提供了 Sharding-Proxy,以及正在规划中的 Sharding-Sidecar,其中 Sharding-JDBC 用来实现分库分表,另外也添加了分布式事务等的支持;
- TDDL:Taobao Distributed Data Layer,是淘宝团队开发的数据库中间件,用来解决分库分表场景下的访问路由。
30、RocketMQ 是阿里巴巴开源的一款消息中间件,使用 Java 语言开发;RocketMQ 在写入磁盘时支持同步刷盘方式,即消息存储磁盘成功,才会返回消息发送成功的响应;RocketMQ 尽可能地保证了消息投递中的顺序一致性及可靠性,并且优化了响应时间;
31、Kafka 是 LinkedIn 开源的一个分布式消息系统,主要使用 Scale 语言开发,已经加入 Apache 顶级项目;Kafka 可以非常方便地进行水平扩展,支持海量数据的传输;Kafka 的另外一个特点是高吞吐率,在消息持久化写入磁盘的过程中使用了多种技术来实现读写的高性能,包括磁盘的顺序读写、零拷贝技术等。
32、Kafka 的消费是基于 Topic 的,属于发布订阅机制,它会持久化消息,消息消费完后不会立即删除,会保留历史消息,可以比较好的支持多消息者订阅。
33、Kafka 为了实现可扩展性,将一个 Topic 分散到多个 Partition 中;Partition 是一段连续的存储,如果在同一个 Broker 上,不能挂载到多个磁盘;一个 Broker 可以对应多个 Topic,对应多个 Partition ;Partition 可以细分为一个或多个的 Segment,每个 Segment 都对应一个 Index 索引文件,以及一个 log 数据文件;
34、为了更好地做负载均衡,Kafka 会将所有的 Partition 均匀的分配到整个集群上;为了提高 Kafka 的系统容错能力,一个 Partition 的副本,也要分配到不同的 Broker 上。
35、Kafka 的分区和副本分配遵循的原则:
- 一个 Topic 的 Partition 数量大于 Broker 的数量,使 Partition 尽量均匀分配到整个集群上;
- 同一个分区,所有的副本要尽量均匀分配到集群中的多台 Broker 上;
- 尽可能保证同一个分区下的主从副本,分配到不同的 Broker 上;
36、引入副本机制之后,同一个 Partition 可能会有多个副本,如果 Leader 挂掉,需要从这些副本之间选出一个新的 Leader。Kafka 数据同步中有一个 ISR(In-Sync Replicas,副本同步队列)的概念,队列中的所有副本,都和 Leader 保持一致,Leader 节点在返回 ACK 响应时,会关注 ISR 中节点的同步状态。
当所有的副本都挂了,Kafka 需要等待某个副本恢复服务:
- 等待 ISR 中的某个副本恢复正常,作为新的 Leader(Kafka 的 ISR 依赖 ZK 进行管理);
- ISR 列表是空,直接抛出 NoReplicationOnlineException 异常,保持一致性;
- ISR 列表是空,等待任一个副本恢复正常,作为新的 Leader(可能会存在数据丢失,不能保证已经包含全部 Commit 的信息);
37、Kafka 的零拷贝技术 —— MMAP 技术:Memory Mapped Files,直接对内存地址的操作。普通文件的 read 操作是把数据先读取到内核空间中,然后再复制到用户空间,而 MMAP 技术将文件直接映射到用户态的内存空间,省去内核空间到用户空间复制的开销。
38、Kafka 的零拷贝技术 —— Sendfile:数据在内核缓冲区完成输入和输出,不需要拷贝到用户空间处理。Kafka 把所有消息都存放在单独的文件里,在消息投递时直接通过 Sendfile 方法发送文件;
39、Netty 关注的是网络 IO 的传输;Kafka 等存储关注的是文件 IO 的传输;
40、Kafka 消息积压怎么办?
- 如果是 Kafka 消费能力不足,则可以考虑增加 topic 的 partition 的个数,同时提升消费者组的消费者数量,消费数 = 分区数 (二者缺一不可);
- 若是下游数据处理不及时,则提高每批次拉取的数量。批次拉取数量过少(拉取数据/处理时间 < 生产速度),使处理的数据小于生产的数据,也会造成数据积压。
41、Guava 中的 load 动作永远都是同步的,不管你是否使用异步包装;而 reload 动作如果是被异步包装过的,那么就会是异步操作的,否则和 load 一样也是同步的;
42、MySQL 主从延迟的原因可以从以下几个方面考虑:https://segmentfault.com/a/1190000015311988
- 主库在很短的时间内提交了大量的写请求,可以考虑打散这些写提交;
- 主库的长事务提交导致时延过长,避免长事务操作;
- 主从在机器性能或表数据结构上不一致导致的时延;
- 数据库实例的参数配置问题导致,如:从库开启了binlog,或者配置了每次事务都去做刷盘操作;