Hi Terje, Sorry to not get to this sooner. Are you still looking into this?
On Tue, Jun 22, 2010 at 12:47 PM, Terje Marthinussen <tmarthinus...@gmail.com> wrote: > Hi, > > I was looking a bit on a case we have with columnfamily which has 439k > supercolumns, each supercolumn with ~3 columns each so a total of some 1.3 > million objects in total. > > This takes about 9 second to read with thrift on first access, 4-5 second on > second access. > > I took a little closer look at this, I noticed that roughly half of this > time was spend in cassandra. > > I will look more at this, but I thought I would just ask people here as it > could be that someone already had good explanations... > > Most of the time is spent here > > public void collectReducedColumns(IColumnContainer container, > Iterator<IColumn> reducedColumns, int gcBefore) > { > int liveColumns = 0; > AbstractType comparator = container.getComparator(); > > while (reducedColumns.hasNext()) > { > if (liveColumns >= count) > break; > > IColumn column = reducedColumns.next(); > if (logger.isDebugEnabled()) > logger.debug(String.format("collecting %s of %s: %s", > liveColumns, count, > column.getString(comparator))); > > if (finish.length > 0 > && ((!reversed && comparator.compare(column.name(), > finish) > 0)) > || (reversed && comparator.compare(column.name(), > finish) < 0)) > break; > > // only count live columns towards the `count` criteria > if (!column.isMarkedForDelete() > && (!container.isMarkedForDelete() > || (ClockRelationship.GREATER_THAN == > column.mostRecentLiveChangeAt().compare(container.getMarkedForDeleteAt())))) > { > liveColumns++; > } > > // but we need to add all non-gc-able columns to the > result for read repair: > if (QueryFilter.isRelevant(column, container, gcBefore)) > container.addColumn(column); > } > } > > Adding some time measuring print revealed a few interesting this. > 1. First time I request the row (I request the entire row in this case), > collectReducedColumns() is called twice. I have not had time to understand > why yet, but there is one difference between the calls. All columns are > returned both times, but the first call is done with MAXINT as "count" while > the second call has the maxcount actually requested by the client as > "count". The first call takes about 3.7 seconds to process, the second about > 1.7 secs. Whatever reason, I think we should be able to remove one of these > calls? > > 2. Almost half the time is spent in "container.addColumn". This is probably > no big surprise as there is a lot of code hidden "down there". I am however > very curious if it could not be significantly optimized, especially in the > case where you have predicates which cases all columns to be included. That > said, I have not manage to read enough cassandra code to understand > tombstones or all the other things which is going on in that part of the > code. > > 3. A bit more of a surprise, most of the remaining 50% of the time seems to > occur at while (reducedColumns.hasNext()) > That is, save system.nanoTime() at the end of the loop and after hasNext and > sum up and it accounts for almost 50% of the total time. That seems quite > weird to me. > > I will dig more, but I was curious if someone had answers already. > > Best regards, > Terje > -- Jonathan Ellis Project Chair, Apache Cassandra co-founder of Riptano, the source for professional Cassandra support http://riptano.com