Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IOPS improvements #35

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

IOPS improvements #35

wants to merge 6 commits into from

Conversation

asqasq
Copy link
Member

@asqasq asqasq commented Nov 28, 2017

This PR contains changes to improve the number of IOPS:

  • Adapt to new DaRPC API
  • Additional Crail benchmark to measure IOPS with multiple namenodes
  • Additional HDFS benchmark to measure namenode IOPS
  • Move Crail namenode statistics out of fast-path to separate class, which can
    be instantiated instead of original one, if we want to do measurements
  • Added properties to tune mempool
  • Request DaRPC version 1.4

Note: This PR has to be merged together with the corresponding DaRPC PR.

double latency = 0.0;
if (executionTime > 0) {
latency = 1000000.0 * executionTime / ops;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this logic has been used elsewhere in this file but can we please change this to not use doubles and millis to calculate execution time. Instead use System.nanoTime() and do calculations with long where it makes sense for latency etc we of course need double

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not exactly sure, why calculating in nanoseconds is better than milliseconds (both return long, but we need double for the division).

If we change that, it should be everywhere to keep it consistent. I'll create an issue, as I think that this is a bigger cleanup step.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with currentTimeMillis is that it returns the actual time, i.e. is not monotonic and that leads to obvious problems, e.g. if you are running a NTP service time can change while you run a benchmark. That is why it is recommended to use System.nanoTime().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok sounds good. Will change all benchmark calculations in a new PR.

}
long end = System.currentTimeMillis();
double executionTime = ((double) (end - start));
double latency = executionTime*1000.0 / ((double) batch);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above

@@ -999,7 +1104,8 @@ public static void main(String[] args) throws Exception {
boolean useBuffered = true;

String benchmarkTypes = "write|writeAsync|readSequential|readRandom|readSequentialAsync|readMultiStream|"
+ "createFile|createFileAsync|createMultiFile|getKey|getFile|getFileAsync|enumerateDir|browseDir|"
+ "createFile|createFileAsync|createMultiFile|getKey|getFile|getFileAsync|getMultiFile"
+ "getMultiFileAsync|enumerateDir|browseDir|"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this more generic. Lot's of Strings duplicated and possible spelling errors.
I would like to see something like a map from string -> benchmark method

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this, there should be no need for string duplication.

I'd prefer to do this as a cleanup step and will create an issue.

@@ -77,7 +79,7 @@ public void run() throws Exception {

public static void usage(){
System.out.println("Usage:");
System.out.println("hdfsbench <readSequentialDirect|readSequentialHeap|readRandomDirect|readRandomHeap|writeSequentialHeap> <size> <iterations> <path>");
System.out.println("hdfsbench <readSequentialDirect|readSequentialHeap|readRandomDirect|readRandomHeap|writeSequentialHeap|getFile|getFileIOPS> <size> <iterations> <path>");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again please make this more generic

}
long end = System.currentTimeMillis();
double iops = ((double)loop) / (end - start) * (double)1000.0;
double executionTime = ((double) (end - start));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again see above.

@@ -55,6 +55,21 @@
public static final String NAMENODE_DARPC_CLUSTERSIZE_KEY = "crail.namenode.darpc.clustersize";
public static int NAMENODE_DARPC_CLUSTERSIZE = 128;

public static final String NAMENODE_DARPC_MEMPOOL_HUGEPAGEPATH_KEY = "crail.namenode.darpc.mempool.hugepagepath";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was under the impression we don't want this multilevel config anymore e.g. everything should be darpc.X

protected AtomicLong renameOps;
protected AtomicLong getOps;
protected AtomicLong locationOps;
protected AtomicLong errorOps;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer putting the Atomics in the stats class instead of making them protected

Copy link
Member

@patrickstuedi patrickstuedi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should take out the code for the statistics that we only used internally (e.g., DaRPCServiceDispatcherStats.java)

@asqasq
Copy link
Member Author

asqasq commented Dec 13, 2017

I removed the IOPS thread. Crail uses now the simple memory pool. I created two cleanup issues based on PepperJo's comments. Please have a look at the newest version.

Copy link
Contributor

@PepperJo PepperJo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor comment.

String _clusterAffinities[] = DaRPCConstants.NAMENODE_DARPC_AFFINITY.split(",");
long clusterAffinities[] = new long[_clusterAffinities.length];
for (int i = 0; i < clusterAffinities.length; i++){
int affinity = Integer.decode(_clusterAffinities[i]).intValue();
clusterAffinities[i] = 1L << affinity;
}
DaRPCServiceDispatcher darpcService = new DaRPCServiceDispatcher(service);
this.namenodeServerGroup = DaRPCServerGroup.createServerGroup(darpcService, clusterAffinities, -1, DaRPCConstants.NAMENODE_DARPC_MAXINLINE, DaRPCConstants.NAMENODE_DARPC_POLLING, DaRPCConstants.NAMENODE_DARPC_RECVQUEUE, DaRPCConstants.NAMENODE_DARPC_SENDQUEUE, DaRPCConstants.NAMENODE_DARPC_POLLSIZE, DaRPCConstants.NAMENODE_DARPC_CLUSTERSIZE);
if (!DaRPCConstants.NAMENODE_DARPC_STATS.isEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it makes sense to treat crail.namenode.darpc.stats as a boolean or similar. I can see this being misinterpreted otherwise and set to "crail.namenode.darpc.stats false" or "crail.namenode.darpc.stats no".

Copy link
Contributor

@PepperJo PepperJo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor comment.

DaRPCConstants.NAMENODE_DARPC_MEMPOOL_ALLOCSZ,
DaRPCConstants.NAMENODE_DARPC_MEMPOOL_ALIGNMENT,
DaRPCConstants.NAMENODE_DARPC_MEMPOOL_ALLOC_LIMIT
);
String _clusterAffinities[] = DaRPCConstants.NAMENODE_DARPC_AFFINITY.split(",");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer doing all parsing in the DaRPCConstants.

Copy link
Member Author

@asqasq asqasq Jan 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not add any parsing here. If you mean the split(), this is old code. I would prefer cleaning aup existing code in a separate PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants