6

挿入前にレコードの存在を確認する必要があるシナリオに取り組んでいます。レコードが既に存在する場合は、再度挿入しません。バッチでやっています。最初に、挿入するレコードの存在を確認するために Get のバッチを作成します。この問題は、テーブル サイズが小さく、断続的に発生する場合には発生しません。Get の推奨バッチ サイズはどれくらいですか。そして、挿入する前にレコードの存在を確認するための最良の方法は何ですか?? あなたの応答に感謝..

これがスタックトレースです..

java.util.concurrent.ExecutionException: java.net.SocketTimeoutException: Call to b16-pf-dv-093.abc.com/10.106.8.103:60020 failed on socket timeout exception: java.net.SocketTimeoutException: 60000 millis timeout while waiting for channel to be ready for read. ch : java.nio.channels.SocketChannel[connected local=/10.106.8.133:41903 remote=b16-pf-dv-093.abc.com/10.106.8.103:60020] 
        at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) 
        at java.util.concurrent.FutureTask.get(FutureTask.java:83) 
        at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.processBatchCallback(HConnectionManager.java:1604) 
        at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.processBatch(HConnectionManager.java:1456) 
        at org.apache.hadoop.hbase.client.HTable.batch(HTable.java:757) 
        at org.apache.hadoop.hbase.client.HTable.get(HTable.java:726) 
        at org.apache.hadoop.hbase.client.HTablePool$PooledHTable.get(HTablePool.java:367) 
        at com.abc.psp.core.metering.util.HBaseClient.get(HBaseClient.java:263) 
        at com.abc.psp.core.metering.dao.MeteringHBaseDAOImpl.addMeteredRecords(MeteringHBaseDAOImpl.java:374) 
        at com.abc.psp.core.metering.dao.MeteringHBaseDAOImpl.addMeteredRecords(MeteringHBaseDAOImpl.java:342) 
        at HBaseTest.main(HBaseTest.java:32) 
Caused by: java.net.SocketTimeoutException: Call to b16-pf-dv-093.abc.com/10.106.8.103:60020 failed on socket timeout exception: java.net.SocketTimeoutException: 60000 millis timeout while waiting for channel to be ready for read. ch : java.nio.channels.SocketChannel[connected local=/10.106.8.133:41903 remote=b16-pf-dv-093.abc.com/10.106.8.103:60020] 
        at org.apache.hadoop.hbase.ipc.HBaseClient.wrapException(HBaseClient.java:1026) 
        at org.apache.hadoop.hbase.ipc.HBaseClient.call(HBaseClient.java:999) 
        at org.apache.hadoop.hbase.ipc.WritableRpcEngine$Invoker.invoke(WritableRpcEngine.java:86) 
        at $Proxy6.multi(Unknown Source) 
        at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation$3$1.call(HConnectionManager.java:1433) 
        at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation$3$1.call(HConnectionManager.java:1431) 
        at org.apache.hadoop.hbase.client.ServerCallable.withoutRetries(ServerCallable.java:215) 
        at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation$3.call(HConnectionManager.java:1440) 
        at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation$3.call(HConnectionManager.java:1428) 
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) 
        at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
        at java.lang.Thread.run(Thread.java:662) 
Caused by: java.net.SocketTimeoutException: 60000 millis timeout while waiting for channel to be ready for read. ch : java.nio.channels.SocketChannel[connected local=/10.106.8.133:41903 remote=b16-pf-dv-093.abc.com/10.106.8.103:60020] 
        at org.apache.hadoop.net.SocketIOWithTimeout.doIO(SocketIOWithTimeout.java:164) 
        at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:155) 
        at org.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:128) 
        at java.io.FilterInputStream.read(FilterInputStream.java:116) 
        at org.apache.hadoop.hbase.ipc.HBaseClient$Connection$PingInputStream.read(HBaseClient.java:373) 
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:218) 
        at java.io.BufferedInputStream.read(BufferedInputStream.java:237) 
        at java.io.DataInputStream.readInt(DataInputStream.java:370) 
        at org.apache.hadoop.hbase.ipc.HBaseClient$Connection.receiveResponse(HBaseClient.java:646) 
        at org.apache.hadoop.hbase.ipc.HBaseClient$Connection.run(HBaseClient.java:580)
4

2 に答える 2

10

ここで提供される解決策は 100% 正しいわけではありません。高負荷時の読み取りと書き込みの両方で socketTimeOut に直面しました。hbase.rpc.timeout を増やすことは、hbase サーバーでのスキャンまたは書き込みが非常に大きくなるまで、またはそうでない限り、解決策にはなりません。

これが私の問題です:

数ミリ秒で hbase によって返された行をスキャンしようとしました。同時スキャン スレッドを 10 から 50 に増やすまでは、すべて正常でした。そうすることで、1 つのプロセスから hbase の読み取りまたは書き込みをスケーリングする際の障害である socketTimeoutException (このスレッドと同じ例外) が発生し始めました。

正確な解決策にたどり着くには、まず原因を理解する必要があります。

socketTimeout の原因

を。hbase サーバーからの読み取りまたは書き込みの戻りが遅い

b. クライアントがサーバーに接続できず、タイムアウトしました。スレッドの混雑?

「a」が発生している場合は、hbase.rpc.timeout を増やすことが解決策になる可能性がありますが、それでも「b」になる可能性が高くなります。

デフォルトでは、hbase クライアントは regionServer ごとに 1 つの接続のみを作成することに気付きました。検証するには、hbase への読み取りが行われるクライアントからこのコマンドを実行してください。実行中の負荷を確認してください。

netstat -an | grep 60020 | grep EST

驚いたことに、すべての regionServer に対して、プロセスは 1 つの接続しか作成しませんでした。これはタイムアウトを説明しました。接続/ソケットは 1 つだけですか? これがデフォルトの hbase クライアントの動作のようです。理由はまだわかりませんか?

解決策:

クライアントの hbase conf にこれら 2 つのプロパティを追加し、クライアントを再起動します。

<property>
   <name>hbase.client.ipc.pool.type</name>
   <value>RoundRobinPool</value>
</property>
<property>
   <name>hbase.client.ipc.pool.size</name>
   <value>10</value>
</property>

これにより、すべてのクライアントから各 regionServer に 10 個のソケットが作成されました。この変更により、クライアント側で大幅な改善が見られるはずです。この変更以降、socketTimeOutException は経験していません。

于 2016-02-10T19:23:53.720 に答える
3

get にかかる時間が、HBase クライアント アプリケーションがリモート呼び出しのタイムアウトにかかるデフォルトの許容時間 ( 60 秒) を超えているため、このエラーが発生しています。テーブルが大きい場合 (フェッチするデータが多いことを意味します)、取得に時間がかかります。hbase-site.xmlファイルでhbase.rpc.timeoutの値をより高い値に設定することで、この値を増やすことができます。

Get の推奨バッチ サイズはどれくらいですか?

設計、構成、仕様、データ、およびアクセス パターンによって異なります。

挿入する前にレコードの存在を確認する最善の方法は何ですか?

何かをチェックしたいときは、チェックするしかありません。ユースケースをもう少し詳しく説明していただけると助かります。それは、適切な提案を思いつくのに役立ちます。

于 2013-07-29T22:27:10.640 に答える