Riak Core Question

David Dawson david.dawson at gmail.com
Tue May 3 19:10:55 EDT 2011


Thanks for getting back to me, I actually have already tried the solution you suggested, although I still came across the problem where in the event of a primary coming back after a failure I would end up with 2 active processes. I am sure I could get around my issue if I could ask the question: "Where would my fallback node be in the event of a failure of the primary? and is it active?". Anyway assuming that it can not be done and storing state somewhere would become a bottleneck I like the idea of a group of processes with an elected leader that just deals with the requests, and in the event of it dying / disappearing another process can take over. I will have a look at the gen_leader work although it may be an overkill and I could do something very simple such as:

	Assuming N=3

	1. Take the 3 primary nodes returned from riak_core_apl:get_primary_apl()
	2. Spawn a process on each of them ( FSM's in a state of inactive )
	3. With each of the Pids do a quick sort on them to find the smallest

	4. Send a request to the smallest pid to make it active but also supply the other pids as part of the args so it can check  that they are not active 

	5. If this returns an ok, then send the desired request otherwise try again a random amount of time later

	6. If one of the 3 processes dies and it happens to be the active one then another will naturally take over on the next request. 

	7. If the process comes back some time later and happens to still have the smallest pid then it will ask the current leader to send it it's current queue of requests ( I will store this in the state ), finish it's current work then  go inactive and let it know once this is done so the new process can go active.

After writing the above I am getting the impression I am re-inventing the wheel and probably should use a tried and tested election algorithm, or even riak_zab if I decide to go down this route.


On 3 May 2011, at 21:54, Joseph Blomstedt wrote:

> If you want to determine if a vnode is a primary or secondary node,
> you can check if a vnode owns the particular index it is handling. If
> it owns the index, it's a primary; otherwise, a secondary.
> riak_core_ring:index_owner is the function to look into. The
> should_handoff function in riak_core_vnode serves as a good example.
> Handoff is triggered when a secondary node determines that the primary
> node is up.
> However, I am not sure if this helps much. Unless you already have a
> solution that works if you can determine this information. Of course,
> there may be other approaches.
> The command/sync_command logic inside riak_core does not directly
> handle routing / re-routing between primary and fallback nodes. You
> have flexibility in your application to route to partitions as
> desired. Yes, the riak_core_apl module handles primary / secondaries,
> but there is no inherent need to use that code.
> So, it is entirely possible for you to have logic within your
> application that is smart in choosing which {node, index} pair to send
> your requests to. The idea would be to favor the actual partition
> owner (ie. the primary) and only fallback to secondaries (adjacent
> partitions in the ring) when the primary is down. Basically, the same
> thing riak_core_apl / riak_kv does. However, you could have additional
> book-keeping that knows where current outstanding requests are and
> ensure no parallel requests.
> Of course, this assumes you have somewhere to do this book-keeping,
> eg. state outside of riak_core.
> In some ways, one instance of this problem is effectively reducible to
> leader election. You could always consider a set of primary/secondary
> vnodes as a group and use a leader election algorithm to always ensure
> a single vnode is the leader at any point -- and only send request to
> that leader. The existing gen_leader module you can find online may
> fit this bill.
> -Joe
> On Tue, May 3, 2011 at 1:06 PM, David Dawson <david.dawson at gmail.com> wrote:
>> I have a quick question regarding riak_core:
>>        Basically I am trying to build an application on top of riak_core that allows me to spawn a session per user interaction, so I can both hold state and queue requests to ensure ( as best I can ) that a user will only be interacting with my system in a serialised manner.
>>        My understandings are as follows with riak_core:
>>        1. You obtain a list of possible vnodes that can serve your request based on a hash of a key which in my case is a user_id
>>        2. You then use each of the vnodes in the list to execute your request which in my case is 1 as I have N=1.
>>        In my situation I want to kill a node ( simulate a failure ) send some further long running requests in that whose primary node is the one that has been killed, and then bring back up the dead node and send some more requests in with the safe knowledge that I will not end up with 2 vnodes  (  primary  and fallback ) that are processing the requests at the same time. Has anyone got any suggestions how I may achieve this? as I have scoured the riak_core source code and can not find a way to test if a vnode is present on a primary and fallback node at the same time, or am I barking up the wrong tree and trying to achieve the unachievable.
>>        Also I know I can not protect from a spit brain using this approach, although this is okay as under these rare occasions I have plans to deal with this in the business logic of the App.
>> Dave
>> _______________________________________________
>> riak-users mailing list
>> riak-users at lists.basho.com
>> http://lists.basho.com/mailman/listinfo/riak-users_lists.basho.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.basho.com/pipermail/riak-users_lists.basho.com/attachments/20110504/2d1bee0c/attachment.html>

More information about the riak-users mailing list