Closed
Description
Python's ZipFile allows writing duplicate files and does this by default. When it writes a duplicate file, it raises a UserWarning. This occurs for each file and is a bit noisy. As there doesn't seem to be a standard way of solving this, would recommend that we simply suppress this warning. Combining this with a resolution to issue ( https://github.com/alimanfoo/zarr/issues/128 ), would ensure that deduplication already occurs so the warning is no longer relevant.
Edit: Added link to Python bug after the fact.
Metadata
Metadata
Assignees
Labels
No labels
Activity
jakirkham commentedon Feb 24, 2017
Proposed fix in PR ( https://github.com/alimanfoo/zarr/pull/130 ).
alimanfoo commentedon Feb 24, 2017
FWIW I think this needs some consideration. If duplicate files are being written into a zip file, and this is happening often, then it is likely that something rather sub-optimal is happening. In the pathological case, a user could be storing many multiples of the actual data for an array without realising, then wonder why the zip file is so large.
Writing directly to a zip file is really only efficient if the array or arrays being stored in the zip store are written only once, and write operations can be perfectly aligned with chunk boundaries, in which case no duplicate chunk files will ever get created. This can be achieved if an array is created with
zarr.array(data=data, ...)or with something likez = zarr.zeros(...); z[:] = data, as in either case zarr internally aligns the write operations with chunk boundaries.If the use case requires that data are written and then overwritten, and/or that write operations cannot be aligned with chunk boundaries, then a better approach is probably to initially store the data using
DirectoryStore. Then when all writing has finished, the containing directory can be stored into a zip file using the standard command line zip utility. The resulting zip file can then be read directly by zarr without having to unpack. This should be at least as efficient in general as deduplicating a zip file on close by copying to a new zip file.jakirkham commentedon Feb 24, 2017
It's a fair point honestly. Though I really do like the idea of operating on a single file that includes all of the array data. Zip is nice as it is easy to inspect. Though I don't feel wedded to it given the issues I'm already experiencing by playing with it. Is there some other reasonable storage type that we could add to Zarr that wouldn't have these limitations?
alimanfoo commentedon Feb 24, 2017
I don't know of anything better. Tar is worse apparently as it doesn't support random access. It would be possible (if a little twisted) to use an HDF5 file, however you'd lose the ability to do multi-threaded reads (which seem to work on a zip store surprisingly). cc @mrocklin.
mrocklin commentedon Feb 24, 2017
When I looked into this a long while ago I found that yes, there are other single-file compression formats out there that support random access, but none seemed common place. Generally speaking writing variable sized byte blocks into a single file is a hard problem.
Another alternative would be an embedded key-value database. Zict has a MutableMapping for LMDB. https://github.com/dask/zict/blob/master/zict/lmdb.py This would be a single directory rather than a single file, but balances large writes and many small writes well.
alimanfoo commentedon Feb 24, 2017
Maybe shelve is an option? It supports the MutableMapping interface so you could probably just use a
Shelfas a store without needing to write any new code...alimanfoo commentedon Feb 24, 2017
Ha, @mrocklin you get much kudos for advocating the MutableMapping interface...
mrocklin commentedon Feb 24, 2017
Hooray standard interfaces!
alimanfoo commentedon Feb 24, 2017
Looks like shelve supports multi-threaded reads...
alimanfoo commentedon Feb 24, 2017
A BerkeleyDB hash table would probably be another option.
jakirkham commentedon Feb 24, 2017
The fact that Zarr is using a
MutableMappingseems like a very useful thing. Not that I have looked into this at all, but I wonder if there are any Key-Value Stores that would work well here.mrocklin commentedon Feb 24, 2017
alimanfoo commentedon Feb 24, 2017
Yes, any key-value store should be an option.
jakirkham commentedon Feb 24, 2017
Thanks for the feedback. I'll give this some more thought.
alimanfoo commentedon Feb 25, 2017
jakirkham commentedon Feb 27, 2017
I added a little bit of Python code to zip up the directories after they are written to in such a way as to ensure Zarr can still load them. This is a good enough near term solution for my needs. Would be willing to contribute the utility function or perhaps add another store if there is interest.
alimanfoo commentedon Feb 27, 2017
jakirkham commentedon Mar 1, 2017
Opened issue ( https://github.com/alimanfoo/zarr/issues/137 ) to keep track of this idea.
jakirkham commentedon Oct 18, 2017
Forgot to mention that
create_group,create_dataset, andopen_groupwill add an empty.zattrsentry to start with. Thus if the attributes need to be set or modified afterwards, this will create duplicate.zattrsentries in a Zip file. Have raised issue ( https://github.com/alimanfoo/zarr/issues/121 ) to allowattrsto be specified in these creation functions.alimanfoo commentedon Oct 18, 2017