druid集群搭建的一些重要的坑 问题分类总结.. 系统资源问题 海量数据自身配置优化问题 版本bug 依赖组件问题 #一些重要的坑记录 ##数据可视化页面加载失败,提示{“error”:”could not get customization”,”message”:”select payload from pivot-store-customizations where key = ‘x’ - ER_NO_SUCH_TABLE: Table ‘druid.pivot-store-customizations’ doesn’t exist”} #原因见var/sv/imply-ui.log #Table creation failed: create table pivot-store-customizations (key varchar(120), created_at bigint, updated_at bigint, payload longtext) default character set utf8mb4 collate utf8mb4_bin - ER_REQUIRES_PRIMARY_KEY: This table type requires a primary key #[2018-04-09T07:37:45.379Z] error: could not get customization // select payload from pivot-store-customizations where key = ‘x’ - ER_NO_SUCH_TABLE: Table ‘druid.pivot-store-customizations’ doesn’t exist #[2018-04-09T07:37:45.379Z] Error: ER_NO_SUCH_TABLE: Table ‘druid.pivot-store-customizations’ doesn’t exist #即程序建表pivot-store-customizations失败,提示需要主键,因为mdb强制要求每个表都要主键。需要修改dist/imply-ui/linux/imply-ui-linux的源码 #pivot-store-customizations需要utf8mb4,所以需要mysql5.5以上。 目前已重新部署了一个mariadb10版本。后面提示druid-config表不存在,重启主节点后就有了。 #bin/post-index-task –file quickstart/wikipedia-index.json导入测试数据,一直卡住,var/sv/overlord.log提示“2018-04-12T07:59:40,962 INFO [TaskQueue-Manager] io.druid.java.util.http.client.pool.ChannelResourceFactory - Generating: http://10-165-6-198:8091 ” #这个原因是其无法curl到这个地址,即 http://10-165-6-198:8091 ,这是因为hostname中的配置问题,原hosts文件中有这个命名,hostname命令也可以看到。将每个节点的hosts文件都改好,然后hostname hadoop-slave01这样直接生效一下,重启服务就好了。 #show页面data页失败,提示127.0.0.1:8082无法访问,这其实是要访问overlord等节点,但是却访问到本机了,尝试改了一些conf文件也没用,最后只能在页面setting处将各节点固定配置下来才行,这会引起单点问题,需要进一步研究原因,正常应该是从zk处获取。 ###启动http监听接收http的数据流 #第一步要编辑对应的json文件,conf-quickstart/tranquility/yyd-dmq-incom.json #第二步 启动监听 nohup bin/tranquility server -configFile conf-quickstart/tranquility/yyd-dmq-incom.json > tranquility_yyb.log & #这个进程是不会被super进程监听守护的,需要自己写监控 #imply-ui这个进程是不在jps里面的,所以要重启时需要单独杀死,然后启动super进程时会一并拉起。 #druid起来后hdfs中没有创建druid目录,很可能是druid中配置的hdfs的地址错了,通过overlord日志可以查到错误。 现在问题是双namenode节点,但druid怎么配置为名字格式的还没搞定,只能写死为activeNamenode #tranquility接收数据后经常挂掉,通过log看是因为outofmemery,解决方法:修改dist/tranquility/conf/application.ini文件中的内存即可。启动进程会读取它的。当然也可以直接在命令上bin/tranquility -J-Xmx1g实现。 #tranquility发现多台机器上启动多个进程,只有一个正常,其他的可以接收,但send会被阻塞,具体可以看log和console的log:Still waiting for Handoff for Segments。目前已将所有任务都合并到一个json中,只启动一个。 #histomical节点会产生var/druid目录,会很快增大,所以需要将var目录放到更大的分区。mkdir /data/imply & & chown -R hadoop.hadoop /data/imply & & cp -a var /data/imply/ & & rm -rf var & & ln -sf /data/imply/var/ var #druid入库任务死了,log提示所有任务死掉,也有“NoBrokersAvailableException: No hosts are available for druidTask”,这时可以检查overlord和middle的log,发现“Operation category WRITE is not supported in state standby”,所以这是写入hdfs失败,检查hfs发现namenode转移了,原因是部分节点因为之前磁盘满而挂掉没有启动。 #druid之前写死hadoop的地址,现在将hadoop的core-site.xml和hdfs.xml拷贝到conf/druid/_common/下,再将druid配置hdfs的地址改为集群名即可。解决了druid写死namenode的问题 问题:毛刺的问题 处理:可能是dmq取数据到处理数据到入库的速率不同所致。目前jt那边把任务并发提高,后端也对摄入任务进行并发提升,tranq任务的线程数增大到120,增大缓存maxRowsInMemory,maxRowsInMemory和task.partitions也进行扩大。 效果:现在并发提升了20倍,毛刺明显减轻。 问题:com.twitter.finagle.NoBrokersAvailableException: No hosts are available for druidTask!druid:overlord!index_realtime_yyb_dmq_install_2018-05-01T00:00:00.000Z_0_0, Dtab.base=[], Dtab.local=[] at com.twitter.finagle.NoStacktrace(Unknown Source) ~[na:na] 产生场景:增加输入流任务。 处理:这个错误初步查明原因应该是中间节点的索引槽的容量问题。目前已将中间节点的线程数调整到跟tranq一样多,druid.worker.capacity个数也扩大到24个。 效果:现在三个任务可以同时跑起了。 我们的consumer通过tranquility,向overlord发送任务模板,overlord接收到任务模板后,会根据任务分配策略发送给某个MiddleManager,MiddleManager启动一个java进程, 即peon。peon可以理解为一个http server。最后: consumer是向http server直接发送数据,而不再依赖overlord和MiddleManager节点。可以理解为我们通过集成tranqulity可以和 每个peon创建一个连接。 一些人的误区主要体现在: consumer将数据发送给了overlord,是通过overlord转发数据给peon,这样理解是错误的。 imply-ui页面提示connect XXX:8082 refused 上对应服务节点检查8082端口,没起来。说明自动拉起也拉不动。这个服务是broker 服务根目录多了很多hs_err_pid文件,包括查看brocker的log,确认是内存不足引起。 相同其他节点的内存是够的,这个节点内存明显偏多,说明有某个进程内存异常,ps auxw|head -1;ps auxw|sort -rn -k4|head -10检查最大的内存消耗者是hadoop的journalnode。 检查journalnode的log,一直报错,提示 这说明该JournalNode维护的edits文件被破坏了(其实应该是上次磁盘满导致hdfs挂掉导致的),网上有修复方法,看都是说要停止整个hdfs集群才行,但是我尝试无损修复成功了。下面就是修复 edits文件的过程。 a. 问题节点的 JournalNode停止,通过hdfs-site.xml文件可以找到edits目录. b. 备份edits目录, tar -zcf journalnode_editefile.tgz datas/journal/hdfscluster/current,删除目录rm -rf datas/journal/hdfscluster/current c. 将正常节点的该目录rsync过来,注意,要多次不间断的rsync,以让目录文件在一个间隔内能做到一致(因为其他节点的该目录可能不停的变),然后迅速重启 JournalNode,如果log还报错,可以继续rsync,直到问题消失。 这种方法可能不适用于繁忙的hdfs集群。 搞定 JournalNode后, JournalNode占用的内存就降下来了,broker也就能起来了。 ################################################################## 备注:Jnode最好是奇数个,最小3个。 Datanode是用于存储hdfs真实数据块的,它的多少和总容量决定了hdfs集群的总存储容量。 JournalNode是用于存储hdfs中,NameNode的操作日志(也就是edits)的,一般由单数个(3个以上)节点组成,保证对于edits的高可靠存储。它不决定集群的容量大小,跟DataNode没什么直接关系。 JournalNode其实不参与NameNode的原信息同步之类的操作,它只是个忠实的存储,存储来自于NameNode的操作日志,由于它可以被ActiveNameNode跟StandbyNameNode同时看到,所以可以使操作日志在不同的NameNode之间得到共享。 ActiveNameNode在文件系统被修改时,会向JournalNode写入修改记录,而StandbyNameNode可以方便的读取到这样的修改记录。 JournalNode的节点和editfile位置都可以在hdfs-site.xml中找到。 解决 JournalNode问题后不久,内存再次不足,通过访问broker的http接口查看内存情况, http://10.165.24.77:8082/status 。(其他几个组件部分也有好这个查询接口)修改 conf/druid/broker/jvm.config的最小内存,可以启动了。所以这里每个组件的jvm内存配置需要进一步优化。 其实后面这里还是没解决,于是进行了扩容,扩容了broker,middle和历史节点,然后减少了内存满的机器的 capacity数。 然后再将slot分配策略改为了equal模式。方法是 通过向Overlord节点发送个一个HTTP请求来修改,实质上是修改保存druid元数据的数据库,即

: curl -XPOST -H ‘X-Druid-Author: lucky’ -H ‘X-Druid-Comment: lucky’ -H ‘Content-Type: application/json’ http://10.1.3.9:8090/druid/indexer/v1/worker -d ‘{ “selectStrategy”: { “type”: “equalDistribution” } }’ 通过 http://10.1.3.9:8090/druid/indexer/v1/worker/history查看配置结果 。 overlord节点如何将任务分配到middlemanager节点进行处理,如果在架构中有 多个 middlemanager节点,那任务将怎么分配呢,分配的测试是什么? 默认策略是 fillCapacity , 意思是当一个MiddleManager的 worker capacity 满了的时候,再有任务到来时,才会分配给另外的MiddleManager节点。 问题:Turns out we decided not to actually make beams for identifier[druid:overlord/lbs_dmxxxxx… 这个问题是在修改了一个机器上的tranq后重启引起的。没有找到原因,做任何操作也没用,包括重启整个集群。后来在下一个整点自己好了。估计是跟主控无法结束原任务有关,还没查清楚。目前看聚合粒度hour的任务周期后会重新加载json并启动新的任务。 问题:hdfs离线数据导入失败。 解决:overlord直接接收hdfs的任务,不经过tranq,查看overlord等后台日志,只能看到结果,真实log可以从overord的页面任务log中找到,从pirod页面添加任务的也可以从那里看到错误。

是无法访问本地的hadoop程序目录的一个路径。 所以我尝试把hadoop的程序拷贝过来,不启动任何hadoop进程,再执行该任务,就成功了。 问题:overlord是主备模式,如何在sparta做好路由,避免访问到备节点并直接跳转到主节点的ip:port而失败? 问题:Cannot create PoolableConnectionFactory 解决:这一般是mysql连接问题,检查mysql配置。 问题:java.util.concurrent.TimeoutException: Idle timeout expired: 300000/300000 ms 解决:这种是任务会话超时了,重启tranq 问题:新扩容的历史节点一直报错。 这是取数据先从本地缓存取没有,然后去hdfs去也没有的意思,问题在于其获取到的hdfs的namenode是一个standyby节点,只有master节点可以读数据的,奇怪。目前还没找到原因。 解决:自己去hdfs找这个文件,也没有,但是其他节点的缓存中有,于是rsync过来了,问题暂时解决。 问题:突然所有任务均停止了,status为空,检查后台log没看出什么。web端看任务log有如下: 2018-05-04T21:16:04,432 INFO [coordinator_handoff_scheduled_0] io.druid.java.util.http.client.pool.ChannelResourceFactory - Generating:

http://hadoop-master:8081 2018-05-04T21:16:04,436 INFO [coordinator_handoff_scheduled_0] io.druid.segment.realtime.plumber.CoordinatorBasedSegmentHandoffNotifier - Still waiting for Handoff for Segments : [[SegmentDescriptor{interval=2018-05-04T12:00:00.000Z/2018-05-04T13:00:00.000Z, version=’2018-05-04T12:00:05.843Z’, partitionNumber=0}]] 看这个应该是数据入库到hdfs阻塞了。检查hadoop的master日志,发现确实有异常, 提示slave01的journalnode不通,果然它挂了,所以namenode也异常。把journalnode启动后立即恢复。 journalnode失败的原因还要继续查。 #我擦:莫名其妙有个datasource的数据丢了一大坨,无语!! 问题:修改tranq的配置通道后,发现tranq进程无法启动,错误信息是io.druid.segment.indexing.RealtimeTuningConfig] value failed: Failed to create directory within 10000 attempts 附加一句,与本故障无关:这里具体操作是修改完server.json后,super守护会自动启动tranq,但原tranq没有被自动杀死,这是super的一个bug吧!所以需要手工杀死原进程。 1.通过该日志分析是写入数据失败导致无法启动,所以推测是hdfs出问题了,网上确实没找出什线索来。 2.进入namenode的页面,发现这个信息,应该是真有问题。 3.检查hadoop的namenode日志,发现连接一个节点的journalnode一直失败。 4.进入该节点,发现这个进程确实挂了。原因是tmp目录无法创建新子目录 进入临时目录手工创建,发现确实失败。提示annot create directory `/tmp/’: Too many links 5.这个原因是ext3文件系统有目录链接数达到上限导致的。具体可以看 http://blog.51cto.com/ckl893/1767570 ,即最多只能有32000个目录 6.检查tmp目录下确实有4w来个目录,于是想办法删除太老的文件,减少到2w多个,再重启jour试试。

所以,一定要把tmp目录放到其他地方,即非ext3文件系统的地方,空间也要足够 。 7.jour启动失败,提示进程优先级错误 ERROR: Cannot set priority of jour process ,具体错误可以见logs/jourXXX.out,是UnsupportedClassVersionError: org/apache/hadoop/hdfs/server/datanode/DataNode : Unsupported major.minor version。这个网上也搜不到东西,也一直没办法解决。所以卡住了。 8.为什么jour挂了一个系统就不可用,为什么主备不切换,继续检查发现备namenode的zkfc挂了,这个是用来做主备切换检查的。先启动起来再说,果然启动了hdfs集群立即可用了。druid的tranq也就正常了。 9.继续想办法启动jour,看out的错误是说什么库的版本52不匹配问题,所以感觉是环境变量的问题。再一想,应该是root su hadoop所致,这样切换用户用的实际还是root的环境变量,所以改用su - hadoop,果然启动成功。找到问题所在了!虽然还没具体了解到是哪个具体的变量不一致引起的。 10。接下来要查zkfc挂的原因了。看样子是连接zk超时了。 问题:有个任务重启tranq后再也不入数据了。【未解决】 检查overlord上也只有一个子任务在跑,而且是三天前的,状态为running,但是runninglog是空。所以为认为是这个过期任务卡住了导致后面的任务都没法加入了。 检查overlord日志发现该任务被分配到一个节点的middle服务在处理,检查该middle的log发现每分钟输出一个Ignoring request to cancel unknown task 上overlordweb页面kill这个任务,检查日志,发现overlord成功将kill任务下发给middle服务,但middle服务一直没任何反应,重启该节点整个druid都不行。 尝试kill其他任务,都是成功kill的。唯独这个不行!没找到原因。 暂时只能将该任务改名做成一个新的项目去摄入数据了。 一直解决不了的问题: 1.Ignoring request to cancel unknown task 这是middle收到overlord结束任务时一直无法结束任务的问题,可能导致后续任务卡住

问题:所有任务均进入等待状态。任务数满了 检查:主overlord和coor均只写结束什么任务,备节点则提示连接db失败。所有middle均只提示结束任务忽略, 这个原来是指历史节点配置设置的缓存大小历史节点数的空间。这个满了会导致 问题:0526 数据查询发现前几个小时数据都空,只能有最近一个小时左右的数据,再过一小时,又丢失前一个小时的数据。 解决:感觉是数据落地存储失败。访问hadoop主页检查hdfsnamenode的log,发现一个namenode失败,其失败的原因是访问一个journode超时,而实际该jn是可以访问的,但其日志不滚动了。 以上现象,分析可能跟数据完整性有关,datanode中的数据丢失不会导致namenode启动问题。那就只剩下namenode中的元数据了。再看其他jn节点,发现一直刷新以下错误: 这表明jn的元数据出现了问题。修复元数据有两种方法:1. 从其他节点拷贝 datas/journal/hdfscluster/current过来,重启jn。 2.把问题节点的 datas/journal/hdfscluster/current目录下文件都删除,但保留VERSION文件,然后重启jn,其会同步其他节点的过来。jn修复后,namedode方可正常运作。 可实际nn又挂了,jn的log如下: 备节点的nn启动失败,错误如下: 于是find datas/journal/hdfscluster/current -name “260998“,发现有一个节点有这个文件,于是将其他节点的该目录按照这个节点的来rsync,就ok了。所以jn文件不一致问题最好还是直接rsync正常节点的数据到问题节点更好 总结hdfs的问题,namenode即使有主备,但是只要大多数jn挂掉,导致nn无法写入同步信息,就会导致主nn挂掉,然后备nn也无法正常运作。hdfs非常怕磁盘满,会导致jn或者nn的元数据同步失败从而引起各种问题,这种一般找到正常节点并将其元数据rsync到坏的节点可解决。记住tmp目录和dates目录要放到大分区且非ext3 问题:super服务对tranq的支持有问题,经常出现同时启动两个进程的情况,而且遇到过修改完conf后tranq自动重启的事,但是又不是必现(当然这是好事) 坑:log的级别要设置好,log和临时文件目录要设置到大分区,否则磁盘满带来的问题很多,而且现在根分区是ext3,有目录个数32000个限制,druid会在默认tmp路径/tmp下创建临时目录,tmp目录要设置好。 问题:历史节点log一直刷部分segment文件下载失败,原因是从本地没找到之后去hdfs找,但是hdfs它找的是standby节点!—还未解决 问题:coor节点的默认缓存策略是loadforever,不小心改为了dropforever后,所有本地数据都没了,然后再改回缓存30天,数据仍然不从hdfs加载到本地,这是什么原因? 临时解决:修改元数据库update druid_segments set used=1 where used=0;可以指定datasource修改。改完之后就会立即从hdfs下载数据。参见 https://m.sohu.com /470876409/ 问题:从hdfs导入离线数据过来,worker直接返回失败,无异常日志。换另一个hdfs又是正常。 解决:对比看出应该是hdfs的权限有问题。实际是druid需要hdfs目录和文件需要755. #####他人经验############################ Druid 集群注意事项 在 Druid 里面配置, 1、维度不要太多,像蚂蜂窝最开始 700 多个维度。每天导进去将近 100 个 G,导进去十分耗时。 2、维度大小,不要太大。比如你来一个维度值几兆的,这个不行。 3、要去合理配置比例。在最开始,我们就拿了跟我们之前节点挂上了 10 个 T 的磁盘,作为整个 Druid 节点的数据存储,但是发现在你去查,无论你是去查任务,或者查历史数据。10 个 T 的磁盘跟不上来,查询各种超时,各种响应。 4、磁盘选用。其实采用的固态盘,基本上像我们现在的配置,就是 256 个 G 内存,1.2T 的固态盘。这个配置起来,你去查询整个历史数据,或者无论你查询其他的数据都是很快的。 5、在segment大小,我们最开始是按天的,100个G,后面拆分成每小时去分。这个时候到几个G,几个G也不行,我们就是要在去拆分几个G,到最终查询相当于是在在300-700兆左右。 6、在Druid里面,不支持逗号,因为 Druid 里 在底层逗号是用来分隔。 7、优先去升级 Druid 的版本。我们在最早从 0.6 慢慢升级到 0.8,我们现在用的是 0.9。每一次 Druid 的发版,优化了很多东西。你觉得每一个查询有问题,或者说你想要去更快查询这些数据,可以优先考虑一下去 github 上面去看看 Druid 的最新近况。 这个就是今天给大家分享的一些东西。当然我们在使用 Druid 的过程当中,其实还遇到其他很多问题。也希望 Druid 能越来越好。 ################################ 精确去重(即 distinct)如何支持? Sketch或者sql的distinct? 文章参考 https://yuzhouwan.com/posts/5845/ https://blog.csdn.net/eric_sunah/article/details/78729089 https://blog.csdn.net/strangerzz/article/details/72771676 性能测评