大数据基础环境配置

大数据的软件通常运行在环境一致、配置规范的集群环境中,允许底层硬件型号和规格的不同,但要充分做好规划和利用, 在软件层面尽量保证环境的一致性,仍然可以避免很多因为环境配置随意、不匹配带来的问题,也可以使问题的定位及处理更加高效,当前页面列出了大数据集群应该保持一致的通用基础或基础配置,有些是需要在集群规划阶段就要提前考虑到的点,能够节省后期不必要的调整,也可以作为对集群的checklist,方便调整配置。

1.操作系统环境

集群的操作系统版本应该保持一致,例如都是CentOS或者都是Ubuntu,不同的发行版的程序包和配置方式都有所不同,为了避免不必要的配置成本,要求集群所有的操作系统环境一致。

2.网络

单个集群的机器应分布在相同的网络环境中,所有节点的网络带宽、延迟应基本一致,推荐使用万兆网络,大数据系统对网络依赖比较大,良好的网络环境可以是集群正常运行的前提,在部署环境之前,建议使用iperf3工具对网络带宽进行测试,确保网络和预期的一致。

下载iperf3 的rpm包,适用于CentOS x86环境:

假如有两个节点分别为:node1node2,测试带宽的方法是:

  1. node1上运行iperf3服务:
iperf3 -s
  1. 然后在node2上运行iperf3客户端连接node1上的服务进行测试:
iperf3 -c node1

运行之后会报告带宽的情况。

image-20220615144941745

其他系统版本的iperf工具下载:iperf download

集群之间的网络要保持畅通,如果开启了防火墙,建议将集群所有节点的ip加入到允许列表中,不建议使用端口号限制,端口号不确定而且临时添加较为繁琐。

3.主机名和hosts文件

每个机器要配置有意义的主机名,并且每个机器的/etc/hosts文件中都应该存在全部机器的列表,例如有如下3个机器:

192.168.0.10, 192.168.0.11, 192.168.0.12

需要先为每个机器设置主机名,假设按照上面的顺序分别为:node1,node2,node3

# 在192.168.0.10上执行
hostnamectl set-hostname node1
# 在192.168.0.11上执行
hostnamectl set-hostname node2
# 在192.168.0.12上执行
hostnamectl set-hostname node3

hostnamectl工具是systemd系列集合的一种,可以方便对主机名修改,修改后可以执行hostnamectl查看当前的主机名。

然后编写hosts文件如下:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

# 添加机器和ip列表
192.168.0.10   node1
192.168.0.11   node2
192.168.0.12   node3

其中最上面两行是系统自带的,需要保留,下面3条是需要手动添加的,每个机器的/etc/hosts的文件内容都需要同步修改保持一致。

主机名本身就是域名,所以命名需要符合域名的规范,可以参考RFC 1035,不论何种规范必须保持统一,例如可以使用UN/LOCODE-项目名-机器编号的方式命名,UN/LOCODE是通用的地点名称编码,机器编号可以是ip地址最后部分也可以是自定义的编号,例如:snz-fusion-21,可以采用破折号-或者点.分割,切勿出现下划线_,否则部分应用不认识会报错,不建议使用简拼地名,容易混淆,例如sz无法区分是深圳还是苏州。

4.集群间配置SSH免密

一些大数据组件例如Hadoop,在启动停止或者运行时,都会通过SSH协议登录集群中的其他机器执行一些命令,这个时候就需要配置SSH免密登录或者SSH互信,才可以正常对集群进行管理,还是假设有3台机器,分别为node1node2node3,假设主机名和hosts文件都已经配置正确,然后我们在所有机器上都操作生成密钥对,包括公钥和私钥:

# 所有节点都要执行一次{node1,node2,node3}
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

执行之后会在~/.ssh下生成两个文件,分别是私钥id_rsa和公钥id_rsa.pub,私钥不要泄露只需要将公钥追加到对方节点的验证列表即可,上面如果为了方便想简化配置,也可以只在1个节点生成密钥,然后所有节点都相同即可。

然后在所有机器执行下面命令:

# 所有节点都要执行一次{node1,node2,node3}
# 都将自己的公钥发送至node1的authorized_keys中 这步操作需要输入密码
ssh-copy-id -i ~/.ssh/id_rsa.pub node1

这样操作的目的是让node1节点的authorized_keys中保存集群所有的公钥,然后再将node1中的authorized_keys文件同步至集群其他的节点,这样就可以实现整个集群中所有节点的两两互信:

# 在node1执行, 将authorized_keys文件发送至集群中所有其他节点 发送时均需要输入密码
scp ~/.ssh/authorized_keys node2:~/.ssh/
scp ~/.ssh/authorized_keys node3:~/.ssh/

这样操作之后,集群中node1node2node3两两之间都可以实现免密登录了,注意第一次登录时需要输入yes确认。

添加节点操作

如果此时集群中加入1个节点node4,首先应该配置好node4的主机名并且更新集群所有节点的hosts文件,这个不再详细叙述,然后要实现免密首先要在新加节点上生成公钥私钥,并将公钥发送至集群中原有的1个节点:

# 在node4上执行 生成密钥对
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
# 在node4上将密钥对同步至node1  需要输入密码
ssh-copy-id -i ~/.ssh/id_rsa.pub node1

此时node1上面的公钥是全的,只需要再次同步到集群全部节点(包括新节点)即可:

# 在node1执行, 将authorized_keys文件发送至集群中所有其他节点 已经免密的节点不需要输入密码
scp ~/.ssh/authorized_keys node2:~/.ssh/
scp ~/.ssh/authorized_keys node3:~/.ssh/
# 发送到新加节点node4时需要输入密码
scp ~/.ssh/authorized_keys node4:~/.ssh/

现在新加的节点和集群中所有原有节点都可以实现免密了。

5.Java环境

Hadoop生态中绝大部分组件都是采用Java或者JVM语言进行开发,所以Java环境已经成为部署大数据组件的基础配置,所以集群开始时就需要安装版本一致的Java环境,可以选择OpenJDK也可以选择Oracle JDK,有些系统发行版例如CentOS 安装时已经选择了JDK环境,这种情况下是不需要额外再进行安装的,检查Java环境是否存在可以使用:

java -version

image-20220616092243780

像这种情况安装的就是OpenJDK环境。

目前安装Java环境要求是1.8.x版本。

JAVA_HOME环境变量设置:

对于OpenJDK来说,通常使用yum或者apt包管理工具安装,在/usr/lib/jvm下有对应的安装目录,使用ll /usr/lib/jvm查看:

image-20220616092646604

所以这里就可以设置为:

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

当然OpenJDK安装时会在系统的PATH下生成对应的可执行文件链接,所以不需要配置环境变量,只在需要的时候设置JAVA_HOME即可。

如果是OracleJDK,是采用二进制包的方式解压安装,这个可以自定义指定位置,例如/usr/local/jdk1.8.0_232,需要在/etc/profile或者~/.bashrc中配置环境变量如下:

export JAVA_HOME=/usr/local/jdk1.8.0_232
export PATH=$PATH:$JAVA_HOME/bin

这样就可以正常使用java相关命令了。

无论是OpenJDK还是OracleJDK,在大数据组件中如果需要JAVA_HOME变量时都需要单独进行配置。

OpenJDK和OracleJDK只能存在1个,同时安装会带来不可预知的问题!

6.时钟同步

大数据中的某些软件例如HBase对时钟同步性依赖比较强,如果集群中节点时间偏离过大,可能导致系统不稳定或者服务终止,时钟同步通常依赖ntp服务,在不同的Linux发行版会有所不同,例如在CentOS 7.x中采用ntp,在CentOS 8.x中采用chrony,而对于Ubuntu/Debian较新的发行版中,时间同步的客户端依赖一个默认的系统服务systemd-timesyncd.service进行,只需要简单配置一下时间服务器即可,所以不同发行版的配置是不一样的。

在配置ntp服务之前,首先要确保所有节点的时区完全一致,国内的时区建议都配置为:Asia/Shanghai

# 所有节点设置统一时区
timedatectl set-timezone Asia/Shanghai
# 查看当前设置
timedatectl

设置时区后可以继续配置ntp时钟同步服务,这里以CentOS 7.x为例,在服务侧需要配置server以及允许客户端的列表,也就是说ntp服务端其实也是客户端,也需要从其他时间服务器同步数据,编辑/etc/ntp.conf配置如下:

server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst
# 如果是离线状态也可以配置为自己本身
server  127.127.1.0
fudge   127.127.1.0 stratum 10

# 配置限制的主机列表
# 默认允许本机
restrict 127.0.0.1
restrict ::1
# 根据实际的集群新增
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

然后保存配置并启动ntp服务:

systemctl start ntpd
# 设置开机自启动
systemctl enable ntpd
# 查看服务状态
systemctl status ntpd

然后在客户端同样编辑/etc/ntp.conf配置要同步的服务器:

# 192.168.1.10是刚才时间服务节点的ip
server 192.168.1.10

# 同步时间间隔范围 6表示2的6次方秒即64s, 10表示1024s
minpoll 6
maxpoll 10

然后保存配置文件,同样启动ntp服务:

systemctl start ntpd
# 设置开机自启动
systemctl enable ntpd
# 查看服务状态
systemctl status ntpd

查看同步状态:

ntpstat
# 或者
ntpq -np

ntpq工具用来查看和时间服务器的同步状态,参数表示为:

-n:表示对源地址按照ip格式输出,默认是输出的主机名。

-p: 打印对等节点以及状态摘要。

上面是在CentOS 7.x发行版上基于ntp对时钟同步的简要配置,其他Linux发行版的后续如有必要会继续补充。

注意ntp服务端如果有防火墙则必须开放服务允许客户端访问,如果是firewall工具可以按照例如:firewall-cmd --add-service=ntp --permanent && firewall-cmd --reload的方式添加。

7.内核参数

大数据软件对资源利用的要求比较高,而系统有些默认参数无法满足需求,所以要调整至合适的值以提升性能,同时不同的框架或系统对参数的要求也不一样,在这里仅抽出一些比较通用的进行配置,其余的在专门的页面中单独介绍。

7.1.最大文件数

程序同时打开过多的文件时,会抛出常见的错误Too many open files. ,原因就是系统对进程所能打开的文件数量进行了限制,查看当前的文件数量限制:

ulimit -n

默认的数量是1024,ulimit也可以查看其它全部的限制参数:

ulimit -a

其中包括文件大小、栈大小以及最大进程数等。

临时调大当前的文件数可以使用:

ulimit -n 65535

这个调整是临时的,当前会话被断开后也就失效了,只有在当前会话断开之前启动的进程才有效。

进程实际的运行状态保存在/proc/<pid>目录中,其中/proc/<pid>/limits是当前正在运行的进程所受到的限制,即使修改了最大文件数,也要确认进程实际的状态是否已经生效,例如:

# 查看pid为16891的进程limits
cat /proc/16891/limits

那么想实现用户会话建立后最大文件数自动生效,有下面两种配置方法。

7.1.1.借助登录时PAM配置

在使用SSH连接时,如果开启PAM策略,就可以实现一系列的限制,例如登录失败次数限制、会话保持时长限制等,当然也包括最大文件数等资源的限制,可以编辑SSH的配置文件/etc/ssh/sshd_config确认是否开启PAM:

UsePAM yes

确认开启后可以查看PAM关于登录的配置/etc/pam.d/login确认其中以及include的相关文件中,是否存在如下的配置:

session required pam_limits.so

默认这个配置都会存在的。

最后编辑配置文件/etc/security/limits.conf,增加如下配置:

# *表示设置所有的用户的文件数 (注意: root用户除外)
* soft nofile 1000000
* hard nofile 1000000
# 设置root用户的文件数
root soft nofile 1000000
root hard nofile 1000000

注意有些发行版root用户需要单独配置,只配置*是匹配不到的,文件数建议设置为100万。

注意:最大文件数的设置绝对不能超过内核参数fs.nr_open的设置,默认这个值在Linux内核代码中被定义为1048576,设置先一定要通过sysctl fs.nr_open确认该参数的值,超出这个值会报错最终导致无法登录系统,只能通过救援方式修改回来。

关于fs.nr_open在Linux源码的fs/file.c中有定义:

unsigned int sysctl_nr_open __read_mostly = 1024*1024;
unsigned int sysctl_nr_open_min = BITS_PER_LONG;
/* our min() is unusable in constant expressions ;-/ */
#define __const_min(x, y) ((x) < (y) ? (x) : (y))
unsigned int sysctl_nr_open_max =
	__const_min(INT_MAX, ~(size_t)0/sizeof(void *)) & -BITS_PER_LONG;

这个值默认是1024*1024也就是1048576,并且最大值受限于sysctl_nr_open_max的值,这个值结果是2147483584,当设置超过这个值的时候也会报错。

在较新的Linux发行版中,systemd的版本也比较新,那么fs.nr_open的值会被修改为1073741816。

总之这个fs.nr_open内核参数不需要修改,只需要在设置之前确认不要超过即可。

保存/etc/security/limits.conf后关掉当前shell客户端再重新连接查看确认生效。

7.1.2.通过登录时的环境变量配置文件实现

可以通过环境变量配置文件如:/etc/profile~/.bashrc或者~/.bash_profile等环境变量配置文件来设置,添加内容如下:

ulimit -HSn 1000000

其中参数-H-S分别指定硬限制和软限制。

保存后再次重新连接shell确认参数是否修改。

systemd管理的进程不受上面配置方式的影响,由具体的systemd独立的参数配置,上面设置的参数只应用于当前会话中直接启动的进程。

7.2.进程VMA(Virtual Memory Area)数量限制

进程的VMA(虚拟内存区域),其实就是进程通过mmap等系统调用创建的虚拟内存空间,当然也包括文件映射I/O,但是操作系统默认对进程所能使用的虚拟内存数量是有限制的,默认值是65530,可以通过命令查看当前的值:

sysctl vm.max_map_count

显然这个值在很多大数据的系统中是比较小的,所以需要调大,这里设置为 2048000:

sysctl -w vm.max_map_count=2048000 >> /etc/sysctl.conf

设置默认是临时生效,所以在设置的同时添加-w参数输出到/etc/sysctl.conf之后下次开机也会自动生效了。

从文件中读取当前设置的参数可以使用-p

sysctl -p

7.3.降低交换分区使用倾向

交换分区是磁盘上的一块空间,可以在物理内存的空间不足时,将一些不太常用的页面换出到交换分区,从而支持更多的进程运行,但是交换分区一旦使用频繁系统运行将被严重拖慢,当我们查看内核进程kswapd0的占用比较高,说明内存已经开始换入换出了,需要排查是哪个进程占用了大量的内存,是内存确实不够用还是应用程序设计缺陷导致,现在服务器的内存通常都比较大,为了保证运行的性能,建议将交换分区关闭掉或者降低交换分区的使用倾向,通过调整内核参数vm.swappiness实现:

sysctl -w vm.swappiness=0 >> /etc/sysctl.conf
# 查看修改的文件内容
sysctl -p

默认vm.swappiness的值为60,很容易就会使用交换分区,调整为0之后就可以降低交换分区的使用,如果最后内存确实不够用,操作系统仍然会使用交换分区,但是对物理内存的使用会激进一些,如果当前交换分区已经被占用可以通过重新开启交换分区来完成清理:

swapoff -a && swapon -a 
free -h

这样就可以清理掉swap空间了。