<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Sep 27, 2013 at 1:56 AM, James <span dir="ltr">&lt;<a href="mailto:purpleidea@gmail.com" target="_blank">purpleidea@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">On Fri, 2013-09-27 at 00:35 -0700, Anand Avati wrote:<br>
&gt; Hello all,<br>
Hey,<br>
<br>
Interesting timing for this post...<br>
I&#39;ve actually started working on automatic brick addition/removal. (I&#39;m<br>
planning to add this to puppet-gluster of course.) I was hoping you<br>
could help out with the algorithm. I think it&#39;s a bit different if<br>
there&#39;s no replace-brick command as you are proposing.<br>
<br>
Here&#39;s the problem:<br>
Given a logically optimal initial volume:<br>
<br>
volA: rep=2; h1:/b1 h2:/b1 h3:/b1 h4:/b1 h1:/b2 h2:/b2 h3:/b2 h4:/b2<br>
<br>
suppose I know that I want to add/remove bricks such that my new volume<br>
(if I had created it new) looks like:<br>
<br>
volB: rep=2; h1:/b1 h3:/b1 h4:/b1 h5:/b1 h6:/b1 h1:/b2 h3:/b2 h4:/b2<br>
h5:/b2 h6:/b2<br>
<br>
What is the optimal algorithm for determining the correct sequence of<br>
transforms that are needed to accomplish this task. Obviously there are<br>
some simpler corner cases, but I&#39;d like to solve the general case.<br>
<br>
The transforms are obviously things like running the add-brick {...} and<br>
remove-brick {...} commands.<br>
<br>
Obviously we have to take into account that it&#39;s better to add bricks<br>
and rebalance before we remove bricks and risk the file system if a<br>
replica is missing. The algorithm should work for any replica N. We want<br>
to make sure the new layout makes sense to replicate the data on<br>
different servers. In many cases, this will require creating a circular<br>
&quot;chain&quot; of bricks as illustrated in the bottom of this image:<br>
<a href="http://joejulian.name/media/uploads/images/replica_expansion.png" target="_blank">http://joejulian.name/media/uploads/images/replica_expansion.png</a><br>
for example. I&#39;d like to optimize for safety first, and then time, I<br>
imagine.<br>
<br>
Many thanks in advance.<br>
<br></blockquote><div><br></div><div>I see what you are asking. First of all, when running a 2-replica volume you almost pretty much always want to have an even number of servers, and add servers in even numbers. Ideally the two &quot;sides&quot; of the replicas should be placed in separate failures zones - separate racks with separate power supplies or separate AZs in the cloud. Having an odd number of servers with an 2 replicas is a very &quot;odd&quot; configuration. In all these years I am yet to come across a customer who has a production cluster with 2 replicas and an odd number of servers. And setting up replicas in such a chained manner makes it hard to reason about availability, especially when you are trying recover from a disaster. Having clear and separate &quot;pairs&quot; is definitely what is recommended.</div>
<div><br></div><div>That being said, nothing prevents one from setting up a chain like above as long as you are comfortable with the complexity of the configuration. And phasing out replace-brick in favor of add-brick/remove-brick does not make the above configuration impossible either. Let&#39;s say you have a chained configuration of N servers, with pairs formed between every:</div>
<div><br></div><div>h(i):/b1 h((i+1) % N):/b2 | i := 0 -&gt; N-1</div><div><br></div><div>Now you add N+1th server.</div><div><br></div><div>Using replace-brick, you have been doing thus far:</div><div><br></div><div>1. add-brick hN:/b1 h0:/b2a # because h0:/b2 was &quot;part of a previous brick&quot;</div>
<div>2. replace-brick h0:/b2 hN:/b2 start ... commit<br></div><div><br></div><div>In case you are doing an add-brick/remove-brick approach, you would now instead do:</div><div><br></div><div>1. add-brick h(N-1):/b1a hN:/b2</div>
<div>2. add-brick hN:/b1 h0:/b2a</div><div>3. remove-brick h(N-1):/b1 h0:/b2 start ... commit</div><div><br></div><div>You will not be left with only 1 copy of a file at any point in the process, and achieve the same &quot;end result&quot; as you were with replace-brick. As mentioned before, I once again request you to consider if you really want to deal with the configuration complexity of having chained replication, instead of just adding servers in pairs.</div>
<div><br></div><div>Please ask if there are any more questions or concerns.</div><div><br></div><div>Avati</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

James<br>
<br>
Some comments below, although I&#39;m a bit tired so I hope I said it all<br>
right.<br>
<div class="im"><br>
&gt; DHT&#39;s remove-brick + rebalance has been enhanced in the last couple of<br>
&gt; releases to be quite sophisticated. It can handle graceful decommissioning<br>
&gt; of bricks, including open file descriptors and hard links.<br>
</div>Sweet<br>
<div class="im"><br>
&gt;<br>
&gt; This in a way is a feature overlap with replace-brick&#39;s data migration<br>
&gt; functionality. Replace-brick&#39;s data migration is currently also used for<br>
&gt; planned decommissioning of a brick.<br>
&gt;<br>
&gt; Reasons to remove replace-brick (or why remove-brick is better):<br>
&gt;<br>
&gt; - There are two methods of moving data. It is confusing for the users and<br>
&gt; hard for developers to maintain.<br>
&gt;<br>
&gt; - If server being replaced is a member of a replica set, neither<br>
&gt; remove-brick nor replace-brick data migration is necessary, because<br>
&gt; self-healing itself will recreate the data (replace-brick actually uses<br>
&gt; self-heal internally)<br>
&gt;<br>
&gt; - In a non-replicated config if a server is getting replaced by a new one,<br>
&gt; add-brick &lt;new&gt; + remove-brick &lt;old&gt; &quot;start&quot; achieves the same goal as<br>
&gt; replace-brick &lt;old&gt; &lt;new&gt; &quot;start&quot;.<br>
&gt;<br>
&gt; - In a non-replicated config, &lt;replace-brick&gt; is NOT glitch free<br>
&gt; (applications witness ENOTCONN if they are accessing data) whereas<br>
&gt; add-brick &lt;new&gt; + remove-brick &lt;old&gt; is completely transparent.<br>
&gt;<br>
&gt; - Replace brick strictly requires a server with enough free space to hold<br>
&gt; the data of the old brick, whereas remove-brick will evenly spread out the<br>
&gt; data of the bring being removed amongst the remaining servers.<br>
<br>
</div>Can you talk more about the replica = N case (where N is 2 or 3?)<br>
With remove brick, add brick you will need add/remove N (replica count)<br>
bricks at a time, right? With replace brick, you could just swap out<br>
one, right? Isn&#39;t that a missing feature if you remove replace brick?<br>
<div class="im"><br>
&gt;<br>
&gt; - Replace-brick code is complex and messy (the real reason :p).<br>
&gt;<br>
&gt; - No clear reason why replace-brick&#39;s data migration is better in any way<br>
&gt; to remove-brick&#39;s data migration.<br>
&gt;<br>
&gt; I plan to send out patches to remove all traces of replace-brick data<br>
&gt; migration code by 3.5 branch time.<br>
&gt;<br>
&gt; NOTE that replace-brick command itself will still exist, and you can<br>
&gt; replace on server with another in case a server dies. It is only the data<br>
&gt; migration functionality being phased out.<br>
&gt;<br>
&gt; Please do ask any questions / raise concerns at this stage :)<br>
</div>I heard with 3.4 you can somehow change the replica count when adding<br>
new bricks... What&#39;s the full story here please?<br>
<br>
Thanks!<br>
James<br>
<br>
&gt;<br>
&gt; Avati<br>
&gt; _______________________________________________<br>
&gt; Gluster-users mailing list<br>
&gt; <a href="mailto:Gluster-users@gluster.org">Gluster-users@gluster.org</a><br>
&gt; <a href="http://supercolony.gluster.org/mailman/listinfo/gluster-users" target="_blank">http://supercolony.gluster.org/mailman/listinfo/gluster-users</a><br>
<br>
</blockquote></div><br></div></div>