[Repost] Key Dependencies
Elizabeth Mattijsen
liz at dijkmat.nl
Mon Mar 12 23:08:23 UTC 2007
At 6:04 PM -0500 3/12/07, clayton collie wrote:
>My apologies for the bungled post (thanks to hotmail)
>
>Anyhow...
>I need the following in an ongoing project, so i'm posting here to
>see if others see merit in the idea.
>
>Proposal
>--------
>Add key-based dependencies to memcached.
>
>Motivation
>----------
>To simplify common caching scenarios (data dependencies and namespaces)
>by centralizing the logic at the server.
>
>Example
>---------
>
>Assume we have an organization selling widgets to the Americas
>and Asia, and that the sales calculations are aggregated and
>cached.
>
> add ns:americas 0 0 nothing\r\n
> add ns:asia 0 0 nothing\r\n
>
> add americas:sales 0 0 25000\r\n
> add americas:sales.usa 0 0 20000\r\n
> add americas:sales.usa.bolts 0 0 10000\r\n
> add americas:sales.usa.grommets 0 0 10000\r\n
> add americas:sales.colombia 0 0 5000\r\n
> add americas:sales.colombia.bolts 0 0 5000\r\n
>
> dependency americas:sales.usa americas:sales.usa.bolts
>americas:sales.usa.grommets\r\n
> dependency americas:sales.combia americas:sales.colombia.bolts\r\n
>
> dependency americas:sales americas:sales.usa americas:sales.colombia\r\n
> dependency americas:sales.usa ns:americas\r\n
> dependency americas:sales.colombia ns:americas\r\n
>
>Here we add keys representing the two sales regions (ns:america,
>ns:asia). The total sales
>per region are stored (e.g. americas:sales), as well as the
>individual country and item sales
>which constitute the total. The aggregate is made dependent on the
>country sales, and
>the country sales are dependent on the region. Any number of
>dependencies can be added,
>but of course this consumes memory per key.
>
>If the sales figures for the USA or Colombia changes, americas:sales
>is automatically
>deleted. To delete the aggregate data for the Americas region, we
>delete ns:americas.
>
>Implementing namespaces in this way may cause issues in that a
>dependency would
>be one of the first items scavenged if there is no need to retrieve it
>- like ns:americas in this example (there is no useful data associated).
>The client can handle this with a multi-key get which always
>includes such a key.
>PHP example :
>
> function GetEx($memcache, $key)
> {
> $pos = strpos($key, ":"); // we use ":" as namespace separator
> if (FALSE == $pos) {
> /* not namespaced, use single get */
> return $memcache->get($key);
> }
> $namespace = "ns:" . substr($key, 0, $pos);
> $arr = $memcache->get( array($key, $namespace) );
> return $arr[$key];
> }
>
>
>Dependency command
>--------------------------
>
>dependency <key> <dependency>*\r\n
>
>- <key> is the key under which the dependent item is stored.
>
>- <dependency>* means one or more key strings separated by whitespace.
>
>Each <dependency> must represent a valid undeleted, unexpired item.
>Each item specified by the dependency key has <key> added to its
>list of dependents.
>An item cannot be added as a dependency to itself.
>
>After sending the command line and the data block the client awaits
>the reply, which may be:
>
>- "OK\r\n", to indicate success.
>
>- "NOT_FOUND\r\n" to indicate the item or one of the dependencies
>was was not found.
>
>
>Needed Changes
>------------------------
>
>- Addition of storage for dependent keys per item struct.
>
>- void item_add_dependencies(conn *c, item *node, item
>**dependencies, int count, int check_cycles)
> Add node as a dependent to each item in the dependencies list. This
>optionally performs a
> topological sort to detect possible dependency cycles.
>
>- Add a server setting to allow/disallow dependency cycle detection.
>
>- Modification of the item_unlink routine to recursively unlink dependents of
> the item. When the dependency is deleted or modified, all of its dependents
> are deleted recursively.
>
>- Modification of item_free to cleanup dependent key storage.
>
>- An addition to the protocol to allow client setting of item dependencies.
>
>
>Caveats
>-------
>This implementation assumes that a key and its dependencies are
>located in a single memcached
>server instance. Cycle detection has an effect performance, so it is
>made optional by setting.
>Dependents of a key are stored per node and consume (2 +
>strlen(key)) bytes each.
On casual inspection, this looks a lot like a server side
implementation of what my Cache::Memcached::Managed Perl module does.
I would be all for it!
Liz
More information about the memcached
mailing list