[
https://issues.apache.org/jira/browse/HBASE-5311?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13202178#comment-13202178
]
Todd Lipcon commented on HBASE-5311:
------------------------------------
I don't think so... funnily enough I was just taking a break from my usually
scheduled work and working on this.
I don't have much so far, but my design uses some lock-free tricks to safely
swap around internal pieces of the data structure. Here's a sketch of what I
was hacking on:
I created a lock free data structure tentatively named "GatedSection" which is
sort of like a lock/critical section but not quite. It has the following API:
{code}
/**
* Return true if the thread should be allowed to enter the critical section,
* false if any other thread has already closed the gate
*/
boolean enterSection();
/**
* Must be called by any thread that has successfully entered above
*/
void exitSection();
/**
* Disallows any new threads from entering the section (future calls to
* enterSection() will return false). Blocks until all other threads which
* are already in the section have called exitSection().
* Postcondition: no threads are in the section or will be able to enter it
* after this method returns.
*/
void closeGateAndFlushThreads();
{code}
If you're familiar with JVM internals, this is a little bit like how
'checkpoints' work.
I then created another data structure:
{code}
class State {
GatedSection gate;
List<Map<K,V>> mapLayers; // writes go to idx 0, reads merge all
}
{code}
and the overall datastructure has a {{volatile State state;}} member.
Operations which mutate the current state (eg put) then do something like:
- in a loop, try to grab a local copy of the State variable, and then enter its
gate, until successful.
- modify its top map layer
- exit the gate
A "flush" works as follows:
- step 1: create a new top layer for writes
-- create a new State object which is identical except a new concurrent map has
been inserted at the "top" of mapLayers
-- swap the volatile "state" pointer to the new state. At this point, writers
will be writing into _either_ of the top two layers
-- close the "gate". After the gate is closed, writers will only be writing to
the _top_ layer
- step 2: freeze the old top layer
-- create a new efficient immutable datastructure for mapLayers.get(1) (no
rush to complete this phase)
-- swap it into place by swapping out the volatile state object
A compaction works similarly to "step 2" above.
Might be worth using a technique like fractional cascading on the "mapLayers"
structure as well to avoid O(k log n) lookups with k layers.
> Allow inmemory Memstore compactions
> -----------------------------------
>
> Key: HBASE-5311
> URL: https://issues.apache.org/jira/browse/HBASE-5311
> Project: HBase
> Issue Type: Improvement
> Reporter: Lars Hofhansl
>
> Just like we periodically compact the StoreFiles we should also periodically
> compact the MemStore.
> During these compactions we eliminate deleted cells, expired cells, cells to
> removed because of version count, etc, before we even do a memstore flush.
> Besides the optimization that we could get from this, it should also allow us
> to remove the special handling of ICV, Increment, and Append (all of which
> use upsert logic to avoid accumulating excessive cells in the Memstore).
> Not targeting this.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators:
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira