天天看点

Hypertable运维中遇到的问题

1.failed expectation: insert_result.second

版本:0.9.7.5之前

问题描述:

在自动failover进行的过程中,手动将之前出问题的机器带回集群,Master日志中出现了如下类似错误:

(/root/src/hypertable/src/cc/Hypertable/Master/RangeServerConnectionManager.cc:50) Contains rs5 host=dlxa125 local=0.0.0.0:0 public=*.*.*.*:38060

 FATAL Hypertable.Master : (/root/src/hypertable/src/cc/Hypertable/Master/RangeServerConnectionManager.cc:52) failed expectation: insert_result.second

解决方法:

有两种解决方法:

1). 社区已经在0.9.7.5版本中解决了这个问题,升级到该版本或者之后的版本;

2). 也可以在自动failover完成后,再手动带回之前出问题的机器。不建议在自动failover未完成时执行带回操作,这样有百害而无一利。

2.failed expectation: m_trailer.filter_items_estimate

版本:0.9.6.5

问题描述:

RangeServer日志中出现了如下类似错误,重启亦是如此:

FATAL Hypertable.RangeServer : (/root/hypertable/src/cc/Hypertable/RangeServer/CellStoreV6.cc:502) failed expectation: m_trailer.filter_items_estimate

解决方法:

社区已经在0.9.7.0版本中解决了这个问题,升级到该版本或者之后的版本

3.select的limit子句bug

版本:0.9.7.12以前

问题描述:

limit 1返回结果集为空,但是limit 2却能得到非空的结果集。

解决方法:

这是一个bug(issue1175),社区已经在0.9.7.14版本中解决了这个问题,升级到该版本或者之后的版本

4.从0.9.7.11升级到0.9.7.14后入库速度变慢

版本:0.9.7.13--0.9.7.16

问题描述:

从0.9.7.11升级到0.9.7.14后发现入库速度变慢,但是升级到0.9.7.12的入库速度正常

解决方法:

这是一个bug(issue1179),发现涉及的版本包括0.9.7.13-0.9.7.16。社区已经在0.9.7.17版本中解决了这个问题,升级到该版本或者之后的版本

5. failed expectation: split_row.compare(end_row)<0 && split_row.compare(start_row) > 0

版本:0.9.7.12

问题描述:

RangeServer日志中出现了如下类似错误,重启亦是如此:

(root/src/hypertable/src/cc/Hypertable/RangeServer/range.cc 1028) failed expectation: split_row.compare(end_row)<0 && split_row.compare(start_row) > 0

解决方法:

这是一个bug(issue1193),该bug触发条件为:未开启自动failover时,如果个别RangeServer节点挂了,虽然导致了大量入库阻塞,但是部分机器还是可以写入,于是写入的数据持久化到commit log之后就会引起这个bug。有两种解决方法:

1)社区已经在0.9.7.17版本中解决了这个问题,升级到该版本或者之后的版本

2)如果不能升级,可以手动删除出问题RangeServer的所有 commit log文件,此方法虽然可以规避bug,但是代价是损失了一些数据。

6. Dfsbroker进程占据了太多的端口,导致其它进程不能启动

版本:0.9.7.12

问题描述:

发现RangeServer机器上的MapReduce程序不能启动,分析后发现是因为启动时获取不到端口。假设Dfsbroker进程ID为5000,执行下列命令可查看该进程占据了多少端口:

[[email protected] ~]# netstat -antup|grep 5000|wc -l

42911     //我们当时查看到的占据的端口数

解决方法:

这是一个bug(issue1197),但不确定社区是否做了修补,因为这个问题很难重现。可以重启dfsbroker来解决此问题。

7. failed expectation: *ptr == Key::AUTO_TIMESTAMP || *ptr == Key::HAVE_TIMESTAMP

版本:0.9.7.12

问题描述:

RangeServer日志中出现如下类似错误:

(/root/src/hypertable/src/cc/Hypertable/RangeServer/RangeServer.cc:1958)failed expectation: *ptr == Key::AUTO_TIMESTAMP || *ptr == Key::HAVE_TIMESTAMP

解决方法:

对此错误,社区说明可以总结为以下三点:

1)触发条件:当插入cell的timestamp为TIMESTAMP_NULL(源码中定义的一个常量)时,会引发这个错误;

2)当前触发时机不合理,即不应该在RangeServer端抛出这个错误,应该在客户端写入时抛出这个错误;

3)将在0.9.7.17中修改为合理的触发时机。

但是我按照上述触发条件模拟时,没有看到这个错误。并且在0.9.7.17中仍然看到了这个错误。社区承认在0.9.7.17中修改时有遗漏,承诺在0.9.8.0中修补此遗漏。

虽然当前此问题没有彻底解决,但是重启RangeServer时此问题不是必现问题,既可以通过重启RangeServer规避此问题。

8. failed expectation: m_last_collection_time

版本:0.9.7.17

问题描述:

当减少一个表的TTL属性值后,例如:表TAB_TEST原TTL为10 day,执行Alter table TAB_TEST modify (F1 TTL=5 day)修改为5 day,RangeServer中出现如下错误:

FATAL Hypertable.RangeServer :(/root/src/hypertable/src/cc/Hypertable/RangeServer/AccessGroupGarbageTracker.cc:132)failed expectation: m_last_collection_time

解决方法:

社区说当上述的alter语句执行后,会在表中增加一个名称为default的新的access group,所以后续对其执行gc引起发这个assert。社区已经在0.9.7.18中修补了这个问题,升级到该版本或者之后的版本可以避免此问题。

9. Error reading directory entries for DFS directory: /hypertable/servers/rs*/log/tab_id/endrow

版本:0.9.7.0以前

问题描述:

RangeServer启动后又会挂掉,日志中具有类似于如下的提示:

ERROR Hypertable.RangeServer :local_recover (/root/src/hypertable/src/cc/Hypertable/RangeServer/RangeServer.cc:908): Hypertable::Exception: Error reading directory entries for DFS directory: /hypertable/servers/rs8/log/3/19/mhXJ7oobjVGJEjtY-1356744895 - DFS BROKER file not found

at void Hypertable::CommitLogReader::load_fragments(Hypertable::String, Hypertable::CommitLogFileInfo*) (/root/src/hypertable/src/cc/Hypertable/Lib/CommitLogReader.cc:204)

at virtual void Hypertable::DfsBroker::Client::readdir(constHypertable::String&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char>>>>&) (/root/src/hypertable/src/cc/DfsBroker/Lib/Client.cc:621): Error reading directory entries for DFS directory: /hypertable/servers/rs8/log/3/19/mhXJ7oobjVGJEjtY-1356744895

at virtual void Hypertable::DfsBroker::Client::readdir(constHypertable::String&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char>>>>&) (/root/src/hypertable/src/cc/DfsBroker/Lib/Client.cc:615): File hdfs://namenode:8020/hypertable/servers/rs8/log/3/19/mhXJ7oobjVGJEjtY-1356744895 does not exist.

解决方法:

手动创建一个空的目录(sudo –u hdfs hadoop fs –mkdir  /hypertable/servers/rs8/log/3/19/mhXJ7oobjVGJEjtY-1356744895),然后重新启动RangeServer服务。

10. 如何删除临时表

版本:目前的所有版本

问题描述:

当查询结果比较大时,会产生一些临时表,例如:tmp/08eb3540-8ba1-44a8-ae9c-9c778ef5814d。查询正常结束时,临时表会被清除,但是如果查询异常结束,这些临时表将会一直存在。

解决方法:

使用下列命令删除临时表:

use tmp;

drop table "08eb3540-8ba1-44a8-ae9c-9c778ef5814d";   //即在表名上加引号

11. 如何增加scanner_get_cell方法返回的Cell数目

版本:目前的所有版本

问题描述:

当使用scanner_get_cell接收查询结果时,如果查询结果较大,需要接收多次。为了减少接收次数,可以设置增加该方法每次接收的Cell数目。

解决方法:

修改hypertable.cfg文件中的以下两个配置项,修改后需要重启Hypertable:

Hypertable.RangeServer.Scanner.BufferSize=2000000 //默认值为1M

ThriftBroker.NextThreshold=256000 //默认值为128K

12. RANGE SERVER row overflow

版本:目前的所有版本

问题描述:

RangeServer日志中出现如下类似错误:

ERROR Hypertable.RangeServer : operator() (/root/src/hypertable/src/cc/Hypertable/RangeServer/MaintenanceQueue.h:162): Hypertable::Exception: Unable to determine split row for range 2/9[9999999103-5088A416Bzz..D0---0---0---0---0-000] - RANGE SERVER row overflow

解决方法:

本问题是由于row设计不合理,或者入库程序生成了非预期的row所致。Hypertable目前规定 一个row不能跨range存在,所以当出现前述两个问题的话,则可能出现一个row的cell太多,从而“挤爆”了一个range,从而出现此错误。有两种解决方法:

1)修改Hypertable.RangeServer.Range.RowSize.Unlimited为true,然后重启hypertable。此方法不推荐,应尽量使用第二种方法;

2)设计合理的row,并保证入库程序生成预期的row。

注意不能通过增大Hypertable.RangeServer.Range.SplitSize配置值来解决此问题,因为该配置项修改后不能改变之前已经生效的数据。

13. ThriftBroker抛出异常“org.apache.thrift.transport.TTransportException: Frame size (144130118) larger than max length (16384000)!

版本:目前的所有版本

问题描述:

当使用HQL或者Thriftclient查询时,如果结果集较大(例如百万计行),则会抛出这个异常

解决方法:

1)当使用hql_exec API时,请设置参数unbuffered为true;

2)连接ThriftBroker时修改framesize和timeout,framesize默认值为20M,timeout默认值为1600000毫秒。例如以下为Java代码将framesize修改为20M:

ThriftClienttc = ThriftClient.create("localhost", 38080, 1600000, true, 20 * 1024 * 1024);

3)在MapReduce时,可在配置文件中修改配置项:hypertable.mapreduce.thriftclient.framesize

14. Hypertable::Exception: decoding scan spec - SERIALIZATION input buffer overrun

版本:目前的所有版本

问题描述:

RangeServer日志中出现如下类似错误:

ERROR Hypertable.RangeServer : run (/root/src/hypertable/src/cc/Hypertable/RangeServer/RequestHandlerCreateScanner.cc:65): Hypertable::Exception: decoding scan spec - SERIALIZATION input buffer overrun

解决方法:

此错误一般是由于客户端和服务器端使用了不同的hypertable版本,假设:集群升级时,集群端已经升级为0.9.7.17,但是入库程序还使用的是0.9.7.12的库,此时可能会出现此问题。只要将客户端程序在新的版本下编译,或者客户端采用新的jar即可。

15. 大部分RangeServer在执行GC compaction时内存暴涨,导致集群无法提供服务

版本:0.9.7.12

问题描述:

如题目所述

解决方法:

社区承认之前的GC compaction算法有些混乱,在0.9.7.17中已经大改了这个逻辑。升级到该版本或者之后的版本即可解决此问题。

16. java.io.IOException: All datanodes *.*.*.*:50010 are bad. Aborting

版本:目前的所有版本

问题描述:

RangeServer日志中出现如下类似错误:

ERROR Hypertable.RangeServer : run_compaction (/root/src/hypertable/src/cc/Hypertable/RangeServer/AccessGroup.cc:790): 2/0[1065795555-52B2C735BKA..10658000---52ABC9F3BKA](IDX) Hypertable::Exception: Problem writing to DFS file '/hypertable/tables/2/0/IDX/YStGMh3ejopuOguz/cs717' : java.io.IOException: All datanodes *.*.*.*:50010 are bad. Aborting... - DFS BROKER i/o error

    at virtual void Hypertable::CellStoreV6::add(const Hypertable::Key&, Hypertable::ByteString) (/root/src/hypertable/src/cc/Hypertable/RangeServer/CellStoreV6.cc:478)

解决方法:

虽然看起来很明显是访问HDFS出错,但是这是一个比较复杂的问题,目前已知两种情况可能引发这个错误:

1)HDFS的DataNode出现卷故障,故导致卷访问失败。此时修复故障卷即可。

2)操作系统或者HDFS的一些特殊权限被修改。这种情况后果很严重,极端情况下,只要对hypertable执行写入就报这个错误。如果不能确定被修改的权限项,即使cleandb也不能解决此问题,只能从重装操作系统开始了。所以杜绝此问题的方法就是严格管理集群的权限。

17. java.io.IOException: Failed on local exception: com.google.protobuf.InvalidProtocolBufferException: Message missing

required fields: callId, status

版本:目前的所有版本

问题描述:

Master日志中出现如下类似错误:

ERROR Hypertable.Master : main (/root/src/hypertable/src/cc/Hypertable/Master/main.cc:384): Hypertable::Exception:

Error checking existence of DFS path: /hypertable/servers/master/log/mml - DFS BROKER i/o error

        at virtual bool Hypertable::DfsBroker::Client::exists(const String&) (/root/src/hypertable/src/cc/DfsBroker/Lib/Client

.cc:679)

        at virtual bool Hypertable::DfsBroker::Client::exists(const String&) (/root/src/hypertable/src/cc/DfsBroker/Lib/Client

.cc:673): java.io.IOException: Failed on local exception: com.google.protobuf.InvalidProtocolBufferException: Message missing

required fields: callId, status

解决方法:

这是由于hypertable和cdh版本不兼容引起的,一般是由于使用了过高的cdh版本。解决此问题需要执行下列修改:

1)修改hypertable源码目录下src\java\Core\org\hypertable\DfsBroker\hadoop\2\HadoopBroker.java中

DFSClient.DFSDataInputStream in =   (DFSClient.DFSDataInputStream)mFilesystem.open(path)为

        HdfsDataInputStream in =  (HdfsDataInputStream)mFilesystem.open(path)

      然后将该文件编译后替换“hypertable-版本号.jar”中同名的class;

2)在hypertable安装目录的子目录lib/java中,将所有cdh的jar替换为cdh新版本的jar。然后重启hypertable即可。

18. java.io.IOException: Failed to add a datanode

版本:目前的所有版本

问题描述:

RangeServer日志中出现如下类似错误:

java.io.IOException: Failed to add a datanode.  User may turn off this feature by setting dfs.client.block.write.replace-datanode-on-failure.policy in

解决方法:

此问题一般出现在小的HDFS集群中(5个datanode以内)。需要在各个DataNode节点的hdfs-site.xml中添加下列配置片段即可:

<property> <name>dfs.client.block.write.replace-datanode-on-failure.enable</name> <value>false</value> </property>

也可通过cloudera manager添加上述配置片段,需要操作的配置项为HDFS Client Advanced Configuration Safety Valve。对于cloudera manager4系列,配置入口为:Client->advanced,对于cloudera manager5系列,配置入口为:Gateway Default Group->advanced。修改后需要执行Actions->Deploy Client Configuration,实践发现在HDFS服务页面执行下发操作不生效,但在YARN服务页面执行则会生效。

19. Master MetaLog本地备份文件和HDFS文件不一致

版本:目前的所有版本

问题描述:

Master不能正常启动,并且日志中出现类似下列错误:

ERROR Hypertable.Master : main (/root/src/hypertable/src/cc/Hypertable/Master/main.cc:384): Hypertable::Exception: MetaLog file '/hypertable/servers/master/log/mml/2' has length 7730400 backup file '/dinglicom/hypertable/0.9.7.17/run/log_backup/mml/master_38050/2' length is 7724704 - METALOG backup file mismatch at void Hypertable::MetaLog::Reader::verify_backup(int32_t) (/root/src/hypertable/src/cc/Hypertable/Lib/MetaLogReader.cc:129)

解决方法:

此问题是由于存储在HDFS上的Master MetaLog与本地备份文件不同步所致,所以需要手动同步。同步方法就是用错误信息中提到的HDFS上的MetaLog文件替换本地备份的同名文件,然后重启集群即可,本例中就是用/hypertable/servers/master/log/mml/2 替换 /dinglicom/hypertable/0.9.7.17/run/log_backup/mml/master_38050/2。当然,为了保险起见,建议替换前先备份文件。