{"id":1748,"date":"2013-05-13T21:12:31","date_gmt":"2013-05-14T02:12:31","guid":{"rendered":"http:\/\/www.kickflop.net\/blog\/?p=1748"},"modified":"2013-05-13T21:12:31","modified_gmt":"2013-05-14T02:12:31","slug":"memory-backed-filesystem-for-temporary-storage-of-whisper-data","status":"publish","type":"post","link":"https:\/\/www.kickflop.net\/blog\/2013\/05\/13\/memory-backed-filesystem-for-temporary-storage-of-whisper-data\/","title":{"rendered":"Memory-backed Filesystem for Temporary Storage of Whisper Data"},"content":{"rendered":"<p>Instead of buying and installing SSDs, storing Graphite&#8217;s whisper files in a memory-backed filesystem can be a good way to go if you have the RAM to spare. Depending on your environment, you may or may not care about losing a few minutes (or hours) of metric data. I know we certainly don&#8217;t care about losing 30 minutes, so there&#8217;s no reason for our carbon-cache instances to be scrawling to persistent storage 24\/7.<!--more--><\/p>\n<p>Here&#8217;s the internal carbon Average Update Time metric showing the switch from writing to spinning disk and then memory. No shocker here:<\/p>\n<p><a href=\"https:\/\/www.kickflop.net\/blog\/wp-content\/uploads\/2013\/05\/tmpfs-graphite-avgUpdateTime.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.kickflop.net\/blog\/wp-content\/uploads\/2013\/05\/tmpfs-graphite-avgUpdateTime.png\" alt=\"tmpfs-graphite-avgUpdateTime\" width=\"509\" height=\"310\" class=\"aligncenter size-full wp-image-1767\" srcset=\"https:\/\/www.kickflop.net\/blog\/wp-content\/uploads\/2013\/05\/tmpfs-graphite-avgUpdateTime.png 509w, https:\/\/www.kickflop.net\/blog\/wp-content\/uploads\/2013\/05\/tmpfs-graphite-avgUpdateTime-300x182.png 300w\" sizes=\"auto, (max-width: 509px) 100vw, 509px\" \/><\/a><\/p>\n<p>Likewise, it&#8217;s no shocker that CPU wait time was greatly reduced. You can see me testing 5 rsyncs from memory-backed filesystem to the old spinning disk in the right of the graph:<\/p>\n<p><a href=\"https:\/\/www.kickflop.net\/blog\/wp-content\/uploads\/2013\/05\/tmpfs-graphite-cpuWait.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.kickflop.net\/blog\/wp-content\/uploads\/2013\/05\/tmpfs-graphite-cpuWait.png\" alt=\"tmpfs-graphite-cpuWait\" width=\"508\" height=\"308\" class=\"aligncenter size-full wp-image-1771\" srcset=\"https:\/\/www.kickflop.net\/blog\/wp-content\/uploads\/2013\/05\/tmpfs-graphite-cpuWait.png 508w, https:\/\/www.kickflop.net\/blog\/wp-content\/uploads\/2013\/05\/tmpfs-graphite-cpuWait-300x181.png 300w\" sizes=\"auto, (max-width: 508px) 100vw, 508px\" \/><\/a><\/p>\n<p>You have 2 commonly found implementation choices for your memory-backed filesystem: tmpfs or a standard RAM disk with non-journaling filesystem applied<\/p>\n<table class=\"table1\">\n<thead>\n<tr>\n<th>&nbsp;<\/th>\n<th>tmpfs<\/th>\n<th>RAM disk<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Create w\/o reboot<\/td>\n<td class=center>yes<\/td>\n<td class=center>no<\/td>\n<\/tr>\n<tr>\n<td>Resize w\/o reboot<\/td>\n<td class=center>yes<\/td>\n<td class=center>no<\/td>\n<\/tr>\n<tr>\n<td>Dynamically allocated<\/td>\n<td class=center>yes<\/td>\n<td class=center>no<\/td>\n<\/tr>\n<tr>\n<td>Can be swapped<\/td>\n<td class=\"center red\">yes<\/td>\n<td class=center>no<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>tmpfs<\/h2>\n<p>The Linux <code>tmpfs<\/code> implementation would look something like the following.<\/p>\n<ol>\n<li>Stop your carbon-cache services, then:\n<pre>\r\ncd \/opt\/graphite\/storage\r\nmv whisper whisper.permanent\r\nmkdir whisper.ephemeral\r\nln -s .\/whisper.ephemeral .\/whisper\r\n\r\necho 0 > \/proc\/sys\/vm\/swappiness\r\n\r\nmount -t tmpfs -o size=5g tmpfs \/opt\/graphite\/storage\/whisper.ephemeral\r\n<\/pre>\n<\/li>\n<li>Add the following, modified to suit, to your <code>\/etc\/rc.local<\/code> or other preferred boot-time mechanism:\n<pre>\r\nmount -t tmpfs -o size=5g tmpfs \/opt\/graphite\/storage\/whisper.ephemeral\r\n<\/pre>\n<\/li>\n<li>One-way synchronize the persistent storage with the state of the ephemeral storage every 30 minutes:\n<pre>\r\n*\/30 * * * * rsync --archive \/opt\/graphite\/storage\/whisper.ephemeral\/ \/opt\/graphite\/storage\/whisper.permanent\r\n<\/pre>\n<\/li>\n<\/ol>\n<h2>Explicit RAM disk<\/h2>\n<p>To implement the more predictable RAM disk setup, you would:<\/p>\n<ol>\n<li>Add <code>ramdisk_size=N<\/code> (where N is the size of the RAM disk you want specified in KB) to the <code>kernel<\/code> line in <code>grub.conf<\/code> for your distribution. Reboot.<\/li>\n<li>Create a filesystem on the RAM disk device and mount it. You pointedly do not want to waste efficiency by using a journaling filesystem here, so use an <code>ext2<\/code> filesystem and do not reserve any &#8220;minfree&#8221; space.\n<pre>\r\ncd \/opt\/graphite\/storage\r\nmv whisper whisper.permanent\r\nmkdir whisper.ephemeral\r\nln -s .\/whisper.ephemeral .\/whisper\r\n\r\nmkfs.ext2 -m 0 \/dev\/ram0\r\nmount \/dev\/ram0 \/opt\/graphite\/storage\/whisper.ephemeral\r\n<\/pre>\n<\/li>\n<li>Add the following, modified to suit, to your <code>\/etc\/rc.local<\/code> or other preferred boot-time mechanism:\n<pre>\r\nmkfs.ext2 -m 0 \/dev\/ram0\r\nmount \/dev\/ram0 \/opt\/graphite\/storage\/whisper.ephemeral\r\n<\/pre>\n<\/li>\n<li>One-way synchronize the persistent storage with the state of the ephemeral storage every 30 minutes:\n<pre>\r\n*\/30 * * * * rsync --archive \/opt\/graphite\/storage\/whisper.ephemeral\/ \/opt\/graphite\/storage\/whisper.permanent\r\n<\/pre>\n<\/li>\n<\/ol>\n<p>As always, I welcome your thoughts.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Instead of buying and installing SSDs, storing Graphite&#8217;s whisper files in a memory-backed filesystem can be a good way to&hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[51,35,11,48],"tags":[],"class_list":["post-1748","post","type-post","status-publish","format-standard","hentry","category-devops","category-linux","category-sysadmin","category-unixlinux"],"_links":{"self":[{"href":"https:\/\/www.kickflop.net\/blog\/wp-json\/wp\/v2\/posts\/1748","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kickflop.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kickflop.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kickflop.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kickflop.net\/blog\/wp-json\/wp\/v2\/comments?post=1748"}],"version-history":[{"count":10,"href":"https:\/\/www.kickflop.net\/blog\/wp-json\/wp\/v2\/posts\/1748\/revisions"}],"predecessor-version":[{"id":1773,"href":"https:\/\/www.kickflop.net\/blog\/wp-json\/wp\/v2\/posts\/1748\/revisions\/1773"}],"wp:attachment":[{"href":"https:\/\/www.kickflop.net\/blog\/wp-json\/wp\/v2\/media?parent=1748"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kickflop.net\/blog\/wp-json\/wp\/v2\/categories?post=1748"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kickflop.net\/blog\/wp-json\/wp\/v2\/tags?post=1748"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}