<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jul 8, 2013 at 12:19 AM, Sanne Grinovero <span dir="ltr">&lt;<a href="mailto:sanne@infinispan.org" target="_blank">sanne@infinispan.org</a>&gt;</span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>On 3 July 2013 10:26, Dan Berindei &lt;<a href="mailto:dan.berindei@gmail.com" target="_blank">dan.berindei@gmail.com</a>&gt; wrote:<br>



&gt;<br>
&gt;<br>
&gt;<br>
&gt; On Tue, Jul 2, 2013 at 8:41 PM, Sanne Grinovero &lt;<a href="mailto:sanne@infinispan.org" target="_blank">sanne@infinispan.org</a>&gt;<br>
&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; On 2 July 2013 17:24, Dan Berindei &lt;<a href="mailto:dan.berindei@gmail.com" target="_blank">dan.berindei@gmail.com</a>&gt; wrote:<br>
&gt;&gt; &gt; It&#39;s not wrong, sending the invalidation only from the primary owner is<br>
&gt;&gt; &gt; wrong :)<br>
&gt;&gt;<br>
&gt;&gt; Agreed, sending a GET operation to multiple nodes might not be wrong<br>
&gt;&gt; per-se but is the root cause of such race conditions, and other subtle<br>
&gt;&gt; complexities we might not even be aware of yet.<br>
&gt;&gt;<br>
&gt;&gt; I don&#39;t know why it was slower, but since the result doesn&#39;t make<br>
&gt;&gt; sense we should look at it a second time rather than throwing the code<br>
&gt;&gt; away.<br>
&gt;&gt;<br>
&gt;<br>
&gt; It does make sense: statistically, the backup owner will sometimes reply<br>
&gt; faster than the primary owner.<br>
&gt;<br>
&gt; <a href="http://markmail.org/message/qmpn7yueym4tbnve" target="_blank">http://markmail.org/message/qmpn7yueym4tbnve</a><br>
&gt;<br>
&gt; <a href="http://www.bailis.org/blog/doing-redundant-work-to-speed-up-distributed-queries/" target="_blank">http://www.bailis.org/blog/doing-redundant-work-to-speed-up-distributed-queries/</a><br>
<br>
</div>Of course, I remember the discussion but you can put may questions<br>
marks on this decision. First off, this is doubling the load on<br>
network, which is supposedly our most precious resource, so I highly<br>
question how we&#39;re measuring the &quot;benefit&quot; of the second request.<br>
If you read the articles you linked to you&#39;ll see google applies such<br>
a strategy to improve the tail latency, but only sends the second<br>
request when the first one is not getting a fast answer, and in their<br>
tests this seems to pay off to a mere 5% of increased network usage..<br>
I would say that&#39;s a significantly different level of trade off.<br>
Also, opposed to Google&#39;s BigTable and Apache Cassandra which use<br>
these techniques, Infinispan is not supporting an eventually<br>
consistent model which makes it far more dangerous to read the<br>
slightly out of date value from the non-owner... sure we can resolve<br>
those things, but it gets hairy.<br> 
<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
In this case specifically, reading from the primary owner only seems a<br>
much &quot;cleaner&quot; solution, as IMHO it&#39;s a move towards simplification<br>
rather than adding yet another special case in the codebase.<br></blockquote><div> </div>It&#39;s cleaner, but it slows down reads, as we&#39;ve seen in our own tests.<br><div><br></div><div>Also, the consistency 
problems with staggered remote gets are the same as the consistency 
problems with simultaneous remote gets. So it would be much harder to go back 
and experiment with staggered gets once we simplify the code on the assumption that we should only 
ever read from the primary owner.<br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; Sending invalidations from a non-primary owner is an interesting<br>
&gt;&gt; approach, but then we&#39;re having each owner to maintain an independent<br>
&gt;&gt; list of nodes who have read the value.<br>
&gt;&gt; For each write, the primary node would send an invalidation to each<br>
&gt;&gt; registered node, plus the copy to the secondary nodes, which in turn<br>
&gt;&gt; sends more L1 invalidation nodes to each of their registered nodes..<br>
&gt;&gt; what&#39;s the likelihood of duplication of invalidation messages here?<br>
&gt;&gt; Sounds like a big network traffic amplifier, lots of network traffic<br>
&gt;&gt; triggered for each write.<br>
&gt;&gt;<br>
&gt;<br>
&gt; The likelihood of duplication is very near to 100%, indeed, and in non-tx<br>
&gt; caches it would add another RPC to the critical path.<br>
&gt;<br>
&gt; As always, it&#39;s a compromise: if we do something to speed up writes, it will<br>
&gt; slow down reads. Perhaps we could send the request to the primary owners<br>
&gt; only when L1 is enabled, as the number of remote gets should be smaller, and<br>
&gt; send the request to all the owners when L1 is disabled, and the number of<br>
&gt; remote gets is higher.<br>
&gt;<br>
&gt; Pedro&#39;s suggestion to send the request to all the owners, but only write the<br>
&gt; value to L1 if the first reply was from the primary owner, sounds like it<br>
&gt; should work just as well. It would make L1 slightly less efficient, but it<br>
&gt; wouldn&#39;t have latency spikes caused by a delay on the primary owner.<br>
<br>
</div>That&#39;s far from an ideal solution; we don&#39;t have a clue on how to<br>
measure what &quot;slightly less efficient&quot; means: that might reveal to be<br>
&quot;unbearably worse&quot; for some usage pattern.<br></blockquote><div><br>True, in a worst case scenario, the primary owner could be replying consistently slower than the others, and the entry may never be stored in L1. And it wouldn&#39;t make sense to try this with numOwners = 10, the chances of the primary owner replying first would be slim.<br>


<br></div><div>I think my &quot;slightly less efficient&quot; description would be more accurate if we had staggered gets, if we ever get that patch in...<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">



<br>
While we have no clue how worse it can be, it will definitely always<br>
provide a worse cache hit/miss ratio, so it&#39;s easily proven that it&#39;s<br>
going to be sub optimal in all cases.<br></blockquote><div><br></div><div>If numOwners = 1 there is only one way to read the value, so it&#39;s clearly optimal in one case :)<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">



If you really go for something like that, at least take the value from<br>
the primary owners when it arrives (second, third, .. whatever but at<br>
some point you might get it) and then store it in L1: will cost you a<br>
second unmarshalling operation but that&#39;s far better than causing<br>
(several?) cache misses.<br></blockquote><div><br><div>That sounds nice, I wonder how easily Will could make it work with the L1 synchronization stuff he has implemented.<br></div><div><br></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">


<div>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; It also implies that we don&#39;t have reliability on the list of<br>
&gt;&gt; registered nodes, as each owner will be maintaining a different set.<br>
&gt;&gt; In this case we should also have each node invalidate its L1 stored<br>
&gt;&gt; entries when the node from which they got these entries has left the<br>
&gt;&gt; cluster.<br>
&gt;&gt;<br>
&gt;<br>
&gt; Right now we invalidate from L1 all the keys for which the list of owners<br>
&gt; changed, whether they&#39;re still alive or not, because we don&#39;t keep track of<br>
&gt; the node we got each entry from.<br>
&gt;<br>
&gt; If we only sent remote get commands to the primary owner, we&#39;d have to<br>
&gt; invalidate from L1 all the keys for which the primary owner changed.<br>
&gt;<br>
&gt; One thing that we don&#39;t do at the moment, but we should do whether we send<br>
&gt; the invalidations from the primary owner or from all the owners, is to clean<br>
&gt; up the requestor lists for the keys that a node no longer owns.<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; Having it all dealt by the primary owner makes for a much simpler<br>
&gt;&gt; design and also makes it more likely that a single L1 invalidate<br>
&gt;&gt; message is sent via multicast, or at least with less duplication.<br>
&gt;&gt;<br>
&gt;<br>
&gt; The simplest design would be to never keep track of requestors and always<br>
&gt; send a multicast from the originator. In fact, the default configuration is<br>
&gt; to always send multicasts (but we still keep track of requestors and we send<br>
&gt; the invalidation from the primary owner).<br>
&gt;<br>
&gt; Intuitively, unicasts would be preferable for keys that have a low<br>
&gt; read:write ratio, as in a write-intensive scenario, but I wonder if<br>
&gt; disabling L1 wouldn&#39;t be even better for that scenario.<br>
<br>
</div>Well put<br>
<br>
Cheers,<br>
Sanne<br>
<div><div><br>
&gt;<br>
&gt; Cheers<br>
&gt; Dan<br>
&gt;<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; Cheers,<br>
&gt;&gt; Sanne<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; On Tue, Jul 2, 2013 at 7:14 PM, Sanne Grinovero &lt;<a href="mailto:sanne@infinispan.org" target="_blank">sanne@infinispan.org</a>&gt;<br>
&gt;&gt; &gt; wrote:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; I see, so we keep the wrong implementation because it&#39;s faster?<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; :D<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; On 2 July 2013 16:38, Dan Berindei &lt;<a href="mailto:dan.berindei@gmail.com" target="_blank">dan.berindei@gmail.com</a>&gt; wrote:<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; On Tue, Jul 2, 2013 at 6:36 PM, Pedro Ruivo &lt;<a href="mailto:pedro@infinispan.org" target="_blank">pedro@infinispan.org</a>&gt;<br>
&gt;&gt; &gt;&gt; &gt; wrote:<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; On 07/02/2013 04:21 PM, Sanne Grinovero wrote:<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; +1 for considering it a BUG<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; Didn&#39;t we decide a year ago that GET operations should be sent to<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; a<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; single node only (the primary) ?<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; +1 :)<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; Manik had a patch for staggering remote GET calls, but it was slowing<br>
&gt;&gt; &gt;&gt; &gt; down<br>
&gt;&gt; &gt;&gt; &gt; reads by 25%: <a href="http://markmail.org/message/vsx46qbfzzxkkl4w" target="_blank">http://markmail.org/message/vsx46qbfzzxkkl4w</a><br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; On 2 July 2013 15:59, Pedro Ruivo &lt;<a href="mailto:pedro@infinispan.org" target="_blank">pedro@infinispan.org</a>&gt; wrote:<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; Hi all,<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; simple question: What are the consistency guaranties that is<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; supposed<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; to<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; be ensured?<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; I have the following scenario (happened in a test case):<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; NonOwner: remote get key<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; BackupOwner: receives the remote get and replies (with the<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; correct<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; value)<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; BackupOwner: put in L1 the value<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; PrimaryOwner: [at the same time] is committing a transaction that<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; will<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; update the key.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; PrimaryOwer: receives the remote get after sending the commit.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; The<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; invalidation for L1 is not sent to NonOwner.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; The test finishes and I perform a check for the key value in all<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; the<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; caches. The NonOwner returns the L1 cached value (==test fail).<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; IMO, this is bug (or not) depending what guaranties we provide.<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; wdyt?<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; Pedro<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; _______________________________________________<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; infinispan-dev mailing list<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; <a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;&gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; _______________________________________________<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; infinispan-dev mailing list<br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; <a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
&gt;&gt; &gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; _______________________________________________<br>
&gt;&gt; &gt;&gt; &gt;&gt; infinispan-dev mailing list<br>
&gt;&gt; &gt;&gt; &gt;&gt; <a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
&gt;&gt; &gt;&gt; &gt;&gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; _______________________________________________<br>
&gt;&gt; &gt;&gt; &gt; infinispan-dev mailing list<br>
&gt;&gt; &gt;&gt; &gt; <a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
&gt;&gt; &gt;&gt; &gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
&gt;&gt; &gt;&gt; _______________________________________________<br>
&gt;&gt; &gt;&gt; infinispan-dev mailing list<br>
&gt;&gt; &gt;&gt; <a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
&gt;&gt; &gt;&gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; _______________________________________________<br>
&gt;&gt; &gt; infinispan-dev mailing list<br>
&gt;&gt; &gt; <a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
&gt;&gt; &gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; infinispan-dev mailing list<br>
&gt;&gt; <a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
&gt;&gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; infinispan-dev mailing list<br>
&gt; <a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
&gt; <a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
_______________________________________________<br>
infinispan-dev mailing list<br>
<a href="mailto:infinispan-dev@lists.jboss.org" target="_blank">infinispan-dev@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/infinispan-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/infinispan-dev</a><br>
</div></div></blockquote></div><br></div></div>