<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Pradeep Banavara</title>
    <description>The latest articles on Forem by Pradeep Banavara (@pbanavara).</description>
    <link>https://forem.com/pbanavara</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F364357%2F6753a4fb-56f8-46f9-816f-fa6c022ead20.jpeg</url>
      <title>Forem: Pradeep Banavara</title>
      <link>https://forem.com/pbanavara</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/pbanavara"/>
    <language>en</language>
    <item>
      <title>Aerospike REST client</title>
      <dc:creator>Pradeep Banavara</dc:creator>
      <pubDate>Wed, 22 Jul 2020 16:44:31 +0000</pubDate>
      <link>https://forem.com/aerospike/aerospike-rest-client-3kk0</link>
      <guid>https://forem.com/aerospike/aerospike-rest-client-3kk0</guid>
      <description>&lt;p&gt;It is fairly well known that Aerospike is synonymous with speed and ultra low latency. While our server holds this badge, many a times, during end-end application development there is this myth that some of our clients are slow especially those written in interpreted languages Python/Ruby etc.&lt;/p&gt;

&lt;p&gt;Now, I am a huge fan of Python and it's my go to language for any web application. So I am bound to defend this and also demonstrate that you don't actually have to use a language specific client. Aerospike offers a &lt;a href="https://www.aerospike.com/docs/client/rest/"&gt;REST client&lt;/a&gt;. Technically this is a full fledged backend, the name is kind of a misnomer as it runs a Spring Boot application under the hood. &lt;/p&gt;

&lt;p&gt;Let's take a typical use case - Push JSON data to a datastore. For example this is the data from my front end/mobile app that I need to persist.&lt;br&gt;
&lt;code&gt;{"name": "xyz", "id", 23234, "email": "blah@blah.com"}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The traditional way to do this is to write a backend or use one of the serverless frameworks or use a platform such as Firebase. &lt;/p&gt;

&lt;p&gt;I have written a simple web backend using a state of the art Python web framework &lt;a href="https://fastapi.tiangolo.com/"&gt;FastAPI&lt;/a&gt; that stores this JSON into Aerospike using a key.&lt;/p&gt;

&lt;p&gt;This took less than 10 minutes to write but a better alternative is to just use the REST client. This is why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplicity - You just run a jar file and that's it.&lt;/li&gt;
&lt;li&gt;Full suite of APIs - The REST client is &lt;a href="https://www.aerospike.com/docs/guide/client_matrix.html"&gt;on par&lt;/a&gt; with all other client libraries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ok, with that, let's do a simple benchmark.&lt;/p&gt;
&lt;h4&gt;
  
  
  Setup
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Install the Aerospike python client. &lt;code&gt;pip install aerospike&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run Aerospike db as a Docker container on interface 0.0.0.0. Here is my previous &lt;a href="https://dev.to/aerospike/getting-started-with-aerospike-on-docker-532f"&gt;blog post&lt;/a&gt; on how to accomplish that&lt;/li&gt;
&lt;li&gt;Download the latest &lt;a href="https://www.aerospike.com/download/client/rest/latest"&gt;Aerospike REST client&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Have Java 8 or higher on the machine and we are all set.&lt;/li&gt;
&lt;li&gt;Download and install &lt;a href="https://httpd.apache.org/docs/2.4/programs/ab.html"&gt;Apache bench&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Comparisons and benchmarks with AB
&lt;/h4&gt;

&lt;p&gt;The Python FastAPI server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;aerospike&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Aerospike connection client
&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hosts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aerospike&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/v1/kvs/{namespace}/{set_name}/{key}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;set_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    The API signature matches the Aerospike REST client&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;user_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;set_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;record&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/v1/kvs/{namespace}/{set_name}/{key}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;post_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;set_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;user_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;set_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the REST client&lt;br&gt;
&lt;code&gt;java -jar as-rest-client-1.5.0.jar --aerospike.restclient.hostname=0.0.0.0'&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  AB results
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://youtu.be/nv4VxHnVFhY"&gt;Uvicorn Benchmark Screencast&lt;/a&gt;&lt;br&gt;
&lt;a href="https://youtu.be/xgaxjvt8nik"&gt;REST Benchmark Screencast&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not surprisingly both of these have similar benchmarks about &lt;code&gt;2700 rps&lt;/code&gt;. One might run Uvicorn with just 1 worker thread and dismiss Python as slow, but that's not correct. To compensate for Java's multithreading the least we can do is run as many workers as the number of cores. Since my machine has 8 cores I chose 8 workers and the results are more or less the same.&lt;/p&gt;

&lt;p&gt;One key difference is that because we are starting multiple processes each of these will open a separate connection to Aerospike. The issue with this is that each process has a client, each client opens its own connections. Without tuning, those connections can swamp the server. &lt;/p&gt;

&lt;p&gt;It's far more efficient to share fewer clients, as the REST server does. In fact, this was one of the guiding principles behind developing the REST client.&lt;/p&gt;

&lt;p&gt;In addition, the amount of time spent on writing the Python application is totally saved if you choose the REST client route.&lt;/p&gt;

&lt;p&gt;I've found the REST client to be a great alternative to writing your own backend for storing data in Aerospike.&lt;/p&gt;

&lt;p&gt;The REST client also offers predicate filtering abilities out of the box which is very helpful. A two part blog series on that topic can be found &lt;a href="https://dev.to/aerospike/dealing-with-predicate-expression-filters-in-aerospike-rest-client-part-1-3njl"&gt;here&lt;/a&gt; and &lt;a href="https://dev.to/aerospike/dealing-with-predicate-expression-filters-in-aerospike-rest-client-part-2-58m9"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Next steps
&lt;/h4&gt;

&lt;p&gt;An Aerospike Docker container with the REST client. This all in one container will be ready to use and saves all the Java and dependencies installation time.&lt;/p&gt;

</description>
      <category>aerospike</category>
    </item>
    <item>
      <title>Getting started with Aerospike on Docker</title>
      <dc:creator>Pradeep Banavara</dc:creator>
      <pubDate>Thu, 04 Jun 2020 14:39:34 +0000</pubDate>
      <link>https://forem.com/aerospike/getting-started-with-aerospike-on-docker-532f</link>
      <guid>https://forem.com/aerospike/getting-started-with-aerospike-on-docker-532f</guid>
      <description>&lt;p&gt;I joined &lt;a href="https://www.aerospike.com"&gt;Aerospike&lt;/a&gt; around mid March just before the Covid lockdown went into effect. Call me fortunate. I was super excited to learn everything about Aerospike and wanted to get my hands dirty as quickly as possible. Somehow, the 'quickly' aspect did turn out to be that quick.&lt;/p&gt;

&lt;p&gt;Fast forward to May and our &lt;a href="https://www.aerospike.com/summit/"&gt;annual summit&lt;/a&gt; was going live, virtually of course. I got the opportunity to present a talk on Docker. I thought of putting some of that talk content here in a blog, so that other developers who are keen on getting started with Aerospike can do so in less than 5 minutes using Docker, and of course Markdown.&lt;/p&gt;

&lt;h5&gt;
  
  
  Why Docker
&lt;/h5&gt;

&lt;p&gt;Containers revolutionized shipping when they came about. The container standard established one size package to transport goods globally. This led to at least a 100x improvement in logistics speed and probably saved billions of dollars in transporting costs.&lt;/p&gt;

&lt;p&gt;Software containers are unleashing a similar revolution in deploying and distributing software applications. Regardless of what environment the container will be shipped to, a developer can be certain that the software they have packaged in that container will execute successfully. Compare this to almost always ending up in 'the application runs fine on my laptop, probably it's an environment problem'. &lt;/p&gt;

&lt;p&gt;Docker is now the most widely used and deployed container platform, even though &lt;a href="https://mesos.apache.org"&gt;Mesos&lt;/a&gt; was the first container platform. So let's see how to get started with Aerospike on Docker.&lt;/p&gt;

&lt;p&gt;Once you have Docker installed, the absolute simplest way to run Aerospike in a container is to just run this command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d --name aerospike -p 3000:3000 -p 3001:3001 -p 3002:3002 -p 3003:3003 aerospike
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to check if this container started or not. So we use &lt;code&gt;docker ps&lt;/code&gt; to do that and if everything went well, the response we see is this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                              NAMES
ff7482742691        aerospike           "/entrypoint.sh asd"   3 seconds ago       Up 3 seconds        0.0.0.0:3000-3003-&amp;gt;3000-3003/tcp   aerospike
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it, we have Aerospike running. This is accessible on the host machine from the 0.0.0.0 address and port 3000.&lt;/p&gt;

&lt;p&gt;To stop the container &lt;code&gt;docker stop ff7482742691&lt;/code&gt; and again to start the container &lt;code&gt;docker start ff7482742691&lt;/code&gt;. There is no need to use the 'docker run' command. &lt;a href="https://docs.docker.com/engine/reference/run/"&gt;docker run&lt;/a&gt; pulls the respective image from the Docker hub. Once that happens, the image is available locally. Just start and stop commands suffice from here.&lt;/p&gt;

&lt;p&gt;To quickly use the database, we can run the &lt;code&gt;aerospike-tools&lt;/code&gt; image and use the command line client &lt;code&gt;aql&lt;/code&gt; to connect to this container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -ti aerospike/aerospike-tools:latest aql -h  $(docker inspect -f '{{.NetworkSettings.IPAddress }}' aerospike)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we are running another container, we need to connect to the interface of the &lt;code&gt;aerospike&lt;/code&gt; container and not &lt;code&gt;0.0.0.0&lt;/code&gt;. This is the beauty of containers. There is no scope for confusion about 'which interface is this container running on' especially when you have multiple interfaces. Once you are connected, you will get the AQL prompt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Seed:         172.17.0.2
User:         None
Config File:  /etc/aerospike/astools.conf /root/.aerospike/astools.conf
Aerospike Query Client
Version 3.26.2
C Client Version 4.6.15
Copyright 2012-2020 Aerospike. All rights reserved.
aql&amp;gt; select * from test.demo
0 rows in set (0.248 secs)

OK

aql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the default container, Aerospike runs in the RAM with a file backup. If we look at the &lt;a href="https://github.com/aerospike/aerospike-server.docker/blob/master/Dockerfile"&gt;Dockerfile&lt;/a&gt; for Aerospike, the image uses a default &lt;a href="https://github.com/aerospike/aerospike-server.docker/blob/master/aerospike.template.conf"&gt;configuration file&lt;/a&gt; which specifies this mode in the namespace configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace ${NAMESPACE} {
    replication-factor ${REPL_FACTOR}
    memory-size ${MEM_GB}G
    default-ttl ${DEFAULT_TTL} # 5 days, use 0 to never expire/evict.
    nsup-period ${NSUP_PERIOD}
    #   storage-engine memory

    # To use file storage backing, comment out the line above and use the
    # following lines instead.

    storage-engine device {
        file /opt/aerospike/data/${NAMESPACE}.dat
        filesize ${STORAGE_GB}G
        data-in-memory true # Store data in memory in addition to file.
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While Aerospike runs fine in this mode and is good for reasonable workloads, it's best to run Aerospike on block SSD devices to get the best of latency and persistence. &lt;/p&gt;

&lt;h5&gt;
  
  
  Aerospike hybrid mode on Docker
&lt;/h5&gt;

&lt;p&gt;This is best done tried on a public cloud infrastructure such as AWS because it is super simple to get a &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-creating-volume.html"&gt;new SSD volume&lt;/a&gt; and use it as a raw block device.&lt;br&gt;
Once we have a new device attached to a EC2 linux VM (which has docker installed of course) we can map that volume to be used inside the container like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -tid --name aerospike -p 3000:3000 -p 3001:3001 -p 3002:3002 -p 3003:3003 -v /opt:/opt/aerospike/etc --device '/dev/xvdf:/dev/xvdf' aerospike/aerospike-server:latest asd --config-file /opt/aerospike/etc/aerospike.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configuration section specific to the device is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace test {
        replication-factor 2
        memory-size 1G
        storage-engine device {
                device /dev/xvdf
                write-block-size 128k
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;/dev/xvdf&lt;/code&gt; is the new device volume, &lt;code&gt;/opt&lt;/code&gt; is the host location where the config file is stored. This is mapped to &lt;code&gt;/opt/aerospike/etc&lt;/code&gt; inside the container.&lt;/p&gt;

&lt;p&gt;With that, Aerospike is now running inside a Docker container in hybrid mode.&lt;/p&gt;

&lt;p&gt;Yet, Aerospike is still running on a single node. Of what good is this, when the real power of Aerospike is in horizontal scaling to hundreds of nodes. The word scaling immediately sets off a few bells - Kubernetes, Docker swarm etc. While these are the best options to scale software, they have a high initial learning curve. Does that mean we have to sacrifice on exploring Aerospike's clustering abilities.&lt;/p&gt;

&lt;p&gt;Absolutely not. In fact it is very straightforward to setup a &lt;a href="https://dev.to/aerospike/how-do-i-get-a-2-nodes-aerospike-cluster-running-quickly-in-docker-without-editing-a-single-file-2bnj"&gt;cluster&lt;/a&gt; on the same host machine. &lt;/p&gt;

&lt;p&gt;In fact, one can run as many Aerospike containers as the host machine hardware can accommodate. So it is very feasible to run a 3 or 5 node cluster.&lt;/p&gt;

&lt;p&gt;At this point, one can test Aerospike in either &lt;a href="https://www.aerospike.com/docs/architecture/clustering.html"&gt;AP&lt;/a&gt; or &lt;a href="https://www.aerospike.com/docs/architecture/consistency.html"&gt;SC&lt;/a&gt; mode.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
