我在异步模式下执行Lua函数,并使用NIOEventLoops。当我尝试获取下一个事件循环并执行Lua函数时,我有一些异常:
com.aerospike.client.AerospikeException$Connection: Error -7 from BB967EF43270008 127.0.0.1 3000: Node BB967EF43270008 127.0.0.1 3000 event loop 5 max connections 100 would be exceeded.
at com.aerospike.client.cluster.Node.getAsyncConnection(Node.java:657) ~[aerospike-client-4.2.2.jar:?]
at com.aerospike.client.async.NioCommand.executeCommand(NioCommand.java:184) [aerospike-client-4.2.2.jar:?]
at com.aerospike.client.async.NioCommand.run(NioCommand.java:146) [aerospike-client-4.2.2.jar:?]
at com.aerospike.client.async.NioEventLoop.registerCommands(NioEventLoop.java:211) [aerospike-client-4.2.2.jar:?]
at com.aerospike.client.async.NioEventLoop.runCommands(NioEventLoop.java:173) [aerospike-client-4.2.2.jar:?]
at com.aerospike.client.async.NioEventLoop.run(NioEventLoop.java:156) [aerospike-client-4.2.2.jar:?]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_181]
Run Code Online (Sandbox Code Playgroud)
那是我获取下一个事件循环的方法:
private synchronized EventLoop getNextEventLoop() {
EventLoop next;
do {
next = eventLoops.next();
} while (next.getProcessSize() >= maxConnectionsPerEventLoop);
return next;
}
Run Code Online (Sandbox Code Playgroud)
这就是我执行Lua函数的方式:
as.execute(getNextEventLoop()
, new ExecuteListener() {
@Override
public void onSuccess(Key key, Object obj) {
...
}
@Override
public void onFailure(AerospikeException exception) {
...
}
}
, writePolicy
, key
, "lua-pack"
, "funcName"
, Value.get(binName), Value.get(value)
);
Run Code Online (Sandbox Code Playgroud)
如何避免这种异常?
小智 5
您正在达到ClientPolicy.maxConnsPerNode极限。对于500 maxConnsPerNode和5个事件循环,每个事件循环可以为每个节点使用最多100(500/5)个连接。我假定您的maxConnectionsPerEventLoop值> =100。而且,不能保证在getProcessSize()调用后将下一条命令发送到事件循环时,该插槽仍然可用。
解决方案是限制maxCommandsInProcess每个事件循环。这是限制飞行命令(以及连接)的线程安全方法。
EventPolicy eventPolicy = new EventPolicy();
eventPolicy.maxCommandsInProcess = 100; // max 100 commands per event loop.
eventPolicy.maxCommandsInQueue = 0; // unbounded queue
int eventLoopSize = 5;
EventLoops eventLoops = new NioEventLoops(eventPolicy, eventLoopSize);
ClientPolicy clientPolicy = new ClientPolicy();
clientPolicy.eventLoops = eventLoops;
clientPolicy.maxConnsPerNode = eventPolicy.maxCommandsInProcess * eventLoopSize;
Run Code Online (Sandbox Code Playgroud)
maxCommandsInProcess达到限制时,异步命令队列用于命令。如果传入命令的速率始终超过处理命令的速率,则您的应用程序可能会耗尽内存。为避免这种情况,您可能需要限制队列大小。
eventPolicy.maxCommandsInQueue = 10000;
Run Code Online (Sandbox Code Playgroud)
如果达到此队列大小,AerospikeException.AsyncQueueFull则会引发异常。您的应用程序应通过将非事件循环线程中的命令延迟到eventLoop.getQueueSize()足够低的水平进行响应。