[infinispan-dev] [ISPN-78] Alternative interface for writing large objects

Olaf Bergner olaf.bergner at gmx.de
Mon Apr 4 05:47:28 EDT 2011


Hi Galder,

thanks for your input. See my comments below:

-------- Original-Nachricht --------
> Datum: Mon, 4 Apr 2011 10:09:39 +0200
> Von: "Galder Zamarreño" <galder at redhat.com>

> 
> Hmmmm, the initial step in writeToKey() is to create an map entry for the
> metadata, so the internal writeToKey() could indeed create a
> PutLargeObjectMetadataCommand and pass that down the interceptor stack, or more simply
> have a ChunkingInterceptor that implements visitPutKeyValue...() that would
> keep an eye for a transaction call that puts an LargeObjectMetadata, and at
> that point, the interceptor could return a new specialised
> outputstream...etc. The first suggestion would be more useful if you expect other normal
> cache commands such as get...etc to deal with large object related cache
> calls in a different way, but I don't think that's the case here since all the
> interaction would be via the Output/Input stream.

Just to make sure that we are on the same page: the supposed call sequence would appear to be

1. User calls OutputStream writeToKey(K key)
2. writeToKey creates a PutKeyValueCommand, marking it as pertaining to a large object.
3. writeToKey passes that command down the interceptor chain.
4. A LargeObjectChunkingInterceptor or maybe LargeObjectMetadataInterceptor processes that command, recognizing it as pertaining to a large object and thus storing a mapping from large object key to an initially empty large object metadata instance.
5. That interceptor returns a specialized output stream.
6. User writes bytes to that output stream until chunk limit is reached.
7. Output stream calls cache.put(key, byte[]) or alternatively creates PutKeyValueCommand itself, passing it down the interceptor chain.
8. LargeObjectChunking/MetadataInterceptor recognizes that it is dealing with a large object and that there already exists a mapping for that key in the metadata cache.
9. Interceptor generates new chunk key.
10. Interceptor replaces key with new cunk key and calls the next interceptor.
11. Interceptor restores original key (if only consistency reasons).
12. Repeat 6 - 11 until user closes output stream.

Makes sense. Thanks.


> Yeah, this information would be stored in an internal cache. There're
> several examples of such caches such as the topology cache for Hot Rod servers.
> When the server is started, it creates a configuration for this type of
> cache (i.e. REPL_SYNC....) and then it's named in a particular way...etc.

Found some example code in the meantime. It's obviously no rocket science.

> > 3. The design suggests to use a fresh UUID as the key for each new 
> > chunk. While this in all likelihood gives us a unique new key for each 
> > chunk I currently fail to see how that guarantees that this key maps to 
> > a node that is different from all the nodes already used to store chunks
> > of the same Large Object. But then again I know next to nothing about 
> > Infinispan's constant hashing algorithm.
> 
> I think there's a service that will generate a key mapped to particular
> node, so that might be a better option here to avoid all chunks going to the
> same node. I think Mircea might be able to help further with this.

Implemented a workaround in the meantime. Would be fab if such a service existed. Haven't found it yet.

> > 
> > 4. Finally, the problem regarding eager locking and transactions 
> > mentioned in Manik's comment seems rather ... hairy. If we indeed forego
> > transactions readers of a key just being written shouldn't be affected 
> > provided we write the LargeObjectMetadata object only after all chunks 
> > have been written. But what about writers?
> 
> Hmmmmm, I don't understand your question.

Well, the problem with transactions in this context seems to be that a transaction *always* holds it entire associated state. In our situation this would potentially blow up the heap.

Reading might not be a problem since in my original design a reader would not find a mapping for a key as long as the writer has not finished writing. It would assume that the large object it is looking for does not exist. In the updated design suggested above I currently think about marking the metadata as being incomplete. A reader could then either block until the writer is finished, or it could inform the reader about it.

I haven't thought deeply about the implications for concurrent writes, though. Is it possible to lock keys outside of a transactional context? If so, this might be a solution for reading and writing.

Cheers,
Olaf
 
> > 
> > _______________________________________________
> > infinispan-dev mailing list
> > infinispan-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/infinispan-dev
> 
> --
> Galder Zamarreño
> Sr. Software Engineer
> Infinispan, JBoss Cache
> 
> 
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/infinispan-dev

-- 
Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir
belohnen Sie mit bis zu 50,- Euro! https://freundschaftswerbung.gmx.de


More information about the infinispan-dev mailing list