YCSB*1でMongoDBを触っている際にスレッド数を増やすとよくinsertに失敗*2してYCSBが止まる事がしばしば。。。
update, read, scanに関しては止まらないのになぜかinsertだけ止まるのでソースコードを覗いてみた。
- src/com/yahoo/ycsb/Client.java
while (((_opcount == 0) || (_opsdone < _opcount)) && !_workload.isStopRequested()) { if (!_workload.doInsert(_db,_workloadstate)) { break; }
- src/com/yahoo/ycsb/workloads/CoreWorkload.java
/** * Do one insert operation. Because it will be called concurrently from multiple client threads, this * function must be thread safe. However, avoid synchronized, or the threads will block waiting for each * other, and it will be difficult to reach the target throughput. Ideally, this function would have no side * effects other than DB operations. */ public boolean doInsert(DB db, Object threadstate) { int keynum=keysequence.nextInt(); String dbkey = buildKeyName(keynum); HashMap<String, ByteIterator> values = buildValues(); if (db.insert(table,dbkey,values) == 0) return true; else return false; }
どうやらinsertの実行結果が成功(0)以外はすべてfalseと扱われ、insertが失敗した時点でOperationが残っていても強制的に処理が終わってしまうらしい。
そんなわけで"src/com/yahoo/ycsb/workloads/CoreWorkload.java"のifの部分を弄る。
- src/com/yahoo/ycsb/workloads/CoreWorkload.java
/** * Do one insert operation. Because it will be called concurrently from multiple client threads, this * function must be thread safe. However, avoid synchronized, or the threads will block waiting for each * other, and it will be difficult to reach the target throughput. Ideally, this function would have no side * effects other than DB operations. */ public boolean doInsert(DB db, Object threadstate) { int keynum=keysequence.nextInt(); String dbkey = buildKeyName(keynum); HashMap<String, ByteIterator> values = buildValues(); db.insert(table,dbkey,values); return true; }
とりあえずこれでinsertに失敗しても止まらなくなった。
が、それでいいのかと言われるとどうなんだろ・・・
が、MongoDBのinsertはなんであんなに失敗するんだろ。。。