diff --git "a/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/flinkOptimization.md" "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/flinkOptimization.md" new file mode 100644 index 0000000000000000000000000000000000000000..6d2717ef25f1a163f20657d08b20a80fdb3e1576 --- /dev/null +++ "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/flinkOptimization.md" @@ -0,0 +1,308 @@ +# 1 调优概述 +## 1.1 flink介绍 +Flink是一个批处理和流处理结合的统一计算框架,其核心是一个提供了数据分发以及并行化计算的流数据处理引擎。它的最大亮点是流处理,是业界最顶级的开源流处理引擎。 +## 1.2 环境介绍 +| 软件 | 版本 | +|-------------------------------|---------------------------| +| OS | openEuler 22.03 | +| JDK | OpenJDK 1.8.0_262 | +| Kafka | 2.11-1.1.0 | +| Flink | 1.7.2 | +| Redis | 3.0.7 | +| yahoo-streaming-benchmark测试工具 | 0.2.0(基于开源适配修改) | +## 1.3 调优原则 +1. Flink的yahoo-streaming-benchmark测试涉及Kafka、Flink、Redis3个组件,Flink测试的时候同时需要调整Kafka的参数,但测试主体是Flink,Kafka可以不调整到Kafka最优的情况,把CPU尽量分给Flink使用。 +2. Flink在网络、磁盘等各项资源均未达到瓶颈的情况下,吞吐量也会达到瓶颈,且吞吐量和测试数据量之间存在正比关系。可以先测试最大数据量,初步估计当前环境的吞吐量瓶颈,再改数据量上下调整,获得较好的性能结果。 +3. 调优主要参数有: +``` +a. Kafka、Redis、Zookeeper所在节点IP、端口。 +b. Topic:即Kafka TOPIC名称,每次运行修改名称即可。 +c. PARTITIONS:即Kafka分区数,比较关键的参数,分区数与Flink的并发度必须保持一致,所以调试Flink性能主要需要修改该参数。 +d. LOAD:数据量,该值直接决定了吞吐量大小,调整该值可以测出一定时延下最大可达到的吞吐量值。 +e. TEST_TIME:测试时间,一般典型值为240s。 +f. -p:Flink run时附带的参数,即并发度,必须小于等于PARTITIONS,一般两者取值相等。 +这些参数在配置完成后,大部分会写入到local_conf.yaml配置文件中,供Flink执行时读取。 +``` +## 1.4 调优思路 +Flink作为一个流处理框架,主要作用是处理数据,将数据通过一定的方法计算、统计、分析,最终输出。典型的数据处理场景,即为Kafka、Flink、Redis三个组件共同使用,数据从Kafka获取,Flink进行计算分析,最终将结果写入Redis。 + +流处理框架,有一定的编程规范,主要思路如图所示。 + +![图1 流处理框架](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0000001089149901.png) + +每个Flink程序都可以以类似的方式编写,主要思路即为先定义Flink流处理过程,每个步骤输入输出对齐,最终把数据输出。整个工作流定义完成后,就可以开始执行了,整个执行过程是无限流,永不停止,直到Flink任务被外部kill为止。 + +yahoo-streaming-benchmark工具主要用途是测试集群Flink处理性能,其测试过程从数据生成->数据写入Kafka->数据从Kafka读出->预处理数据->窗口处理数据->结果写入Redis,端到端的测试Flink流处理过程。主要性能指标为数据吞吐量和处理时延。 + +![输入图片说明](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0000001089006855.png) + +数据从Flink其中一个进程生成,不断写入Kafka,由另一个进程读出数据进行处理,最终写入Redis,在Flink job执行完成后,Redis进行结果统计分析。 +# 2 硬件调优 +## 2.1 配置BIOS +### 目的 +对于不同的硬件设备,通过在BIOS中设置一些高级选项,可以有效提升服务器性能。 + +- 服务器上的SMMU一般用来完成设备的地址转换,并且可以实现设备隔离,在虚拟化中很实用,但是在物理机测试场景下,SMMU可能会导致性能下降,尤其对于小包网络场景,因此建议关闭该功能提升服务器性能。在虚拟机场景需要打开此配置来使用PCI直通功能。 +- 在本测试场景中,预取会导致Cache污染,Cache miss增加,因此建议关闭预取功能。 +### 方法 +#### 1) 关闭SMMU。 +- a.重启服务器,进入BIOS设置界面。 +具体操作请参见《TaiShan 服务器 BIOS 参数参考(鲲鹏920处理器)》中“进入BIOS界面”的相关内容。 +- b.依次进入“Advanced > MISC Config > Support Stmmu”。 +![BIOS设置界面](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0226825857.png) +- c.将“Support Smmu”设置为“Disabled”,按“F10”保存退出(永久有效)。 +![关闭SMMU BIOS界面](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0226825858.png) +#### 2) 关闭预取。 +- a.进入BIOS设置界面。 +- b.依次进入“Advanced > MISC Config > CPU Prefetching Configuration”。 +![BIOS设置界面](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0226825862.png) +- c.将“CPU Prefetching Configuration”设置为“Disabled”,按“F10”保存退出(永久有效)。 +![关闭Prefetching Configuration界面](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0226825863.png) +## 2.2 调整rx_buff +### 目的 +1822网卡默认的rx_buff配置为2KB,在聚合64KB报文的时候需要多片不连续的内存,使用率较低;该参数可以配置为2/4/8/16KB,修改后可以减少不连续的内存,提高内存使用率。 +### 方法 +- 1.查看rx_buff参数值,默认为2。 + +``` +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +``` +- 2.在目录“/etc/modprobe.d/”中增加文件hinic.conf,修改rx_buff值为8。 + +``` +options hinic rx_buff=8 +``` +- 3.重新挂载hinic驱动,使得新参数生效。 + +``` +rmmod hinic +modprobe hinic +``` +- 4.查看rx_buff参数是否更新成功。 + +``` +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +``` +## 2.3 调整Ring Buffer +### 目的 +1822网卡Ring Buffer最大支持4096,默认配置为1024,可以增大buffer大小用于提高网卡Ring大小。 +### 方法 +- 1.查看Ring Buffer默认大小,假设当前网卡名为enp131s0。 + +``` +ethtool -g enp131s0 +``` +![输入图片说明](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0231041158.png) + +- 2.修改Ring Buffer值为4096。 + +``` +ethtool -G enp131s0 rx 4096 tx 4096 +``` +- 3.查看Ring Buffer值是否更新成功。 + +``` +ethtool -g enp131s0 +``` +![输入图片说明](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0231041266.png) +## 2.4 开启LRO +### 目的 +1822网卡支持LRO(Large Receive Offload),可以打开该选项,并合理配置1822 LRO参数。 +### 方法 +- 1.查看LRO参数是否开启,默认为off,假设当前网卡名为enp131s0。 + +``` +ethtool -k enp131s0 +``` +![输入图片说明](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0231038281.png) +- 2.打开LRO。 + +``` +ethtool -K enp131s0 lro on +``` +- 3.查看LRO参数是否开启。 + +``` +ethtool -k enp131s0 +``` +![输入图片说明](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0231039073.png) +## 2.5 配置网卡中断绑核 +### 目的 +相比使用内核的irqbalance使网卡中断在所有核上进行调度,使用手动绑核将中断固定住能有效提高业务网络收发包的能力。 + +### 方法 +- 1.关闭irqbalance。 +``` +- a. 若要对网卡进行绑核操作,则需要关闭irqbalance。 +systemctl stop irqbalance.service +- b. 关闭irqbalance服务,永久有效。 +systemctl disable irqbalance.service +- c. 查看irqbalance服务状态是否已关闭。 +systemctl status irqbalance.service +``` +- 2.查看网卡PCI设备号,假设当前网卡名为enp131s0。 + +``` +ethtool -i enp131s0 +``` +![输入图片说明](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0231023410.png) +- 3.查看PCIe网卡所属NUMA node。 +``` +lspci -vvvs +``` +![输入图片说明](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0231022972.png) +- 4.查看NUMA node对应的core的区间,例如此处就可以绑到48~63。 + +``` +lscpu +``` +![输入图片说明](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0231023247.png) +- 5.进行中断绑核,1822网卡共有16个队列,将这些中断逐个绑至所在NumaNode的16个Core上(例如此处就是绑到NUMA node1对应的48-63上面)。 + +``` +bash smartIrq.sh +``` +脚本内容如下: +``` +#!/bin/bash +irq_list=(`cat /proc/interrupts | grep enp131s0 | awk -F: '{print $1}'`) +cpunum=48 # 修改为所在node的第一个Core +for irq in ${irq_list[@]} +do +echo $cpunum > /proc/irq/$irq/smp_affinity_list +echo `cat /proc/irq/$irq/smp_affinity_list` +(( cpunum+=1 )) +done +``` +- 6.利用脚本查看是否绑核成功。 + +``` +sh irqCheck.sh enp131s0 +``` +![输入图片说明](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0303198443.png) + +脚本内容如下: +``` +#!/bin/bash +# 网卡名 +intf=$1 +log=irqSet-`date "+%Y%m%d-%H%M%S"`.log +# 可用的CPU数 +cpuNum=$(cat /proc/cpuinfo |grep processor -c) +# RX TX中断列表 +irqListRx=$(cat /proc/interrupts | grep ${intf} | awk -F':' '{print $1}') +irqListTx=$(cat /proc/interrupts | grep ${intf} | awk -F':' '{print $1}') +# 绑定接收中断rx irq +for irqRX in ${irqListRx[@]} +do +cat /proc/irq/${irqRX}/smp_affinity_list +done +# 绑定发送中断tx irq +for irqTX in ${irqListTx[@]} +do +cat /proc/irq/${irqTX}/smp_affinity_list +done +``` +## 2.6 创建RAID0 +### 目的 +磁盘创建RAID可以提高磁盘的整体存取性能,环境上若使用的是LSI 3108/3408/3508系列RAID卡,推荐创建单盘RAID 0/RAID 5,充分利用RAID卡的Cache(LSI 3508卡为2GB),提高读写速率。 +### 方法 +- 1.使用storcli64_arm文件检查RAID组创建情况。 + +``` +./storcli64_arm /c0 show +``` +- 2.创建RAID 0,命令表示为第2块1.2T硬盘创建RAID 0,其中,c0表示RAID卡所在ID、r0表示组RAID 0。依次类推,对除了系统盘之外的所有盘做此操作。 + +``` +./storcli64_arm /c0 add vd r0 drives=65:1 +``` +![输入图片说明](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/Flink/zh-cn_image_0226841019.png) + +## 2.7 开启RAID卡Cache +### 目的 +使用RAID卡的RAWBC(无超级电容)/RWBC(有超级电容)性能更佳。 + +使用storcli工具修改RAID组的Cache设置,Read Policy设置为Read ahead,使用RAID卡的Cache做预读;Write Policy设置为Write back,使用RAID卡的Cache做回写,而不是Write through透写;IO policy设置为Cached IO,使用RAID卡的Cache缓存IO。 +### 方法 +- 1.配置RAID卡的Cache。 + +``` +./storcli64_arm /c0/vx set rdcache=RA +./storcli64_arm /c0/vx set wrcache=WB/AWB +./storcli64_arm /c0/vx set iopolicy=Cached +``` +- 2.检查配置是否生效。 + +``` +./storcli64_arm /c0 show +``` +# 3 flink 调优 +## 3.1 Flink参数修改 +### 目的 +修改Flink参数保证资源可最大限度供Flink使用。 + +### 方法 +修改Flink根目录下的conf目录中的flink-conf.yaml文件。 +| 参数 | 建议值 | 描述 | +|--------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| vcores | 根据实际调整。 | YARN container vcores数量,其中一个taskmanager即为一个container,该参数即指定了一个taskmanager可以使用的vcores数量。而jobmanager也是一个container,但是jobmanager固定分配1个vcore,并不受该参数影响。该参数对性能影响非常大,可以尽可能的调大,其中jobmanager必定会占用1个vcore,除去之后,剩下每个节点都可以使用该节点的核,所以可以根据taskmanager数目计算出vcores数目。 | +| network.numberofBuffers | 根据实际调整。 | TaskManager网络传输缓冲栈数量 ,如果作业运行中出错提示系统中可用缓冲不足,可以增加这个配置项的值。 | +| taskmanager.compute.numa | 详见参数配置。 | 该参数在默认Flink配置文件里没有,需要手动加入该参数。该参数的用途是开启taskmanager的numa绑核,必须与yarn的相关参数配合使用,具体使用方法请参见 | + +## 3.2 Yarn/Kafka参数修改 +### 目的 +配置Yarn和Kafka相关参数,保证Kafka不会成为Flink调优瓶颈。 +### 方法 +在Flink服务的Web界面搜索以下参数,并根据实际情况进行修改。 +| 参数 | 建议值 | 描述 | +|-----------------------------------------------|-----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| yarn.nodemanager.resource.cpu-vcores | 每个Kafka服务节点的核数。 | 该参数在Web界面“yarn > CONFIGS > SETTINGS > Number of virtual cores”。一个nodemanager可以使用的cpu-vcores数目,直接配置成1个节点的核数即可。 | +| yarn.nodemanager.numa-awareness.enabled | true | 该参数在yarn配置中默认没有,需要手动添加,将其添加到Web界面“yarn > CONFIGS > ADVANCED > Nodemanager > Custom yarn > site > Add Property” 。该参数为是否使能container的numa感知功能,默认为false,如果需要开启,需要设置为true。 | +| yarn.nodemanager.numa-awareness.read-topology | true | 该参数在yarn配置中默认没有,需要手动添加,将其添加到Web界面“yarn > CONFIGS > ADVANCED > Nodemanager > Custom yarn > site > Add Property” 。该参数为是否从系统或配置中读取numa的topo结构。如果设置为true,那么会直接通过numactl –hardware命令从系统中读取系统的numa 结构。Flink测试需要开启numa绑核则设置为true。 | +| kafka.num.network.threads | 8 | 该参数在Web界面“Kafka > CONFIGS > Advanced kafka > broker > num.network.threads”。Kafka网络线程数,影响Kafka读写效率。但Flink处理资源有限,不建议将该值设置过大,否则Kafka占用资源影响Flink调优性能,该值可根据实际情况调整为默认值的1~2倍。 | +## 3.3 Yarn提交Flink任务参数修改 +### 目的 +Flink应用运行前,需要先提交Flink任务,向Yarn申请相关内存CPU等资源,提交任务命令为:yarn-session.sh -n 4 -s 64 -jm 5000 -tm 50000 -d;修改提交任务参数,调整并发及分配资源参数。 +### 方法 +提交Yarn任务时,根据实际情况对以下参数进行调整: +| 参数 | 建议值 | 描述 | +|-------------------------|------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| -n (taskmanager) | 节点数*(4-8)。 | 该参数为Flink的taskmanager数目,Flink引擎运行需要由一个jobmanager以及若干个taskmanager构成。每个taskmanager都是独立的一部分,当有Flink应用需要运行时,会被随机分配到一个taskmanager运行,所以taskmanager的数目增多,可以互不干扰的并行运行更多的Flink应用。但是很显然,集群中的资源时有限的,taskmanager越多,单个taskmanager能够分配的资源则越少,也会导致Flink性能下降。所以,根据经验值,taskmanager数目可以取集群节点数*4 ~节点数*8。 | +| -s (slot) | 根据实际场景配置。 | 该参数为单个taskmanager所拥有的槽位数,Flink任务提交后,集群中可以使用的总槽位数即为slot * taskmanager。一个slot可以为一个taskmanager提供1个并发,例如slot=30,即1个taskmanager最多可以跑30并发,当然实际运行的时候,也可以只跑20并发,那么此时剩余10个slot即为空闲。剩余未使用的slot,并不会占用CPU资源,但是会占用相关内存资源。该参数的修改,根据实际需要用到的并发度而动态调节。在内存足够的情况下,可以适当设置较大。 | +| -tm(taskmanager memory) | 30000 | 该参数为分配给单个taskmanager的内存资源。只要taskmanager内存足够使用,内存资源分配增多对性能也无直接提高。可以在jobmanager内存分配之后,先将所有剩余内存分配给taskmanager。根据经验值,分配30000MB左右即可。 | +| -jm(jobmanager memory) | 5000 | 该参数为分配给jobmanager的内存资源。该参数对整体性能几乎无影响,不需要分配太大。根据经验值,分配5000MB~15000MB即可。 | +## 3.4 Flink任务参数调整 +### 目的 +使用yahoo- streaming-benchmark工具测试时,测试脚本中也有相关Flink配置需要修改,这些配置都在stream-bench-hdp.sh里,需要对这些参数根据实际情况调整。 +### 方法 +在stream-bench-hdp.sh文件中搜索以下参数并修改: +| 参数 | 建议值 | 描述 | +|------------|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Partitions | Kafka服务节点上磁盘数目的2~3倍。 | 该值为Kafka的分区数目,但在修改该值的同时,必须同步修改Flink任务启动时的两个并发度值。这是因为前面那个Flink任务是Flink随机生成数据,并且写入Kafka中,所以Flink并发度必须<=kafka的partitions数目,不然将会无法写入。而后者是Flink消费Kafka数据,虽然并发度不受partitions数目限制,但尽量将Flink两个任务并发度保持一致进行测试。由于Flink在向Yarn提交任务的时候,已经将slot、内存、taskmanager等分配完毕,所以此时Flink能够利用的资源时有限的。而-p后的并发度参数,就是需要占用taskmanager slot的参数。该用例需要两个进程同时运行,所以partitions参数不能超过总slot的1/2。即partitions <= -n(taskmanager) * -s(slot) / 2, 并发度对Flink性能的影响是比较大的,而且也没有太清晰的规律。一般来说,随partitions增加,时延的变化是先降低,再到一个平台期,最后再上升。 | +| Load | 根据实际调整。 | 数据量,该值唯一控制了单位时间的吞吐量,而当TEST_TIME固定的时候,设置LOAD即设置了该次用例运行的吞吐量(在Flink引擎足够处理的情况下)。所以Flink测试的性能数据有两种观察方式。 1是固定LOAD看时延大小。 2是固定时延看最大能将LOAD加到多大。 目前比较通用的都是方式2,即调整LOAD。 | +| TOPIC | ad-event{$partitions} | 该参数即为Kafka topic名称,不同的partition数目,必须修改不同的topic名称,一般采取ad-event{$partitions}的命名方式以避免重复。 | +| TEST_TIME | 240 | 测试时间,一般都固定时间为240s。 | +# 调优实例 +## 参数配置 +### Web配置 +| 组件 | 参数名 | 推荐值 | 修改原因 | +|-------------------|-----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------| +| Kafka->Broker | log.dir | /hadoop/data1/kafka-logs, /hadoop/data2/kafka-logs, /hadoop/data3/kafka-logs, ... /hadoop/data11/kafka-logs, /hadoop/data12/kafka-logs | 配置Kafka使用盘的数量为12盘,防止硬盘读写成为瓶颈。 | +| Kafka->Broker | num.partitions | 36 | 使用更多的partition数量,配合log.dir参数提升Kafka性能。以及对应Flink数据生成器的并发度。 | +| Kafka->Broker | num.network.threads | 128 | 增大Kafka网络线程数。 | +| Kafka->Broker | num.io.threads | 8 | Flink数据量不大,保持IO线程数较小,减轻CPU压力。 | +| Yarn->Nodemanager | yarn.nodemanager.resource.memory-mb | 224256 | 增大Yarn每个nodemanager能分配的最大内存数。 | +| Yarn->Nodemanager | yarn.nodemanager.resource. cpu-vcores | 48 | 增大Yarn每个nodemanager能分配的最大vcores数。 | +| Yarn->Nodemanager | yarn.nodemanager.numa-awareness.enabled | true | Yarn NUMA绑核开关开启。 | +| Yarn->Nodemanager | yarn.nodemanager.numa-awareness.read-topology | true | 选择由参数进行绑核还是启动命令中进行绑核,Flink选择启动命令中绑核。 | +| Yarn->Nodemanager | yarn.nodemanager.numa-awareness.numactl.cmd | /usr/bin/numactl | NUMA绑核工具系统路径。 | + + + + + + + + + diff --git "a/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/hbaseOptimization.md" "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/hbaseOptimization.md" new file mode 100644 index 0000000000000000000000000000000000000000..63bceab0fceebb1870564a939c2460e72c99f1d3 --- /dev/null +++ "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/hbaseOptimization.md" @@ -0,0 +1,592 @@ +# 1.调优概述 +## 1.1 HBase介绍 +HBase–Hadoop Database,是一个高可靠性、高性能,面向列、可伸缩的分布式存储系统,利用HBase技术可以在廉价的PC Server上搭建起大规模结构化存储集群。 + +HBase主要有三个组件,分别是HMaster、HRegionServer和ZooKeeper,三个组件的主要职责如下。 + +### HMaster + +HMaster是整个HBase组件的控制者,主要有以下职责: + +- 负载均衡。 +- 权限管理(ACL)。 +- HDFS上的垃圾文件回收。 +- 管理namespace和table的元数据。 +- 表格的创建、删除和更新(列族的更新)。 +- Region分配:启动时分配、失效RegionServer上Region的再分配、Region切分时分配。 + +### HRegionServer + +HRegionServer是HBase实际读写者,主要有以下职责: + +- Region切分。 +- HDFS交互,管理table数据。 +- 响应client的读写请求,进行I/O操作。 + +### ZooKeeper + +ZooKeeper是HBase的协调者,主要有以下职责: + +- 存储HBase中表格的元数据信息。 +- 保证集群中有且只有一个HMaster为Active。 +- 存储hbase:meta,即所有Region的位置信息。 +- 监测RegionServer状态,将RS的上下线情况汇报给HMaster。 +- ZooKeeper集群本身使用一致性协议(PAXOS协议)保证每个节点状态的一致性。 + +## 1.2 环境介绍 +### 物理组网 + +物理环境采用控制节点*1+数据节点*3的部署方案,在网络层面,管理与业务分离部署,管理网络使用GE电口来进行网络间的通信,业务网络使用10GE光口来进行网络间的通信,组网如图1所示。 + +**图1** 物理环境组网 +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108626930.png) + +### 软件版本 + +使用到的相关软件版本如表1所示。 + +| 软件 | 版本 | +| --------- | ------------------------- | +| OS | openEuler 20.03 LTS | +| JDK | OpenJDK version 1.8.0_272 | +| Zookeeper | 3.4.9 | +| Hadoop | 3.1.1 | +| HBase | 2.0.0 | + +### 节点部署规划 + +| 服务器 | 组件部署 | +| ------- | ------------------------------------------------------------ | +| server1 | NameNode、ResourceManager、Timeline Service V2.0 Reader、YARN Registry DNS、Timeline Service V1.5、History Server、HBase Master、Zookeeper Server、Metricks Collector、Grafana、Activity Analyzer、Activity Explorer、HST Server | +| agent1 | SNameNode、DataNode、RegionServer、NodeManager | +| agent2 | Zookeeper Server、DataNode、RegionServer、NodeManager | +| agent3 | Zookeeper Server、DataNode、RegionServer、NodeManager | + +## 1.3 调优原则 +性能调优就是对计算机硬件、操作系统和应用有相当深入的了解,调节三者之间的关系,实现整个系统(包括硬件、操作系统、应用)的性能最大化,并能不断的满足现有的业务需求。在性能优化时,我们必须遵循一定的原则,否则,有可能得不到正确的调优结果。主要有以下几个方面: + +- 对性能进行分析时,利用nmon等性能分析工具,多方面分析系统的资源瓶颈所在,因为系统某一方面性能低,也许并不是它自己造成的,而是其他方面造成的。 +- 一次只对影响性能的某方面的一个参数进行调整,例如在HBase调优过程中,Bulkload的影响参数有表的region大小、map的个数等,每次选取某一个参数进行调优,否则很难界定性能的影响是由哪个参数造成的。 +- 在进行系统性能分析时,性能分析工具本身会占用一定的系统资源,如CPU资源、内存资源等等。我们必须注意到这点,即分析工具本身运行可能会导致系统某方面的资源瓶颈情况更加严重。 + +## 1.4 调优思路 +性能调优首先要发现问题,找到性能瓶颈点,然后根据瓶颈所处层级选择优化的方法。 + +调优分析思路如下: + +1. 对于服务端的问题,需要重点定位的硬件指标包括CPU、内存、硬盘、BIOS配置,对于读写测试用例重点关注磁盘以及网络的IO性能;对于计算密集型例如Bulkload,需要关注CPU瓶颈。 +2. 对于网络问题,网卡中断绑核对于性能提升增益可观。 + +# 2.硬件调优 +## 2.1 配置BIOS +### 目的 + +对于不同的硬件设备,通过在BIOS中设置一些高级选项,可以有效提升服务器性能。 + +- 服务器上的SMMU一般用来完成设备的地址转换,并且可以实现设备隔离,在虚拟化中很实用,但是在物理机测试场景下,SMMU可能会导致性能下降,尤其对于小包网络场景,因此建议关闭该功能提升服务器性能。在虚拟机场景需要打开此配置来使用PCI直通功能。 +- 在本测试场景中,预取会导致cache污染,cache miss增加,因此建议关闭预取功能。 + +### 方法 + +1. 关闭SMMU。 + + 1. 重启服务器,按Esc键进入BIOS设置界面。 + + 2. 依次进入 “Advanced > MISC Config > > Support Smmu”。 + + **图1** BIOS设置界面 + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154826923.png) + + 3. 将“Support Smmu”设置为“Disabled”,按“F10”保存退出(永久有效)。 + + **图2** 关闭SMMU BIOS界面 + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108147314.png) + +2. 关闭预取。 + + 1. 进入BIOS设置界面。 + + 2. 依次进入 “Advanced > MISC Config > CPU Prefetching Configuration” 。 + + **图3** BIOS设置界面 + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154986843.png) + + 3. 将 “CPU Prefetching Configuration”设置为 “Disabled”,按“F10”保存退出(永久有效)。 + + **图4** 关闭Prefetching Configuration界面 + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154706973.png) +## 2.2 创建RAID 0 +### 目的 + +磁盘创建RAID可以提高磁盘的整体存取性能,环境上若使用的是LSI 3108/3408/3508系列RAID卡,推荐创建单盘RAID 0/RAID 5,充分利用RAID卡的Cache(LSI 3508卡为2GB),提高读写速率。 + +### 方法 + +1. 使用storcli64_arm文件检查RAID组创建情况。 + + + + `./storcli64_arm /c0 show ` + + ![img](https://r.huaweistatic.com/s/ascendstatic/lst/as/software/mindx/modelzoo/img_modelzoo_ts1227.svg)说明 + + + + storcli64_arm文件放在任意目录下执行皆可。 + + 文件下载路径:https://docs.broadcom.com/docs/007.1507.0000.0000_Unified_StorCLI.zip + + + +2. 创建RAID 0,命令表示为第2块1.2T硬盘创建RAID 0,其中,c0表示RAID卡所在ID、r0表示组RAID 0。依次类推,对除了系统盘之外的所有盘做此操作。 + + + + `./storcli64_arm /c0 add vd r0 drives=65:1 ` + + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108626926.png) +## 2.3 开启RAID卡Cache +### 目的 + +使用RAID卡的RAWBC(无超级电容)/RWBC(有超级电容)性能更佳。 + +使用storcli工具修改RAID组的Cache设置,Read Policy设置为Read ahead,使用RAID卡的Cache做预读;Write Policy设置为Write back,使用RAID卡的Cache做回写,而不是Write through透写;IO policy设置为Cached IO,使用RAID卡的Cache缓存IO。 + +### 方法 + +1. 配置RAID卡的Cache。 + + + + `./storcli64_arm /c0/vx set rdcache=RA ./storcli64_arm /c0/vx set wrcache=WB/AWB ./storcli64_arm /c0/vx set iopolicy=Cached ` + + ![img](https://r.huaweistatic.com/s/ascendstatic/lst/as/software/mindx/modelzoo/img_modelzoo_ts1227.svg)说明 + + + + ./storcli64_arm /c0/vx set wrcache=WB/AWB #命令中的WB/AWB取决于RAID卡是否有超级电容,无超级电容使用AWB。 + + + +2. 检查配置是否生效。 + + + + `./storcli64_arm /c0 show` +## 2.4 调整rx_buff +### 目的 + +1822网卡默认的rx_buff配置为2KB,在聚合64KB报文的时候需要多片不连续的内存,使用率较低;该参数可以配置为2/4/8/16KB,修改后可以减少不连续的内存,提高内存使用率。 + +### 方法 + +1. 查看rx_buff参数值,默认为2。 + + + + `cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff ` + + + +2. 在目录“/etc/modprobe.d/”中增加文件hinic.conf,修改rx_buff值为8。 + + + + ```reasonml + options hinic rx_buff=8 + ``` + + + +3. 重新挂载hinic驱动,使得新参数生效。 + + + + `rmmod hinic modprobe hinic ` + + + +4. 查看rx_buff参数是否更新成功。 + + + + `cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff` +## 2.5 调整Ring Buffer +### 目的 + +1822网卡Ring Buffer最大支持4096,默认配置为1024,可以增大buffer大小用于提高网卡Ring大小。 + +### 方法 + +1. 查看Ring Buffer默认大小,假设当前网卡名为enp131s0。 + + + + `ethtool -g enp131s0 ` + + ![img](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108307122.png) + + + +2. 修改Ring Buffer值为4096。 + + + + ```reasonml + ethtool -G enp131s0 rx 4096 tx 4096 + ``` + + + +3. 查看Ring Buffer值是否更新成功。 + + + + `ethtool -g enp131s0 ` + + ![img](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108147308.png) +## 2.6 开启LRO +### 目的 + +1822网卡支持LRO(Large Receive Offload),可以打开该选项,并合理配置1822 LRO参数。 + +### 方法 + +1. 查看LRO参数是否开启,默认为off,假设当前网卡名为enp131s0。 + + + + `ethtool -k enp131s0 ` + + ![img](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108467080.png) + + + +2. 打开LRO。 + + + + ```reasonml + ethtool -K enp131s0 lro on + ``` + + + +3. 查看LRO参数是否开启。 + + + + `ethtool -k enp131s0 ` + + ![img](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154986839.png) +## 2.7 配置网卡中断绑核 +### 目的 + +相比使用内核的irqbalance使网卡中断在所有核上进行调度,使用手动绑核将中断固定住能有效提高业务网络收发包的能力。 + +### 方法 + +1. 关闭irqbalance。 + + + + 若要对网卡进行绑核操作,则需要关闭irqbalance。 + + 1. 停止irqbalance服务,重启失效。 + + `systemctl stop irqbalance.service ` + + 2. 关闭irqbalance服务,永久有效。 + + `systemctl disable irqbalance.service ` + + 3. 查看irqbalance服务状态是否已关闭。 + + `systemctl status irqbalance.service ` + + + +2. 查看网卡pci设备号,假设当前网卡名为enp131s0。 + + + + `ethtool -i enp131s0 ` + + ![img](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108467078.png) + + + +3. 查看pcie网卡所属NUMA node。 + + + + `lspci -vvvs ` + + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154986837.png) + + + +4. 查看NUMA node对应的core的区间,例如此处就可以绑到48~63。 + + + + `lscpu ` + + ![img](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154826917.png) + + + +5. 进行中断绑核,1822网卡共有16个队列,将这些中断逐个绑至所在NumaNode的16个Core上(例如此处就是绑到NUMA node1对应的48-63上面)。 + + + + `bash smartIrq.sh ` + + 脚本内容如下: + + ```SHELL + #!/bin/bash + irq_list=(`cat /proc/interrupts | grep enp131s0 | awk -F: '{print $1}'`) + cpunum=48 # 修改为所在node的第一个Core + for irq in ${irq_list[@]} + do + echo $cpunum > /proc/irq/$irq/smp_affinity_list + echo `cat /proc/irq/$irq/smp_affinity_list` + (( cpunum+=1 )) + done + ``` + + + + + +6. 利用脚本查看是否绑核成功。 + + + + `sh irqCheck.sh enp131s0 ` + + ![img](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154706967.png) + + 脚本内容如下: + + ```shell + #!/bin/bash + # 网卡名 + intf=$1 + log=irqSet-`date "+%Y%m%d-%H%M%S"`.log + # 可用的CPU数 + cpuNum=$(cat /proc/cpuinfo |grep processor -c) + # RX TX中断列表 + irqListRx=$(cat /proc/interrupts | grep ${intf} | awk -F':' '{print $1}') + irqListTx=$(cat /proc/interrupts | grep ${intf} | awk -F':' '{print $1}') + # 绑定接收中断rx irq + for irqRX in ${irqListRx[@]} + do + cat /proc/irq/${irqRX}/smp_affinity_list + done + # 绑定发送中断tx irq + for irqTX in ${irqListTx[@]} + do + cat /proc/irq/${irqTX}/smp_affinity_list + done + ``` + +# 3.操作系统调优 +## 3.1 关闭内存大页 +### 目的 + +关闭内存大页,防止内存泄漏,减少卡顿。 + +### 方法 + +1. 关闭内存大页。 + + ```shell + echo never > /sys/kernel/mm/transparent_hugepage/enabled + echo never > /sys/kernel/mm/transparent_hugepage/defrag + ``` + + + +2. 检查是否关闭。 + + + + `cat /sys/kernel/mm/transparent_hugepage/enabled ` + + 从下图可以看出内存大页已经从always变成never。 + + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154867011.png) + + +## 3.2 关闭swap +### 目的 + +Linux的虚拟内存会根据系统负载自动调整,内存页(page)swap到磁盘会影响测试性能。 + +### 方法 + +``` +swapoff -a +``` + +修改前后对比。 + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108467084.png) + +# 4.HBase调优 +## 4.1 组件参数配置 +对于参数的修改,Ambari基本都是在集群的网页上面修改即可,以Yarn组件为例,单击右边需要更改参数的组件Yarn,参数修改都是在对应组件的CONFIGS里面。修改配置的地方对应的就是在SETTING以及ADVANCED中,如下图所示。 + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154706969.png) + +当要修改具体的参数的时候,主要分两种情况,第一种对于参数原本就在网页设置了初始值的,只需要在CONFIGS页面的搜索栏直接搜索、修改即可,例如修改Yarn中的yarn.nodemanager.resource.cpu-vcores,只需要在搜索框搜索“yarn.nodemanager.resource.cpu-vcores”,单击修改按钮,设置对应的参数即可。 + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154826919.png) + +第二种对于原本页面上没有设置初始值的参数,例如yarn.nodemanager.numa-awareness.enabled这一参数,就需要在对应组件的Custom yarn-site中手动添加(其余组件需要手动添加的也是在对应的Custom ***-site文件中)。 + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108147310.png) + +如下参数为本次测试所配置参数,x86计算平台和鲲鹏920计算平台参数仅有Yarn部分参数有差异(差异处表格中有体现),HBase和HDFS采用同一套参数进行测试。 + +| 组件 | 参数名 | 推荐值 | 修改原因 | +| -------------------------------------- | --------------------------------------------- | -------------------------------- | ------------------------------------------------------------ | +| Yarn->NodeManagerYarn->ResourceManager | ResourceManager Java heap size | 1024 | 修改JVM内存大小,保证内存水平较高,减少GC的频率。 | +| NodeManager Java heap size | 1024 | | | +| Yarn->NodeManager | yarn.nodemanager.resource.cpu-vcores | 与实际数据节点物理核相等。 | 可分配给Container的CPU核数。 | +| Yarn->NodeManager | yarn.nodemanager.resource.memory-mb | 与实际数据节点物理内存总量相等。 | 可分配给Container的内存。 | +| Yarn->NodeManager | yarn.nodemanager.numa-awareness.enabled | true | NodeManager启动Container时的Numa感知,需手动添加。 | +| Yarn->NodeManager | yarn.nodemanager.numa-awareness.read-topology | true | NodeManager的Numa拓扑自动感知,需手动添加。 | +| MapReduce2 | mapreduce.map.memory.mb | 7168 | 一个Map Task可使用的内存上限。 | +| MapReduce2 | mapreduce.reduce.memory.mb | 14336 | 一个Reduce Task可使用的资源上限。 | +| MapReduce2 | mapreduce.job.reduce.slowstart.completedmaps | 0.35 | 当Map完成的比例达到该值后才会为Reduce申请资源。 | +| HDFS->NameNode | NameNode Java heap size | 3072 | 修改JVM内存大小,保证内存水平较高,减少GC的频率。 | +| NameNode new generation size | 384 | | | +| NameNode maximum new generation size | 384 | | | +| HDFS->DataNode | dfs.datanode.handler.count | 512 | DataNode服务线程数,可适量增加。 | +| HDFS->NameNode | dfs.namenode.service.handler.count | 128 | NameNode RPC服务端监测DataNode和其他请求的线程数,可适量增加。 | +| HDFS->NameNode | dfs.namenode.handler.count | 1200 | NameNode RPC服务端监测客户端请求的线程数,可适量增加。 | +| HBase->RegionServer | HBase RegionServer Maximum Memory | 31744 | 修改JVM内存大小,保证内存水平较高,减少GC的频率。 | +| HBase->RegionServer | hbase.regionserver.handler.count | 150 | RegionServer上的RPC服务器实例数量。 | +| HBase->RegionServer | hbase.regionserver.metahandler.count | 150 | RegionServer中处理优先请求的程序实例的数量。 | +| HBase->RegionServer | hbase.regionserver.global.memstore.size | 0.4 | 最大JVM堆大小(Java -Xmx设置)分配给MemStore的比例。 | +| HBase->RegionServer | hfile.block.cache.size | 0.4 | 数据缓存所占的RegionServer GC -Xmx百分比。 | +| HBase->RegionServer | hbase.hregion.memstore.flush.size | 267386880 | Regionserver memstore大小,增大可以减小阻塞。 | + +## 4.2 NUMA特性开启 +Yarn组件在3.1.0版本合入的新特性支持,支持Yarn组件在启动Container时使能NUMA感知功能,原理是读取系统物理节点上每个NUMA节点的CPU核、内存容量,使用Numactl命令指定启动container的CPU范围和membind范围,减少跨片访问。 + +1. 安装numactl。 + + + + `yum install numactl.aarch64 -y ` + + + +2. 开启NUMA感知(在[组件参数配置](https://www.hikunpeng.com/document/detail/zh/kunpengbds/ecosystemEnable/HBase/kunpenghbasehdp_05_0018_0.html)中已经做过的可以不做)。 + + + + 增加Yarn->NodeManager: + + ```reasonml + yarn.nodemanager.numa-awareness.enabled true + yarn.nodemanager.numa-awareness.read-topology true + ``` + +## 4.3 读写测试用例 +### 用例分析 + +随机写:随机写CPU平均占用为8%,但是会产生大量的IO。主要是为HBase写hlog、memstore flush和compaction三个流程会产生大量IO。其中写hlog会产生大量的小IO。因此该用例对IO性能比较敏感,同样对CPU性能不敏感,通用由于有较多的网络小包,因此通过使能网卡lro会使写的性能提升。 + +随机读:随机读用例整体CPU资源利用很低,整体的IO也是在用例初始时进行hfile的读取到blockcache中,之后数据会有大量的cache命中。由于网络中存在的较多小包,因此主要使能了网卡lro功能,对网络小包进行聚合。 + +顺序扫描:顺序扫描用例CPU资源利用也很低,整体的IO也是在用例初始时进行hfile的读取到blockcache中,之后的数据都是从blockcache中进行读取。该用例和随机读用例的流程是相同的,只是在读取keyvalue时会顺序的读取一段连续的keyvalue区域。因此scan时的网络包聚合效果不明显。 + +### Slow sync调优 + +**问题描述** + +HBase在高并发put场景(随机写用例),由于同步写WAL机制导致随机写性能很差,日志中打印sync时延很高。![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108307124.png) + +**问题分析** + +由于同步写WAL机制,必须保证数据落盘才能保证可靠性,所以导致在写流程中写WAL时延很高,严重影响性能。 + +**解决方法** + +硬盘组单盘创建RAID 0,然后配置RAID卡Cache策略为RAWBC,使用RAID卡的Cache做回写,而不是Write through透写,可以极大提高随机写性能。 + +RAID组Cache策略配置: + +RWBC -> Read ahead + Write back + Cached IO + +### 网卡参数调优 + +在HBase读写测试场景,测试的记录条的大小为1KB,因此使能网卡lro功能和调大网卡Ring buffer。将网络中的小包进行聚合,挺高网络性能。 + +## 4.4 Bulkload测试用例 +### 用例分析 + +Bulkload用例前半部分鲲鹏计算平台48核CPU占用90%+,x86计算平台CPU占用100%。分析Bulkload用例具体流程如下: + +1. map阶段:该阶段是并发生成hfile,根据数据量的大小,map阶段会有上万个并发去加载hdfs中待导入的数据,然后进行格式转换,格式转换过后会对数据进行校验,检测kv是否有效。最后会对生成的hfile进行压缩。这一过程会消耗大量的CPU。现有mapreduce配置为1个map申请一个vcore。 +2. reduce阶段:根据region个数将生成的hfile放置到不同的region。reduce阶段的并发数量是根据region个数来决定的。 + +### Map优化 + +Bulkload的ImportTsv默认是以HDFS的blocksize(默认128MB)来切分数据文件,如200G的数据文件大概有1600多个map任务,但是并没有相应的参数设定来修改map数,故通过更改ImportTsv源码,ImportTsv该类具体位于HBase源码的hbase-mapreduce-2.0.2.3.1.0.0-78.jar中,具体的路径如下。 + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154867013.png) + +在ImportTsv.java增加一个配置参数,即增加一个成员变量: + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108467082.png) + +在createSubmittableJob方法中增加如下代码: + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154986841.png) + +将该jar包重新编译后,通过find查找到jar包所在位置,替换到对应的HBase源码中。 + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154706971.png) + +替换之后就可以在ImportTsv上配置一个mapreduce.split.minsize参数,参照如下。 + +``` +hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.columns=HBASE_ROW_KEY,f1:H_NAME,f1:ADDRESS -Dimporttsv.separator="," -Dimporttsv.skip.bad.lines=true -Dmapreduce.split.minsize=5368709120 -Dimporttsv.bulk.output=/tmp/hbase/hfile ImportTable /tmp/hbase/datadirImport +``` + +![img](https://r.huaweistatic.com/s/ascendstatic/lst/as/software/mindx/modelzoo/img_modelzoo_ts1227.svg)说明 + + + +-Dmapreduce.split.minsize=5368709120:该值就是设定了数据文件的分割数值,进而可以修改map数值,设置map数时可以将map数与CPU核数设置差不多。 + +### Reduce优化 + +查看任务运行的时间,发现reduce运行时间很不均衡,有的3分钟,有的40秒,相差很大,故尝试增加reduce数,使每个reduce处理数据更均衡。 + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154826921.png) + +通过修改预分区数(region),可以修改reduce数量。(本次测试设定的是800region) + +修改对应文件run_create.txt中的split_num即可修改region数量。 + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108147312.png) + +### 顺序数据测试 + +本次bulkload测试的数据为每条1K,单条格式如下: + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108307126.png) + +HBase的Rowkey是按照ASCII字典排序设计的,排序时会先比对两个Rowkey的第一个字节,如果相同,然后会比对第二个字节,依次类推,直到比较到最后一位。为了保证数据能够均衡写入到每个region,利用位补齐的方法将Rowkey的位数长度设置成一样。 + +![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108626928.png) + + + diff --git "a/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/hiveOptimization.md" "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/hiveOptimization.md" new file mode 100644 index 0000000000000000000000000000000000000000..c89a2b202007741eabead3bd0c66ab2b03db1e4a --- /dev/null +++ "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/hiveOptimization.md" @@ -0,0 +1,512 @@ +### 1.调优概述 +#### 1.1 Hive介绍 +**Hive工作流** +Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。 + +![hive执行任务流程图](https://foruda.gitee.com/images/1679293870604619016/63e29923_12582270.png "hive执行任务流程图") + **流程大致步骤为:** +1)用户提交查询等任务给Driver。 +2)编译器获得该用户的任务Plan。 +3)编译器Compiler根据用户任务去MetaStore中获取需要的Hive的元数据信息。 +4)编译器Compiler得到元数据信息,对任务进行编译,先将HiveQL转换为抽象语法树,然后将抽象语法树转换成查询块,将查询块转化为逻辑的查询计划,重写逻辑查询计划,将逻辑计划转化为物理的计划(TEZ), 最后选择最佳的策略。 +5)将最终的计划提交给Driver。 +6)Driver将计划Plan转交给ExecutionEngine去执行,获取元数据信息,提交给JobTracker或者SourceManager执行该任务,任务会直接读取HDFS中文件进行相应的操作。 +7)获取执行的结果。 +8)取得并返回执行结果。 + +从上面的流程可以看出,影响Hive执行的主要有两部分: +1)编译器任务编译。这部分会直接影响查询计划,不同的查询计划影响实际的物理计划(TEZ)。 +2)TEZ引擎。这个是Hive任务的主体。 + + **Tez引擎** +Tez是基于Hadoop YARN之上的DAG(有向无环图,Directed Acyclic Graph)计算框架。Tez直接源于MapReduce框架,核心思想是将Map和Reduce两个操作进一步拆分,即Map被拆分成Input、Processor、Sort、Merge和Output, Reduce被拆分成Input、Shuffle、Sort、Merge、Processor和Output等,被分解后的元操作可灵活组合,产生新的操作,这些操作经一些控制程序组装后,可形成一个大的DAG作业。采用Tez计算框架,生成一个简洁的DAG作业,算子跑完不退出,下轮继续使用上一轮的算子,这样大大减少磁盘IO操作,从而计算速度更快。 +![tez引擎](https://foruda.gitee.com/images/1679294129068361556/cf8c79c8_12582270.png "tez引擎") + +总结起来,Tez有以下特点: + +1)运行在YARN之上。 +2)与MapReduce兼容,继承了MapReduce的各种优点(比如良好的扩展性与容错性)。 +3)适用于DAG应用场景。 + +Tez在底层提供了DAG编程接口,用户利用这些接口进行程序编写,其主要由两部分组成:数据处理引擎和DAGAppMaster,其中数据处理引擎为其提供了一套编程接口和数据计算操作符,而DAGAppMaster则是一个YARN ApplicationMaster,它使得Tez应用程序可运行在YARN上。 + +简单举例演示,例如以下Hive SQL会翻译成四个MR作业,而采用Tez则生成一个DAG作业,可大大减少磁盘IO。 +![tez引擎执行任务图](https://foruda.gitee.com/images/1679294292394163183/f5929a81_12582270.png "tez引擎执行任务图") + +#### 1.2 环境介绍 + +物理环境采用控制节点*1(server1)+数据节点*3(agent1、agent2、agent3)的部署方案,在网络层面,管理与业务分离部署,管理网络使用GE电口来进行网络间的通信,业务网络使用10GE光口来进行网络间的通信,组网如下图所示。 +![组网](https://foruda.gitee.com/images/1679294533567297550/34c614ad_12582270.png "组网") + + **软件版本** +| 软件 | 版本 | +|-----------|---------------------------| +| OS | OpenEuler22.03 | +| JDK | OpenJDK version 1.8.0_272 | +| Zookeeper | 3.4.9 | +| Hive | 3.0.0 | +| Hadoop | 3.1.1 | +| Spark2x | 2.3.0 | +| Tez | 0.9.0 | + + **节点部署规划** +| 机器名称 | 服务名称 | +| ---------------- |---------------- | +|server1|Namenode、ResourceManager、RunJar、RunJar| +|agent1|QuorumPeerMain、DataNode、NodeManager、JournalNode| +|agent2|QuorumPeerMain、DataNode、NodeManager、JournalNode| +|agent3|QuorumPeerMain、DataNode、NodeManager、JournalNode| + +#### 1.3 调优规则 + +性能调优就是对计算机硬件、操作系统和应用有相当深入的了解,调节三者之间的关系,实现整个系统(包括硬件、操作系统、应用)的性能最大化,并能不断的满足现有的业务需求。在性能优化时,我们必须遵循一定的原则,否则,有可能得不到正确的调优结果。主要有以下几个方面: + +1)对性能进行分析时,利用nmon等性能分析工具,多方面分析系统的资源瓶颈所在,因为系统某一方面性能低,也许并不是它自己造成的,而是其他方面造成的。 +2)一次只对影响性能的某方面的一个参数进行调整,例如在Hive调优过程中,影响参数有内存大小、cbo查询计划等,每次选取某一个参数进行调优,否则很难界定性能的影响是由哪个参数造成的。 +3)由于在进行系统性能分析时,性能分析工具本身会占用一定的系统资源,如CPU资源、内存资源等等。我们必须注意到这点,即分析工具本身运行可能会导致系统某方面的资源瓶颈情况更加严重。 +#### 1.4 调优思路 +性能调优首先要发现问题,找到性能瓶颈点,然后根据瓶颈所处层级选择优化的方法。 + +调优分析思路如下: + +1)对于服务端的问题,需要重点定位的硬件指标包括CPU、内存、硬盘、BIOS配置,利用监测得到的数据进行性能分析,查看性能瓶颈点。 +2)对于网络问题,网卡中断绑核对于性能提升增益可观。 +3)具体而言,在Hive优化时,主要是两方面影响了性能,一个是查询计划,一个是Tez的任务执行。 +Hive调优需要看HiveServer的运行日志及GC日志。 +HiveServer日志路径为:HiveServer节点的“/var/log/hive”。 + +主要分为以下过程: + +a.分析SQL待处理的表及文件。统计待处理的表的文件数、数据量、条数、文件格式、压缩格式,分析是否有更适合的文件存储格式、压缩格式,是否能够使用分区或分桶,是否有大量小文件需要map前合并。如果有优化空间,则执行优化。 +1.如何判断是否有更合适的文件存储格式 +当前TPC-DS测试,使用的文件存储格式为orc,当前测试性能最优,推荐使用该存储格式。 + +2.如何判断是否有更合适的压缩格式 +当前TPC-DS测试,在map/reduce阶段,使用的数据压缩格式为SNAPPY,当前测试性能最优,推荐使用该压缩格式。 + +3.如何判断是否能够使用分区或分桶 +庞大的数据集可能需要耗费大量的时间去处理。在许多场景下,可以通过分区或切片的方法减少每一次扫描总数据量,这种做法可以显著地改善性能。Hive的分区使用HDFS的子目录功能实现。每一个子目录包含了分区对应的列名和每一列的值。但是由于HDFS并不支持大量的子目录,这也给分区的使用带来了限制。我们有必要对表中的分区数量进行预估,从而避免因为分区数量过大带来一系列问题。Hive查询通常使用分区的列作为查询条件。这样的做法可以指定MapReduce任务在HDFS中指定的子目录下完成扫描的工作。HDFS的文件目录结构可以像索引一样高效利用。 + +如: +``` +CREATE TABLE logs( +timestamp BIGINT, +line STRING +) +PARTITIONED BY (date STRING,country STRING); +``` +PARTITONED BY子句中定义的列是表中正式的列(分区列),但是数据文件内并不包含这些列。 + +Hive还可以把表或分区,组织成桶。将表或分区组织成桶有以下几个目的: +第一个目的是为看取样更高效,因为在处理大规模的数据集时,在开发、测试阶段将所有的数据全部处理一遍可能不太现实,这时取样就必不可少。 +第二个目的是为了获得更好的查询处理效率。 + +桶为表提供了额外的结构,Hive在处理某些查询时利用这个结构,能够有效地提高查询效率。 +桶是通过对指定列进行哈希计算来实现的,通过哈希值将一个列名下的数据切分为一组桶,并使每个桶对应于该列名下的一个存储文件。 +在建立桶之前,需要设置hive.enforce.bucketing属性为true,使得Hive能识别桶。 + +以下为创建带有桶的表的语句: +``` +CREATE TABLE bucketed_user( +id INT, +name String +) +CLUSTERED BY (id) INTO 4 BUCKETS; +``` +分区中的数据可以被进一步拆分成桶,bucket,不同于分区对列直接进行拆分,桶往往使用列的哈希值进行数据采样。 + +在分区数量过于庞大以至于可能导致文件系统崩溃时,建议使用桶。 +4.如何判断是否有大量小文件需要map前合并。 +查看每张表的下文件的大小,如果小文件(文件大小小于blocksize)很多,那么建议在map前将小文件进行合并,合并语句如下。 +``` +ALTER TABLE $table_name CONCATENATE. +``` +b.根据nmon抓取的数据分析性能瓶颈,根据CPU以及内存的使用情况,修改hive.tez.container.size等参数。 + +### 2.硬件调优 +#### 2.1 配置BIOS + **目的** +对于不同的硬件设备,通过在BIOS中设置一些高级选项,可以有效提升服务器性能。 + +1)服务器上的SMMU一般用来完成设备的地址转换,并且可以实现设备隔离,在虚拟化中很实用,但是在物理机测试场景下,SMMU可能会导致性能下降,尤其对于小包网络场景,因此建议关闭该功能提升服务器性能。在虚拟机场景需要打开此配置来使用PCI直通功能。 +2)在本测试场景中,预取会导致cache污染,cache miss增加,因此建议关闭预取功能。 + + **方法** +1.关闭SMMU。 +1)重启服务器,按Esc键进入BIOS设置界面。 +2)依次进入“Advanced > MISC Config > Support Stmmu”。 +3)将“Support Smmu”设置为“Disabled”,按“F10”保存退出(永久有效)。 + +2.关闭预取。 +1)进入BIOS设置界面。 +2)依次进入“Advanced > MISC Config > CPU Prefetching Configuration”。 +3)将“CPU Prefetching Configuration”设置为“Disabled”,按“F10”保存退出(永久有效)。 +#### 2.2 创建RAID0 + **目的** +磁盘创建RAID可以提高磁盘的整体存取性能,环境上若使用的是LSI 3108/3408/3508系列RAID卡,推荐创建单盘RAID0/RAID5,充分利用RAID卡的Cache(LSI 3508卡为2GB),提高读写速率。 + **方法** +1.使用storcli64_arm文件检查RAID组创建情况。 +``` +./storcli64_arm /c0 show +``` +2.创建RAID 0,命令表示为第2块1.2T硬盘创建RAID 0,其中,c0表示RAID卡所在ID、r0表示组RAID 0。依次类推,对除了系统盘之外的所有盘做此操作。 +``` +./storcli64_arm /c0 add vd r0 drives=65:1 +``` +![raid0硬盘信息](https://foruda.gitee.com/images/1679296692757699634/3edc3db6_12582270.png "raid0硬盘信息") +#### 2.3 开启RAID卡Cache + **目的** +使用RAID卡的RAWBC(无超级电容)/RWBC(有超级电容)性能更佳。 + +使用storcli工具修改RAID组的Cache设置,Read Policy设置为Read ahead,使用RAID卡的Cache做预读;Write Policy设置为Write back,使用RAID卡的Cache做回写,而不是Write through透写;IO policy设置为Cached IO,使用RAID卡的Cache缓存IO。 + **方法** +1.配置RAID卡的cache。 +``` +./storcli64_arm /c0/vx set rdcache=RA +./storcli64_arm /c0/vx set wrcache=WB/AWB +./storcli64_arm /c0/vx set iopolicy=Cached +``` +2.检查配置是否生效。 +``` +./storcli64_arm /c0 show +``` +#### 2.4 调整rx_buff + **目的** +1822网卡默认的rx_buff配置为2KB,在聚合64KB报文的时候需要多片不连续的内存,使用率较低;该参数可以配置为2/4/8/16KB,修改后可以减少不连续的内存,提高内存使用率。 + **方法** +1.查看rx_buff参数值,默认为2。 +``` +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +``` +2.在目录“/etc/modprobe.d/”中增加文件hinic.conf,修改rx_buff值为8。 +``` +options hinic rx_buff=8 +``` +3.重新挂载hinic驱动,使得新参数生效。 +``` +rmmod hinic +modprobe hinic +``` +4.查看rx_buff参数是否更新成功。 +``` +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +``` +#### 2.5 调整Ring Buffer + **目的** +1822网卡Ring Buffer最大支持4096,默认配置为1024,可以增大buffer大小用于提高网卡Ring大小。 + **方法** +1.查看Ring Buffer默认大小,假设当前网卡名为enp131s0。 +``` +ethtool -g enp131s0 +``` +![Ring Buffer](https://foruda.gitee.com/images/1679297097168932888/086eddb2_12582270.png "Ring Buffer信息") +2.修改Ring Buffer值为4096。 +``` +ethtool -G enp131s0 rx 4096 tx 4096 +``` +3.查看Ring Buffer值是否更新成功。 +``` +ethtool -g enp131s0 +``` +!Ring Buffer值](https://foruda.gitee.com/images/1679297151878395704/1b4e76b5_12582270.png "Ring Buffer值信息") +#### 2.6 开启LRO + **目的** +1822网卡支持LRO(Large Receive Offload),可以打开该选项,并合理配置1822 LRO参数。 + **方法** +1.查看LRO参数是否开启,默认为off,假设当前网卡名为enp131s0。 +``` +ethtool -k enp131s0 +``` +![LRO参数信息](https://foruda.gitee.com/images/1679297290754554842/dea3f5bb_12582270.png "LRO参数信息") +2.打开LRO。 +``` +ethtool -K enp131s0 lro on +``` +3.查看LRO参数是否开启。 +``` +ethtool -k enp131s0 +``` +![LRO参数信息](https://foruda.gitee.com/images/1679297341729933809/2f81569d_12582270.png "LRO参数信息") +#### 2.7 配置网卡中断绑核 + **目的** +相比使用内核的irqbalance使网卡中断在所有核上进行调度,使用手动绑核将中断固定住能有效提高业务网络收发包的能力。 + **方法** +1.关闭irqbalance。 +若要对网卡进行绑核操作,则需要关闭irqbalance。 +a.停止irqbalance服务,重启失效。 +``` +systemctl stop irqbalance.service +``` +b.关闭irqbalance服务,永久有效。 +``` +systemctl disable irqbalance.service +``` +c.查看irqbalance服务状态是否已关闭。 +``` +systemctl status irqbalance.service +``` +2.查看网卡pci设备号,假设当前网卡名为enp131s0。 +``` +ethtool -i enp131s0 +``` +![网卡pci设备号](https://foruda.gitee.com/images/1679297453531256848/9c085b58_12582270.png "网卡pci设备号") +3.查看pcie网卡所属NUMA node。 +``` +lspci -vvvs +``` +![pcie网卡所属NUMA node](https://foruda.gitee.com/images/1679297480360574839/d79861bd_12582270.png "pcie网卡所属NUMA node") +4.查看NUMA node对应的core的区间,例如此处就可以绑到48~63。 +``` +lscpu +``` +![cpu](https://foruda.gitee.com/images/1679297507730165344/9160f1e3_12582270.png "cpu") +5.进行中断绑核,1822网卡共有16个队列,将这些中断逐个绑至所在NumaNode的16个Core上(例如此处就是绑到NUMA node1对应的48-63上面)。 +``` +bash smartIrq.sh + +脚本内容如下: +#!/bin/bash +irq_list=(`cat /proc/interrupts | grep enp131s0 | awk -F: '{print $1}'`) +cpunum=48 # 修改为所在node的第一个Core +for irq in ${irq_list[@]} +do +echo $cpunum > /proc/irq/$irq/smp_affinity_list +echo `cat /proc/irq/$irq/smp_affinity_list` +(( cpunum+=1 )) +done +``` +6.利用脚本查看是否绑核成功。 +``` +sh irqCheck.sh enp131s0 + +脚本内容如下: +#!/bin/bash +# 网卡名 +intf=$1 +log=irqSet-`date "+%Y%m%d-%H%M%S"`.log +# 可用的CPU数 +cpuNum=$(cat /proc/cpuinfo |grep processor -c) +# RX TX中断列表 +irqListRx=$(cat /proc/interrupts | grep ${intf} | awk -F':' '{print $1}') +irqListTx=$(cat /proc/interrupts | grep ${intf} | awk -F':' '{print $1}') +# 绑定接收中断rx irq +for irqRX in ${irqListRx[@]} +do +cat /proc/irq/${irqRX}/smp_affinity_list +done +# 绑定发送中断tx irq +for irqTX in ${irqListTx[@]} +do +cat /proc/irq/${irqTX}/smp_affinity_list +done +``` +![绑核信息](https://foruda.gitee.com/images/1679297565768443806/03c2f828_12582270.png "绑核信息") +#### 2.8 磁盘配置 + **磁盘规划** +在Hadoop类环境中,基本为单盘做数据盘,因此存在两种选项——JBOD和单盘RAID 0。 + +环境上若使用的是LSI 3108/3408/3508系列RAID卡,推荐组建单盘RAID 0,充分利用RAID卡的Cache(LSI 3508卡为2GB),提高读写速率。 + **Cache策略** +使用storcli工具修改RAID组的Cache设置,Read Policy设置为Read ahead,使用RAID卡的Cache做预读;Write Policy设置为Write back,使用RAID卡的Cache做回写,而不是Write through透写;IO policy设置为Cached IO,使用RAID卡的Cache缓存IO。 + +在实测中,RAWBD与RAWBC之间会有3~5%的端到端性能差异,使用RAWBC(无超级电容)/RWBC(有超级电容)性能更佳。 + +配置命令如下: +``` +./storcli /c0/vx set rdcache=RA +./storcli /c0/vx set wrcache=WB/AWB +./storcli /c0/vx set iopolicy=Cached +``` + **块设备配置** +主要涉及scheduler、sector_size、read_ahead_kb配置。 + +根据实测,scheduler应使用deadline性能最优。 +``` +cat /sys/block/sdx/queue/scheduler +``` +![scheduler信息](https://foruda.gitee.com/images/1679297834015460513/293de6c1_12582270.png "scheduler信息") + +块设备的sector_size应与物理盘的扇区大小进行匹配。可通过hw_sector_size、max_hw_sectors_kb、max_sectors_kb三者进行匹配,前两者是从硬件中读取出来的值,第三者是内核块设备的聚合最大块大小,推荐与硬件保持一致,即后两者参数保证一致。 +a.查看三者参数。 +``` +cat /sys/block/sdx/queue/hw_sector_size +cat /sys/block/sdx/queue/max_hw_sectors_kb +cat /sys/block/sdx/queue/max_sectors_kb +``` +![输入图片说明](https://foruda.gitee.com/images/1679297894129006604/c5acf731_12582270.png "屏幕截图") +b.修改参数并查看是否修改成功。 +![输入图片说明](https://foruda.gitee.com/images/1679297915770767981/2f1a6577_12582270.png "屏幕截图") + +块设备的预读推荐设置为4M,读性能更佳,默认值一般为128KB。 +a.查看预读设置值 +``` +/sbin/blockdev --getra /dev/sdb +``` +![输入图片说明](https://foruda.gitee.com/images/1679297949082595011/86046816_12582270.png "屏幕截图") +b.设置并检验。 +``` +/sbin/blockdev --setra 4096 /dev/sdb +``` +![输入图片说明](https://foruda.gitee.com/images/1679297976912084956/b4f830e3_12582270.png "屏幕截图") + +### 3.操作系统优化 +#### 3.1 内存参数配置 + **目的** +通过关闭内存大页、配置脏页参数等方法提升整体性能。 + **方法** +1.关闭内存大页。 +``` +echo never > /sys/kernel/mm/transparent_hugepage/enabled +echo never > /sys/kernel/mm/transparent_hugepage/defrag +``` +2.配置脏页参数。 +``` +echo 500 > /proc/sys/vm/dirty_expire_centisecs +echo 100 > /proc/sys/vm/dirty_writeback_centisecs +``` +3.其他 +``` +echo 1 > /proc/sys/kernel/numa_balancing +echo 0 > /proc/sys/kernel/sched_autogroup_enabled +``` +#### 3.2 调整IO调度策略 + **目的** +对agent节点,将IO调度策略调整成mq-deadline,能有更高的IO效率。 + **方法** +在agent节点上,把所有的HDD数据盘的IO策略都调整成mq-deadline。 +``` +list="a b c d e f g h i j k l" # 按需修改 +for i in $list +do +echo mq-deadline > /sys/block/sd$i/queue/scheduler +done +``` +#### 3.3 关闭swap + **目的** +Linux的虚拟内存会根据系统负载自动调整,内存页(page)swap到磁盘会影响测试性能。 + **方法** +``` +swapoff -a +``` +修改前后对比如下: +![输入图片说明](https://foruda.gitee.com/images/1679298358283896974/7a1db435_12582270.png "屏幕截图") +### 4.Hive调优 +#### 4.1 组件参数配置 +具体的各个组件的参数设置如表1所示。 + +表1 参数设置 +| 组件 | 参数名 | 推荐值 | 修改原因 | +| -------------------------------------- | --------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------ | +| Yarn->NodeManagerYarn->ResourceManager | ResourceManager Java heap size | 1024 | 修改JVM内存大小,保证内存水平较高,减少GC的频率。**说明:**非固定值,需要根据GC的释放情况来调大或调小Xms及Xmx的值。 | +| NodeManager Java heap size | 1024 | | | +| Yarn->NodeManager | yarn.nodemanager.resource.cpu-vcores | 鲲鹏计算平台48核环境推荐值48。 | 可分配给Container的CPU核数。 | +| Yarn->NodeManager | yarn.nodemanager.resource.memory-mb | 与实际数据节点物理内存总量相等。 | 可分配给Container的内存。 | +| Yarn->NodeManager | yarn.nodemanager.numa-awareness.enabled | True | NodeManager启动Container时的Numa感知。 | +| Yarn->NodeManager | yarn.nodemanager.numa-awareness.read-topology | True | NodeManager的Numa拓扑自动感知。 | +| MapReduce2 | mapreduce.map.memory.mb | 7168 | 一个 Map Task可使用的内存上限。 | +| MapReduce2 | mapreduce.reduce.memory.mb | 14336 | 一个 Reduce Task可使用的资源上限。 | +| MapReduce2 | mapreduce.job.reduce.slowstart.completedmaps | 0.35 | 当Map完成的比例达到该值后才会为Reduce申请资源。 | +| HDFS->NameNode | NameNode Java heap size | 3072 | 修改JVM内存大小,保证内存水平较高,减少GC的频率。**说明:**非固定值,需要根据GC的释放情况来调大或调小Xms及Xmx的值。 | +| NameNode new generation size | 384 | | | +| NameNode maximum new generation size | 384 | | | +| HDFS->DataNode | dfs.datanode.handler.count | 512 | DataNode服务线程数,可适量增加。 | +| HDFS->NameNode | dfs.namenode.service.handler.count | 32 | NameNode RPC服务端监测DataNode和其他请求的线程数,可适量增加。 | +| HDFS->NameNode | dfs.namenode.handler.count | 1200 | NameNode RPC服务端监测客户端请求的线程数,可适量增加。 | +| TEZ | tez.am.resource.memory.mb | 7168 | 等同于yarn.scheduler.minimum-allocation-mb,默认7168。 | +| TEZ | tez.runtime.io.sort.mb | SQL1: 32SQL2: 256SQL3: 256SQL4: 128SQL5: 64 | 根据不同的场景进行调整。 | +| TEZ | tez.am.container.reuse.enabled | true | Container重用开关。 | +| TEZ | tez.runtime.unordered.output.buffer.size-mb | 537 | 10%* hive.tez.container.size。 | +| TEZ | tez.am.resource.cpu.vcores | 10 | 使用的虚拟CPU数量,默认1,需要手动添加。 | +| TEZ | tez.container.max.java.heap.fraction | 0.85 | 基于Yarn提供的内存,分配给java进程的百分比,默认是0.8,需要手动添加。 | + + **客户端配置** +表2 SQL1 +| 参数名 | 参数配置 | +| ---------------------------------------- | -------- | +| hive.map.aggr | TRUE | +| hive.vectorized.execution.enabled | TRUE | +| hive.auto.convert.join | TRUE | +| hive.auto.convert.join.noconditionaltask | TRUE | +| hive.limit.optimize.enable | TRUE | +| hive.exec.parallel | TRUE | +| hive.cbo.enable | TRUE | +| hive.exec.compress.intermediate | TRUE | +| hive.tez.container.size | 7941 | +| tez.runtime.io.sort.mb | 32 | + +表3 SQL2 +| 参数名 | 参数配置 | +| ---------------------------------------- | -------- | +| hive.map.aggr | TRUE | +| hive.vectorized.execution.enabled | TRUE | +| hive.auto.convert.join | TRUE | +| hive.auto.convert.join.noconditionaltask | TRUE | +| hive.exec.parallel | TRUE | +| hive.cbo.enable | TRUE | +| hive.exec.compress.intermediate | TRUE | +| hive.exec.reducers.max | 576 | +| hive.tez.container.size | 5120 | +| tez.runtime.io.sort.mb | 256 | + + +表4 SQL3 +| 参数名 | 参数配置 | +| ---------------------------------------- | -------- | +| hive.map.aggr | TRUE | +| hive.vectorized.execution.enabled | TRUE | +| hive.auto.convert.join | TRUE | +| hive.auto.convert.join.noconditionaltask | TRUE | +| hive.limit.optimize.enable | TRUE | +| hive.exec.parallel | TRUE | +| hive.exec.reducers.max | 376 | +| hive.tez.container.size | 9216 | +| tez.runtime.io.sort.mb | 256 | + + +表5 SQL4 +| 参数名 | 参数配置 | +| ---------------------------------------- | -------- | +| hive.map.aggr | TRUE | +| hive.vectorized.execution.enabled | TRUE | +| hive.auto.convert.join | TRUE | +| hive.auto.convert.join.noconditionaltask | TRUE | +| hive.limit.optimize.enable | TRUE | +| hive.exec.parallel | TRUE | +| hive.cbo.enable | TRUE | +| hive.tez.container.size | 11264 | +| tez.runtime.io.sort.mb | 128 | + +表6 SQL5 +| 参数名 | 参数配置 | +| ---------------------------------------- | -------- | +| hive.map.aggr | TRUE | +| hive.vectorized.execution.enabled | TRUE | +| hive.auto.convert.join | TRUE | +| hive.auto.convert.join.noconditionaltask | TRUE | +| hive.limit.optimize.enable | TRUE | +| hive.exec.parallel | TRUE | +| hive.cbo.enable | TRUE | +| hive.tez.container.size | 15121 | +| tez.runtime.io.sort.mb | 64 | + +#### 4.2 numa特性开启 +Yarn组件在3.1.0版本合入的新特性支持,支持Yarn组件在启动Container时使能NUMA感知功能,原理是读取系统物理节点上每个NUMA节点的CPU核、内存容量,使用Numactl命令指定启动container的CPU范围和membind范围,减少跨片访问。 + +1.安装numactl(在server和agent上都安装)。 +``` +yum install numactl.aarch64 -y +``` +2.开启NUMA感知(在组件参数配置中已经做过的可以不做)。 +增加Yarn->NodeManager: +``` +yarn.nodemanager.numa-awareness.enabled true +yarn.nodemanager.numa-awareness.read-topology true +``` + + + + + + + + diff --git "a/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/kafkaOptimization.md" "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/kafkaOptimization.md" new file mode 100644 index 0000000000000000000000000000000000000000..f47380d09a850a0d47a880db9668ccdcd63a89b6 --- /dev/null +++ "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/kafkaOptimization.md" @@ -0,0 +1,197 @@ +# kafka 调优指南 +## 1-环境介绍 +### 1.1 软件版本信息 +| 软件 | 版本 | +|---|---| +| OS | openEuler 22.03 LTS | +| kernel | 4.19.90-2005.1.0.0038.oe1.aarch64 | +| JDK | Openjdk version “1.8.0_272” | +| Kafka | 2.11-2.0.0| +测试工具使用自带的Kafka的kafka-perf测试。 +| 工具名称 | 工具版本 | +|---|---| +|kafka-perf|2.11-2.0.0| + +### 1.2 调优原则 +- 建议根据盘数设置parition的值,一般partition数量为所有数据节点盘数总量的1~2倍。 +- 数据节点和Kafka测试客户端尽量分开,避免客户端生产数据对数据节点的影响。 +- Kafka处理网络和IO的线程数可以尽量增大。 +- 主机可以起多个线程启动Kafka的测试命令,且消费并发一般为生产的2~3倍左右,可根据实际场景调整;如在生产场景启动10个kafka-perf的线程(命令),消费场景启动30个线程(消费命令)消费数据。 + +### 1.3 调优思路 +- 为了能够让磁盘性能达到最大,partitions的数目总数需要大于磁盘数目,这样可以让每个磁盘至少拥有1个partition,否则该盘可能未被利用。 +- Kafka的一个重要特点就是会对收到的消息都保存到磁盘,而不是只存在于内存中。但是磁盘的读写速率较慢会对数据的实时性产生一定影响,所以Kafka一般会先使用内存cache保存数据,然后再使用异步线程进行刷盘操作。这样极大的提高了Kafka持久化数据的速度,保证了实时性。Kafka主要为IO型组件,在不启用压缩算法时,对CPU的消耗非常低;但如果使用压缩算法,特别是在消费场景会占用大量CPU(由于压缩算法特性,往往解压速度较快,所以可以令消费吞吐量发生质的提升)。 +- 由于集群部署以及多副本的原因,Kafka的数据要写入到各个节点前,数据都是通过网络来传输的,所以Kafka对网络的要求非常高,从一定程度上来讲,Kafka多少吞吐量,就需要多少网络带宽。虽然Kafka是一个只将数据保存在磁盘中的组件,但事实上,Kafka对硬盘的依赖反而并没有这么高。Kafka的性能指标时延与吞吐量,其中时延是由系统缓存来保证的,kafka在生产数据时,都只将数据写在缓存中,而由异步线程从缓存中同步到硬盘,所以Kafka会要求硬盘读写总带宽有一定的程度(可通过累加磁盘数目解决),但对硬盘的读写速率要求并不高。 +- 生产测试时,可以在每台客户端上启动多个kafka-producer-perf-test.sh进行生产,生产的消息为同一个topic的,生产时间180秒,到时间后停止所有生产进程。 +- 消费测试时,可以在每台客户端上启动多个kafka-consumer-perf-test.sh对生产测试的topic进行消费,消费时所有进程采用相同的group,将消息消费完所需时间与生产时间基本一致也为180秒。 +## 2-硬件调优 +### 2.1 配置BIOS +- 目的 + +对于不同的硬件设备,通过在BIOS中设置一些高级选项,可以有效提升服务器性能。 + +服务器上的SMMU一般用来完成设备的地址转换,并且可以实现设备隔离,在虚拟化中很实用,但是在物理机测试场景下,SMMU可能会导致性能下降,尤其对于小包网络场景,因此建议关闭该功能提升服务器性能。在虚拟机场景需要打开此配置来使用PCI直通功能。 +在本测试场景中,预取会导致cache污染,cache miss增加,因此建议关闭预取功能。 + +- 方法 + +关闭SMMU。 +重启服务器,按Esc键进入BIOS设置界面。 +依次进入“Advanced > MISC Config > Support Stmmu”。 +将“Support Smmu”设置为“Disabled”,按“F10”保存退出(永久有效)。 +关闭预取。 +进入BIOS设置界面。 +依次进入“Advanced > MISC Config > CPU Prefetching Configuration”。 +将“CPU Prefetching Configuration”设置为“Disabled”,按“F10”保存退出(永久有效)。 +### 2.2 创建RAID 0 +``` +- 目的 +磁盘创建RAID可以提高磁盘的整体存取性能,环境上若使用的是LSI 3108/3408/3508系列RAID卡,推荐创建单盘RAID 0/RAID 5,充分利用RAID卡的Cache(LSI 3508卡为2GB),提高读写速率。 +- 方法 +使用storcli64_arm文件检查RAID组创建情况。 +./storcli64_arm /c0 show +创建RAID 0,命令表示为第2块1.2TB硬盘创建RAID 0,其中,c0表示RAID卡所在ID、r0表示组RAID 0。依次类推,对除了系统盘之外的所有盘做此操作。 +./storcli64_arm /c0 add vd r0 drives=65:1 +``` +![输入图片说明](https://foruda.gitee.com/images/1679292452664538651/90ba8b2b_10227919.png "屏幕截图") +### 2.3 开启RAID卡Cache +``` +- 目的 +使用RAID卡的RWTD性能更佳。 + +使用storcli工具修改RAID组的Cache设置,Read Policy设置为Read ahead,使用RAID卡的Cache做预读;Write Policy设置为Write Through;IO policy设置为Direct IO。 + +- 方法 +配置RAID卡的cache,其中vx是卷组号(v0/v1/v2....),根据环境上的实际情况进行设置。 +./storcli64_arm /c0/vx set rdcache=RA +./storcli64_arm /c0/vx set wrcache=WT +./storcli64_arm /c0/vx set iopolicy=Direct +检查配置是否生效。 +./storcli64_arm /c0 show +``` +![输入图片说明](https://foruda.gitee.com/images/1679292548783445749/728f38d6_10227919.png "屏幕截图") + +### 2.4 调整rx_buff +``` +目的 +1822网卡默认的rx_buff配置为2KB,在聚合64KB报文的时候需要多片不连续的内存,使用率较低;该参数可以配置为2/4/8/16KB,修改后可以减少不连续的内存,提高内存使用率。 +方法 +查看rx_buff参数值,默认为2。 +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +在目录“/etc/modprobe.d/”中增加文件hinic.conf,修改rx_buff值为8。 +options hinic rx_buff=8 +重新挂载hinic驱动,使得新参数生效。 +rmmod hinic +modprobe hinic +查看rx_buff参数是否更新成功。 +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +``` +### 2.5 调整队列深度和队列数 +``` +目的 :1822网卡队列深度最大支持4096,默认配置为1024,可以增大buffer大小用于提高网卡Ring大小。 +方法 +- 查看队列深度默认大小,假设当前网卡名为enp131s0。 +ethtool -g enp131s0 +- 修改队列深度值为4096。 +ethtool -G enp131s0 rx 4096 tx 4096 +- 查看队列深度值是否更新成功。 +ethtool -g enp131s0 +- 减少队列数。 +ethtool -L enp131s0 combined 4 +ethtool -l enp131s0 +``` +### 2.6 开启LRO +``` +目的 +1822网卡支持LRO(Large Receive Offload),可以打开该选项,并合理配置1822 LRO参数。 + +方法 +查看LRO参数是否开启,默认为off,假设当前网卡名为enp131s0。 +ethtool -k enp131s0 +打开LRO。 +ethtool -K enp131s0 lro on +查看LRO参数是否开启。 +ethtool -k enp131s0 +``` +### 2.7 配置网卡中断绑核 +``` +目的:相比使用内核的irqbalance使网卡中断在所有核上进行调度,使用手动绑核将中断固定住能有效提高业务网络收发包的能力。 + +方法 +关闭irqbalance。 +若要对网卡进行绑核操作,则需要关闭irqbalance。 + +- 停止irqbalance服务,重启失效。 +systemctl stop irqbalance.service +- 关闭irqbalance服务,永久有效。 +systemctl disable irqbalance.service +- 查看irqbalance服务状态是否已关闭。 +systemctl status irqbalance.service +- 查看网卡pci设备号,假设当前网卡名为enp131s0。 +ethtool -i enp131s0 +- 查看pcie网卡所属NUMA node。 +lspci -vvvs +- 进行中断绑核,1822网卡共有16个队列,将这些中断逐个绑至所在NumaNode的16个Core上(例如此处就是绑到NUMA node1对应的48-63上面)。 +bash smartIrq.sh +脚本内容如下: +#!/bin/bash +irq_list=(`cat /proc/interrupts | grep enp131s0 | awk -F: '{print $1}'`) +cpunum=48 # 修改为所在node的第一个Core +for irq in ${irq_list[@]} +do +echo $cpunum > /proc/irq/$irq/smp_affinity_list +echo `cat /proc/irq/$irq/smp_affinity_list` +(( cpunum+=1 )) +done +- 利用脚本查看是否绑核成功。 +sh irqCheck.sh enp131s0 +脚本内容如下: +#!/bin/bash +# 网卡名 +intf=$1 +log=irqSet-`date "+%Y%m%d-%H%M%S"`.log +# 可用的CPU数 +cpuNum=$(cat /proc/cpuinfo |grep processor -c) +# RX TX中断列表 +irqListRx=$(cat /proc/interrupts | grep ${intf} | awk -F':' '{print $1}') +irqListTx=$(cat /proc/interrupts | grep ${intf} | awk -F':' '{print $1}') +# 绑定接收中断rx irq +for irqRX in ${irqListRx[@]} +do +cat /proc/irq/${irqRX}/smp_affinity_list +done +# 绑定发送中断tx irq +for irqTX in ${irqListTx[@]} +do +cat /proc/irq/${irqTX}/smp_affinity_list +done +``` +## 3-操作系统调优 +目的 +修改脏页刷新参数,提高脏页后台刷新的频率。 + +方法 +修改dirty_writeback_centisecs。 +echo 5 > /proc/sys/vm/dirty_writeback_centisecs +## 4-Kafka参数配置 +| 参数 | 建议值 | 描述 | +|---|---|---| +|num.network.threads|128|broker处理消息的最大线程数,主要处理网络IO,读写缓冲区数据。由于当前Kafka主要是网络瓶颈,所以该参数影响特别大。该参数默认值为3,此时对Kafka性能有决定性影响,当不断调大此参数时,性能会有比较大的提升。该参数的建议值是核数+1,但实际由于网卡瓶颈,该参数调到一定程度后对性能几乎没有影响。为了方便调试,我们可以直接将该参数定为核数+1甚至定为最大值(128)。| +|num.io.threads|65|broker处理磁盘IO的线程数,由于目前Kafka是网络瓶颈,所以磁盘IO的线程数影响并不是很大。目前典型场景单broker部署了23个Kafka盘,均为SAS盘,单盘性能较强。实际3~4个盘,就可以将网络IO跑到瓶颈,所以理论上IO线程数的修改对性能影响非常有限。该参数默认值为8,最高可以调到256。| +|compression.type|根据实际场景调整。|Kafka压缩算法选择。可以配置为producer(由client生产者决定)、None(不压缩)、gzip、snappy、lz4。实测几种压缩算法lz4与与snappy表现较好,gzip尽量不选择。但在大多数场景下,还是不压缩更加有优势。压缩算法有时候是双刃剑,并不一定能带来比较好的收益,需要在系统场景中综合考虑使用。| +|partitions|根据磁盘数量调整,一般为磁盘的1~2倍。|Kafka topic的分区数,该参数与topic强相关,即Kafka数据保存的分区数目,一般要比盘总数大,以保证每个盘都有IO读写。但实际情况由于硬盘IO没有瓶颈,所以可以综合情况进行考虑。| +## 5-Client参数配置 +目的:修改Client参数增大测试压力,Client参数主要为kafka-perf工具测试生产和消费场景时的设置参数,主要包括副本数、数据块大小、消息数量等。 +| 参数 | 建议值 | 描述 | +|---|---|---| +|replication-factor|2|生产数据的副本数,为了保证数据的可靠性,副本数至少为2,该参数是1是很危险的操作。在性能测试的时候,副本数一般就取2。| +|record-size|1024-65535|数据块大小。实际场景的数据块大小是由具体业务所决定的,一般常见业务的数据块大小在1024~65535之间,一般做性能测试会从这个取值范围内选取至少5个数据块大小进行测试。不同数据块大小的生产与消费性能会有所区别(实际和网络大小包性能有关)。| +|num-fetch-threads|默认|拉取数据的线程数量,即为消费者的数量。在网络瓶颈下,调整此参数基本没有效果。| +|threads|默认|消费处理线程数。在网络瓶颈下,调整此参数基本没有效果。| +|messages|800000000|消费消息的条数,由于Kafka在进行消费时,性能会有所起伏与波动,所以在进行性能测试时,需要对不同消息条数进行测试,得到性能最优值。一般该值取8亿左右。| +|request.required.acks|0|发消息后,是否需要broker端返回。默认需要返回,可以尝试设置为0,在数据块大小较小,发送比较频繁的场景下可能有一定效果。| +|linger.ms|0|多条消息聚合的延时,默认为0,一般保持默认值即可。| + + + + diff --git "a/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/redisOptimization.md" "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/redisOptimization.md" new file mode 100644 index 0000000000000000000000000000000000000000..fc1f2e51196f544ed8b29214d34c3d463f641f6e --- /dev/null +++ "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/redisOptimization.md" @@ -0,0 +1,259 @@ +# redis 调优指南 +## 1-调优概述 +### 1.1 环境介绍 + |软件 |版本 | + |-------------|-----------| + |OS |CentOS 7.6、openEuler 22.03| + |JDK |OpenJDK version 1.8.0_222| + |Redis |3.x/4.x/5.x| + |Redis_tool |自研工具| + +### 1.2 调优原则 +性能调优就是对计算机硬件、操作系统和应用有相当深入的了解,调节三者之间的关系,实现整个系统(包括硬件、操作系统、应用)的性能最大化,并能不断的满足现有的业务需求。在性能优化时,我们必须遵循一定的原则,否则,有可能得不到正确的调优结果。主要有以下几个方面: + +- 对性能进行分析时,要多方面分析系统的资源瓶颈所在,因为系统某一方面性能低,也许并不是它自己造成的,而是其他方面造成的。如CPU利用率是100%时,很可能是内存容量太小,因为CPU忙于处理内存调度。 +- 一次只对影响性能的某方面的一个参数进行调整,多个参数同时调整的话,很难界定性能的影响是由哪个参数造成的。 +- 在进行系统性能分析时,性能分析工具本身会占用一定的系统资源,如CPU资源、内存资源等等。我们必须注意到这点,即分析工具本身运行可能会导致系统某方面的资源瓶颈情况更加严重。 + +### 1.3 调优思路 +- 1. 对于服务端的问题,需要重点定位的硬件指标包括CPU、内存、硬盘、BIOS配置,其中CPU是需要重点关注的:服务端CPU未压满或存在明显热点函数直接影响最终测试结果。需要重点关注的软件指标包括应用软件、OS层的优化,该部分的调优对于性能的提升是很可观的。 +- 2. 对于网络问题,需要重点定位的包括网络带宽和网络中断,处理网络中断的核是否压满是需要重点关注的。 +- 3. 对于客户端问题:客户端的性能是否满足测试需要。 +- 4. 识别网卡物理插槽所在NUMA node的CPU,将网卡中断平均绑定至该片CPU的两个NUMA node上,每个中断绑定一个核。 +- 5. Redis集群master节点绑定至网卡中断所在CPU上,同时保证与网卡中断使用不同的核,slave节点绑定至另一片CPU上。 +- 6. 对于规模较小的集群(单个物理节点上master和slave的总数小于等于网卡中断所在CPU核数减去中断使用的核数),可以把slave节点同时绑定至5中master使用的核上。 +- 7. 对于规模极小的集群(单个NUMA node就可以包含所有的中断和进程,此时由于集群规模小,网卡可以多个中断绑定在一个核上),可以将网卡中断和进程绑定在单个NUMA node上,即网卡物理插槽所在NUMA node。 + +## 2-硬件调优 +### 2.1 配置BIOS + +#### 1. 关闭SMMU。 + 1. 重启服务器,按Esc键进入BIOS设置界面。 + 2. 依次进入 + “Advanced > MISC Config > > Support Smmu”。 + **图1** BIOS设置界面 + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154826923.png) + + 3. 将“Support Smmu”设置为“Disabled”,按“F10”保存退出(永久有效)。 + **图2** 关闭SMMU BIOS界面 + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001108147314.png) + +#### 2. 关闭预取。 + 1. 进入BIOS设置界面。 + 2. 依次进入 + “Advanced > MISC Config > CPU Prefetching Configuration”。 + **图3** BIOS设置界面 + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154986843.png) + + 3. 将“CPU Prefetching Configuration”设置为 “Disabled” ,按“F10”保存退出(永久有效)。 + **图4** 关闭Prefetching Configuration界面 + ![点击放大](https://www.hikunpeng.com/doc_center/source/zh/kunpengbds/ecosystemEnable/HBase/zh-cn_image_0000001154706973.png) + +### 2.2 调整rx_buff +``` +目的 :1822网卡默认的rx_buff配置为2KB,在聚合64KB报文的时候需要多片不连续的内存,使用率较低;该参数可以配置为2/4/8/16KB,修改后可以减少不连续的内存,提高内存使用率。 + +方法 +- 查看rx_buff参数值,默认为2。 +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +- 在目录“/etc/modprobe.d/”中增加文件hinic.conf,修改rx_buff值为8。 +options hinic rx_buff=8 +- 重新挂载hinic驱动,使得新参数生效。 +rmmod hinic +modprobe hinic +- 查看rx_buff参数是否更新成功。 +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +``` +### 2.3 调整Ring Buffer +``` +目的 +1822网卡默认的rx_buff配置为2KB,在聚合64KB报文的时候需要多片不连续的内存,使用率较低;该参数可以配置为2/4/8/16KB,修改后可以减少不连续的内存,提高内存使用率。 +方法 +- 查看rx_buff参数值,默认为2。 +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +- 在目录“/etc/modprobe.d/”中增加文件hinic.conf,修改rx_buff值为8。 +options hinic rx_buff=8 +- 重新挂载hinic驱动,使得新参数生效。 +rmmod hinic +modprobe hinic +- 查看rx_buff参数是否更新成功。 +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +``` + +### 2.4 开启LRO +``` +目的:1822网卡支持LRO(Large Receive Offload),可以打开该选项,并合理配置1822 LRO参数。 +方法 +- 查看LRO参数是否开启,默认为off,假设当前网卡名为enp131s0。 +ethtool -k enp131s0 +- 打开LRO。 +ethtool -K enp131s0 lro on +- 查看LRO参数是否开启。 +ethtool -k enp131s0 +``` + +### 2.5 配置MTU +``` +目的:当MTU与业务收发包接近时,可以达到最优的吞吐量,由于当前测试数据包大小为1000,因此采用默认的1500可以达到最优的性能。当数据包大于MTU时,在发包过程中数据将被切割后发送,导致网络利用率下降,因此可以适当修改该值使之与业务收发包大小匹配。 + +方法 +- 配置MTU为1500,假设当前网卡名为enp136s0。 +ifconfig enp136s0 mtu 1500 +``` + +### 2.6 配置网卡中断合并 +``` +目的:开启中断合并自适应,当网络上小包占比大时,会自动进行合并中断,有助于提升系统性能,当前测试模型小包占比大,因此需要开启中断合并。 + +方法 +- 开启中断合并,假设当前网卡名为enp136s0。 +ethtool -C enp136s0 adaptive-rx on +``` +### 2.7 配置网卡中断绑核 +``` +目的:相比使用内核的irqbalance使网卡中断在所有核上进行调度,使用手动绑核将中断固定住能有效提高业务网络收发包的能力。 + +方法 +- 关闭irqbalance。 +若要对网卡进行绑核操作,则需要关闭irqbalance。 + +- 停止irqbalance服务,重启失效。 +systemctl stop irqbalance.service +- 关闭irqbalance服务,永久有效。 +systemctl disable irqbalance.service +- 查看irqbalance服务状态是否已关闭。 +systemctl status irqbalance.service +- 查看网卡pci设备号,假设当前网卡名为enp131s0。 +ethtool -i enp131s0 +- 查看pcie网卡所属NUMA node。 +lspci -vvvs +- 查看NUMA node对应的core的区间,例如此处就可以绑到48~63。 +lscpu +- 进行中断绑核,1822网卡共有16个队列,将这些中断逐个绑至所在NumaNode的16个Core上(例如此处就是绑到NUMA node1对应的48-63上面)。 +bash smartIrq.sh +脚本内容如下: +#!/bin/bash +irq_list=(`cat /proc/interrupts | grep enp131s0 | awk -F: '{print $1}'`) +cpunum=48 # 修改为所在node的第一个Core +for irq in ${irq_list[@]} +do +echo $cpunum > /proc/irq/$irq/smp_affinity_list +echo `cat /proc/irq/$irq/smp_affinity_list` +(( cpunum+=1 )) +done +利用脚本查看是否绑核成功。 +sh irqCheck.sh enp131s0 + +脚本内容如下: +#!/bin/bash +# 网卡名 +intf=$1 +log=irqSet-`date "+%Y%m%d-%H%M%S"`.log +# 可用的CPU数 +cpuNum=$(cat /proc/cpuinfo |grep processor -c) +# RX TX中断列表 +irqListRx=$(cat /proc/interrupts | grep ${intf} | awk -F':' '{print $1}') +irqListTx=$(cat /proc/interrupts | grep ${intf} | awk -F':' '{print $1}') +# 绑定接收中断rx irq +for irqRX in ${irqListRx[@]} +do +cat /proc/irq/${irqRX}/smp_affinity_list +done +# 绑定发送中断tx irq +for irqTX in ${irqListTx[@]} +do +cat /proc/irq/${irqTX}/smp_affinity_list +done +``` + +### 2.8 组件Raid 0 +``` +目的:磁盘创建RAID可以提高磁盘的整体存取性能,环境上若使用的是LSI 3108/3408/3508系列RAID卡,推荐创建单盘RAID 0/RAID 5,充分利用RAID卡的Cache(LSI 3508卡为2GB),提高读写速率。 + +方法 +- 使用storcli64_arm文件检查RAID组创建情况。 +./storcli64_arm /c0 show + +说明 +storcli64_arm文件放在任意目录下执行皆可。 + +- 创建RAID 0,命令表示为第2块1.2T硬盘创建RAID 0,其中,c0表示RAID卡所在ID、r0表示组RAID 0。依次类推,对除了系统盘之外的所有盘做此操作。 +./storcli64_arm /c0 add vd r0 drives=65:1 + +``` +### 2.9 开启Raid卡Cache +``` +目的:使用RAID卡的RAWBC(无超级电容)/RWBC(有超级电容)性能更佳。 + +- 使用storcli工具修改RAID组的Cache设置,Read Policy设置为Read ahead,使用RAID卡的Cache做预读;Write Policy设置为Write back,使用RAID卡的Cache做回写,而不是Write through透写;IO policy设置为Cached IO,使用RAID卡的Cache缓存IO。 +方法 +- 配置RAID卡的Cache。 +./storcli64_arm /c0/vx set rdcache=RA +./storcli64_arm /c0/vx set wrcache=WB/AWB +./storcli64_arm /c0/vx set iopolicy=Cached + +说明 +./storcli64_arm /c0/vx set wrcache=WB/AWB #命令中的WB/AWB取决于RAID卡是否有超级电容,无超级电容使用AWB。 + +- 检查配置是否生效。 +./storcli64_arm /c0 show +``` +## 3-操作系统调优 +### 3.1 配置内核参数 +``` +目的:配置内核参数,包括TCP/IP协议栈、透明大页等相关参数,提升性能。 + +方法 +- 配置OS内核参数。 +sysctl -w net.core.netdev_budget = 600 +sysctl -w net.core.rmem_max = 16777216 +sysctl -w net.core.somaxconn = 2048 +sysctl -w net.core.optmem_max = 40960 +sysctl -w net.core.rmem_default = 65535 +sysctl -w net.core.wmem_default = 65535 +sysctl -w net.core.wmem_max = 8388608 +sysctl -w net.ipv4.tcp_rmem = 16384 349520 16777216 +sysctl -w net.ipv4.tcp_wmem = 16384 349520 16777216 +sysctl -w net.ipv4.tcp_mem = 8388608 8388608 8388608 +sysctl -w vm.overcommit_memory= 1 +echo never > /sys/kernel/mm/transparent_hugepage/enabled +``` +### 3.2 配置进程NUMA绑核 +``` +目的 +根据Redis node在集群中的角色可以将具体的实例分为Master和Slave两类,其中,Master节点负责request的处理,写入、读取、更新数据,定时同步数据到备用Redis node,数据持久化。Slave节点负责当主用Redis node故障时,取代主用Redis node对外提供服务。由于角色不同,在实际业务中,Master实例需要更多的CPU资源与网络资源,因此在Redis集群部署完成后,根据Redis节点在集群中负责的角色,将相应的Redis实例进行NUMA绑核操作。当集群规模不同时,需要调整该绑核策略以发挥不同规模集群的最优性能。 + +方法 +- 获取当前集群的节点(实例)信息,首先使用如下命令通过集群中任一节点登录集群。 +redis-cli -h ${ip_server} -p ${port_server} +- 查询当前集群各节点的角色信息,示例如下(简化版),可以看到通过该方式可以获得当前集群中各个实例的具体角色,将该信息保存至临时文件tmp_nodes_info.log中。 +cluster nodes +- 根据实例的角色进行绑核,因为Redis集群是部署在多个物理服务器上的分布式数据库,因此需要分别获取每个服务器上Redis实例的角色信息。使用如下命令从tmp_nodes_info.log中批量获取属于某个服务IP地址的实例角色信息。 +local_master_ports=($(cat tmp_nodes_info.log |grep "master"|awk '{print $2}'|awk -F@ '{print $1}' | grep ${ip} | awk -F: '{print $2}')) +local_slave_ports=($(cat tmp_nodes_info.log |grep "slave"|awk '{print $2}'|awk -F@ '{print $1}'|grep ${ip} | awk -F: '{print $2}')) +- 根据local_master_ports和local_slave_ports中的端口信息获取相应的进程pid,再根据pid对相应的Redis实例进行绑核操作。 +pid=$(ps -ef | grep "redis" | grep ${port} | awk '{print $2}') +taskset -cp ${destCores} ${pid} +``` + +## 4-resdis服务端调优 +### 4.1 目的 + +服务端参数保持默认。 + +### 4.2 方法 + +每个Redis实例的参数在redis.conf文件配置。 + +| 参数 | 含义 | 默认值 | +| ----------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | +| appendfsync | fsync()策略:no:不配置fsync,OS在需要的时候将数据刷入磁盘。always:每次写盘都调fsync,速度慢,但是最安全。everysec:每秒fsync,折中。 | 【默认值】everysec【取值范围】no,always,everysec | +| appendonly | 如果启用了AOF,Redis启动时会加载AOF。 | 【默认值】no【取值范围】yes,no | +| cluster-require-full-coverage | 默认情况下如果一个槽位没有被分配(该槽位没有分配可用的实例)那么Redis集群会停止接受查询请求,在这种情况下,如果集群部分实例故障(例如一部分槽位没有被覆盖),那整个集群也将不可用。一旦所有槽位被分配,集群会自动变为可用。 | 【默认值】yes【取值范围】yes,no | +| maxmemory | Redis能使用的最大内存(单位:MB)。 | 【默认值】1024【取值范围】1~1048576 | +| maxmemory-policy | 最大内存策略:当达到最大内存时,Redis选择移除的数据。可在以下八个行为中选择:volatile-lru -> 使用LRU算法淘汰有一个过期配置的key。allkeys-lru -> 根据LRU算法淘汰所有key。volatile-random -> 在设置了过期时间的key中随机选择一个进行淘汰。allkeys-random -> 在所有的key中随机选择一个进行淘汰。volatile-ttl -> 淘汰最快过期的key。allkeys-smart -> 使用冷却算法在所有的key中选择一个进行淘汰。volatile-smart -> 使用冷却算法在设置了过期时间的key中选择一个进行淘汰。noeviction -> 不会淘汰任何key,执行写操作时返回错误。 | 【默认值】noeviction【取值范围】volatile-lru,allkeys-lru,volatile-random,allkeys-random,volatile-ttl,allkeys-smart,volatile-smart,noeviction | +| rdbchecksum | 使用RDB校验。 | 【默认值】yes【取值范围】yes,no | +| rdbcompression | 使用RDB压缩。 | 【默认值】yes【取值范围】yes,no | +| stop-writes-on-bgsave-error | 如果启用了RDB快照并且最近的后台保存失败,Redis会停止接受写入请求。 | 【默认值】yes【取值范围】yes,no | +| activerehashing | 将在每100毫秒时使用1毫秒的CPU时间来对redis的hash表进行重新hash,可以降低内存的使用。 | 【默认值】no【取值范围】yes,no | +| activedefrag | 自动内存碎片整理功能。 | 【默认值】no【取值范围】yes,no | \ No newline at end of file diff --git "a/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/sparkOptimization.md" "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/sparkOptimization.md" new file mode 100644 index 0000000000000000000000000000000000000000..4754387d900a055a6a490a0120bee3e5ca4f5c05 --- /dev/null +++ "b/Docs/\350\260\203\344\274\230\346\214\207\345\215\227/sparkOptimization.md" @@ -0,0 +1,437 @@ +# spark调优指南 +## 1-组件架构 +### 1.1 物理组网 +物理环境HDP采用控制节点*1+数据节点*3的部署方案,在网络层面,管理与业务分离部署,管理网络使用GE电口来进行网络间的通信,业务网络使用10GE光口来进行网络间的通信。 +### 1.2 软件版本 +| 软件 | 版本 | +|---|---| +| OS | openEuler 22.03 | +| JDK | Openjdk version “1.8.0_272” | +| Zookeeper |3.4.9 | +| Hadoop | 3.1.1 | +| Hive | 3.0.0 | +| Spark | 2.3.0 | +| Tez | 0.9.0 | +### 1.3 节点部署规划 +| 服务器 | 组件部署 | +|---|---| +| server1 | NameNode、ResourceManager、Timeline Service V2.0 Reader、YARN Registry DNS、Timeline Service V1.5、SNameNode 、History Server、Metricks Collector、Grafana、Activity Analyzer、Activity Explorer、HST Server、Spark2 History Server、Spark2 Thrift Server | +| agent1 | Zookeeper Server、DataNode | +| agent2 | Zookeeper Server、DataNode | +| agent3 | Zookeeper Server、DataNode | +### 1.4 调优原则 + +![输入图片说明](https://foruda.gitee.com/images/1679283857872121110/890f3193_10227919.png "屏幕截图") + +在性能优化时,我们必须遵循一定的原则,否则有可能得不到正确的调优结果。 +主要包括以下几个方面: +- 对性能进行分析时,要多方面分析系统资源瓶颈所在,学会利用web端获取到的日志进行分析。 +- 每一次调整参数时,采用控制变量法,只对影响性能的某方面的一个参数进行调整,避免调整多个参数带来的问题分析定位不准确的问题 + +### 1.5 调优思路 +- 对sql性能进行分析时,在客户端及Web按照基础固定值配置的基础上,按照理论计算公式得到较合理的一组Executor执行参数,使能在鲲鹏上效果明显的亲和性配置调优,进行SQL测试能跑出较优的一组性能结果。 +- 在Hibench场景下,根据集群总核数,采用3-5倍总核数作为数据分片的Partitions和Parallelism进行数据分片,减小单Task文件大小,对性能有正面提升。 +- 调优时尽量在任务运行时CPU与内存尽量压满,当然若不能满足同时压满,则优先压满CPU,然后根据实际GC的log判断是否需要增加内存;在内存需求较高的场景,最终逐步调整可能会趋向内存压满,CPU留有一定余量的情况。 + +## 2-硬件优化 +### 2.1 配置BIOS + **目的:** 对于不同的硬件设备,通过在BIOS中设置一些高级选项,可以有效提升服务器性能。 +- 服务器上的SMMU一般用来完成设备的地址转换,并且可以实现设备隔离,在虚拟化中很实用,但是在物理机测试场景下,SMMU可能会导致性能下降,尤其对于小包网络场景,因此建议关闭该功能提升服务器性能。在虚拟机场景需要打开此配置来使用PCI直通功能。 +- 在本测试场景中,预取会导致cache污染,cache miss增加,因此建议关闭预取功能。 +``` +方法 +关闭SMMU。 +说明 +- 此优化项只在非虚拟化场景使用,在虚拟化场景,则开启SMMU。 +- 重启服务器过程中,单击Delete键进入BIOS,选择“Advanced > MISC Config”,单击Enter键进入。 +- 将“Support Smmu”设置为“Disable” 。 +- 关闭预取。 +在BIOS中,选择“Advanced>MISC Config”,单击Enter键进入。 +- 将“CPU Prefetching Configuration”设置为“Disabled”。 +``` +### 2.2 创建RAID 0 +``` +目的 +磁盘创建RAID可以提高磁盘的整体存取性能,环境上若使用的是LSI 3108/3408/3508系列RAID卡,推荐创建单盘RAID 0/RAID 5,充分利用RAID卡的Cache(LSI 3508卡为2GB),提高读写速率。 +方法 +- 使用storcli64_arm文件检查RAID组创建情况。 +./storcli64_arm /c0 show +- 创建RAID 0,命令表示为第2块1.2TB硬盘创建RAID 0,其中,c0表示RAID卡所在ID、r0表示组RAID 0。依次类推,对除了系统盘之外的所有盘做此操作。 +./storcli64_arm /c0 add vd r0 drives=65:1 +``` +![输入图片说明](https://foruda.gitee.com/images/1679292452664538651/90ba8b2b_10227919.png "屏幕截图") +### 2.3 开启RAID卡Cache +``` +目的 +使用RAID卡的RWTD性能更佳。 + +使用storcli工具修改RAID组的Cache设置,Read Policy设置为Read ahead,使用RAID卡的Cache做预读;Write Policy设置为Write Through;IO policy设置为Direct IO。 + +方法 +- 配置RAID卡的cache,其中vx是卷组号(v0/v1/v2....),根据环境上的实际情况进行设置。 +./storcli64_arm /c0/vx set rdcache=RA +./storcli64_arm /c0/vx set wrcache=WT +./storcli64_arm /c0/vx set iopolicy=Direct +- 检查配置是否生效。 +./storcli64_arm /c0 show +``` +![输入图片说明](https://foruda.gitee.com/images/1679292548783445749/728f38d6_10227919.png "屏幕截图") + +### 2.4 调整rx_buff +``` +目的 +1822网卡默认的rx_buff配置为2KB,在聚合64KB报文的时候需要多片不连续的内存,使用率较低;该参数可以配置为2/4/8/16KB,修改后可以减少不连续的内存,提高内存使用率。 +方法 +- 查看rx_buff参数值,默认为2。 +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +- 在目录“/etc/modprobe.d/”中增加文件hinic.conf,修改rx_buff值为8。 +options hinic rx_buff=8 +- 重新挂载hinic驱动,使得新参数生效。 +rmmod hinic +modprobe hinic +- 查看rx_buff参数是否更新成功。 +cat /sys/bus/pci/drivers/hinic/module/parameters/rx_buff +``` +### 2.5 调整队列深度和队列数 +``` +目的 +1822网卡队列深度最大支持4096,默认配置为1024,可以增大buffer大小用于提高网卡Ring大小。 +方法 +- 查看队列深度默认大小,假设当前网卡名为enp131s0。 +ethtool -g enp131s0 +- 修改队列深度值为4096。 +ethtool -G enp131s0 rx 4096 tx 4096 +- 查看队列深度值是否更新成功。 +ethtool -g enp131s0 +- 减少队列数。 +ethtool -L enp131s0 combined 4 +ethtool -l enp131s0 +``` +### 2.6 开启GRO、TSO、GSO +``` +1822网卡支持LRO(Large Receive Offload),可以打开该选项,并合理配置1822 LRO参数。 + +方法 +- 查看LRO参数是否开启,默认为off,假设当前网卡名为enp131s0。 +ethtool -k enp131s0 +- 打开LRO。 +ethtool -K enp131s0 lro on +ethtool -K enp131s0 gro on +ethtool -K enp131s0 tso on +ethtool -K enp131s0 gso on +ifconfig enp131s0 mtu 9000 up +- 查看LRO参数是否开启。 +ethtool -k enp131s0 +``` +### 2.7 配置网卡中断绑核 +``` +目的 +相比使用内核的irqbalance使网卡中断在所有核上进行调度,使用手动绑核将中断固定住能有效提高业务网络收发包的能力。 + +方法 +- 关闭irqbalance。 +若要对网卡进行绑核操作,则需要关闭irqbalance。 +- 停止irqbalance服务,重启后会失效。 +systemctl stop irqbalance.service +- 关闭irqbalance服务,永久有效。 +systemctl disable irqbalance.service +- 查看irqbalance服务状态是否已关闭。 +systemctl status irqbalance.service +- 查看网卡pci设备号,假设当前网卡名为enp131s0。 +ethtool -i enp131s0 +- 查看pcie网卡所属NUMA node。 +lspci -vvvs +- 查看NUMA对应哪些CORE。 +numactl -H +新建一个shell脚本,在脚本内复制以下内容来进行绑核。其中$1是网卡名称,即上面的enp131s0。 +# /bin/bash +t=60 +for i in `cat /proc/interrupts |grep -e $1 |awk -F ':' '{print $1}'` +do +cat /proc/irq/$i/smp_affinity_list +echo $t > /proc/irq/$i/smp_affinity_list +cat /proc/irq/$i/smp_affinity_list +t=`expr $t + 1` +done +``` +## 3-通用优化项 +### 3.1 内存参数 +#### 3.1.1 队列调整 +``` +目的 +如果没有特殊说明,全部使用单队列(软队列)模式,单队列模式在spark测试时会有更佳的性能。 +方法 +- 在/etc/grub2-efi.cfg +142 的内核启动命令行中添加scsi_mod.use_blk_mq=0,重启生效。 +linux /vmlinuz-5.10.0-60.63.0.89.oe2203.aarch64 root=UUID=2d3d625b-c1c9-48cd-ab63-fe5f76f195a2 ro video=VGA-1:640x480-32@60me rhgb quiet console=tty0 crashkernel=1024M,high smmu.bypassdev=0x1000:0x17 smmu.bypassdev=0x1000:0x15 video=efifb:off scsi_mod.use_blk_mq=0 +``` +#### 3.1.2 其他io相关的配置 +``` +目的 +对调度参数、IO参数进行调整,能有一定的性能提升。 + +方法 +新建一个shell脚本,在脚本内复制以下内容并运行: + +#! /bin/bash + +echo 3000 > /proc/sys/vm/dirty_expire_centisecs +echo 500 > /proc/sys/vm/dirty_writeback_centisecs + +echo 15000000 > /proc/sys/kernel/sched_wakeup_granularity_ns +echo 10000000 > /proc/sys/kernel/sched_min_granularity_ns + +systemctl start tuned +sysctl -w kernel.sched_autogroup_enabled=0 +sysctl -w kernel.numa_balancing=0 + +echo 11264 > /proc/sys/vm/min_free_kbytes +echo 60 > /proc/sys/vm/dirty_ratio +echo 5 > /proc/sys/vm/dirty_background_ratio + +list="b c d e f g h i j k l m" +for i in $list +do + echo 1024 > /sys/block/sd$i/queue/max_sectors_kb + echo 32 > /sys/block/sd$i/device/queue_depth + echo 256 > /sys/block/sd$i/queue/nr_requests + echo deadline > /sys/block/sd$i/queue/scheduler + echo 2048 > /sys/block/sd$i/queue/read_ahead_kb + echo 2 > /sys/block/sd$i/queue/rq_affinity + echo 0 > /sys/block/sd$i/queue/nomerges +done + +注意 +在wordcount等IO密集型的场景,建议使用多队列mq-deadline调度,效果稍好。该场景会在下面单独配置和说明。 +``` +### 3.2 内存参数 +``` +目的 :关闭内存大页,防止内存泄漏,减少卡顿。 +方法 : +- 透明大页对性能影响甚大,关闭: +echo never > /sys/kernel/mm/transparent_hugepage/enabled +echo never > /sys/kernel/mm/transparent_hugepage/defrag +``` +### 3.3 JVM参数和版本适配 +``` +目的 :最新版本的JDK对Spark性能进行了优化。 + +- JDK参数更新 +可在spark-defaults.conf文件中添加以下配置来使用新的JDK。 + +spark.executorEnv.JAVA_HOME /usr/local/jdk8u222-b10 +spark.yarn.appMasterEnv.JAVA_HOME /usr/local/jdk8u222-b10 +spark.executor.extraJavaOptions -XX:+UseNUMA -XX:BoxTypeCachedMax=100000 -XX:ParScavengePerStrideChunk=8192 +spark.yarn.am.extraJavaOptions -XX:+UseNUMA -XX:BoxTypeCachedMax=100000 -XX:ParScavengePerStrideChunk=8192 +``` +### 3.4 spark应用参数 +``` +目的 :在Spark基础配置值的基础上,按照理论公式得到一组较合理的Executor执行参数,使能在鲲鹏上会带来明显的性能提升。 + +方法 +- 如果用Spark-Test-Tool工具测试sql1~sql10场景,打开工具目录下的“script/spark-default.conf”文件,添加以下配置项: +yarn.executor.num 15 +yarn.executor.cores 19 +spark.executor.memory 44G +spark.driver.memory 36G +- 如果使用HiBench工具测试wordcount、terasort、bayesian、kmeans场景,打开工具目录下的“conf/spark.conf”文件,可以根据实际环境对运行核数、内存大小做调整: +yarn.executor.num 15 +yarn.executor.cores 19 +spark.executor.memory 44G +spark.driver.memory 36G +``` +### 3.5 专用场景优化项--SQL场景 +#### 3.5.1 sql1-IO密集型SQL +``` +目的 :sql1是IO密集型场景,可以优化IO参数来带来最佳性能。 +方法 +- 对以下IO相关参数进行设置,其中sd$i指所有参与测试的磁盘名: +echo 128 > /sys/block/sd$i/queue/nr_requests +echo 512 > /sys/block/sd$i/queue/read_ahead_kb +- 对内存脏页参数进行设置: +/proc/sys/vm/vm.dirty_expire_centisecs 500 +/proc/sys/vm/vm.dirty_writeback_centisecs 100 +该场景其余参数都使用通用优化项的通用优化值。 +``` +#### 3.5.2 sql2 & sql7 - CPU密集型SQL +``` +目的 :sql2和sql7是CPU密集型场景,可以优化spark执行参数来带来最佳性能。 + +方法 +- Spark-Test-Tool在配置文件(script/spark-default.conf)中指定的运行核数、内存大小可以根据实际环境来做调整,来达到最优性能。比如对于鲲鹏920 5220处理器,sql2和sql7场景建议以下Executor参数。 + +yarn.executor.num 42 +yarn.executor.cores 6 +spark.executor.memory 15G +spark.driver.memory 36G +``` +#### 3.5.3 sql3-IO + CPU +``` +目的 :sql3是IO+CPU密集型场景,可以优化spark执行参数、调整IO参数来带来最佳性能。 + +方法 +- Spark-Test-Tool在配置文件(script/spark-default.conf)中指定的运行核数、内存大小可以根据实际环境来做调整,来达到最优性能。比如对于鲲鹏920 5220处理器,sql3场景建议以下Executor参数。 +yarn.executor.num 30 +yarn.executor.cores 6 +spark.executor.memory 24G +spark.driver.memory 36G +- 调整io预取值,其中sd$i表示所有参与spark的磁盘名: +echo 4096 > /sys/block/sd$i/queue/read_ahead_kb +其余参数都使用硬件优化的默认参数。 +``` +#### 3.5.4 sql4 - CPU密集 +``` +目的 :sql4是CPU密集型场景,可以优化spark执行参数、调整IO参数来带来最佳性能。 + +方法 +Spark-Test-Tool在配置文件中指定的运行核数、内存大小可以根据实际环境来做调整,来达到最优性能。比如对于鲲鹏920 5220处理器,sql4场景建议以下Executor参数。 + +- 打开工具目录下的script/spark-default.conf文件,添加以下配置项: +yarn.executor.num 42 +yarn.executor.cores 6 +spark.executor.memory 15G +spark.driver.memory 36G +- 同时调整io预取值,其中sd$i表示所有参与spark的磁盘名: +echo 4096 > /sys/block/sd$i/queue/read_ahead_kb +``` +#### 3.5.5 sql5/6//8/9/10 +都使用通用优化项的默认参数。 +### 3.6 专用场景优化项--HiBench场景 +#### 3.6.1 Wordcount – IO + CPU密集型 +``` +目的 :Wordcount是IO+CPU密集型场景,二者均衡,采用单队列的deadline调度算法反而不好,采用多队列的mq-deadline算法并调整相关io参数,能得到较好的性能结果。 + +方法 +- 对以下配置进行修改,其中sd$i指所有参与测试的磁盘名称: +echo mq-deadline > /sys/block/sd$i/queue/scheduler +echo 512 > /sys/block/sd$i/queue/nr_requests +echo 8192 > /sys/block/sd$i/queue/read_ahead_kb +echo 500 > /proc/sys/vm/dirty_expire_centisecs +echo 100 > /proc/sys/vm/dirty_writeback_centisecs +echo 5 > /proc/sys/vm/dirty_background_ratio +- 该场景下采用3-5倍总核数作为数据分片的Partitions和 Parallelism进行数据分片,减小单Task文件大小,对性能有正面提升。可以使用以下分片设置: +spark.sql.shuffle.partitions 300 +spark.default.parallelism 600 +- HiBench在配置文件中指定的运行核数、内存大小可以根据实际环境来做调整,来达到最优性能。比如对于鲲鹏920 5220处理器,Wordcount场景建议以下Executor参数: +yarn.executor.num 51 +yarn.executor.cores 6 +spark.executor.memory 13G +spark.driver.memory 36G +- 调整Jdk参数,对性能有正面影响(3%性能提升),以下配置添加到spark.conf文件中: +spark.executor.extraJavaOptions -XX:+UseNUMA -XX:BoxTypeCachedMax=100000 -XX:ParScavengePerStrideChunk=8192 +spark.yarn.am.extraJavaOptions -XX:+UseNUMA -XX:BoxTypeCachedMax=100000 -XX:ParScavengePerStrideChunk=8192" +``` +#### 3.6.2 Terasort – IO + CPU密集型 +网卡绑核调整 +``` +目的 :该场景下可以通过减少网卡队列数并绑固定核来优化。 + +方法 +- 请新建一个shell脚本,将以下代码复制到其中并执行。 +#! /bin/bash +ethtool -K enp134s0 gro on +ethtool -K enp134s0 tso on +ethtool -K enp134s0 gso on +ifconfig enp134s0 mtu 9000 up +ethtool -G enp134s0 rx 4096 tx 4096 +ethtool -G enp134s0 rx 4096 tx 4096 +ethtool -L enp134s0 combined 4 +- 请新建一个shell脚本,将以下代码复制到其中并执行,其中$1是网卡名称。执行后可以实现绑核: +# /bin/bash +t=32 +for i in `cat /proc/interrupts |grep -e $1 |awk -F ':' '{print $1}'` +do +cat /proc/irq/$i/smp_affinity_list +echo $t > /proc/irq/$i/smp_affinity_list +cat /proc/irq/$i/smp_affinity_list +t=`expr $t + 1` +done +``` +其他调优 +``` +echo cfq > /sys/block/sd$i/queue/scheduler +echo 512 > /sys/block/sd$i/queue/nr_requests +echo 8192 > /sys/block/sd$i/queue/read_ahead_kb +echo 4 > /sys/block/sd$i/queue/iosched/slice_idle +echo 0 > /sys/module/scsi_mod/parameters/use_blk_mq +echo 500 > /proc/sys/vm/dirty_expire_centisecs +echo 100 > /proc/sys/vm/dirty_writeback_centisecs +- 该场景下采用3-5倍总核数作为数据分片的Partitions和 Parallelism进行数据分片,减小单Task文件大小,对性能有正面提升。可以使用以下分片设置: +spark.sql.shuffle.partitions 1000 +spark.default.parallelism 2000 +- HiBench在配置文件中指定的运行核数、内存大小可以根据实际环境来做调整,来达到最优性能。比如对于鲲鹏920 5220处理器,Terasort场景建议以下Executor参数: +yarn.executor.num 27 +yarn.executor.cores 7 +spark.executor.memory 25G +spark.driver.memory 36G +``` +#### 3.6.3 Bayesian – CPU密集型 +``` +目的 :Bayesian是CPU密集型场景,可以对IO参数和spark执行参数进行调整。 + +方法 +- 该场景可以使用以下分片设置: +spark.sql.shuffle.partitions 1000 +spark.default.parallelism 2500 +- 打开HiBench工具的“conf/spark.conf”文件,增加以下Executor参数: +yarn.executor.num 9 +yarn.executor.cores 25 +spark.executor.memory 73G +spark.driver.memory 36G +- 该场景使用以下内核参数: +echo mq-deadline > /sys/block/sd$i/queue/scheduler +echo 0 > /sys/module/scsi_mod/parameters/use_blk_mq +echo 50 > /proc/sys/vm/dirty_background_ratio +echo 80 > /proc/sys/vm/dirty_ratio +echo 500 > /proc/sys/vm/dirty_expire_centisecs +echo 100 > /proc/sys/vm/dirty_writeback_centisecs +- 调整Jdk参数,以下配置添加到spark.conf文件中: +spark.executor.extraJavaOptions -XX:+UseNUMA -Xms60g -Xmn25g -XX:+UseParallelOldGC -XX:ParallelGCThreads=24 -XX:+AlwaysPreTouch -XX:-UseAdaptiveSizePolicy +``` +#### 3.6.4 Kmeans – 纯计算密集型 +``` +目的 +Kmeans是CPU密集型场景,可以对IO参数和spark执行参数进行调整。 + +方法 +- 主要是调整Spark Executor参数适配到一个较优值,该场景可以使用以下分片设置: +spark.sql.shuffle.partitions 1000 +spark.default.parallelism 2500 +- 使用以下内核参数: +echo 4096 > /sys/block/sd$i/queue/read_ahead_kb +- HiBench在配置文件中指定的运行核数、内存大小可以根据实际环境来做调整,来达到最优性能。比如对于鲲鹏920 5220处理器,K-means场景建议以下Executor参数: +yarn.executor.num 42 +yarn.executor.cores 6 +spark.executor.memory 15G +spark.driver.memory 36G +spark.locality.wait 10s +- 调整Jdk参数,以下配置添加到spark-default.conf文件中: +spark.executor.extraJavaOptions -XX:+UseNUMA -XX:BoxTypeCachedMax=100000 -XX:ParScavengePerStrideChunk=8192 +spark.yarn.am.extraJavaOptions -XX:+UseNUMA -XX:BoxTypeCachedMax=100000 -XX:ParScavengePerStrideChunk=8192 +- 毕昇JDK对Kmeans有特定的优化,可以使用毕昇JDK进行加速。 + +- 下载毕昇JDK地址 +下载地址:https://mirrors.huaweicloud.com/kunpeng/archive/compiler/bisheng_jdk/bisheng-jdk-8u262-linux-aarch64.tar.gz +- 更换毕昇JDK +- 停止集群 +- 将BiSheng JDK解压并移动到/usr/local/下 +tar –zxvf bisheng-jdk-8u262-linux-aarch64.tar.gz + +mv bisheng-jdk1.8.0_262 /usr/local/ + +- 将原来已有的jdk文件重命名并将BiSheng JDK重命名为命名为原来的jdk的文件名并更改权限 +mv jdk8u222-b10/ jdk8u222-b10-openjdk/ + +mv bisheng-jdk1.8.0_262/ jdk8u222-b10/ + +chmod -R 755 jdk8u222-b10/ + +重启集群 +- 参数优化 +/opt/HiBench-HiBench-7.0/conf/spark.conf 中修改spark.executor.extraJavaOptions的值 +- 设置为spark.executor.extraJavaOptions -XX:+UnlockExperimentalVMOptions +-XX:+EnableIntrinsicExternal -XX:+UseF2jBLASIntrinsics -Xms43g + +-XX:ParallelGCThreads=8 + +其中-xms(n)g 取决于/opt/HiBench-HiBench-7.0/conf/spark.conf中spark.executor.memory值得大小n的值建议设置为spark.executor.memory的值减1。 +```