第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计

1、Kafka高可用设计

1.1、Kafka服务端高可用设计

  • 高可用:leader挂了会通过Zookeeper重新选举,不存在单点故障问题

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第1张图片

  • Controller:负责各partition的Leader选举一级Replica的重新分配

kafka让所有的Broker都在Zookeeper的Controller节点注册一个Watcher,当Controller发生故障时对应的Controller临时节点会自动删除,此时注册在其上的Watcher会被触发,让所有活着的Broker都会区竞争成为新的Controller,竞选成功者即为Controller。

1.2、kafka服务端高并发设计

(1)同步顺序处理:每个请求必须等待前一个请求处理完了以后才会得到处理,吞吐量太差!

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第2张图片

while(true){
    Request request=accept(connection);
    handle(request);
}

缺点:

  • ①并发低:所有的处理放在一个线程里,这个线程压力很大,网络IO的处理总是要比CPU慢的多

  • ②网络延迟很大:如果这里有一个客户端的请求,处理比较复杂则会影响后面其他客户端的请求响应能力;

(2)半异步半同步编程:

  • T1线程
while(1)
{
    epoll_wait(...);
    for(){
        if(fd == listenner_socket)
        {
            cfd=accpt(listenner_socket);
        }
        else{
            read(fd,buf,size);
            enqueue(buf);
        }
    }
}
  • T2线程
while(1){
    wait_queue(buf);
    process(buf);
}
  • 缺点
    • ①线程间需要同步;
    • ②线程间有数据的拷贝(memcpy),这个拷贝也是很耗CPU

(3)异步处理:每个请求都创建一个线程去处理,请求不会阻塞,但是每个请求都创建一个线程开销太大

while(true){
    Request request=accept(connection);
    Thread thread =  new Thread(handle(request));
    thread.start();
}

(4)Reactor设计模式:引入NIO多路复用,高并发保证

  • 架构概要设计:

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第3张图片

  • 架构详细设计:

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第4张图片

  • 注意事项:

    • 第一层:对应Read HandlePool,线程数默认num.network.threads=3,如果想提高性能则可调大参数增加线程个数

    • 第二层:对应MessageQueue

    • 第三层:对应Handler ThreadPool,线程数默认num.io.threads=8,如果想提供性能则可调大参数增加线程个数,最好不高于CPU个数。

    每个线程:2000QPS
    8个线程:2000QPS=1.6wQPS
    

①客户端发送请求到服务端;

服务端由acceptor线程监听客户端请求,如果请求到来会将其封装为SocketChannel

SocketChannel被发送到线程池,按照轮询的方式将其线程池的一个连接队列里面;

④SocketChannel注册OP_READ事件真正接收到客户端发送过来的请求**,此时请求以为跨网络传输为二进制格式**;

⑤Processor线程解析请求将其封装为一个Request对象发送到RequestQueue,主要起到缓冲作用

⑥RequestHandlerPool从RequestChannel中不断获取请求,通过工具类将数据写到磁盘

工具类封装响应结果,将Response存到ResponseQueue队列里面。

Processor线程拉取Response,将其注册为OP_WRITE事件,并发送回客户端

2、Kafka的高性能设计

2.1、Kafka的服务端高性能设计

2.1.1、数据写入高性能 - 顺序写磁盘
  • P:kafka将详细记录持久化到本地磁盘中,一般人会认为是磁盘的读写性能比较差,对kafka性能如何提出质疑。

  • A:不管是内存还是磁盘,快或慢关键在于寻址的方式。磁盘和内存都有顺序读写和随机读写,基于磁盘的顺序读写高出磁盘的随机读写三个量级,甚至高于内存随机读写。

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第5张图片

  • 注意事项:kafka不断将数据写入到os cache中达到一定阈值批量顺序写磁盘。
2.1.2、数据读取高性能 - 索引文件

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第6张图片

  • kafka的文件存储:
    • ①log文件:里面存储的是消息数据,文件名以log文件中的第一条消息的offset命名的。
    • ②index文件:里面存储的是索引信息

Ⅰ、跳表设计快速定位消息所在文件位置

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第7张图片

  • P:快速找到offset=5000的消息
  • A:跳表设计,构建多级索引,快速定位文件位置,以空间换时间

Ⅱ、稀松索引快速定位文件中的消息位置

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第8张图片

  • P:如何在已定位的文件中快速找到消息位置
  • A:稀疏索引(index文件),消息位置对应磁盘位置,,每隔4kb数据在index文件中记录下偏移量+物理磁盘位置

​ 业务场景:查找offset=1115的消息,首先在index文件中定位offset=1113的物理磁盘位置,之后顺序扫描1731之后的物理磁盘找到offset=1115的消息

Ⅲ、零拷贝:

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第9张图片

  • 传统读取数据并发场景:
    • ①操作系统将数据从磁盘文件中读取到内核空间的页面进行缓存
    • ②第一次拷贝:应用程序将数据从内核空间读入用户空间缓冲区
    • ③第二次拷贝:应用程序将读到的数据写回到内核空间并放入socket缓冲区
    • ④操作系统将数据从socket缓冲区复制到网卡接口,此时数据才能通过网络进行发送。

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第10张图片

​ 零拷贝技术只用将磁盘文件的数据复制到系统缓冲区一次,然后将数据从页面的缓存直接发送到网络中(发送给不同的订阅者时,都可以使用同一个页面进行缓存),避免了重复复制操作。

  • 零拷贝场景:如果有10个消费者,传统方式下数据复制次数为4 * 10 = 40 次,而是用零拷贝技术只需要复制1 + 10 = 11 次,其中一次为从磁盘复制到页面缓存,10 次表示10个消费者各自读取一次页面缓存,由此可以看出kafka的效率是非常高的。

2.2、kafka客户端高性能设计

2.2.1、批处理方案设计

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第11张图片

①生产者发送消息请求,生产者将其封装为ProducerRecord对象

②将其序列化请求broker获取集群元数据

③根据partitionor分区算法确定将消息存储到topic的某个分区,确定好将消息发送到某台服务器上;

  • 0.8以前就截至到这里:来一条消息发送一条请求,这种设计性能上会比较差,请求建立连接次数太多

④将**消息先存入RecordAccumulator(缓存)**中

Sender线程将多条消息封装成一个batch发送到服务器

2.2.2、RecordAccumulator内存池方案设计

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第12张图片

​ RecordAccumulator 会由业务线程写入,经过哈希/轮询等分区策略计算出分区号,最后写入到对应TopicPartition,在Batchs队列中写入到RecordBatch中,等到RecordBatch达到批处理阈值后,最后Sender 线程批量读取到Broker的partition中。

3、服务配置文件参数

(1)num.io.threads=8

  • broker处理磁盘IO的线程数 :主要进行磁盘io操作,高峰期可能有些io等待,因此配置需要大些。配置线程数量为cpu核数2倍,最大不超过3倍.

(2)num.network.threads=3

  • broker处理消息的最大线程数:主要处理网络io,读写缓冲区数据,基本没有io等待,配置线程数量为cpu核数加1.

(3)log.dirs=/data/kafka-logs

  • 生产环境下会有多个目录,一个目录对应一个磁盘

4、实时存储平台资源评估与架构设计

  • 评估目标:平台每天hold住10亿请求

4.1、QPS设计

(1)二八法则定QPS

​ 每天集群需要承载10亿数据请求,一天24小时,对于网站晚上12点到陵城8点这8个小时几乎没有多少数据。使用二八法则估计,也就是80%的数据(8亿)会在其余16个小时涌入,而且8亿的80%的数据(6.4亿)会在16个小时的20%时间(3个小时)涌入。

QPS计算公式=6.4亿÷(3*60*60)=6万,故高峰期集群需要抗住每秒6万的并发

(2)副本数量估算存储

​ 每天10亿条数据,每天请求10kb,也就是9T的数据,如果保存3副本,9✖3=27T,保留最近5天的数据,故需保留27*5=135T数据。

存储资源=10kb*10亿*3副本*5天

(3)QPS评估

​ 如果资源充足,让高峰期QPS控制在集群能承载的总QPS的30%左右,故集群能承载的总QPS为20w才是安全的,根据经验一台物理机能支持4万QPS是没问题的,所以从QPS的角度上讲,需要5台物理机,再考虑上消费者请求,增加1.5倍,需要7~8台服务器

4.2、磁盘评估

(1)磁盘数据评估

7台物理机,需要存储135T的数据,每台存储11T的数据,一般也就是11块盘一个盘2T,要做磁盘预留。

log.dirs=/data1,/data2,/data3,......
#多磁盘目录

(2)磁盘类型选择

​ SSD是固态硬盘,比机械硬盘要快,主要快在磁盘随机读写性能上。

​ kafka是顺序写磁盘,机械硬盘顺序写性能跟内存读取性能差不多,所以kafka集群使用机械硬盘就可以了。

4.3、内存评估

​ 经过相关业务处理,此集群有100各topic,这100个topic的partition的数据在os cache里效果是最好的。100个topic,一个topic有9个partition,则总共会有900个partition,每个partition的Log文件大小是1G,我们有3个副本,也就是说要900个topic的artition数据都驻留在内存需要2700G的内存。

​ 我们现在有7台服务器,所以平均下来每台服务器需要400G内存,但是其实partition的数据我们没必要所有的都要驻留在内存中,10~20%的数据在内存里就非常好了,400G*0.2=80G就可以了,kafka进程需要6G内存(并没有创建很多对象),所以需要86G内存,故我们可以挑选128G内存的服务器就非常够用了。

  • 注意事项:kafka与实时结合读取最新数据,大概占比10~20%比例。

4.4、CPU评估

CPU规划主要看Kafka进程里面有多少线程线程主要是依托多核CPU来执行的,如果线程特别多,但是CPU核很少就会导致CPU负载很高,会导致整体工作线程执行的效率不高。

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第13张图片

  • kafka进程中的线程个数:
    • Acceptor线程:1个
    • Processor线程:默认3个,一般设置为9个
    • RequestHandle线程:默认8个,一般设置为32个
    • 日志清理线程
    • 感知Controller状态的线程
    • 副本同步的线程
估算下来Kafka内部有接近100个线程

​ 4个CPU core,一般来说几十个线程,在高峰期CPU几乎都快打满了,8个CPU core,也就能够比较宽裕的支撑几十个线程繁忙工作,所以Kakfa的服务器一般建议是16核,基本上可以hold住一两百线程的工作,当然如果给到32cpu core那就更好。

5、实时存储平台规划

  • 总体规划:10亿写请求,6w/s的吞吐量,9T的数据,7台物理机
    • 硬盘:11(SAS) 1T,7200转*
    • 内存:128GB,JVM分配6G,剩余给os cache
    • CPU:16核/32核
    • 网络:万兆网卡更佳

6、实时存储平台架构设计

第四章 数据中台架构PaaS层(平台服务层)之实时存储资源规划与架构设计_第14张图片

(1)Zookeeper服务器:3台
(2)Kafka服务器:台

  • kafka集群和HDFS集群的zookeeper可共用,一般建议分开(除非资源遇到瓶颈)
    • 风险点:zookeeper集群挂掉则两个服务都不可用

7、实时存储平台核心配置

7.1、日志保留策略配置优化

建议减少日志保留时间,建议三天或者更短时间。通过log.retention.hours来实现,例如设置:

log.retention.hours=72 

7.2、段文件大小优化

段文件配置1GB,有利于快速回收磁盘空间,重启kafka加载也会加快,相反,如果文件过小,则文件数量比较多,kafka启动 时是单线程扫描目录(log.dir)下所有数据文件,文件较多时性能会稍微降低。可通过如下选项配置段文件大小:

log.segment.bytes=1073741824 

7.3、log数据文件刷盘策略优化

​ 为了大幅度提高producer写入吞吐量,需要定期批量写文件 优化建议为:每当producer写入10000条消息时,刷数据到磁盘。可通过如下选项配置:

log.flush.interval.messages=10000 

每间隔1秒钟时间,刷数据到磁盘。可通过如下选项配置:

log.flush.interval.ms=1000 

7.4、提升并发处理能力

num.io.threads =8,num.network.threads =4

你可能感兴趣的:(大数据架构师专题,架构,paas,java)