複数のノードに分割された Cassandra データベースがあります。Pig でクエリを実行すると、Pig によって作成された mapreduce ジョブが Hadoop ノードで「クラッシュ」しますが、次の例外があります。
2013-03-18 00:57:19,374 WARN org.apache.hadoop.mapred.Child: 子の実行中にエラーが発生しました java.lang.RuntimeException: org.apache.thrift.TException: メッセージの長さを超えました: 674 org.apache.cassandra.hadoop.ColumnFamilyRecordReader$StaticRowIterator.maybeInit (ColumnFamilyRecordReader.java:384) で org.apache.cassandra.hadoop.ColumnFamilyRecordReader$StaticRowIterator.computeNext (ColumnFamilyRecordReader.java:390) で org.apache.cassandra.hadoop.ColumnFamilyRecordReader$StaticRowIterator.computeNext (ColumnFamilyRecordReader.java:313) で com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:143) で com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:138) で org.apache.cassandra.hadoop.ColumnFamilyRecordReader.getProgress (ColumnFamilyRecordReader.java:103) で org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigRecordReader.getProgress (PigRecordReader.java:169) で org.apache.hadoop.mapred.MapTask$NewTrackingRecordReader.getProgress(MapTask.java:514) で org.apache.hadoop.mapred.MapTask$NewTrackingRecordReader.nextKeyValue(MapTask.java:539) で org.apache.hadoop.mapreduce.MapContext.nextKeyValue(MapContext.java:67) で org.apache.hadoop.mapreduce.Mapper.run (Mapper.java:143) で org.apache.hadoop.mapred.MapTask.runNewMapper (MapTask.java:764) で org.apache.hadoop.mapred.MapTask.run (MapTask.java:370) で org.apache.hadoop.mapred.Child$4.run(Child.java:255) で java.security.AccessController.doPrivileged(ネイティブメソッド)で javax.security.auth.Subject.doAs (Subject.java:396) で org.apache.hadoop.security.UserGroupInformation.doAs (UserGroupInformation.java:1121) で org.apache.hadoop.mapred.Child.main (Child.java:249) で 原因: org.apache.thrift.TException: メッセージの長さを超えました: 674、readLength: 192 org.apache.thrift.protocol.TBinaryProtocol.checkReadLength (TBinaryProtocol.java:393) で org.apache.thrift.protocol.TBinaryProtocol.readBinary (TBinaryProtocol.java:363) で org.apache.cassandra.thrift.Column.read (Column.java:535) で org.apache.cassandra.thrift.ColumnOrSuperColumn.read (ColumnOrSuperColumn.java:507) で org.apache.cassandra.thrift.KeySlice.read (KeySlice.java:408) で org.apache.cassandra.thrift.Cassandra$get_range_slices_result.read (Cassandra.java:12905) で org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:78) で org.apache.cassandra.thrift.Cassandra$Client.recv_get_range_slices (Cassandra.java:734) で org.apache.cassandra.thrift.Cassandra$Client.get_range_slices (Cassandra.java:718) で org.apache.cassandra.hadoop.ColumnFamilyRecordReader$StaticRowIterator.maybeInit (ColumnFamilyRecordReader.java:346) で ... 17以上
際立っているのはorg.apache.thrift.TException: Message length exceeded: 674
. 例外で吐き出されるメッセージの長さは、Pig クエリが起動されるたびに異なります。Hadoop ノードでタスクが初期化された瞬間から、例外がトリガーされるまでに 1 秒もかかりません。
Cassandra には、約 1 GB のデータが取り込まれます。この例外の原因となった Pig クエリは次のとおりです。
rows = LOAD 'cassandra://[keyspace here]/[cf here]' USING org.apache.cassandra.hadoop.pig.CassandraStorage() AS([列の定義はこちら]); testvals = foreach 行は mycolumn.$1 を生成します。 名前 = testvals 57343 を制限します。 名前をダンプします。
なぜあなたが尋ねる57343の制限ですか?57343 未満の数値では Pig ジョブが正常に終了し、57343 以上の数値ではクラッシュします。Cassandra に同梱されている Pig の例も、同じ例外で終了します。また、Cassandra でより小さなデータセットを使用すると、Pig はジョブを正常に完了できます。
Thrift がメッセージの長さについて不平を言う同様のエラーをいくつか見つけましたが、通常、これは cassandra.yaml で指定された最大メッセージ長を超えた場合です。この場合、cassandra.yaml のメッセージ長は 64MB に設定され、それが役に立ったかどうかをテストしましたが、それでも同じ例外が発生しました。また、この場合、メッセージ自体が 674 バイトしかないと例外に記載されている場合でも、メッセージの長さが長すぎると例外に記載されています。
私が試したこと:
- cassandra.yamlの
thrift_max_message_length_in_mb
と の値を増やしますthrift_framed_transport_size_in_mb
- Thrift jar を再構築する
- Cassandra キースペースを削除し、再設定します
設定:
- ハドゥープ 1.0.4
- カサンドラ 1.2.2
- 豚 0.11.0
TL;DR
Pig + Cassandra は、より大きなデータセットでクラッシュします ( org.apache.thrift.TException: Message length exceeded: 674
)。小さいデータセットまたは大きいデータセットの小さいサブセットは正常に機能します。
Cassandra のログを編集してもエラーは表示されません。ジョブの要求に応じてスライスを提供し、Cassandra がこれを実行している間、ジョブは終了します。