爬出过的坑
大数据运维过程就是一个踩坑的过程。如下分享一些踩过的坑,以供参考,此文不定期更新,敬请关注。
Hive
* hive的udf使用全名如select mydatabase.myfun(id) from mytable
* hive.hadoop.supports.splittable.combineinputformat参数为true时在textfile的gzip压缩下可以合并文件。
* hive中export HIVE_OPTS=1G可以控制beeline的内存。
* filesinkoperator在写bucketfile时,如果相关安装目录权限异常可能无法加载lib*.so文件从而导致写文件时抛出filesystem closed异常
java.lang.unsupporttedopeationException: Currently the writer can only accept ByteArrayWritable 通常是rc表的serde设置问题。可使用lazyBinaryCOlumnSerde或者ColumnarSerde
* 不经过回收站的删除表 drop table mytable purge.
* select count(distinct id) from mytable只有一个reduce,可以考虑改为 select count(*)from select distinct id from mytable
* beeline出现operation cancelled的的原因有: 1) 客户端full gc 2) 服务端fullgc 3)客户端服务端网络断开 4) 服务端县城执行耗时超过客户端的sockettimeout时间,出发客户端主动关闭
* hivesql处理完后的数据的avgsize小于16M的情况下,会触发mr的merge操作。
* hive的sql对hdfs的操作很重。单个load操作,可能触发20次的操作。对性能影响大
* 在执行beeline时添加--verbose=true参数可打印更多信息
* 执行sql时,hive.metastore.client.socketTimeout出现连接数据库timeout,如果是表分区过多,可以考虑元数据中手动删除表:
select *from tbls where TBL_NAME="tableToDelete" (取出表的"id")
delete from partition_key_values where part_id in select part_id from partitions where tbl_id = "id"
delete from partition_params where partid in select part_id from partitions where tbl_id = "id"
delete from partition where tbl_id = "id"
* 执行union all的操作可能导致stackoverflow
* 处理数据时cant be cast的异常同城是数据异常导致
Spark
* driver节点需要配置所有hbase进程的hostname和ip对应关系,否则可能出现无法解析节点导致访问异常 creating new stage failed due to exception
* spark读取parquet表时,每个文件都需要和hdfs交互,先访问到备namenode情况下对性能影响较大
* spark或者hbasetoken的用户需要有hbase:meta表的exec权限
* hivecontext不能重复创建
* spark的beeline则需要通过spark_driver_memory来设置
* 多个字段的group by 易引发oom
* spark写hdfs的应用应保证可重入
* kafka单挑消息过大可能引发classnotfoundexception : kafka.common.failedtosendmessag或者sockettimeoutexception can't find leader offset for set 可考虑调整"socket.request.max.bytes"socket.receive.buffer.bytes, socket.send.buffer.bytes, replica.socket.receive.buffer.bytes
* spark应用打包时,不应包含除应用的包之前的jar包
* Thriftserver的默认handler线程是500
* spark的单个task不能支持2G以上的
* 值为空的配置或者boolean类型(true或者false)时,单词拼错的情况下可能导致driver启动异常
* 执行union all的操作可能导致stackoverflow
* 在eventlog指定的目录写满时(hdfs单个目录的文件数限制在104万),可能导致spark应用无法提交
* 运行structed Streaming 抛出异常 java.lang.classNotFoundException : kafka.DefaultSource,是由于缺少jar包,spark-sql-kafka-*_*.jar导致serviceloader加载时,找不到kafkasource,从而引发异常
* Spark应用开发需要导入import org.apache.spark.sql.functions._ 以及import spark.implicits._ 否则在编译/运行时可能抛出各种异常(如: value $ is not a member of StringContext )
* 开源Spark在hdp的yarn集群中运行原生页面的executor页面无法打开,需要将HADOOP_CONF_DIR/YARN_CONF_DIR下的yarn-site.xml文件中的yarn.timeline-service.enabled参数设置为false,可参考https://www.jianshu.com/p/460f98111d43
* 开源Spark在hdp的yarn集群中运行找不到executorLauncher类, 可参考https://www.jianshu.com/p/de762c244663
* Spark的安全配置(principal和keytab文件)可以通过如下方式传入:
1) --principal和--keytab的方式传入
2)在spark-defaults.conf配置文件中配置spark.yarn.principal和spark.yarn.keytab
3) 在提交命令行时,传入--properties-file指定配置文件,并配置spark.yarn.principal和spark.yarn.keytab
* Structed Streaming基于eventtime的消息,需要该字段是timestamp类型,格式应当是"yyyy-mm-dd HH:mm:ss" 如果设置微微“yyyymmdd HH:mm:ss” 可能导致接收到数据后无法完成后续处理,从而无法得到结果。
* Structed streaming 如果是从kafka消费数据,应用在多个writestream时,每个writestream分别从kafka获取消息
* Structed Streaming 应用在UI页面显示不连续的问题可参考(https://www.jianshu.com/p/43b43c5cd5d9)
* 安全场景下提交Spark应用抛出如下异常:
org.apache.hadoop.yarn.exceptions.YarnException: Failed to submit application_1524902307937_0021 to YARN : Failed to renew token: Kind: HDFS_DELEGATION_TOKEN, Service: ha-hdfs:paasjq, Ident: (HDFS_DELEGATION_TOKEN token 69 for spark) 此异常是rm在handlesubmitApplication时从nn中获取token失败,导致应用提交异常。可重启yarn规避该问题
* Structed Streaming 应用运行时,抛出异常
“Exception in thread "main" java.lang.NoSuchMethodError: net.jpountz.lz4.LZ4BlockInputStream.<init>(Ljava/io/InputStream;Z)V
at org.apache.spark.io.LZ4CompressionCodec.compressedInputStream(CompressionCodec.scala:122)”原因是应用在执行时对数据解码(反序列化)时,使用了默认的lz4解压缩算法,在spark-core中依赖的lz4版本是1.4,而kafka-client中依赖的lz4版本是1.3版本,在生成解压器时,版本不兼容异常。 解决方法可参考网上修改源码解决,也可通过设置"spark.io.compression.codec","snappy"或其他压缩算法规避。鉴于修改源码重新打包替换较为繁琐,建议设置其他压缩算法规避。
* Sparkstreaming应用在jobgenerator阶段抛出如下异常:“Error generating jobs for time”会调用到reprotError方法,进而设置error=e,将导致streamingContext.awaitTermination方法退出,进而结束应用
* SparkStreaming应用在job异常时,jobScheduler的handleJobCompletion方法,调用reportError方法,进而设置error=e,将导致streamingContext.awaitTermination方法退出,进而结束streaming应用。
* spark应用在遇到磁盘异常的情况下,默认会将task的retry同样发送到该container进程内运行,连续失败后,将导致task失败次数超限进而退出。在1.*版本可以通过设置spark.scheduler.executorTaskBlacklistTime禁止task的在一定时间内重新分配在之前运行异常的container内。在2.*版本中可通过设置spark.blacklist.enabled打开黑名单机制并配置相关参数即可(可参考https://spark.apache.org/docs/2.3.1/configuration.html)
* Spark应用访问Kafka抛出"java.lang.AssertionError: assertion failed: Failed to get records for (...) after polling for 512",是由于kafka无法响应客户端请求,可查看kafka-request-handler线程是否一致处于消耗CPU的繁忙状态,如果是需要调整num.io.threads参数并重启Kafka集群
* Structured Streaming中,如果出现消息流的时间异常,比如单条消息的时间戳远远大于其他正常条件的时间戳,则会出现大量消息被丢弃(如正常的时间戳为12:00时,异常消息为晚上18:00,假定延迟时间设定的时间为10min,则后续的接收的时间早于17:50的消息会被丢弃);针对这种场景,我们可以将基于当前系统时间设定,将异常消息过滤。过滤方法是加入filter条件,如unix_timestamp(EVENT_DATE) - unix_timestamp(current_timestamp) < 3600, 其中EVENT_DATE为消息流中表示消息时间戳的字段,意思是 所有时间戳比当前系统时间大1小时的消息将被丢弃。
Flink
* flink开发过程中需要导入org.apache.flink.streaming.api.scala._ 否则可能运行时某些转换异常
* Flink的TimeCharacteristic.EventTime模式下,默认的watermark生成时间间隔设置为200ms(代码写死的), 可以通过env.getConfig.setAutoWatermarkInterval(2000)来进行设置间隔,但该函数需要在env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)后面调用,否则会被复写为200
* flink使用tableapi时,需要导入org.apache.flink.table.api.scala._ 有些函数才能使用
* Flink使用CsvRowSerializationSchema序列化消息时,会自动在消息结果添加”\r“,"\n","\r\n",截止Flink1.8版本,该问题没有解决。如果是发送目的地是kafka,则可以通过kafka的interceptor机制在发送前将多余的字符去掉
* Flink使用消息使用CsvRowSerializationSchema序列化时,如果发送消息的字段类型是SQL_TIME,SQL_DATE,SQL_TIMESTAMP,则发送出去的消息会自动添加双引号”“,如发送2019-08-01 12:00:00,如果是SQL_TIMESTAMP格式,则真正发送的是”2019-08-01 12:00:00“。
Yarn
* Yarn通过配置获取集群总资源(cpu/mem/网络/io)信息(与实际无关)
* Yarn集群的资源状态(cpu/mem使用)和主机的cpu/mem消耗无直接关系(Yarn只负责分配资源给应用,不*
管应用如何使用)
* yarn通过app申请资源,根据用户,以及剩余资源判断是否接受和运行app
* Yarn根据配置的粒度以及app的申请分配资源
* Yarn只负责分配资源给应用,不管应用如何使用
* yarn监控container进程的memory来判断container使用资源是否超限
* Yarn调度策略考虑vcore和不考虑vcore的策略
* score的概念只是用来划分粒度,控制集群能启动的container数目
* Yarn只负责分配资源给应用(container),无法管控container如何使用资源(Yarn管理内存的使用,但无法直接cpu。cpu可通过cgroup控制)
Kafka
* 某些groupid的consumer无法消费数据,而其它groupid的consumer可以消费,可能是Kafka内部的consumer_offset的topic出现异常
* 消费kafka小时时,consumer端一直抛出如下异常“NetworkClient: Bootstrap broker ***:6667 disconnected”异常,此时服务端抛出异常如下:“ERROR Closing socket for *****:6667-******:53026 because of error (kafka.network.Processor)kafka.network.InvalidRequestException: Error getting request for apiKey: 3 and apiVersion: 2”,通常出现改现象端原因是消费端和kafka服务端端版本不匹配 。如客户端使用0.10.1.10服务端时0.10.0.1.
* 安全集群下消费kafka消息 Error while fetching metadata for correlation Id ** [UNKNOWN_TOPIC_OR_PARTITION] 原因可能是使用的用户没有想过topic的读取权限
* 客户端访问kafka抛出如下异常:“Couldn't find leader offsets for Set([topictest,1]))”,该异常是在获取leader后冲leader获取offset失败,通常是kafka集群不稳定(如长时间gc,网络异常等)导致,可参考调整如下参数:KAFKA_HEAP_OPTS、socket.request.max.bytes、socket.receive.buffer.bytes、socket.send.buffer.bytes、replica.socket.receive.buffer.bytes这些参数值的大小(例如配置KAFKA_HEAP_OPTS值为“-Xmx4G -XX:MaxDirectMemorySize=128m”)
* 安全模式下访问kafka,抛出异常“Empty namestring not allowed”。 此时是访问kafka使用的jaas.conf配置文件中缺少serviceName字段所致。添加即可。
* Kafka集群的topic的partition的ISR列表不全(Isr列表replica数<创建topic时的partition的replica数)表明kafka集群存在不稳定的情况,需要调优Kafka集群
HDFS
* hdfs datanode节点挂在磁盘数据或者规格不一致的情况下,hdfs的读写性能相差可能很大从而影响某些sql或者其他操作的性能
* HDFS性能可通过查看查看平均wait和processing时间来查看hdfs是否存在性能瓶颈
* 在安全/kerberos模式下,连接hdfs抛出异常 Couldn't setup io streams : java.lang.IllegalArgumentException: Server has invalid invalid kerberos principal, 原因是连接kerberos之后,无法找到hdfs在kdc中的principal,需要查看core-site.xml,hdfs-site.xml中的相关配置,如dfs.namenode.kerberos.principal是否正确
Zookeeper相关
* zookeeper单独挂盘或者调整-Dzookeeper.snapCount=3000减少zk写入数据时间
* rm启动异常时抛出无法加载某个app文件,需要再zk上删除该app信息
* 组件与zk连接出现异常(经常性断链),可通过增大zksessiontimeout设置来提高服务可靠性
Hbase
* hbase没有指定startkey endkey时,会全表扫描(rpc server kerberos principal name for service ***),性能较差
* rs节点的hostname和ip的一对多关系会引发rs个数的显示和真实的个数不一致
* 在处理hbase表数据时,出现如下异常“hbaserowkey can't be null error while processing *******”,说明有value为空,此时可通过select* from tablename a where a.rowkey is null or a.rowkey=""
* 通过hive查询相关表时,出现查询失败(权限不足异常),部分region查询成功,可能是部分节点的nscd/sssd服务异常。
codis/redis
* 客户端访问codis-proxy时,抛出异常“ERR router is not online” 表示此时codis-proxy已经完成在zk上注册zNode但是还未能完成上线,但无法提供服务。如果是在sparkstreaming应用中,该异常将导致executor退出,应用结束。 应用层需要再此场景下catch异常并处理(等待/丢弃)。
* 在Redis集群/单示例中使用scan命令时,默认的scan的count是10,在正则模式下,如果数据量较大时,可能存在性能问题,可以考虑使用较大的count值,来减少scan次数
Others
* 应用出现读文件挂死,发消息无返回,应用运行忙,各种timeout(connect,socket,read)等,需要考虑排查网络定保,full gc,死锁,cpu异常,cpu节能,磁盘慢的硬件原因
* unknow compression method等类型的异常通常是文件损坏导致。
* impala和hive使用不同的parquet来,二者的parquet格式的表互相读取可能引发类型转换异常
* hue需要reset操作才能使某些配置生效或者变更生效
* 出现Distributed filesyste can't be cast to filesystem的情况下,一般都是classloader加载异常。
* /usr/lib64下的so文件替换可能引发jvm启动异常
* 存储leveldb数据的磁盘异常,目录权限异常可能导致nm启动异常
* nscd服务服务异常时处理方法:
nscd -i password
nscd -i group
nscp -i services
nscd -i hosts
service nscd/sssd restart
* 执行shell脚本时,抛出异常, line 73: syntax error: unexpected end of file导致脚本执行异常,在排除文件格式(dos/unix)后,需要排查脚本本身逻辑,如代码段不完备(if 语句缺少结束标志“fi”)等方向排查问题
* 使用ObjectMapper将一个scala map通过writeValueAsString转化为json String时,打印{"traversableAgain":true,"empty":false},需要将scala的map使用asJava的方式转换为java的map。