<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>All things Sysadmin &#187; misc</title>
	<atom:link href="http://northernmost.org/blog/category/miscellaneous-stuff/feed/" rel="self" type="application/rss+xml" />
	<link>http://northernmost.org/blog</link>
	<description>Just another manic Monday</description>
	<lastBuildDate>Sat, 10 Mar 2012 10:34:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>How does MySQL hide the command line password in ps?</title>
		<link>http://northernmost.org/blog/how-does-mysql-hide-the-command-line-password-in-ps/</link>
		<comments>http://northernmost.org/blog/how-does-mysql-hide-the-command-line-password-in-ps/#comments</comments>
		<pubDate>Sat, 10 Mar 2012 10:34:51 +0000</pubDate>
		<dc:creator>Erik Ljungstrom</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://northernmost.org/blog/?p=425</guid>
		<description><![CDATA[If you do decide to write an application which takes a password (or any other sensitive information) on the command line, you can prevent other users on the system from easily seeing it like this <a href="http://northernmost.org/blog/how-does-mysql-hide-the-command-line-password-in-ps/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I saw this question asked today, and thought I&#8217;d write a quick post about it.<br />
Giving passwords on the command line isn&#8217;t necessarily a fantastic idea &#8211; but you can sort of see where they&#8217;re coming from. Configuration files and environment variables are better, but just slightly. Security is a night mare!</p>
<p>But if you do decide to write an application which takes a password (or any other sensitive information) on the command line, you can prevent other users on the system from easily seeing it like this:</p>
<p><code>#include &lt;stdio.h&gt;<br />
#include &lt;unistd.h&gt;<br />
#include &lt;string.h&gt;<br />
#include &lt;sys/types.h&gt;</p>
<p>int main(int argc, char *argv[]){</p>
<p>	int i = 0;<br />
	pid_t mypid = getpid();<br />
	if (argc == 1)<br />
		return 1;<br />
	printf("argc = %d and arguments are:\n", argc);<br />
	for (i ; i < argc ; i++)<br />
		printf("%d = %s\n" ,i, argv[i]);<br />
	printf("Replacing first argument with x:es... Now open another terminal and run: ps p %d\n", (int)mypid);<br />
	fflush(stdout);<br />
	memset(argv[1], 'x', strlen(argv[1]));<br />
	getc(stdin);<br />
        return 0;<br />
}</code></p>
<p>A sample run looks like this:<br />
<code>$ ./pwhide abcd<br />
argc = 2 and arguments are:<br />
0 = ./pwhide<br />
1 = abcd<br />
Replacing first argument with x:es... Now run: ps p 27913</code></p>
<p>&lt;In another terminal&gt;<br />
<code>$ ps p 27913<br />
  PID TTY      STAT   TIME COMMAND<br />
27913 pts/1    S+     0:00 ./pwhide xxxx<br />
</code></p>
<p>In the interest of brevity, the above code isn't very portable - but it works on Linux and hopefully the point of it comes across. In other environments, such as FreeBSD, you have the setproctitle() syscall to do the dirty work for you. The key thing here is the overwriting of argv[1]<br />
Because the size of argv[] is allocated when the program starts, you can't easily obfuscate the length of the password. I say easily - because of course <a href="http://stupefydeveloper.blogspot.com/2008/10/linux-change-process-name.html">there is a way</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://northernmost.org/blog/how-does-mysql-hide-the-command-line-password-in-ps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Font rendering &#8211; no more jealousy</title>
		<link>http://northernmost.org/blog/font-rendering-no-more-jealousy/</link>
		<comments>http://northernmost.org/blog/font-rendering-no-more-jealousy/#comments</comments>
		<pubDate>Tue, 28 Feb 2012 23:14:52 +0000</pubDate>
		<dc:creator>Erik Ljungstrom</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[Sundry sysadmin]]></category>

		<guid isPermaLink="false">http://northernmost.org/blog/?p=417</guid>
		<description><![CDATA[f you like me is an avid Fedora user, I'm sure you've thrown glances at colleague's or friend's Ubuntu machines and thought that there was something that was slightly different about the way it looked (aside from the obvious Gnome vs Unity differences). Shinier somehow...  So had I, but I mainly dismissed it as a case of "the grass is always greener...".  <a href="http://northernmost.org/blog/font-rendering-no-more-jealousy/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I suppose this kind of content is what most people use twitter for these days. But since I&#8217;ve remained strong and stayed well away from that, I suppose I will have to be a tad retro and write a short blog post about it.<br />
If you like me are an avid <a href="http://fedoraproject.org">Fedora</a> user, I&#8217;m sure you&#8217;ve thrown glances at colleague&#8217;s or friend&#8217;s Ubuntu machines and thought that there was something that was slightly different about the way it looked (aside from the obvious Gnome vs Unity differences). Shinier somehow&#8230;  So had I, but I mainly dismissed it as a case of &#8220;the grass is always greener&#8230;&#8221;. </p>
<p>It turns out that the grass actually IS greener. Tonight I stumbled upon <a href="http://www.infinality.net/blog/infinality-freetype-patches/">this</a>. It&#8217;s a patched version of freetype. For what I assume are political reasons (free as in speech), Fedora ships a Freetype version without subpixel rendering. These patches fixes that and <a href="http://www.infinality.net/forum/viewtopic.php?f=2&#038;t=18">other things</a>. </p>
<p>With a default configuration file of 407 lines, it&#8217;s quite extensible and configurable as well. Lucky, I quite like the default!</p>
<p>If you&#8217;re not entirely happy with the way your fonts look on Fedora &#8211; it&#8217;s well worth a look</p>
]]></content:encoded>
			<wfw:commentRss>http://northernmost.org/blog/font-rendering-no-more-jealousy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Example using Cassandra with Thrift in C++</title>
		<link>http://northernmost.org/blog/example-using-cassandra-with-thrift-in-c/</link>
		<comments>http://northernmost.org/blog/example-using-cassandra-with-thrift-in-c/#comments</comments>
		<pubDate>Sat, 21 May 2011 20:28:02 +0000</pubDate>
		<dc:creator>Erik Ljungstrom</dc:creator>
				<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://northernmost.org/blog/?p=362</guid>
		<description><![CDATA[The only somewhat useful example of using Cassandra with C++ one can find online is <a href="http://posulliv.github.com/2010/02/22/cpp-cassandra.html">this</a>, but due to the API changes, this is now outdated (it's still worth a read). 
So in the hope that nobody else will have to spend the better part of a day piecing things together to achieve even the most basic thing, here's an example which works with Cassandra 0.7 and Thrift 0.6. <a href="http://northernmost.org/blog/example-using-cassandra-with-thrift-in-c/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Due to a very exciting, recently launched project at work, I&#8217;ve had to interface with Cassandra through C++ code. As anyone who has done this can testify, the API docs are vague at best, and there are very few examples out there. The constant API changes between 0.x versions and the fact that the Cassandra API has its <a href="http://wiki.apache.org/cassandra/API">docs</a> and Thrift has <a href="http://wiki.apache.org/thrift/">its own</a>, but there is nothing bridging the two isn&#8217;t helpful either.<br />
So at the moment it is very much a case of dissecting header files and looking at implementation in the Thrift generated source files.</p>
<p>The only somewhat useful example of using Cassandra with C++ one can find online is <a href="http://posulliv.github.com/2010/02/22/cpp-cassandra.html">this</a>, but due to the API changes, this is now outdated (it&#8217;s still worth a read). </p>
<p>So in the hope that nobody else will have to spend the better part of a day piecing things together to achieve even the most basic thing, here&#8217;s an example which works with Cassandra 0.7 and Thrift 0.6.</p>
<p>First of all, create a new keyspace and a column family, using cassandra-cli:</p>
<p><code>[default@unknown] create keyspace nm_example;<br />
c647b2c0-83e2-11e0-9eb2-e700f669bcfc<br />
Waiting for schema agreement...<br />
... schemas agree across the cluster<br />
[default@unknown] use nm_example;<br />
Authenticated to keyspace: nm_example<br />
[default@nm_example] create column family nm_cfamily with comparator=BytesType and default_validation_class=BytesType;<br />
30466721-83e3-11e0-9eb2-e700f669bcfc<br />
Waiting for schema agreement...<br />
... schemas agree across the cluster<br />
[default@nm_example]<br />
</code></p>
<p>Now go to the directory where you have cassandra installed and enter the <strong>interface/</strong>directory and run: <strong>thrift &#8211;gen cpp cassandra.thrift</strong><br />
This will create the <strong>gen-cpp/</strong> directory. From this directory, you need to copy all files bar the Cassandra_server.skeleton.cpp one to wherever you intend to keep your sources.<br />
Here&#8217;s some example code which inserts, retrieves, updates, retrieves and deletes keys:</p>
<p><code>#include "Cassandra.h"</p>
<p>#include &lt;protocol/TBinaryProtocol.h&gt;<br />
#include &lt;thrift/transport/TSocket.h&gt;<br />
#include &lt;thrift/transport/TTransportUtils.h&gt;</p>
<p>using namespace std;<br />
using namespace apache::thrift;<br />
using namespace apache::thrift::protocol;<br />
using namespace apache::thrift::transport;<br />
using namespace org::apache::cassandra;<br />
using namespace boost;</p>
<p>static string host("127.0.0.1");<br />
static int port= 9160;</p>
<p>int64_t getTS(){<br />
    /* If you're doing things quickly, you may want to make use of tv_usec<br />
     * or something here instead<br />
     */<br />
    time_t ltime;<br />
    ltime=time(NULL);<br />
    return (int64_t)ltime;</p>
<p>}</p>
<p>int main(){<br />
    shared_ptr<TTransport> socket(new TSocket(host, port));<br />
    shared_ptr<TTransport> transport(new TFramedTransport(socket));<br />
    shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));<br />
    CassandraClient client(protocol);</p>
<p>    const string&#038; key="your_key";</p>
<p>    ColumnPath cpath;<br />
    ColumnParent cp;</p>
<p>    ColumnOrSuperColumn csc;<br />
    Column c;</p>
<p>    c.name.assign("column_name");<br />
    c.value.assign("Data for our key to go into column_name");<br />
    c.timestamp = getTS();<br />
    c.ttl = 300;</p>
<p>    cp.column_family.assign("nm_cfamily");<br />
    cp.super_column.assign("");</p>
<p>    cpath.column_family.assign("nm_cfamily");<br />
    /* This is required - thrift 'feature' */<br />
    cpath.__isset.column = true;<br />
    cpath.column="column_name";</p>
<p>    try {<br />
        transport->open();<br />
        cout << "Set keyspace to 'dpdns'.." << endl;<br />
        client.set_keyspace("nm_example");</p>
<p>        cout << "Insert key '" << key << "' in column '" << c.name << "' in column family '" << cp.column_family << "' with timestamp " << c.timestamp << "..." << endl;<br />
        client.insert(key, cp, c, org::apache::cassandra::ConsistencyLevel::ONE);</p>
<p>        cout << "Retrieve key '" << key << "' from column '" << cpath.column << "' in column family '" << cpath.column_family << "' again..." << endl;<br />
        client.get(csc, key, cpath, org::apache::cassandra::ConsistencyLevel::ONE);<br />
        cout << "Value read is '" << csc.column.value << "'..." << endl;</p>
<p>        c.timestamp++;<br />
        c.value.assign("Updated data going into column_name");<br />
        cout << "Update key '" << key << "' in column with timestamp " << c.timestamp << "..." << endl;<br />
        client.insert(key, cp, c, org::apache::cassandra::ConsistencyLevel::ONE);</p>
<p>        cout << "Retrieve updated key '" << key << "' from column '" << cpath.column << "' in column family '" << cpath.column_family << "' again..." << endl;<br />
        client.get(csc, key, cpath, org::apache::cassandra::ConsistencyLevel::ONE);<br />
        cout << "Updated value is: '" << csc.column.value << "'" << endl; </p>
<p>        cout << "Remove the key '" << key << "' we just retrieved. Value '" << csc.column.value << "' timestamp " << csc.column.timestamp << " ..." << endl;<br />
        client.remove(key, cpath, csc.column.timestamp, org::apache::cassandra::ConsistencyLevel::ONE);</p>
<p>        transport->close();<br />
    }<br />
    catch (NotFoundException &#038;nf){<br />
        cerr << "NotFoundException ERROR: "<< nf.what() << endl;<br />
    }<br />
    catch (InvalidRequestException &#038;re) {<br />
        cerr << "InvalidRequest ERROR: " << re.why << endl;<br />
    }<br />
    catch (TException &#038;tx) {<br />
        cerr << "TException ERROR: " << tx.what() << endl;<br />
    }</p>
<p>    return 0;<br />
}</code></p>
<p>Say we've called the file cassandra_example.cpp, and you have the files mentioned above in the same directory, you can comile things like this:</p>
<p><code>$ g++ -lthrift -Wall  cassandra_example.cpp cassandra_constants.cpp Cassandra.cpp cassandra_types.cpp -o cassandra_example<br />
$ ./cassandra_example<br />
Set keyspace to 'nm_example'..<br />
Insert key 'your_key' in column 'column_name' in column family 'nm_cfamily' with timestamp 1306008338...<br />
Retrieve key 'your_key' from column 'column_name' in column family 'nm_cfamily' again...<br />
Value read is 'Data for our key to go into column_name'...<br />
Update key 'your_key' in column with timestamp 1306008339...<br />
Retrieve updated key 'your_key' from column 'column_name' in column family 'nm_cfamily' again...<br />
Updated value is: 'Updated data going into column_name'<br />
Remove the key 'your_key' we just retrieved. Value 'Updated data going into column_name' timestamp 1306008339 ...</code></p>
<p>As my WP template isn't very suitable for code, I've put up the cpp file <a href="http://northernmost.org/files/cassandra_example.cpp">here</a> for download<br />
Another thing worth mentioning is <a href=" http://posulliv.com/">Padraig O'Sullivan's</a> <a href="https://github.com/posulliv/libcassandra">libcassandra</a>, which may or may not be worth a look depending on what you want to do and what versions of Thrift and Cassandra you're tied to.</p>
]]></content:encoded>
			<wfw:commentRss>http://northernmost.org/blog/example-using-cassandra-with-thrift-in-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Development, just as important as dual NICs</title>
		<link>http://northernmost.org/blog/development-just-as-important-as-dual-nics/</link>
		<comments>http://northernmost.org/blog/development-just-as-important-as-dual-nics/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 12:05:43 +0000</pubDate>
		<dc:creator>Erik Ljungstrom</dc:creator>
				<category><![CDATA[misc]]></category>

		<guid isPermaLink="false">http://northernmost.org/blog/?p=208</guid>
		<description><![CDATA[So after you've demanded dual power feeds to your rack, bonded NICs and a gazillion physical paths to your dual controller SAN, it would make sense to apply the same attitude towards your developers. After all, they are carbon based humans and are far more likely to break than your silicon NIC. <a href="http://northernmost.org/blog/development-just-as-important-as-dual-nics/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There is a popular saying which I find you can apply  to most things in life; &#8220;You get what you pay for&#8221;. Sadly, this does not seem to apply for software development in any way. You who know me know that I work for a reasonably sized hosting company in the upper market segment. We have thousands of servers and hundreds of customers, so after a while you get a quite decent overview of how things work and a vast arsenal of &#8220;stories from the trenches&#8221;.</p>
<p>So here&#8217;s a small tip; ensure that your developers know what they are doing! It will save you a lot of hassle and money in the long run.</p>
<p>Without having made a science out of it, I can confidently say that at the very least 95% of the downtime I see on a daily basis is due to faulty code in the applications running on our servers.</p>
<p>So after you&#8217;ve demanded dual power feeds to your rack, bonded NICs and a gazillion physical paths to your dual controller SAN, it would make sense to apply the same attitude towards your developers. After all, they are carbon based humans and are far more likely to break than your silicon NIC. Now unfortunately it is not as simple as &#8220;if I pay someone a lot of money and let them do their thing, I will get good solid code out of it&#8221;, so a great deal of due diligence is required in this part of your environment as well. I have seen more plain stupid things coming from 50k pa. people than I care to mention, and I have seen plain brilliant things coming out of college kids&#8217; basements.</p>
<p>This is important not only from an availability point of view, it&#8217;s also about running cost. The amount of hardware in our data centers which is completely redundant, and would easily be made obsolete with a bit of code and database tweaking is frightening. So you think you may have cut a great deal when someone said they could build your e-commerce system in 3 months for 10k less than other people have quoted you. But in actual fact, all you have done is got someone to effectively re-brand a bloated, way too generic, stock framework/product which the developer has very little insight into and control over. Yes, it works if you &#8220;click here, there and then that button&#8221;, the right thing does appear on the screen. But only after executing hundreds of SQL queries, looking for your session in three different places, done four HTTP redirects, read five config files and included 45 other source files. Needless to say, those one-off 10k you think you have saved, will be swallowed in recurring hardware cost in no time. You have probably also severely limited your ability to scale things up in the future.</p>
<p>So in summary, don&#8217;t cheap out on your development but at the same time don&#8217;t think that throwing money at people will make them write good code. Ask someone else to look things over every now and then, even if it will cost you a little bit. Use the budget you were planning on spending on the SEO consultant. Let it take time.</p>
]]></content:encoded>
			<wfw:commentRss>http://northernmost.org/blog/development-just-as-important-as-dual-nics/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>GlusterFS tcp_nodelay patch update</title>
		<link>http://northernmost.org/blog/glusterfs-tcp_nodelay-patch-update/</link>
		<comments>http://northernmost.org/blog/glusterfs-tcp_nodelay-patch-update/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 22:22:12 +0000</pubDate>
		<dc:creator>Erik Ljungstrom</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[glusterfs]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[tcp_nodelay]]></category>

		<guid isPermaLink="false">http://northernmost.org/blog/?p=202</guid>
		<description><![CDATA[As mentioned in my previous post, I wrote a patch for GlusterFS to increase its performance when operating on many smaller files. Someone told me the other day that this functionality has been pushed to the git repository.  <a href="http://northernmost.org/blog/glusterfs-tcp_nodelay-patch-update/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As mentioned in my <a href="http://northernmost.org/blog/improving-glusterfs-performance/">previous post</a>, I wrote a patch for GlusterFS to increase its performance when operating on many smaller files. Someone told me the other day that this functionality has been pushed to the <a href="http://git.savannah.gnu.org/cgit/gluster.git/commit/?h=release-2.0&amp;id=7a797746b9276493a0891da63124092ddc98f01b">git repository</a>. Would have been good to have heard about this sooner&#8230;</p>
<p>So all of you who emailed me positive feedback and asked to make it a tuneable in the translator config (thanks!) &#8211; please check out  the above link to the git repository.</p>
<p>On another note, it seems as if they&#8217;re breaking away from having the <a href="http://git.savannah.gnu.org/cgit/gluster.git/commit/?h=release-2.0&amp;id=72e83f9b52b5ed4bbeed1cc1163dc8392ccf6b05">protocol version bound to the release</a> version, good progress in my opinion!</p>
]]></content:encoded>
			<wfw:commentRss>http://northernmost.org/blog/glusterfs-tcp_nodelay-patch-update/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Improving GlusterFS performance</title>
		<link>http://northernmost.org/blog/improving-glusterfs-performance/</link>
		<comments>http://northernmost.org/blog/improving-glusterfs-performance/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 21:11:12 +0000</pubDate>
		<dc:creator>Erik Ljungstrom</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[glusterfs]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://northernmost.org/blog/?p=188</guid>
		<description><![CDATA[Then I tried many frequent filesystem operations, untarring the 2.6.9 linux kernel from and onto the mount.  Not so brilliant! It took 23-24 minutes from start to finish. The 2.6.9 kernel contain 17477 files and the average size is just a few kilobytes. This is obviously a lot of smaller bursts of network traffic! <a href="http://northernmost.org/blog/improving-glusterfs-performance/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had a closer look at <a href="http://www.gluster.com">glusterfs</a> in the last few days following the <a href="http://www.gluster.com/news.php">release of version 2.0.1</a>. We often get customers approaching us with web apps dealing with user generated content which needs to be uploaded. If you have two or more servers in a load balanced environment, you usually have a few options, an NFS/CIFS share on one of them (single point of failure &#8211; failover NFS is, well&#8230;), a SAN (expensive), <a href="http://www.danga.com/mogilefs/">MogileFS</a> (good, but alas not application agnostic),  periodically rsync/tar | nc files between the nodes (messy, not application agnostic and slow), store files in a database (not ideal for a number of reasons). There are a few other approaches and combinations of the above, but neither is perfect. GlusterFS solves this. It&#8217;s fast, instant and redundant! </p>
<p>I&#8217;ve got four machines set up, two acting as redundant servers. Since they&#8217;re effectively acting as a RAID 1, each write is done twice over the wire, but that&#8217;s kind of inevitable. They&#8217;re all connected in a private isolated gigabit network. When dealing with larger files (a la `cp yourfavouritedistro.iso /mnt/gluster`) the throughput is really good at around 20-25 MB/s leaving the client. CPU usage on the client doing the copy was in the realms of 20-25% on a dual core. Very good so far! </p>
<p>Then I tried many frequent filesystem operations, untarring the 2.6.9 linux kernel from and onto the mount.  Not so brilliant! It took 23-24 minutes from start to finish. The 2.6.9 kernel contain 17477 files and the average size is just a few kilobytes. This is obviously a lot of smaller bursts of network traffic!</p>
<p>After seeing this, I dove into the source code to have a look, when I reached the socket code, I realised that the performance for smaller files would probably be improved by a lot if Nagle&#8217;s algorithm was disabled on the socket. Said and done, I added a few setsockopt()s and went to test. The kernel tree now extracted in 1m 20s!</p>
<p>Of course there&#8217;s always the drawback.. In this case it is that larger files take longer to transfer as the raw throughput is decreasing (kernel buffer is a lot faster than a cat5!). Copying a 620 MB ISO from local disk onto the mount takes 1.20 s with the vanilla version of GlusterFS, and 3m 34s with Nagle&#8217;s algorithm disabled. </p>
<p>I&#8217;m not seeing any performance hit on sustained transfer of larger files, but at the moment I&#8217;m guessing I&#8217;m hitting another bottleneck before that becomes a problem, as it &#8220;in theory&#8221; should have a slight negative impact in this case.</p>
<p>If you want to have a look at it, you can find the patch <a href="http://northernmost.org/files/glusterfs-2.0.1-patch-erik.diff">here</a>. Just download to the source directory and do patch -p1 &lt; glusterfs-2.0.1-patch-erik.diff  and then proceed to build as normal.</p>
<p>Until I&#8217;ve done some more testing on it and received some feedback, I won&#8217;t bother making it a tuneable in the vol-file just in case it&#8217;d be wasted effort!</p>
]]></content:encoded>
			<wfw:commentRss>http://northernmost.org/blog/improving-glusterfs-performance/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Multiple backends with Varnish</title>
		<link>http://northernmost.org/blog/multiple-backends-with-varnish/</link>
		<comments>http://northernmost.org/blog/multiple-backends-with-varnish/#comments</comments>
		<pubDate>Mon, 15 Sep 2008 23:25:54 +0000</pubDate>
		<dc:creator>Erik Ljungstrom</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[Webservers]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[load balancing]]></category>
		<category><![CDATA[varnish]]></category>

		<guid isPermaLink="false">http://northernmost.org/blog/?p=123</guid>
		<description><![CDATA[So as of now, you can safely use one varnish instance for several front-ends, thus eliminate double-caching (memory waste, unnecessary load on back-ends), reduce network traffic, do rudimentary load balancing, ease management etc.
With the obscene amount of traffic Varnish can push without putting a fairly basic system under any load worth mentioning, you can use a single front-end to serve several nodes in most setups. <a href="http://northernmost.org/blog/multiple-backends-with-varnish/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://varnish.projects.linpro.no/">Varnish</a> has been able to provide caching for more than one backend for quite some time. The achilles heel with this has up until now been that it hasn&#8217;t been able to determine whether a backend is healthy or not. This is now a problem of the past! The backend health polling code is available in <a href="http://sourceforge.net/project/showfiles.php?group_id=155816">2.0 beta1</a> Sadly it had a bug, so when using the &#8216;random&#8217; director, it was unable to use the remaining healthy backend if all but one went MIA. I reported this <a href="http://varnish.projects.linpro.no/ticket/306">bug</a> and it was fixed in changeset r3174. </p>
<p>So as of now, you can <strong>safely</strong> use one varnish instance for several front-ends, thus eliminate double-caching (memory waste, unnecessary load on back-ends), reduce network traffic, do rudimentary load balancing, ease management etc.<br />
With the obscene amount of traffic Varnish can push without putting a fairly basic system under any load worth mentioning, you can use a single front-end to serve several nodes in most setups.</p>
<p>Here&#8217;s an elementary sample VCL for how to do this:</p>
<pre>backend node0 {
  .host = "127.0.0.1";
  .port = "80";
  .probe = {
           .url = "/";
           .timeout = 50 ms;
           .interval = 1s;
           .window = 10;
           .threshold = 8;

  }
}

backend node1 {
  .host = "10.0.0.2";
  .port = "80";
  .probe = {
#           .url = "/";
           .timeout = 100 ms;
           .interval = 1s;
           .window = 10;
           .threshold = 8;
        .request =
            "GET /healthcheck.php HTTP/1.1"
            "Host: 10.0.0.2"
            "Connection: close"
            "Accept-Encoding: foo/bar" ;
  }
}
director cl1 random {
    { .backend = node0; .weight = 1; }
    { .backend = node1; .weight = 1; }
}

#director cl1 round-robin {
#   { .backend = node1; }
#   { .backend = node0; }
#}

sub vcl_recv {
        set req.backend = cl1;
}</pre>
<p><br/><br />
As you can see I&#8217;m defining the backends slightly differently. You need to define one of .url or .request, but not both for obvious reasons. If you go for the slighly simpler .url the default request looks like this:</p>
<pre>GET / HTTP/1.1
Host: something
Connection: close
</pre>
<p><br/></p>
<p>If this does not suit your need, comment out .url and use .request to roll your own. This aspect of Varnish is actually quite well documented, so I won&#8217;t repeat what&#8217;s on the <a href="http://varnish.projects.linpro.no/wiki/BackendPolling">trac page</a>.</p>
<p>There is clearly a lot more you can and, more often than not, should do in the VCL than the above. This is a stripped down version which only pertains to the backend polling functionality. </p>
]]></content:encoded>
			<wfw:commentRss>http://northernmost.org/blog/multiple-backends-with-varnish/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>btrfs &#8211; filesystem to end all filesystems?</title>
		<link>http://northernmost.org/blog/btrfs-filesystem-to-end-all-filesystems/</link>
		<comments>http://northernmost.org/blog/btrfs-filesystem-to-end-all-filesystems/#comments</comments>
		<pubDate>Thu, 04 Sep 2008 02:05:31 +0000</pubDate>
		<dc:creator>Erik Ljungstrom</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[Sundry sysadmin]]></category>
		<category><![CDATA[btrfs]]></category>
		<category><![CDATA[crfs]]></category>
		<category><![CDATA[filesystem]]></category>

		<guid isPermaLink="false">http://northernmost.org/blog/?p=83</guid>
		<description><![CDATA[There are some good stuff on the horizon! It&#8217;s called btrfs (&#8220;butter-fs&#8221;). It was originally announced/&#8221;released&#8221; over a year ago by our friends at Oracle and has, in my opinion, not quite received the attention it deserves. I&#8217;m keeping a &#8230; <a href="http://northernmost.org/blog/btrfs-filesystem-to-end-all-filesystems/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There are some good stuff on the horizon! It&#8217;s called <a title="btrfs" href="http://btrfs.wiki.kernel.org/index.php/Main_Page" target="_blank">btrfs</a> (&#8220;butter-fs&#8221;). It was originally announced/&#8221;released&#8221; over a year ago by our friends at Oracle and has, in my opinion, not quite received the attention it deserves. I&#8217;m keeping a close eye on the very intensive devlopment of this as the feature list is very interesting from several aspects. It&#8217;s got some of the big names behind it and will undoubtedly be widely deployed and accepted into the vanilla kernel once stable.</p>
<p>btrfs, like <a href="http://opensolaris.org/os/community/zfs/">ZFS</a>, implements copy-on-write model, so yes &#8211; it will be able to do snapshots! Writeable ones at that. In fact, it&#8217;s got the ability to do snapshots of snapshots! Quasi-MVC filesystem!<br />
COW unfortunately makes a filesystem more prone to fragmentation, but luckily btrfs comes with online defragmentation and fs check abilities. The speed of read and write operations will obviously be impaired during such operations, but there&#8217;s always ways around that in most performance sensitive setups! If not, there should be!<br />
Sadly, COW isn&#8217;t that good of a choice for database workloads. But fret not, COW can be disabled with a mount option (-o nodatacow). This doesn&#8217;t mean you will lose the snapshot ability, as btrfs ignores this option if a data extent is referenced by more than one snapshot, so COW will, as far as I understand, be enabled from that you initiate a snapshot and stay that way until you&#8217;re done with it.</p>
<p>Early <a href="http://oss.oracle.com/projects/btrfs/dist/documentation/benchmark.html">benchmarks</a> show that btrfs is extremely fast at writing, and a little poorer at reading. It will be interesting to see how these numbers change as development proceeds. If added features will have any negative impact on performance. As a side note &#8211; I was quite surprised to see the poor numbers for ext3 in these benchmarks! </p>
<p>So if you&#8217;re a DBA and your data fits in memory, this filesystem will be right up your alley. With a reasonable amount of tables and some proper values for innodb_open_files and table_cache, I wouldn&#8217;t expect any remarkable difference in day-to-day database operation since the real bottleneck usually is in the hardware.<br />
This is generally speaking of course. I&#8217;m sure there are workloads out there which will benefit a lot more than &#8220;the norm&#8221;. Likewise, people with awkward read heavy setups with a lot of data in a lot of files may probably be better off not using btrfs.<br />
If you, like myself, often use blinks of an eye as a unit, you know what I&#8217;m talking about. </p>
<p>Yet another interesting functionality built in is the multiple device support. I will not call it a substitute for proper hardware based RAID, but could well be one for LVM (bearing the snapshots in mind as well)!</p>
<p>Another thing worth keeping an eye on is a related project; <a href="http://oss.oracle.com/projects/crfs/">CRFS</a> which may turn out to be a worthy NFS replacement. While it&#8217;s planned to get failover capabilities, I would much rather have seen a client-agnostic <a href="http://www.danga.com/mogilefs/">MogileFS-</a> style implementation.</p>
<p>Sadly, they are not production ready yet. By far. But it&#8217;s something to look forward to. I&#8217;ll give it a version or two until I will put it under the microscope further and chuck some real world load onto it. Can&#8217;t wait!</p>
]]></content:encoded>
			<wfw:commentRss>http://northernmost.org/blog/btrfs-filesystem-to-end-all-filesystems/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>tooltip &#8211; inotify-tools</title>
		<link>http://northernmost.org/blog/tooltip-inotify-tools/</link>
		<comments>http://northernmost.org/blog/tooltip-inotify-tools/#comments</comments>
		<pubDate>Tue, 26 Aug 2008 21:49:38 +0000</pubDate>
		<dc:creator>Erik Ljungstrom</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[I/O utilization]]></category>
		<category><![CDATA[inotify]]></category>
		<category><![CDATA[inotify-tools]]></category>

		<guid isPermaLink="false">http://northernmost.org/blog/?p=47</guid>
		<description><![CDATA[You can monitor pretty much any file operation, so this tool can be used in a whole range of scenarios. Ever wondered just how many temp files your application creates or? Are you sure it doesn't open and close the file handle for each operation? Do you want to know which file on your website is the most popular download at the moment but can't wait until the webstats crontab has ran? I could go on... <a href="http://northernmost.org/blog/tooltip-inotify-tools/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A nifty tool which might be handy when getting to know a system or tracking down I/O usage is <a href="http://inotify-tools.sourceforge.net/">inotify-tools</a> . It&#8217;s a lightweight interface to the kernel&#8217;s inotify function. It gives a quick overview over which files are accessed and how in any given directory and it&#8217;s subdirectories (if asked to).<br />
It can quickly give an overview of efficiency of caching, frequency of commits, and all sorts of useful information for a whole range of applications. </p>
<p>Here&#8217;s some example output from the inotifywatch utility during a mysqlslap run:</p>
<pre># inotifywatch  /var/lib/mysql/mysqlslap/*
Establishing watches...
Finished establishing watches, now collecting statistics.
total  access  modify  close_write  close_nowrite  open  delete_self  filename
728    450     274     1            0              1     1            /var/lib/mysql/mysqlslap/t1.MYD
241    0       238     1            0              0     1            /var/lib/mysql/mysqlslap/t1.MYI
5      1       0       0            1              1     1            /var/lib/mysql/mysqlslap/t1.frm
2      0       0       0            0              0     1            /var/lib/mysql/mysqlslap/db.opt
.
</pre>
<p>Granted &#8211; as far as MySQL is concerned &#8211; most information is accessible through SHOW GLOBAL STATUS and/or SHOW ENGINE INNODB STATUS commands. But if you for instance have an erratic fear of the key_read_requests variable, you could always look at how often your MYI files are accessed. You catch my drift.. </p>
<p>If you&#8217;re only interested in certain file operations, you can apply filters. If you for instance only have interest in file writes, your run would look like this:</p>
<pre># inotifywatch -e modify -e delete_self /var/lib/mysql/mysqlslap/*
Establishing watches...
Finished establishing watches, now collecting statistics.
total  modify  delete_self  filename
49     47      1            /var/lib/mysql/mysqlslap/t1.MYI
44     42      1            /var/lib/mysql/mysqlslap/t1.MYD
2      0       1            /var/lib/mysql/mysqlslap/db.opt
2      0       1            /var/lib/mysql/mysqlslap/t1.frm
.
</pre>
<p>You can monitor pretty much any file operation, so this tool can be used in a whole range of scenarios. Ever wondered just how many temp files your application creates or? Are you sure it doesn&#8217;t open and close the file handle for each operation? Do you want to know which file on your website is the most popular download at the moment but can&#8217;t wait until the webstats crontab has ran? I could go on&#8230;</p>
<p>inotify-tools come with another utility inotifywait. This tool looks for activity on a specified file or directory and instantly tells you which operation was performed. Nothing amazing, but I can see a few areas of use for that as well, though most of them have tools for that purpose already. </p>
]]></content:encoded>
			<wfw:commentRss>http://northernmost.org/blog/tooltip-inotify-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

