我正在运行我编写的示例代码来测试 HBase lockRow()
和unlockRow()
方法。示例代码如下:
HTable table = new HTable(config, "test");
RowLock rowLock = table.lockRow(Bytes.toBytes(row));
System.out.println("Obtained rowlock on " + row + "nRowLock: " + rowLock);
Put p = new Put(Bytes.toBytes(row));
p.add(Bytes.toBytes("colFamily"), Bytes.toBytes(colFamily), Bytes.toBytes(value));
table.put(p);
System.out.println("put row");
table.unlockRow(rowLock);
System.out.println("Unlocked row!");
当我执行我的代码时,我得到一个UnknownRowLockException
.文档指出,当将未知行锁传递到区域服务器时,将引发此错误。我不确定这是怎么发生的以及如何解决它。
堆栈跟踪如下:
Obtained rowlock on row2
RowLock: org.apache.hadoop.hbase.client.RowLock@15af33d6
put row
Exception in thread "main" org.apache.hadoop.hbase.UnknownRowLockException: org.apache.hadoop.hbase.UnknownRowLockException: 5763272717012243790
at org.apache.hadoop.hbase.regionserver.HRegionServer.unlockRow(HRegionServer.java:2099)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.hadoop.hbase.ipc.HBaseRPC$Server.call(HBaseRPC.java:604)
at org.apache.hadoop.hbase.ipc.HBaseServer$Handler.run(HBaseServer.java:1055)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.apache.hadoop.hbase.RemoteExceptionHandler.decodeRemoteException(RemoteExceptionHandler.java:96)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.translateException(HConnectionManager.java:1268)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.getRegionServerWithRetries(HConnectionManager.java:1014)
at org.apache.hadoop.hbase.client.HTable.unlockRow(HTable.java:870)
at HelloWorld.Hello.HelloWorld.main(HelloWorld.java:41)
编辑:
我刚刚意识到我应该打印rowLock.getLockId()
而不是rowLock
.我这样做并将其与堆栈跟踪中的行锁进行了比较,它们是相同的,所以我不确定为什么会发生UnknownRowLockException
。
请更改底层系统上的"文件描述符限制"。
在 Linux 上,您可以使用 ulimit 来做到这一点
请注意,HBase 在其日志中打印为第一行,限制其看到。
我能够通过这种方式解决此错误:
获取的 rowLock 需要作为参数传递给 put 构造函数。
HTable table = new HTable(config, "test");
RowLock rowLock = table.lockRow(Bytes.toBytes(row));
System.out.println("Obtained rowlock on " + row + "nRowLock: " + rowLock);
Put p = new Put(Bytes.toBytes(row), rowLock);
p.add(Bytes.toBytes("colFamily"), Bytes.toBytes(colFamily), Bytes.toBytes(value));
table.put(p);
System.out.println("put row");
table.unlockRow(rowLock);
System.out.println("Unlocked row!");
在我之前的方法中,在表的一行上获取了 rowLock。但是,由于未使用 rowLock(未传递给 put 构造函数),因此当我调用 unlockRow 方法时,该方法会等待 60 秒(锁定超时)以检查是否已使用锁。60 秒后,锁过期,我最终得到UnknownRowLockException