2013-07-29 14 views
5

Stiamo lavorando a uno scenario in cui è necessario verificare l'esistenza del record prima dell'inserimento. Se il record esiste già, non inserirlo di nuovo. Stiamo facendo in lotti. Per prima cosa creiamo un batch di Gets per vedere l'esistenza dei record che vogliamo inserire. Questo problema non si verifica quando la dimensione della tabella è inferiore ed è anche molto intermittente. Qual è la dimensione del batch consigliata per Get. E qual è l'approccio migliore per verificare l'esistenza dei record prima di inserire ?? Apprezzate le vostre risposte ..SocketTimeoutException issue from HBase Client

Ecco la traccia dello stack ..

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) 

risposta

3

State ottenendo questo errore perché il tempo impiegato dal ottiene è più che il tempo concesso di default che un applicazioni client HBase può prendere per un chiamata remota a timeout, ovvero 60 secondi. Quando il tuo tavolo è grande (il che significa che hai più dati da recuperare) ci vorrà del tempo. È possibile aumentare questo valore impostando il valore di hbase.rpc.timeout con un valore superiore nel file hbase-site.xml.

Qual è la dimensione del lotto consigliata per Get?

A seconda del design, della configurazione, delle specifiche, dei dati e del modello di accesso.

qual è l'approccio migliore per verificare l'esistenza dei record prima dell'inserimento?

Quando si desidera controllare qualcosa, il controllo è l'unica opzione. Sarebbe utile se potessi elaborare un po 'di più il tuo caso d'uso. Questo mi aiuterà a trovare qualche suggerimento adeguato.

+0

Grazie mille per la tua risposta Tariq. Ho aumentato il timeout di rpc ad un numero maggiore e non lo sto ottenendo ora. Ma quello che non sono in grado di capire è perché è stato intermittente. Voglio dire, perché non ho avuto questo timeout tutte le volte. E un altro problema di prestazioni che sto affrontando in questo momento è quasi il 90 - 95% del tempo di inserimento totale è stato speso per il controllo unico anche dopo l'utilizzo di batch ottiene. E l'orario di controllo è anche molto incoerente. Qual è la ragione di questo comportamento? –

+0

Siete i benvenuti @NareshReddy. In realtà dipende da molte cose, come la progettazione dello schema, la distribuzione dei dati, ecc. Un possibile motivo potrebbe essere ** Hotspotting RegionServer **. Avete i tasti sequenziali sequenziali (come timestamp o qualcosa che aumenta costantemente con il tempo). Ti suggerisco di seguire le migliori pratiche HBase e analizzare correttamente il tuo progetto, nel caso in cui ci sia un certo margine di miglioramento. HTH – Tariq

6

La soluzione fornita qui non è corretta al 100%. Ho affrontato socketTimeOut su entrambe le letture e le scritture a carico elevato. L'aumento di hbase.rpc.timeout non è una soluzione fino a meno che la scansione o le scritture sul server hbase non siano molto grandi.

Ecco il mio problema:

ho cercato di eseguire la scansione di file che sono stati restituiti indietro di HBase in pochi millisecondi. Tutto era normale fino a quando ho aumentato i thread di scansione simultanea da 10 a 50. Così facendo ho iniziato a sperimentare socketTimeoutException (stessa eccezione di questa discussione) che è un ostacolo per ridimensionare la lettura o la scrittura di hbase da un processo.

Per ottenere la soluzione esatta, è necessario prima capire la causa.

Cause di socketTimeout

a. Il ritorno in lettura o scrittura dal server hbase è lento

b. Il client non è in grado di connettersi al server e scaduto. La congestione dei thread?

Se si verifica "a", poi aumentando hbase.rpc.timeout potrebbe essere la soluzione, ma ancora molto probabilmente finirà su "b" pure.

Ho notato che il client hbase crea automaticamente una sola connessione per regionServer. Per convalidare, si prega di eseguire questo comando dal client in cui vengono fatte le letture su hbase. Assicurati che il carico sia in esecuzione.

netstat -an | grep 60020 | grep EST 

Con mia grande sorpresa, per ogni regionServer, il processo ha fatto una sola connessione. Questo ha spiegato i timeout. Una sola connessione/presa? Sembra che questo sia il comportamento predefinito del client hbase. Non sei sicuro del perché, ancora?

Soluzione:

Aggiungi queste due proprietà in HBase conf nel client e riavviare il client

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

Questo ha creato 10 prese su ogni regionServer da ogni cliente. Con questo cambiamento dovresti vedere un notevole miglioramento dal lato del cliente. Non ho provato socketTimeOutException, dal momento che questa modifica.