High latency issue on client.get

java
amazon

#1

I need to be able to get a record from Aerospike within 20ms.

We use 2 dedicated amazon instances (one for client, one for server). We do not care much about write operation latency, but restrictive to read operation.

write operation:

AerospikeClient client = new AerospikeClient( host, port );
WritePolicy policy = new WritePolicy();
policy.timeout = timeout;
Key key = new Key( "Users", "actionMap", "userXXX" );
List<Object> list = Optional.ofNullable( client.get( policy, key ) )
       .map( r -> ( List ) r.getValue( actionName ) )
       .orElse( Lists.empty() );
list.add( DateTime.now() );
client.put( policy, key, Bin.asList( actionName, list ) );

read operation:

Policy policy = new Policy();
Future<T> task = executorService.submit( () -> client.get( policy, key ) ) );
Optional.ofNullable(  task.get( 20, TimeUnit.MILLISECONDS )  ).map( r -> r.bins ) ; 

Brief to domain: we have users that perform different operations. We need to store exact time when user performed an operation. Read operation should return map of <ACTION_NAME, List>. My concern was whether joda::DateTime wasn’t a “good” data time to be store. But it really shouldn’t matter that significantly.

It seems that when map has somewhat 10 values it works fine, but when it comes to 100 (but we expect a record to have ~20000 values) half of reads do not fit into cut-off time. There are ~5K tps on client.


#2

AerospikeClient does not know about joda::DateTime, so it serializes the datetime using the very slow default java serialization. Java serialization is most likely the cause of your high latencies.

Instead, convert joda::DateTime to a long (ticks) and store that. The long can be converted back to a joda:DateTime after reading from the server.

Also, the lastest client and server supports list append operations that are performed on the server. You don’t have to read the entire list, modify it, and write it back anymore.

long ticks = // convert joda:DateTime to ticks
Record record = client.operate(policy, key, ListOperation.append(actionName, Value.get(ticks)));