[sheepdog] VDI r/w performance comparison test

yuyang justyuyang at foxmail.com
Wed May 27 10:24:29 CEST 2015


Hello everyone,

Recently we need copy one VDI from sheepdog to another storage 
system(such as sheepdog or RAID). There are 2 ways to choose,
1. dog vdi r | dog vdi w,(only for sheepdog, or temp file is needed)
2. lib client, which is on the way.

And then I did a R/W IO performance comparison.
Now I want to share the results.

In this test, we read from sheepdog and write to the same sheepdog. Or we just call 
it "copy task". For the sake of simplicity, the sheepdog only has one node.

The first step is to prepare the source VDI. The size of source VDI is 50GB,
and the data is 10GB/25GB/40GB(we do three tests).

The task by lib client is done by the following code:

/****** copy.c *********/
#include <stdio.h>
#include <stdlib.h>
#include <sheepdog sheepdog.h="">

#define BUFSIZE (1024*1024*128)  /**128M**/

void copy(struct sd_cluster *csrc, char *srcname,
		  struct sd_cluster *cdst, char *dstname)
{
	int ret = 0;
	struct sd_vdi * srcv = sd_vdi_open(csrc, srcname, 0, NULL);
	if (!srcv) {
		fprintf(stderr, "open %s failed\n", srcname);
		return ;
	}
	uint64_t size = srcv->inode->vdi_size;
	ret = sd_vdi_create(cdst, dstname, size, 0);
	if (ret != SD_RES_SUCCESS) {
		fprintf(stderr, "create failed %s\n", sd_error2str(ret));
		return;
	}
	struct sd_vdi * dstv = sd_vdi_open(cdst, dstname, 0, NULL);
	if (!dstv) {
		fprintf(stderr, "open %s failed\n", dstname);
		return ;
	}
	char *buf = malloc(BUFSIZE);
	if ( !buf ) {
		printf("OOM\n");
		return ;
	}
	uint64_t offset = 0, left = size, onew;
	while(offset < size) {
		left = size - offset;
		onew = left > BUFSIZE ? BUFSIZE : left;
		memset(buf, 0, BUFSIZE);
	
		ret = sd_vdi_read(srcv, buf, onew, offset);
		if (ret != SD_RES_SUCCESS) {
			fprintf(stderr, " read error: offset=%"PRIx64, offset);
			return;
		}
		ret = sd_vdi_write(dstv, buf, onew, offset);
		if (ret != SD_RES_SUCCESS) {
			fprintf(stderr, " write error: offset=%"PRIx64, offset);
			return;
		}
		offset += onew;
	}
	free(buf);
}

int main(int argc, char *argv[])
{
		char host1[256] = {};
		char host2[256] = {};
		memset(host1, 0, 256);
		memset(host2, 0, 256);
		if (argc != 5) {
			printf("too small argument\n");
			printf("usage: copy srcIP srcvdiname dstIP dstvdiname\n");
			return 0;
		}

		strcpy(host1, argv[1]);
		strcpy(host2, argv[3]);

		strcat(host1, ":7000");
		strcat(host2, ":7000");

		struct sd_cluster *c1 = sd_connect(host1);
		struct sd_cluster *c2 = sd_connect(host2);

		if (!c1 || !c2) {
			printf("connect failed\n");
			return 0;
		}
		copy(c1, argv[2], c1, argv[4]);
		return 0;
}

compile: gcc copy.c -lpthread -lsheepdog
run it:
./a.out 127.0.0.1 $vlibsrc 127.0.0.1 $vlibdst

we record the runtime of the programme.

And the copy task by dog cmd is done by the following script:
dog vdi create $vdogdst 50g
dog vdi read $vdogsrc  | dog vdi write $vdogdst 0 50g

we also record the runtime.

Then we prepare 2 new source VDI in which there is 25GB(and then 40GB) 
and repeat the steps above.
The result is as follows:

	data(GB)	lib/dog		time(s) 
	10			lib			101
	10			dog			239

	25			lib			128
	25			dog			251

	40			lib			134
	40			dog			249

As is shown in the table above, we can see that most of the time,
the lib client can speed up to more than 50% in VDI r/w.

Most of operations of VDI such as create/snapshot/clone/rollback/delete are already
finished in the lib client. And we will send the patches ASAP.

Yang
Thanks.</sheepdog></stdlib.h></stdio.h>


More information about the sheepdog mailing list