面试记录-中间件

157 阅读14分钟

一、Kafka

1、Kafka概念

kafka是一种高吞吐量、分布式、基于发布/订阅的消息系统,最初有LinkedIn公司开发,使用Scala语言编写,目前是Apache的开源项目。

2、kafka特点

同时为发布和定于提供高吞吐量。据了解,kafka每秒可以生产月25W消息(50MB),每秒处理55W消息(110MB)。

可进行持久化操作。将消息持久化到磁盘(或者db),因此可以用于批量消费。通过将数据持久化到硬盘已经replication防止丢失。

分布式系统,易于向外扩展。所有的producer,broker和consumer都会有多个,均为分布式的,无需停机即可扩展机器。

消息被处理的状态是在consumer端维护,而不是由server端维护。当失败时能自动平衡。

支持online和offline场景。

3、kafka架构

见图-process-扩展

kafka的整体架构非常简单,是显示分布式架构,producer、broker(kafka)和consumer都可以有多个。

Producer,Consumer实现kafka注册接口,数据从producer发送到broker,broker承担一个中间缓存和分发的作用。broker分发注册到系统中的consumer。broker的作用类类似于缓存,即活跃的数据和离线系统之间的缓存。客户端和服务器的通信,是基于简单,高性能,且与编程语言无关的TCP协议。

几个基本概念:

Topic:特指kafka处理的消息源(feeds of message)的不同分类。

Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。topic消息保存在各个partition中。partition中的每条消息都会被分配一个有序的id(offset)。

Offset:消息在日志中的位置,可以理解是消息在partition上的偏移量,也是代表该消息的唯一序号。

Message:消息,是通信的基本单位,每个Producer可以向一个Topic(主题)发布一些消息。

Producer:消息和数据生产者,向Kafka的一个topic发布消息的过程叫做producers。

Consumer:消息和数据消费者,定于topics并处理其发布的消息的过程叫做consumers。

Consumer Group:消费分组,每个Consumer必须属于一个group

Broker:缓存代理,Kafka集群中的一台或多台服务器统称为broker。一个节点

Zookeeper:保存着集群broker,topic,partition等meta(一种抽dao象思维,用zhi来描述数据的数据)数据;另外,还负责broker故障发现,partition leader选举,负载均衡等功能。

4、消息发送流程

见图-process-扩展

Producer根据指定的partition方法(round-robin、hash等),将消息发布到指定的topic的partition里面。

kafka集群接收到producer发过来的消息之后,将其持久化到硬盘,并保留消息指定时长(可配置),而不关注消息是否被接受。

Consumer从kafka集群pull数据,并控制获取消息的offset。

5、kafka数据存储设计

(1)partition的数据文件(offset,MessageSize,data)

partition中的每条Message包含以下三个属性:offset,MessageSize,data,其中offset表示Message在这个partition中的偏移量,offset不是该Message在partition数据文件中实际存储位置,而是一个逻辑上一个值,它确定了一个partition中的一条Message,

可以认为offset是partition中Message的id;MessageSize表示消息内容data的大小;data为Message的具体内容。

(2)数据文件分段segment(顺序读写,分段命令,二分查找)

partition物理上由多个segment文件组成,每个segment大小相等,顺序读写。每个segment数据文件以该段中最小的offset命名,文件扩展名为.log。这样在查找指定offset的Message是时候,用二分查找就可以定位到Message在哪个segment数据文件中。

(3)数据文件索引(分段索引,稀疏存储)

kafka为每个分段后的数据文件建立了索引文件,文件名与数据文件的名字是一样的,只是文件扩展名为.index。index文件中并没有为数据文件中的每条Message建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一个索引。这样避免了索引文件占用过多的空间,

从而可以将索引文件保留在内存中。

6、生产者设计

(1)负载均衡(partition会均衡分不到不同broker上)

由于消息topic由多个partition组成,且partition会均衡分不到不同broker上,因此为了有效利用broker集群的性能,提高消息的吞吐量,producer可以通过随机或者hash等方式,将消息平均发送到多个partition上,已实现负载均衡。

(2)批量发送

批量发送是提高消息吞吐量的重要方式,Producer端可以在内存中合并多条消息后,已一次请求的方式发送批量的消息给broker,从而大大减少broker存储消息的IO操作次数。但也一定程度上影响消息的实时性,相当于以延时代价,换取更好的吞吐量。

(3)压缩(GZIP或Snappy)

Producer端可以通过GZIP或Snappy格式对消息集合进行压缩。Producer端进行压缩之后,在Consumer端需进行解压。压缩的好处是减少传输的数据量,减少对网络传输的压力,在对大数据处理上,瓶颈往往体现在网络上而不是CPU(压缩和解压会耗掉部分CPU资源)

7、消费者设计

同一个ConsumerGroup中的多个Consumer实例,不同时消费同一个partition,等效于队列模式。partition内消息是有序的,Consumer通过pull方式消费消息。Kafka不删除已消费的消息对于partition,顺序读写磁盘数据,已时间复杂度O(1)方式提供消息持久化能力。

8、写入数据

kafka会把收到的消息都写入到硬盘中,它绝对不会丢失数据。为了优化写入速度kafka采用了两个技术,顺序写入和MMFile。

顺序写入:硬盘读写都会寻址->写入,其中寻址是一个“机械动作”,它是最好事的。所以为了提高硬盘的读写速度,kafka使用了顺序IO。每个partition其实都是一个文件,收到消息后kafka会把数据插入到文件末尾。这种做法缺陷没办法删除数据,所以kafka不会删除数据的,

它会把所有的数据都保留下来,每个消费者(Consumer)对每个Topic都有一个offset用来表示读取到第几条数据。

kafka提供了两种策略删除数据,一个基于时间,一个基于partition文件大小。

Memory Mapped Files:即便顺序写入磁盘,硬盘的访问速度环视不可能追上内存。所以kafka利用分析存储。Memory Mapped Files(简称MMap)内存映射文件,在64为操作系统中可以表示20G的数据文件,它的工作原理是直接利用操作系统的page来实现文件到物理内存的直接映射。

完成映射后你对物理内存的操作会被同步到硬盘上(操作系统在适当的时候)。

9、读取数据

基于sendfile实现zero copy(零Copy):sendfile提供了一种减少多次copy,提升文件传输性能的方法。kafka把所有的消息都存放在一个个文件中,当消费者需要数据的时候kafka直接把文件发送给消费者,配置mmap作为文件赌侠方式,直接把它传给sendfile

批量压缩:很多情况下,系统瓶颈不是CPU或者磁盘,而是网络IO。kafka允许使用递归的消息集合,批量的消息可以通过压缩(Gzip和Sanppy压缩协议)的形式传输并且在日志中也可以保持压缩格式,知道被消费者解压。

10、kafka设计实现性能

高吞吐量:

高吞吐量是kafka需要实现的核心目标之前一,为此kafka做了一下设计

(1)数据磁盘持久化:消息不在内存中cache,直接写入磁盘,充分利用磁盘的顺序读写性能。

(2)zero-copy:减少IO操作步骤

(3)数据批量发送

(4)数据压缩

(5)topic划分为多个partition,提高parallelism(并行)

负载均衡:

producer根据用户指定算法,将消息发送到指定的partition存在多个partition,每个partition有自己的replica,每个replica分布在不同的broker节点上,多个partition需要选取出lead partition,lead partition负责读写,

并由zookeeper负责fail ovder通过zookeeper管理broker与consumer的动态加入与离开。

拉取系统:

由于kafka broker会持久化数据,broker没有内存压力,因此consumer非常适合采取pull的方式消息数据,具有以下好处:

简化kafka设计

consumer根据消费能力自主控制消息拉取速度

consumer根据自身情况自主选择消费模式,例如批量,重复消费,从尾端开始消费等。

可扩展性:

当需要增加broker节点时,新增的broker会向zookeeper注册,而producer及consumer会根据注册在zookeeper上的watcher感知这些变化, 并及时做出调整。

11.应用场景

消息队列,行为跟踪,元信息监控,日志收集,流数据,事件源

12、kafka面试

特性:消息持久化,高吞吐量,扩展性,安全机制,数据备份,轻量级,消息压缩。

5个核心api:Producer API,Consumer API,Stream API, Connector APi, Admin API

一个分区对应多个broker,一个broker可以管理多个分区。

每个topic在创建时会要求制定它的副本数(默认1)

RAID优势:提供冗余的磁盘存储空间,提供负载均衡。

磁盘容量考虑因素:新增消息数,消息存留时间,平均消息大小,备份数,是否启用

kafka消息丢失问题:不要使用send(msg),而使用send(msg,callback);设置ack=all,确保消息消费完成后提交。

消息重复问题:做好幂等,数据库方面可以唯一建,业务上控制。

二、MQ

1、MQ优点

MQ就是消息队列,

异步处理:相比于传统的串行,并行方式,提供了系统吞吐量

应用解耦:系统间通过消息通信,不用关系其他系统处理

流量肖峰:通过消息队列控制请求量;缓解段时间内的高并发请求

日志处理:解决大量日志传输

消息通讯:消息队列内置了高效的通信机制,因此也可以用在纯的消息通讯。

缺点:系统可用性降低,复杂度提高,一致性问题。

2、MQ常见问题解决

消息顺序问题:

保证生产者

三、elasticsearch

1、什么是elasticsearch

es是一个基于Lucene的搜索服务,是一个实时的分布式存储、搜索、分析的引擎。

2、为什么要用elasticsearch

elasticsearch是专门做搜索的,对于模糊搜索非常擅长(搜索速度很快)。

从elasticsearch搜索的数据可以根据评分过率(原生支持排序,召回)

没有那么准确的关键字也能搜出相关结果(能匹配有相关性的记录)。

3、数据结构

4、术语和架构

Index:相当于数据库的table

Type:新版本已经废弃,(在以前的elasticsearch版本,一个Index下支持多个Type。)

四、Hbase

1、概念

Hbase是分布式,面向列的开源数据库(面向列族)。HDFS为Hbase提供可靠的底层数据存储服务,MapReduce为Hbase提供高性能的计算能力,Zookeeper为Hbase提供稳定服务和Failover机制,因此说Hbase是一个通过大量廉价的机器解决海量数据的高速存储

好读取的分布式数据库解决方案。使用索引LSM树

2、列式存储

列方式所带来的重要好处之一就是,由于查询中的选择规则是通过列来定义的,因此整个数据库是自动索引化的。

这里的列式存储其实说的是列族存储,Hbase是根据列族来存储数据的。

3、Hbase核心概念

(1)Column Family列族

Column Family又叫列族,Hbase通过列族划分数据的存储,列族下面可以包含任意多的列,实现灵活的数据存取。Hbase表创建的时候就必须指定列族。就像关系型数据库创建的时候必须指定的列是一样的。Hbase的列族不是越多越好,官方推荐的是列族最好小于或者等于3。

(2)Rowkey(Rowkey查询,Rowkey范围扫描,全表扫描)

RowKey的概念和mysql中的主键是完全一样的,Hbase使用RowKey来唯一的区分某一行的数据。Hbase只支持3中查询方式:基于Rowkey的单行查询,基于Rowkey的范围扫描,全表扫描。

(3)Region分区

Region:Region的概念和关系型数据库的分区或者分片差不多。Hbase会将一个大表的数据基于Rowkey的不同范围分配到不同的Region中,每个Region负责一定范围的数据访问和存储。在行业内个即时一个巨大的表,由于被切割到不同的region,访问起来的时延很低。

(4)TimeStamp多版本

TimeStamp是实现Hbase多版本的关键。在Hbase中使用不同的timestamp来标识相同rowkey行对应的不同版本的数据。在写入数据的时候,如果用户没有指定对应的timestamp,Hbase会自动添加一个timestamp,timestamp和服务器时间保持一致。

4、Hbase核心架构

Hbase是由Client,Zookeepr,Master,HRegionServer,HDFS等几个组件组成。

(1)Client

Clinet包内含了访问Hbase的接口,另外Client还维护了对应的cache来加速Hbase的访问,比如cache的.META元数据信息。

(2)Zookeeper:

Habse通过Zookeeper来做master的高可用,RegionServer的监控,元数据的入口以及集群配置的维护等工作。

通过Zookeeper来保证集群中只有一个master来运行,如果master异常,会通过竞争机制产生新的master提供服务。

通过Zookeeper来监控RegionServer的状态,当RegionServer有异常的时候,通过回调的形式通知Master RegionServer上下限的信息。

通过Zookeeper存储元数据的统一入口地址。

(3)HMaster

Master节点的主要职责如下;

为RegionServer分配Region

维护整个集群的负载均衡

维护集群的元数据信息发现失效的Region,并将失效的Region分配到正常RegionServer上,当RegionServer失效的时候,协调对应Hlog的拆分。

(4)HRegionServer

HRegionServer直接对接用户的读写请求,是真正“干活”的节点。

管理master为其分配的Region

处理来自客户端的读写请求

负责和底层HDFS的交互,存储数据到HDFS。

负责Region变大以后的拆分。

负责Storefile的合并工作。

(5)Region寻址方式(通过zookeeper .META)

第一步:Client请求ZK获取.META所在的ReionServer的地址。

第二步:Client请求.META所在的RegionServer获取访问数据所在的RegionServer地址,client会将.META的相关信息cache下来,以便下一次快速访问。

第三步:Client请求数据所在的RegionServer,获取所需要的数据。

(6)HDFS

HDFS为Hbase提供最终的磁层数据存储服务,同时为Hbase提供高可用(Hlog存储在HDFS)的支持。

5、Hbase的写逻辑

(1)获取RegionServer:Client获取数据写入的Region所在的RegionServer

(2)请求写Hlog:请求写Hlog,Hlog存储在HDFS,当RegionServer出现异常,需要使用Hlog来恢复数据。

(3)请求写MemStore:请求写MemStore,只有当写Hlog和写MemStore都成功了才算请求写入完成。MemStore后续会逐渐刷到HDFS中。

五、Zookeeper

1、Zookeeper是什么

Zookeeper是一个开源的分布式协调服务。它是一个为分布式应用提供一致性服务的软件,分布式应用程序可以基于Zookeeper实现诸如数据发布/订阅,负载均衡,命名服务,分布式协调/通知,集群管理,Master选举,分布式锁好分布式队列功能。

Zookeeper的目标是封装好复杂易出错的关键服务,将简单应用的接口和性能高效,功能稳定的系统提供给用户。