<?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>Blog Archives - Albert Nogués</title>
	<atom:link href="https://www.albertnogues.com/category/blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.albertnogues.com/category/blog/</link>
	<description>Data and Cloud Freelancer</description>
	<lastBuildDate>Sun, 12 May 2024 16:01:13 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.albertnogues.com/wp-content/uploads/2020/12/cropped-cropped-AlbertLogo2-32x32.png</url>
	<title>Blog Archives - Albert Nogués</title>
	<link>https://www.albertnogues.com/category/blog/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Unload data from AWS Redshift to S3 in Parquet</title>
		<link>https://www.albertnogues.com/unload-data-from-aws-redshift-to-s3-in-parquet/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=unload-data-from-aws-redshift-to-s3-in-parquet</link>
		
		<dc:creator><![CDATA[Albert]]></dc:creator>
		<pubDate>Thu, 31 Dec 2020 09:59:14 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[BigData]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[parquet]]></category>
		<category><![CDATA[redshift]]></category>
		<category><![CDATA[s3]]></category>
		<category><![CDATA[snappy]]></category>
		<category><![CDATA[unload]]></category>
		<guid isPermaLink="false">http://192.168.1.40/?p=1007</guid>

					<description><![CDATA[<p>Following the previous redshift articles in this one I will explain how to export data from redshift to parquet in s3. This can be interesting when we want to archive (infrequently queried) data to be queried cheaper with spectrum, or to store in s3 archive, or to export to another storage solution like glacier. The &#8230; </p>
<p>The post <a href="https://www.albertnogues.com/unload-data-from-aws-redshift-to-s3-in-parquet/">Unload data from AWS Redshift to S3 in Parquet</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Following the previous redshift articles in this one I will explain how to export data from redshift to parquet in s3. This can be interesting when we want to archive (infrequently queried) data to be queried cheaper with spectrum, or to store in s3 archive, or to export to another storage solution like glacier.</p>



<p>The first thing we need to do is to modify our redshift cluster iam role to allow write to s3. We go to our cluster in the redshift panel, we click on properties, and then we will see the link to the iam role attached to the cluster. we click on it and it will open the IAM role page.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="183" src="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet1-1024x183.png" alt="" class="wp-image-1008" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet1-1024x183.png 1024w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet1-300x54.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet1-768x137.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet1-1536x275.png 1536w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet1-336x60.png 336w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet1.png 1628w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Then we add the policy named AmazonS3ReadOnlyAccess as shown in the following pic:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="329" height="143" src="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet2.png" alt="" class="wp-image-1009" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet2.png 329w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet2-300x130.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet2-138x60.png 138w" sizes="(max-width: 329px) 100vw, 329px" /></figure>



<p>And with this we already have all the required permissions ready. The next step now is to make sure we have an available s3 bucket. I&#8217;ve created one for the demo purposes with a folder called parquet_exports.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="889" height="422" src="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet3.png" alt="" class="wp-image-1010" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet3.png 889w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet3-300x142.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet3-768x365.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet3-126x60.png 126w" sizes="(max-width: 889px) 100vw, 889px" /></figure>



<p>For starting the extraction, we will use the customers table we used in the previous articles. This table was loaded as well from the TPC-DS test data from s3 in a gzip file but now it sits inside our redshift node. The instruction to unload the data is called <a rel="noreferrer noopener" href="https://docs.aws.amazon.com/es_es/redshift/latest/dg/r_UNLOAD.html" data-type="URL" data-id="https://docs.aws.amazon.com/es_es/redshift/latest/dg/r_UNLOAD.html" target="_blank">UNLOAD</a> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>Since we want our data in parquet + snappy format, which is usually the recommended way (avro is not supported in redshift UNLOAD, only CSV and parquet), we need to express it in the unload statement.</p>



<p>Contrary to spectrum, here we can unload data to buckets in another region. So if thats your need make sure you fill the bucket region as well in the unload statement. The statement is as follows</p>



<pre class="wp-block-code"><code>UNLOAD ('<em>select-statement</em>')
TO '<em>s3://object-path/name-prefix</em>'
<em>authorization</em>
&#91; <em>option</em> &#91; ... ] ]

where <em>option</em> is
{ &#91; FORMAT &#91; AS ] ] CSV | PARQUET
| PARTITION BY ( <em>column_name</em> &#91;, ... ] ) &#91; INCLUDE ]
| MANIFEST &#91; VERBOSE ] 
| HEADER           
| DELIMITER &#91; AS ] '<em>delimiter-char</em>' 
| FIXEDWIDTH &#91; AS ] '<em>fixedwidth-spec</em>'   
| ENCRYPTED &#91; AUTO ]
| BZIP2  
| GZIP 
| ZSTD
| ADDQUOTES 
| NULL &#91; AS ] '<em>null-string</em>'
| ESCAPE
| ALLOWOVERWRITE
| PARALLEL &#91; { ON | TRUE } | { OFF | FALSE } ]
| MAXFILESIZE &#91;AS] <em>max-size</em> &#91; MB | GB ] 
| REGION &#91;AS] 'aws-region' }</code></pre>



<p>As you can see, it allows to pass a select statement instead of a table name. This way we can project the required columns and there is no need to export the whole table if we do not need it. We can also specify the max filesize. Usually with parquet 256 MB is a good split size. And make sure with Parquet not to specify any compression format as otherwise it will crash, as by default redshift already compresses it with Snappy.</p>



<p>To run the export we also need to fetch the arn of our redshift role, and incliude it just after the bucket path:</p>



<pre class="wp-block-code"><code>UNLOAD ('select * from customer')
TO 's3://albertnogues-parquet/parquet_exports/'
iam_role 'arn:aws:iam::742123541312:role/Redshift_Albertnogues.com'
FORMAT AS PARQUET
MAXFILESIZE 256 MB</code></pre>



<p>After about two minutes, the query finished sucessfully. We can go to our s3 bucket to see the parquet files there and check that the split file size is the one we requested</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="430" src="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet4-1024x430.png" alt="" class="wp-image-1011" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet4-1024x430.png 1024w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet4-300x126.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet4-768x322.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet4-1536x644.png 1536w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet4-143x60.png 143w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet4.png 1664w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>We can check first the size of the table in redshift with the following query:</p>



<pre class="wp-block-code"><code>SELECT "table", tbl_rows, size size_in_MB FROM SVV_TABLE_INFO
order by 1</code></pre>



<figure class="wp-block-table"><table><tbody><tr><td><strong>Table</strong></td><td><strong>Num Rows</strong></td><td><strong>Size (MB)</strong></td></tr><tr><td>customer</td><td>30.000.000</td><td>2098</td></tr></tbody></table></figure>



<p>So its quite clear that the export looks ok as the size is similar. We can now download one fo the parquet files and inspect it with some parquet tool analyzer. I tend to use the python version of parquet-tools based on apache arrow project. You can install it with:</p>



<pre class="wp-block-code"><code>pip install parquet-tools</code></pre>



<p>And then we will inspect the file with the following:</p>



<pre class="wp-block-code"><code>parquet-tools inspect 0001_part_03.parquet</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="627" height="620" src="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet5.png" alt="" class="wp-image-1012" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet5.png 627w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet5-300x297.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet5-61x60.png 61w" sizes="auto, (max-width: 627px) 100vw, 627px" /></figure>



<p>And if we scroll down a little bit we can see the total number of files on our parquet file:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="531" height="614" src="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet6.png" alt="" class="wp-image-1013" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet6.png 531w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet6-259x300.png 259w, https://www.albertnogues.com/wp-content/uploads/2020/12/RedsiftParquet6-52x60.png 52w" sizes="auto, (max-width: 531px) 100vw, 531px" /></figure>
<p>The post <a href="https://www.albertnogues.com/unload-data-from-aws-redshift-to-s3-in-parquet/">Unload data from AWS Redshift to S3 in Parquet</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Use Redshift Spectrum to query infrequently used data on S3</title>
		<link>https://www.albertnogues.com/use-redshift-spectrum-to-query-infrequently-used-data-on-s3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=use-redshift-spectrum-to-query-infrequently-used-data-on-s3</link>
		
		<dc:creator><![CDATA[Albert]]></dc:creator>
		<pubDate>Wed, 30 Dec 2020 11:14:01 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[BigData]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[datawarehousing]]></category>
		<category><![CDATA[redshift]]></category>
		<category><![CDATA[spectrum]]></category>
		<guid isPermaLink="false">http://192.168.1.40/?p=994</guid>

					<description><![CDATA[<p>Redshift spectrum lets us to query data in s3 buckets using redshift. This scenario is specially interesting in large datawarehouses with data that we do not need to query often but it may be nevessary from time to time to run some of our queries. In this situation, probably we dont want the data to &#8230; </p>
<p>The post <a href="https://www.albertnogues.com/use-redshift-spectrum-to-query-infrequently-used-data-on-s3/">Use Redshift Spectrum to query infrequently used data on S3</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Redshift spectrum lets us to query data in s3 buckets using redshift. This scenario is specially interesting in large datawarehouses with data that we do not need to query often but it may be nevessary from time to time to run some of our queries. In this situation, probably we dont want the data to be loaded into our redshift cluster as this may push us to provision larger redshift clusters that the ones we need for procession our usual queries (take into account that redshift clusters are set with specific cpu, ram and space and they can not be totally tailored to our needs, so only few combinations are available)</p>



<p>There are a few requirements however to be able to use redshift spectrum. First, the data loaded will be like an external table in other systems (RDBMS) or like hive external tables. So this means that we can forget about updating or deleting our data. We will only get read only capability, but usually thats we are looking for (think in historical data from already closed exercices, archived data and so on), where the cost of storing it in s3 even in a cool tier can ve several orders of magnitude cheaper than keeping it inside redshift.</p>



<p>There are other technical limitations tough. For example, <strong>the s3 bucket has to be in the same region as our redshift cluster</strong>, so plan in advance or move the data to another s3 bucket. There are other requirements like permissions and so on, you can read it <a rel="noreferrer noopener" href="https://docs.aws.amazon.com/redshift/latest/dg/c-using-spectrum.html" data-type="URL" data-id="https://docs.aws.amazon.com/redshift/latest/dg/c-using-spectrum.html" target="_blank">here</a>.</p>



<p>Before starting we need to attach a role to our redshift cluster that grants access to read s3 buckets. If you followed my previous article on redshift you will already have this role, otherwise check how to do it <a href="https://www.albertnogues.com/load-data-from-s3-and-run-tpc-ds-queries-on-amazon-redshift/" data-type="URL" data-id="https://www.albertnogues.com/load-data-from-s3-and-run-tpc-ds-queries-on-amazon-redshift/">here</a>.</p>



<p>If you followed my previous article, apart of the s3 read only permisison, you need to add the glue catalog permission to create a table. For this, modify the role (or if you&#8217;re creating a new one, add the following permission: <code>AWSGlueConsoleFullAccess</code></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="633" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum0-1024x633.png" alt="" class="wp-image-997" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum0-1024x633.png 1024w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum0-300x185.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum0-768x475.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum0-97x60.png 97w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum0.png 1031w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>For the sake of this exercise I&#8217;ve load part of the TPC-DS customer data into a s3 bucket i made public on the Paris region. Then we will create an external customer table pointing to the data in the bucket (which is in fact compressed in gz) and we will query that data from redshift.</p>



<p>Once the bucket data is loaded, we are ready to go back to our redshift cluster. I&#8217;ve used <a href="https://redshift-downloads.s3.amazonaws.com/TPC-DS/2.13/3TB/customer/customer_1_14.dat.gz" data-type="URL" data-id="https://redshift-downloads.s3.amazonaws.com/TPC-DS/2.13/3TB/customer/customer_1_14.dat.gz" target="_blank" rel="noreferrer noopener">this file</a> for the tests. We will create an external schema and an external customers table. For this we need first to copy the arn of the role we created with the s3 read access. To get that let&#8217;s go to our cluster, then click on properties and later on click in Copy Amazon Resource Name (ARN):</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="383" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum1-1024x383.png" alt="" class="wp-image-996" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum1-1024x383.png 1024w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum1-300x112.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum1-768x287.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum1-1536x574.png 1536w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum1-161x60.png 161w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum1.png 1787w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Once we have the arn of our role, then run the folloowing in your editor. It will create the external schema in a new spectrum database (feel free to choose any other database name if you need)</p>



<pre class="wp-block-code"><code>create external schema spectrum_albertnogues 
from data catalog 
database 'spectrum' 
iam_role 'arn:aws:iam::742123541312:role/Redshift_Albertnogues.com'
create external database if not exists;</code></pre>



<p>Then we are ready to create our external table:</p>



<pre class="wp-block-code"><code>create external table spectrum_albertnogues.customer
(
  c_customer_sk int4,                 
  c_customer_id char(16),             
  c_current_cdemo_sk int4 ,   
  c_current_hdemo_sk int4 ,   
  c_current_addr_sk int4 ,    
  c_first_shipto_date_sk int4 ,                 
  c_first_sales_date_sk int4 ,
  c_salutation char(10) ,     
  c_first_name char(20) ,     
  c_last_name char(30) ,      
  c_preferred_cust_flag char(1) ,               
  c_birth_day int4 ,          
  c_birth_month int4 ,        
  c_birth_year int4 ,         
  c_birth_country varchar(20) ,                 
  c_login char(13) ,          
  c_email_address char(50) ,  
  c_last_review_date_sk int4
)
row format delimited
fields terminated by '|'
stored as textfile
location 's3://redshift-spectrum-albertnogues/customers/';</code></pre>



<p>As you can see it&#8217;s not really 100% the same customers table from the TPC-DS data. This is because external tables do not support primary keys, not null syntax and some other keywords that do not make sense in external tables. Make sure you used the right separator and selected the right format of data (compression is determined by the file extension).</p>



<p>Then, as you will see the table creation takes virtually nothing. This is because in fact, the data is not loaded, its only a shortcut to our s3 data. But to make sure it&#8217;s working we can run a few queries to our new table:</p>



<pre class="wp-block-code"><code>select count(*) from spectrum_albertnogues.customer;</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="448" height="163" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum2.png" alt="" class="wp-image-998" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum2.png 448w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum2-300x109.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum2-165x60.png 165w" sizes="auto, (max-width: 448px) 100vw, 448px" /></figure>



<p>And to make sure data is properly loaded, we can query it as well:</p>



<pre class="wp-block-code"><code>select * from spectrum_albertnogues.customer LIMIT 5;</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="189" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum3-1024x189.png" alt="" class="wp-image-999" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum3-1024x189.png 1024w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum3-300x55.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum3-768x142.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum3-324x60.png 324w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum3.png 1238w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>As a last example, if you run my previous blog post on redshift, we can now join our new external customers table with our web returns fact table, to see how many objects these users returned depending on their origin country, to see if there is any pattern or not.</p>



<pre class="wp-block-code"><code>select c_birth_country as customer_birth_country, sum(wr_return_quantity) as qty_returned_total
 from web_returns,
      date_dim,
     spectrum_albertnogues.customer
 where wr_returned_date_sk = d_date_sk 
   and d_year =2002
   and wr_returning_customer_sk = c_customer_sk
 group by c_birth_country
 order by 2 desc;</code></pre>



<p>Of course the query should take a bit more since the data is not inside redshift, and needs to be fetched from s3 but we can get our output quite fast and easily:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="709" height="547" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum4.png" alt="" class="wp-image-1000" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum4.png 709w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum4-300x231.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Spectrum4-78x60.png 78w" sizes="auto, (max-width: 709px) 100vw, 709px" /></figure>



<p>Thats it!. For more advanced topics like performance improvements when querying from s3 and others, you can read <a rel="noreferrer noopener" href="https://docs.aws.amazon.com/redshift/latest/dg/c-spectrum-external-performance.html" data-type="URL" data-id="https://docs.aws.amazon.com/redshift/latest/dg/c-spectrum-external-performance.html" target="_blank">here</a> and <a href="https://blog.openbridge.com/10-simple-tips-that-help-you-quickly-find-success-adopting-amazon-redshift-spectrum-810db089abbe" data-type="URL" data-id="https://blog.openbridge.com/10-simple-tips-that-help-you-quickly-find-success-adopting-amazon-redshift-spectrum-810db089abbe" target="_blank" rel="noreferrer noopener">here</a>. I recommend basically partitioning, a splittable file format like parquet compressed with snappy or some other codec, small files (but not very small), add as many filers as you can to avoid retrieving unnecesary data, and if you use a columnar format like parquet, you will avoid fetching unused columns in your select statement. This is important (and can have a huge impact in costs) because now it&#8217;s the time of discussing the price of all this.</p>



<p>Bear in mind that <strong>AWS charges 5 dollars for each Terabyte of data scanned from s3 with spectrum</strong>, so make sure you do the right usage on this (only data infrequently queried) and do not overestimate these charges as they grew quickly.</p>



<p>For expert advice or project requests you can contact me <a rel="noreferrer noopener" href="https://www.albertnogues.com/contact/" data-type="URL" data-id="https://www.albertnogues.com/contact/" target="_blank">here</a>. Happy Querying!</p>
<p>The post <a href="https://www.albertnogues.com/use-redshift-spectrum-to-query-infrequently-used-data-on-s3/">Use Redshift Spectrum to query infrequently used data on S3</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Load data from s3 and run TPC-DS queries on amazon Redshift.</title>
		<link>https://www.albertnogues.com/load-data-from-s3-and-run-tpc-ds-queries-on-amazon-redshift/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=load-data-from-s3-and-run-tpc-ds-queries-on-amazon-redshift</link>
		
		<dc:creator><![CDATA[Albert]]></dc:creator>
		<pubDate>Tue, 29 Dec 2020 12:49:50 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[BigData]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://192.168.1.40/?p=969</guid>

					<description><![CDATA[<p>In this article we will see how to provision a redshift cluster, load some large quantity of data from s3 and run a query to see the contents and check performance. I plan to write a serie of articles arround data warehousing in the cloud so check out for new articles where i will do &#8230; </p>
<p>The post <a href="https://www.albertnogues.com/load-data-from-s3-and-run-tpc-ds-queries-on-amazon-redshift/">Load data from s3 and run TPC-DS queries on amazon Redshift.</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In this article we will see how to provision a redshift cluster, load some large quantity of data from s3 and run a query to see the contents and check performance. I plan to write a serie of articles arround data warehousing in the cloud so check out for new articles where i will do someting similar but from Synapse, Snowflake and Databricks Delta.</p>



<p>I&#8217;ve split the article in 4 steps that cover diverse topics:</p>



<ul class="wp-block-list"><li>Part 1. Deploying a redshift cluster.</li><li>Part 2. Load TPC-DS data.</li><li>Part 3. Run queries to verify the performance.</li><li>Part 4. Performance tricks.</li></ul>



<ol class="wp-block-list"><li>Deploying a redshift cluster</li></ol>



<p>As always with cloud providers, we have many ways to deploy resources. We can use the native tools (aws cli) or the portal, or we can use some external software, like <a href="https://www.albertnogues.com/deploying-and-interacting-with-an-azure-storage-account-and-a-queue-with-terraform-and-python-part-i/" data-type="URL" data-id="https://www.albertnogues.com/deploying-and-interacting-with-an-azure-storage-account-and-a-queue-with-terraform-and-python-part-i/">terraform</a>.</p>



<p>For this example we will go through the aws portal as we only plan to create one for test purposes. If you never created one, there is a promotion on aws that let&#8217;s you to create a <a rel="noreferrer noopener" href="https://aws.amazon.com/es/redshift/free-trial/" data-type="URL" data-id="https://aws.amazon.com/es/redshift/free-trial/" target="_blank">two month dc2.Large node for free</a>.</p>



<p>To create the cluster go to the redshift area of the aws portal <a rel="noreferrer noopener" href="https://console.aws.amazon.com/redshift/" data-type="URL" data-id="https://console.aws.amazon.com/redshift/" target="_blank">here</a> and click on create cluster. For this we will need to define the name of the cluster, the size and the type of cluster (production, free test), the number of nodes, the name of the database, admin username and password, the port and other aspects like vpc and subnet, security groups, parameter group and backup policies we want to apply. We can leave the defaults for these. For the rest of values choose non used ones and a strong user and password combination. If you want to use the free ofer, make sure you select the same as me:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="773" height="797" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift1.png" alt="" class="wp-image-971" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift1.png 773w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift1-291x300.png 291w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift1-768x792.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift1-58x60.png 58w" sizes="auto, (max-width: 773px) 100vw, 773px" /></figure>



<p>The fill the rest of the information and press the create cluster button. In a few minutes the cluster will be up and running.</p>



<p>2. Load TPC-DS Data</p>



<p>Before starting loading the data, let&#8217;s connect to our brand new cluster. For connecting, we can use the integrated editor in the aws portal or use some other software like <a rel="noreferrer noopener" href="https://dbeaver.io/" data-type="URL" data-id="https://dbeaver.io/" target="_blank">dbeaver</a>. I personally recommend the latter as it&#8217;s more flexible. If our usual client does not support redshift we can always use the postgre driver.</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift2.png" alt="" class="wp-image-972" width="554" height="589" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift2.png 554w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift2-282x300.png 282w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift2-56x60.png 56w" sizes="auto, (max-width: 554px) 100vw, 554px" /><figcaption>Choose Redshift driver in DBeaver</figcaption></figure>



<p>Then, DBeaver will automatically download the jar driver from internet unless we already have it and we then have to configure our connection:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="557" height="627" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift4.png" alt="" class="wp-image-973" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift4.png 557w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift4-267x300.png 267w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift4-53x60.png 53w" sizes="auto, (max-width: 557px) 100vw, 557px" /></figure>



<p>But before connecting, lets open the port in the security group. For this we need to go to our cluster in the aws portal, click on properties:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="930" height="513" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift3.png" alt="" class="wp-image-975" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift3.png 930w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift3-300x165.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift3-768x424.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift3-109x60.png 109w" sizes="auto, (max-width: 930px) 100vw, 930px" /></figure>



<p>And check for the Network and Security section. If we want to access the cluster from our computer, as it&#8217;s the case (although in a corporate environment probably you dont want this!) we need to enable the publickly accessible section. This change will take some time.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="428" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift5-1024x428.png" alt="" class="wp-image-976" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift5-1024x428.png 1024w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift5-300x125.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift5-768x321.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift5-143x60.png 143w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift5.png 1028w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>But before being able to connect we still have to click in the VPC security group and add a rule to be able to access redshift port from our location:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="308" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift6-1024x308.png" alt="" class="wp-image-977" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift6-1024x308.png 1024w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift6-300x90.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift6-768x231.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift6-1536x462.png 1536w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift6-199x60.png 199w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift6.png 1944w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>With this we can now test the connection from DBeaver, and now the connection should be succesful:</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift7.png" alt="" class="wp-image-978" width="355" height="199" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift7.png 414w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift7-300x168.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift7-107x60.png 107w" sizes="auto, (max-width: 355px) 100vw, 355px" /></figure>



<p>So, now, the next step is to load the information into redshift. For this, we will load some tables from a public s3 bucket maintained by aws. We will create four tables and then populate them from data in a public s3 bucket. We can get the ddl from <a rel="noreferrer noopener" href="https://github.com/awslabs/amazon-redshift-utils/blob/master/src/CloudDataWarehouseBenchmark/Cloud-DWB-Derived-from-TPCDS/3TB/ddl.sql" data-type="URL" data-id="https://github.com/awslabs/amazon-redshift-utils/blob/master/src/CloudDataWarehouseBenchmark/Cloud-DWB-Derived-from-TPCDS/3TB/ddl.sql" target="_blank">here</a>. We will crate the following three tables:</p>



<pre class="wp-block-code"><code>create table customer_address
(
 ca_address_sk int4 not null ,
  ca_address_id char(16) not null ,
  ca_street_number char(10) ,      
  ca_street_name varchar(60) ,   
  ca_street_type char(15) ,     
  ca_suite_number char(10) ,    
  ca_city varchar(60) ,         
  ca_county varchar(30) ,       
  ca_state char(2) ,            
  ca_zip char(10) ,             
  ca_country varchar(20) ,      
  ca_gmt_offset numeric(5,2) ,  
  ca_location_type char(20)     
  ,primary key (ca_address_sk)
) distkey(ca_address_sk);

create table customer
(
  c_customer_sk int4 not null ,                 
  c_customer_id char(16) not null ,             
  c_current_cdemo_sk int4 ,   
  c_current_hdemo_sk int4 ,   
  c_current_addr_sk int4 ,    
  c_first_shipto_date_sk int4 ,                 
  c_first_sales_date_sk int4 ,
  c_salutation char(10) ,     
  c_first_name char(20) ,     
  c_last_name char(30) ,      
  c_preferred_cust_flag char(1) ,               
  c_birth_day int4 ,          
  c_birth_month int4 ,        
  c_birth_year int4 ,         
  c_birth_country varchar(20) ,                 
  c_login char(13) ,          
  c_email_address char(50) ,  
  c_last_review_date_sk int4 ,
  primary key (c_customer_sk)
) distkey(c_customer_sk);

create table date_dim
(
    d_date_sk                 integer               not null,
    d_date_id                 char(16)              not null,
    d_date                    date,
    d_month_seq               integer                       ,
    d_week_seq                integer                       ,
    d_quarter_seq             integer                       ,
    d_year                    integer                       ,
    d_dow                     integer                       ,
    d_moy                     integer                       ,
    d_dom                     integer                       ,
    d_qoy                     integer                       ,
    d_fy_year                 integer                       ,
    d_fy_quarter_seq          integer                       ,
    d_fy_week_seq             integer                       ,
    d_day_name                char(9)                       ,
    d_quarter_name            char(6)                       ,
    d_holiday                 char(1)                       ,
    d_weekend                 char(1)                       ,
    d_following_holiday       char(1)                       ,
    d_first_dom               integer                       ,
    d_last_dom                integer                       ,
    d_same_day_ly             integer                       ,
    d_same_day_lq             integer                       ,
    d_current_day             char(1)                       ,
    d_current_week            char(1)                       ,
    d_current_month           char(1)                       ,
    d_current_quarter         char(1)                       ,
    d_current_year            char(1)                       ,
    primary key (d_date_sk)
) diststyle all;

create table web_returns
(
wr_returned_date_sk int4 ,   
  wr_returned_time_sk int4 , 
  wr_item_sk int4 not null , 
  wr_refunded_customer_sk int4 ,
  wr_refunded_cdemo_sk int4 ,   
  wr_refunded_hdemo_sk int4 ,   
  wr_refunded_addr_sk int4 ,    
  wr_returning_customer_sk int4 ,
  wr_returning_cdemo_sk int4 ,   
  wr_returning_hdemo_sk int4 ,  
  wr_returning_addr_sk int4 ,   
  wr_web_page_sk int4 ,         
  wr_reason_sk int4 ,           
  wr_order_number int8 not null,
  wr_return_quantity int4 ,     
  wr_return_amt numeric(7,2) ,  
  wr_return_tax numeric(7,2) ,  
  wr_return_amt_inc_tax numeric(7,2) ,
  wr_fee numeric(7,2) ,         
  wr_return_ship_cost numeric(7,2) ,
  wr_refunded_cash numeric(7,2) ,   
  wr_reversed_charge numeric(7,2) ,  
  wr_account_credit numeric(7,2) ,   
  wr_net_loss numeric(7,2)           
  ,primary key (wr_item_sk, wr_order_number)
) distkey(wr_order_number) sortkey(wr_returned_date_sk);</code></pre>



<p>You can create a new schema or use the public one for this test. I&#8217;ve created all four in the public schema.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="233" height="325" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift8.png" alt="" class="wp-image-979" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift8.png 233w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift8-215x300.png 215w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift8-43x60.png 43w" sizes="auto, (max-width: 233px) 100vw, 233px" /></figure>



<p>Once the tables have been created, then lets populate them. To populate the four tables we need to pass some AWSKeys or a Role with permission to read data from S3 (even if the bucket is public). If it&#8217;s a one off job maybe the keys can be quick to set up, but if we intend to do this often, we should create an IAM role and attach it to the Redshift cluster. We will go this second way. For this lets go to the IAM portal and create a new role following <a rel="noreferrer noopener" href="https://docs.aws.amazon.com/redshift/latest/gsg/rs-gsg-create-an-iam-role.html" data-type="URL" data-id="https://docs.aws.amazon.com/redshift/latest/gsg/rs-gsg-create-an-iam-role.html" target="_blank">this instructions</a>.</p>



<p>Then in the Redshift section, go to Actions, Manage IAM Roles, find your new IAM role and add it to the redshift cluster</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="822" height="480" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift9.png" alt="" class="wp-image-980" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift9.png 822w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift9-300x175.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift9-768x448.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift9-103x60.png 103w" sizes="auto, (max-width: 822px) 100vw, 822px" /></figure>



<p>After a few seconds / minutes you should see the new role being added to the cluster:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="184" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift10-1024x184.png" alt="" class="wp-image-981" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift10-1024x184.png 1024w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift10-300x54.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift10-768x138.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift10-1536x276.png 1536w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift10-333x60.png 333w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift10.png 1623w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Then we are ready to move to DBeaver and start the data loading. Since we have to load three tables we will use the following commands (First click on copy Amazon Resource Name (ARN) from the role we just added to our cluster, and then ran the three following commands (leave the region as us-east-1 no matter from where you are launching it as the data we are loading it&#8217;s in a bucket in that region. And replace my ARN by yours:</p>



<pre class="wp-block-code"><code>copy customer_address from 's3://redshift-downloads/TPC-DS/2.13/3TB/customer_address/' credentials 'aws_iam_role=arn:aws:iam::742123541312:role/Redshift_Albertnogues.com' gzip delimiter '|' EMPTYASNULL region 'us-east-1';

copy customer from 's3://redshift-downloads/TPC-DS/2.13/3TB/customer/' credentials 'aws_iam_role=arn:aws:iam::742123541312:role/Redshift_Albertnogues.com' gzip delimiter '|' EMPTYASNULL region 'us-east-1';

copy date_dim from 's3://redshift-downloads/TPC-DS/2.13/3TB/date_dim/' credentials 'aws_iam_role=arn:aws:iam::742123541312:role/Redshift_Albertnogues.com' gzip delimiter '|' EMPTYASNULL region 'us-east-1';

copy web_returns from 's3://redshift-downloads/TPC-DS/2.13/3TB/web_returns/' credentials 'aws_iam_role=arn:aws:iam::742123541312:role/Redshift_Albertnogues.com' gzip delimiter '|' EMPTYASNULL region 'us-east-1';</code></pre>



<p>The load of the data should finish sucesfully after several minutes. For the biggest table (web_returns) it took me 50 minutes. After the load we can do a few checks (counts):</p>



<pre class="wp-block-code"><code>select 'customer_address' table_name, count (*) from customer_address
UNION
select 'customer' table_name, count (*) from customer
UNION
select 'date_dim' table_name, count (*) from date_dim
UNION
select 'web_returns' table_name, count (*) from web_returns</code></pre>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="478" height="152" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift11-1.png" alt="" data-id="983" data-full-url="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift11-1.png" data-link="https://www.albertnogues.com/?attachment_id=983" class="wp-image-983" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift11-1.png 478w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift11-1-300x95.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift11-1-189x60.png 189w" sizes="auto, (max-width: 478px) 100vw, 478px" /></figure></li></ul></figure>



<pre class="wp-block-code"><code>select count(*) from customer_address;  -- 15000000
select count(*) from customer;  -- 30000000
select count(*) from date_dim;  -- 73049
select count(*) from web_returns;  -- 216003761</code></pre>



<p>3. Query the data</p>



<p>We can now launch a query to see the results:</p>



<pre class="wp-block-code"><code>-- start template query30.tpl query 3 in stream 1
with /* TPC-DS query30.tpl 0.75 */ customer_total_return as
 (select wr_returning_customer_sk as ctr_customer_sk
        ,ca_state as ctr_state, 
 	sum(wr_return_amt) as ctr_total_return
 from web_returns
     ,date_dim
     ,customer_address
 where wr_returned_date_sk = d_date_sk 
   and d_year =2002
   and wr_returning_addr_sk = ca_address_sk 
 group by wr_returning_customer_sk
         ,ca_state)
  select  c_customer_id,c_salutation,c_first_name,c_last_name,c_preferred_cust_flag
       ,c_birth_day,c_birth_month,c_birth_year,c_birth_country,c_login,c_email_address
       ,c_last_review_date_sk,ctr_total_return
 from customer_total_return ctr1
     ,customer_address
     ,customer
 where ctr1.ctr_total_return &gt; (select avg(ctr_total_return)*1.2
 			  from customer_total_return ctr2 
                  	  where ctr1.ctr_state = ctr2.ctr_state)
       and ca_address_sk = c_current_addr_sk
       and ca_state = 'OH'
       and ctr1.ctr_customer_sk = c_customer_sk
 order by c_customer_id,c_salutation,c_first_name,c_last_name,c_preferred_cust_flag
                  ,c_birth_day,c_birth_month,c_birth_year,c_birth_country,c_login,c_email_address
                  ,c_last_review_date_sk,ctr_total_return
limit 100;
</code></pre>



<p>And the query returns the first 100 results in just 4 minutes:</p>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-2 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="1024" height="260" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift12-1024x260.png" alt="" data-id="984" data-full-url="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift12.png" data-link="https://www.albertnogues.com/?attachment_id=984" class="wp-image-984" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift12-1024x260.png 1024w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift12-300x76.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift12-768x195.png 768w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift12-1536x389.png 1536w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift12-237x60.png 237w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift12.png 1712w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure></li></ul></figure>



<p>4. Performance Tricks</p>



<p>With Redshift as almost all databases, there is always room for improvement. The possibilities for tuning start with compression and then go to distribution and sort keys. Right now, after loading the 4 tables, these are taking (we can see in storage used in the main page of our cluster in the aws redshift portal) :</p>



<p>11.88% (19.01 of 160 GB used)</p>



<p>Which is not bad taking into account that in .gz the size of the files in total is about 15.37 GB, so the db has done pretty much a good job (<strong>Caution, while loading you need much more space than this, as the bulk load needs stagging space before being able to optimize it, based on my tests you need 3 times the final space at least</strong>) . But this can be improved. We didnt specify any compression when we defined our table structure. The rationale here is that if we compress the data, the engine wil process less volume of data and the resoults should come faster right?. Let&#8217;s see:</p>



<pre class="wp-block-code"><code>analyze compression customer;</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="531" height="404" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift13.png" alt="" class="wp-image-985" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift13.png 531w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift13-300x228.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift13-79x60.png 79w" sizes="auto, (max-width: 531px) 100vw, 531px" /></figure>



<p>As we can see there are optimizations to be made to save both space (and possibly) processing time. Let&#8217;s create a better table:</p>



<pre class="wp-block-code"><code>create table customer_compressed
(
  c_customer_sk int4 encode delta not null ,                 
  c_customer_id char(16) encode zstd not null ,             
  c_current_cdemo_sk int4 encode az64,   
  c_current_hdemo_sk int4 encode az64,   
  c_current_addr_sk int4 encode az64,    
  c_first_shipto_date_sk int4 encode az64,                 
  c_first_sales_date_sk int4 encode az64  ,
  c_salutation char(10) encode zstd,     
  c_first_name char(20) encode zstd,     
  c_last_name char(30) encode zstd,      
  c_preferred_cust_flag char(1)  encode zstd,               
  c_birth_day int4 encode az64,          
  c_birth_month int4 encode az64,        
  c_birth_year int4 encode az64,         
  c_birth_country varchar(20) encode bytedict,                 
  c_login char(13) encode lzo,          
  c_email_address char(50) encode zstd,  
  c_last_review_date_sk int4 encode az64,
  primary key (c_customer_sk)
) distkey(c_customer_sk);</code></pre>



<p>And then insert back:</p>



<pre class="wp-block-code"><code>insert into customer_compressed select * from customer;</code></pre>



<p>And then later:</p>



<pre class="wp-block-code"><code>SELECT "table", tbl_rows, size size_in_MB FROM SVV_TABLE_INFO
order by 1</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="440" height="166" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift14.png" alt="" class="wp-image-986" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift14.png 440w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift14-300x113.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift14-159x60.png 159w" sizes="auto, (max-width: 440px) 100vw, 440px" /></figure>



<p>So we easily saved 25% of space in this table. Let&#8217;s do the same for the rest (mainly for web_returns, the others are small so probably no need to compress them)</p>



<pre class="wp-block-code"><code>analyze compression web_returns;</code></pre>



<p>but unfortunately we see that there is no improvement to be made.</p>



<figure class="wp-block-gallery columns-1 is-cropped wp-block-gallery-3 is-layout-flex wp-block-gallery-is-layout-flex"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><img loading="lazy" decoding="async" width="432" height="513" src="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift15.png" alt="" data-id="988" data-full-url="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift15.png" data-link="https://www.albertnogues.com/?attachment_id=988" class="wp-image-988" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift15.png 432w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift15-253x300.png 253w, https://www.albertnogues.com/wp-content/uploads/2020/12/Redshift15-51x60.png 51w" sizes="auto, (max-width: 432px) 100vw, 432px" /></figure></li></ul></figure>



<p>So the compression is over. Next steps are the distribution and the sort keys but being tpc-ds queries these have been already optimized for the tpc-ds queries. For this you can follow the excellent guide in aws documentation <a rel="noreferrer noopener" href="https://docs.aws.amazon.com/redshift/latest/dg/t_Creating_tables.html" data-type="URL" data-id="https://docs.aws.amazon.com/redshift/latest/dg/t_Creating_tables.html" target="_blank">here.</a></p>
<p>The post <a href="https://www.albertnogues.com/load-data-from-s3-and-run-tpc-ds-queries-on-amazon-redshift/">Load data from s3 and run TPC-DS queries on amazon Redshift.</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>HowTo run (Any Linux) Centos8 inside windows 10</title>
		<link>https://www.albertnogues.com/howto-run-any-linux-centos8-inside-windows-10/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=howto-run-any-linux-centos8-inside-windows-10</link>
		
		<dc:creator><![CDATA[Albert]]></dc:creator>
		<pubDate>Thu, 24 Dec 2020 17:38:00 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[wsl]]></category>
		<guid isPermaLink="false">http://192.168.1.40/?p=953</guid>

					<description><![CDATA[<p>Since some time ago, windows ships with something called WSL or Windows subsystem for linux. This allows windows users to run linux images withouth having to physically install linux, running cygwin or running vm&#8217;s or docker containers with linux. So it&#8217;s quite practical. And the good part is that from within the linux shell you &#8230; </p>
<p>The post <a href="https://www.albertnogues.com/howto-run-any-linux-centos8-inside-windows-10/">HowTo run (Any Linux) Centos8 inside windows 10</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Since some time ago, windows ships with something called WSL or Windows subsystem for linux. This allows windows users to run linux images withouth having to physically install linux, running cygwin or running vm&#8217;s or docker containers with linux. So it&#8217;s quite practical. And the good part is that from within the linux shell you can see all your attached disks in windows, including the OS disk, so you can for example use a gui or a code editor in windows and interact with linux command line tools inside the shell.</p>



<p>If you want to read more about it you can read <a rel="noreferrer noopener" href="https://docs.microsoft.com/en-us/windows/wsl/install-win10" data-type="URL" data-id="https://docs.microsoft.com/en-us/windows/wsl/install-win10" target="_blank">Microsoft post on their website</a>.</p>



<p>Basically there are two versions, version 1, and version 2. You can see the differences between both in this <a rel="noreferrer noopener" href="https://docs.microsoft.com/en-us/windows/wsl/compare-versions" data-type="URL" data-id="https://docs.microsoft.com/en-us/windows/wsl/compare-versions" target="_blank">post</a>. I recommend using version 2 when possible as it&#8217;s more performant. As started on Microsoft website:</p>



<p><em>The primary difference and reasons for updating the Windows Subsystem for Linux from WSL 1 to WSL 2 are to:</em></p>



<ul class="wp-block-list">
<li><em><strong>increase file system performance</strong>,</em></li>



<li><em><strong>support full system call compatibility</strong>.</em></li>
</ul>



<p><em>WSL 2 uses the latest and greatest in virtualization technology to run a Linux kernel inside of a lightweight utility virtual machine (VM). However, WSL 2 is not a traditional VM experience.</em></p>



<p>So, let&#8217;s see the steps to make all this work. First of all we need to enable wsl in windows optional features. For this we can go through the control Panel or the windows search and make a few clicks to enable it or we can run some command from powershell. Make sure you run them as administrator (Right click to Powershell, run as Admin&#8230;)</p>



<p>The commands are either one of these two:</p>



<pre class="wp-block-code"><code>dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart</code></pre>



<p>or</p>



<pre class="wp-block-code"><code>Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux</code></pre>



<p>Any of the two will do the work. After it, restart your computer. </p>



<p><strong>(OPTIONAL)</strong> If optionally you want to upgrade to wsl v2, you need to make sure you are running one of the newer windows 10 releases:</p>



<ul class="wp-block-list">
<li>For x64 systems: <strong>Version 1903</strong> or higher, with <strong>Build 18362</strong> or higher.</li>



<li>For ARM64 systems: <strong>Version 2004</strong> or higher, with <strong>Build 19041</strong> or higher.</li>



<li>Builds lower than 18362 do not support WSL 2. Use the <a href="https://www.microsoft.com/software-download/windows10">Windows Update Assistant</a> to update your version of Windows.</li>
</ul>



<p>If this is the case, you can simply then upgrade it to wsl v2 by running the following to enavle the Virtual Machine Platform support:</p>



<pre class="wp-block-code"><code>dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart</code></pre>



<p>Download and install the v2 kernel package from <a rel="noreferrer noopener" href="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" data-type="URL" data-id="https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi" target="_blank">here</a>.</p>



<p>And set wsl v2 as the default mode with the following command:</p>



<pre class="wp-block-code"><code>wsl --set-default-version 2</code></pre>



<p>Then we are good, we can open now the <a rel="noreferrer noopener" href="https://aka.ms/wslstore" data-type="URL" data-id="https://aka.ms/wslstore" target="_blank">microsoft store</a> and download any of the supported images there, like Ubuntu, Suse, Debian, Fedora, Alpine&#8230; But if you want to use Centos8, we need some extra work.</p>



<p>There is a Github project that now has been archived due to the Centos / Centos Stream controversy but is still working for our purpose. We can use it as long as we are in Windows 10 version 2004, otherwise upgrade your windows 10.</p>



<p>We go to the <a rel="noreferrer noopener" href="https://github.com/wsldl-pg/CentWSL/releases" data-type="URL" data-id="https://github.com/wsldl-pg/CentWSL/releases" target="_blank">release page of the github repo</a> and download the zip file. Another option is to go to the new github repo continuing the work of the original one with the new Centos versions (including CentOs stream and CentOs 8.3 <a rel="noreferrer noopener" href="https://github.com/mishamosher/CentOS-WSL/releases/" data-type="URL" data-id="https://github.com/mishamosher/CentOS-WSL/releases/" target="_blank">here</a>), the procedure will be the same.</p>



<p>Once downloaded, we extract the zip file and we run the exe file inside. This will unpack all the content of the root filesystem inside the tar.gz file and will make everything ready to be run. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="347" height="96" src="https://www.albertnogues.com/wp-content/uploads/2020/12/CentosInstall.png" alt="" class="wp-image-956" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/CentosInstall.png 347w, https://www.albertnogues.com/wp-content/uploads/2020/12/CentosInstall-300x83.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/CentosInstall-217x60.png 217w" sizes="auto, (max-width: 347px) 100vw, 347px" /></figure>



<p>To enter into the bash shell we simply click again into the exe file once it has been installed and voilà!. Another way is to write the bash command in the cmd, which will open bash inside our cmd window.</p>



<p>Then we can update our system to the latest version by running dnf update:</p>



<pre class="wp-block-code"><code>&#91;root@DESKTOP-JONAOMM ~]# cat /etc/redhat-release
CentOS Stream release 8
&#91;root@DESKTOP-JONAOMM ~]# dnf update
CentOS Stream 8 - AppStream                                                             3.2 MB/s | 6.4 MB     00:02
CentOS Stream 8 - BaseOS                                                                2.5 MB/s | 2.4 MB     00:00
CentOS Stream 8 - Extras                                                                 10 kB/s | 7.0 kB     00:00
Dependencies resolved.
========================================================================================================================
 Package                                    Arch       Version                                      Repository     Size
========================================================================================================================
Installing:
 kernel                                     x86_64     4.18.0-259.el8                               baseos        5.0 M                     baseos         31 M
...
Installing weak dependencies:
 dconf                                      x86_64     0.28.0-4.el8                                 appstream     108 k

Transaction Summary
========================================================================================================================
Install   53 Packages
Upgrade  138 Packages

Total download size: 326 M
Is this ok &#91;y/N]:</code></pre>



<p>At the same time I recommend you to <a rel="noreferrer noopener" href="https://docs.microsoft.com/en-us/windows/terminal/get-started" data-type="URL" data-id="https://docs.microsoft.com/en-us/windows/terminal/get-started" target="_blank">install windows terminal</a> as well to get better experience (tab support, search, custom themes&#8230;)</p>



<p>If we look around we can see our local volumes &#8220;mounted&#8221; inside</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="480" height="154" src="https://www.albertnogues.com/wp-content/uploads/2020/12/WSLMount.png" alt="" class="wp-image-957" srcset="https://www.albertnogues.com/wp-content/uploads/2020/12/WSLMount.png 480w, https://www.albertnogues.com/wp-content/uploads/2020/12/WSLMount-300x96.png 300w, https://www.albertnogues.com/wp-content/uploads/2020/12/WSLMount-187x60.png 187w" sizes="auto, (max-width: 480px) 100vw, 480px" /></figure>



<p>We can also share our image with others (friends, coworkers) if we customized it or installed some software which is great for people like me that have many friends, which I met in sites like <a href="https://chatempanada.com">https://chatempanada.com</a> online. </p>



<p>. We can export it with:</p>



<pre class="wp-block-code"><code>wsl --export ImageName FileName</code></pre>



<p>with Image Name the name of the linux flavour we want to export. We can check all the available ones with the following command:</p>



<pre class="wp-block-code"><code>wsl --list
Distribuciones del subsistema de Windows para Linux:
CentOS8 (predet.)
CentOS8-stream</code></pre>



<p>And then pack the tar file inside a compressed file and send it to whom we want.</p>



<p>Another useful trick is that if we dont want to log in as root (which is what wsl by default does), we can run the following:</p>



<pre class="wp-block-code"><code>wsl -d ImageName -u username</code></pre>



<p>Happy Linuxing!</p>
<p>The post <a href="https://www.albertnogues.com/howto-run-any-linux-centos8-inside-windows-10/">HowTo run (Any Linux) Centos8 inside windows 10</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automatizing a Bigdata (CDH) cluster installation</title>
		<link>https://www.albertnogues.com/automatizing-a-bigdata-cdh-cluster-installation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=automatizing-a-bigdata-cdh-cluster-installation</link>
		
		<dc:creator><![CDATA[Albert]]></dc:creator>
		<pubDate>Tue, 30 Jul 2019 19:29:37 +0000</pubDate>
				<category><![CDATA[BigData]]></category>
		<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">http://anogues.azurewebsites.net/?p=309</guid>

					<description><![CDATA[<p>It&#8217;s been a while without writing any post but this one is going to be useful for people that face the task of installing a CDH cluster from scratch. There are a few prerequisites before starting with the installation that need to be configured or otherwise the installation can/will crash. To address some of these &#8230; </p>
<p>The post <a href="https://www.albertnogues.com/automatizing-a-bigdata-cdh-cluster-installation/">Automatizing a Bigdata (CDH) cluster installation</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>It&#8217;s been a while 
without writing any post but this one is going to be useful for people 
that face the task of installing a CDH cluster from scratch.</p>



<p>There
 are a few prerequisites before starting with the installation that need
 to be configured or otherwise the installation can/will crash. To 
address some of these I wrote some small scripts in ansible to 
automatize the adjustment of these parameters or the data copy. The 
scripts are not finished, and I plan to improve them adding a few parts 
that I still haven&#8217;t automatized like the creation of the yum 
repositories for installing cloudera manager and a few other small 
tasks.</p>



<p>For this manual we assume that Cloudera manager has already
 been installed, and the database to hold Cloudera manager data 
repository and some of the other tools has been installed as well.</p>



<p>The  script is written in ansible and it has three playbooks and an  inventory file. The inventory file is in yaml format. I grouped the  nodes between master(s) / workers (datanodes) the Cloudera manager  server and the gateway. The inventory file is defined as follows and you can save it as inventory.yaml:</p>



<pre class="wp-block-code"><code>all:
  children:
    cm:
      hosts:
        cm_host:
    master:
      hosts:
        master_host:
    workers:
      hosts:
        worker1_host:
        worker2_host:
        worker3_host:
    gateway:
      hosts:
        gateway_host:</code></pre>



<p>Replace the xxx_host by the fully qualified domain name of your server.</p>



<p>Then  we have the prerequisites playbook, this one has more substance. Apart  from the prerequisites enunciated in Cloudera’s website I added some  tweaks and actions like the change of the mysql jdbc driver, as the one  in yum is outdated and will make the creation of the dbs to crash in the  wizard. You can save this one as cloudera_prerequisites.yaml:</p>



<pre class="wp-block-code"><code>---
- hosts: all
  connection: ssh
  remote_user: youruser
  become: yes
  become_method: sudo
  become_user: root
  tasks:
   - service: name=firewalld state=stopped enabled=False
   - selinux: state=disabled
   - sysctl: name=net.ipv6.conf.all.disable_ipv6 value=1 state=present
   - sysctl: name=net.ipv6.conf.default.disable_ipv6 value=1 state=present
   - sysctl: name=vm.swappiness value=1 state=present
   - shell: sysctl -w vm.swappiness=1
   - copy: src=/etc/hosts dest=/etc/hosts owner=root group=root mode=0644
   - yum: name=java-1.8.0-openjdk-devel state=latest
   - systemd: name=tuned state=started
   - shell: tuned-adm off
   - systemd: name=tuned state=stopped enabled=False
   - name: Disable THP support scripts added to rc.local
     lineinfile:
       path: /etc/rc.local
       line: |
         echo never &gt; /sys/kernel/mm/transparent_hugepage/enabled
         echo never &gt; /sys/kernel/mm/transparent_hugepage/defrag
   - name: Change permissions of /etc/rc.local to make it run on boot
     shell: chmod +x /etc/rc.d/rc.local
     become_method: sudo
   - service: name=ntpd state=started
   - name: Allow 'simigsolutions' user to have passwordless sudo
     lineinfile:
       path: /etc/sudoers
       state: present
       regexp: '^youruser'
       line: 'youruser ALL =(ALL) NOPASSWD: ALL'
#   - name: Install mysql jdbc driver
#     yum:
#       name: mysql-connector-java
#       state: latest
   - name: download newer jdbc for mysql to avoid crash
     get_url: url=https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.46.tar.gz dest=/tmp/mysql-connector-java-5.1.46.tar.gz
   - name: Check if /tmp/mysql-connector-java-5.1.46.tar.gz exists
     stat:
       path: /tmp/mysql-connector-java-5.1.46.tar.gz
     register: stat_result
   - block:
     - name: Extract downloaded jdbc
       unarchive:
         src: /tmp/mysql-connector-java-5.1.46.tar.gz 
         dest: /tmp/
     - name: Creates directory for the java driver if it does not exist
       file:
         path: /usr/share/java
         state: directory
         mode: 0755
         recurse: yes
     - name: Copies the file
       copy:
         src: /tmp/mysql-connector-java-5.1.46/mysql-connector-java-5.1.46-bin.jar
         dest: /usr/share/java/mysql-connector-java.jar
         owner: root
         group: root
         mode: 0644
     - name: Copies the file to sqoop as well
       copy:
         src: /tmp/mysql-connector-java-5.1.46/mysql-connector-java-5.1.46-bin.jar
         dest: /var/lib/sqoop/mysql-connector-java.jar
         owner: sqoop
         group: sqoop
         mode: 0644		
     when: stat_result.stat.exists == True</code></pre>



<p>The
 script can be called with the following: ansible-playbook -i 
inventory.yaml cloudera_prerequisites.yaml &#8211;ask-pass &#8211;ask-become-pass</p>



<p>I&#8217;ve also created two aditional playbooks, one to create folders in the mount points to store hdfs and yarn data:</p>



<pre class="wp-block-code"><code>---
- hosts: workers
  connection: ssh
  remote_user: youruser
  become: yes
  become_method: sudo
  become_user: root
  tasks:
  - name: Creates directory datanodes
    file:
      path: /home/data/dfs/dn
      state: directory
      owner: hdfs
      group: hdfs
      mode: 0700
      recurse: yes
  - name: Creates directory namenodes
    file:
      path: /home/data/yarn/nm
      state: directory
      owner: yarn
      group: yarn
      mode: 0700
      recurse: yes
  - name: Creates directory namenodes
    file:
      path: home/data/impala/impalad
      state: directory
      owner: impala
      group: impala
      mode: 0700
      recurse: yes

- hosts: master
  connection: ssh
  remote_user: youruser
  become: yes
  become_method: sudo
  become_user: root
  tasks:
  - name: Creates directory namenode
    file:
      path: /home/data/dfs/nn
      state: directory
      owner: hdfs
      group: hdfs
      mode: 0700
      recurse: yes
  - name: Creates directory secondary namenode
    file:
      path: /home/data/dfs/snn
      state: directory
      owner: hdfs
      group: hdfs
      mode: 0700
      recurse: yes</code></pre>



<p>And  another one to copy some jdbc driver and distribute it in all machines  of the cluster (sql server) but can be adapted to any downloadable jdbc  driver:</p>



<pre class="wp-block-code"><code>- hosts: all
  connection: ssh
  remote_user: youruser
  become: yes
  become_method: sudo
  become_user: root
  tasks:
   - name: download sqlserver jdbc driver
     get_url: url=https://download.microsoft.com/download/4/D/C/4DCD85FA-0041-4D2E-8DD9-833C1873978C/sqljdbc_7.2.2.0_enu.tar.gz dest=/tmp/sqljdbc_7.2.2.0_enu.tar.gz
   - name: Check if /tmp/sqljdbc_7.2.2.0_enu.tar.gz exists
     stat:
       path: /tmp/sqljdbc_7.2.2.0_enu.tar.gz
     register: stat_result
   - block:
     - name: Extract downloaded jdbc
       unarchive:
         src: /tmp/sqljdbc_7.2.2.0_enu.tar.gz
         dest: /tmp/
     - name: Copies the file into the aqoop folder
       copy:
         src: /tmp/sqljdbc_7.2/enu/mssql-jdbc-7.2.2.jre8.jar
         dest: /var/lib/sqoop/mssql-jdbc-7.2.2.jre8.jar
         owner: sqoop
         group: sqoop
         mode: 0644
     when: stat_result.stat.exists == True</code></pre>



<p>Happy Installation <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a href="https://www.albertnogues.com/automatizing-a-bigdata-cdh-cluster-installation/">Automatizing a Bigdata (CDH) cluster installation</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Cloudera Manager installation in Google Cloud</title>
		<link>https://www.albertnogues.com/cloudera-manager-installation-in-google-cloud/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cloudera-manager-installation-in-google-cloud</link>
		
		<dc:creator><![CDATA[Albert]]></dc:creator>
		<pubDate>Mon, 04 Dec 2017 21:25:39 +0000</pubDate>
				<category><![CDATA[BigData]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[chd]]></category>
		<category><![CDATA[cloudera]]></category>
		<category><![CDATA[cloudera manager]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[manager]]></category>
		<guid isPermaLink="false">http://192.168.1.40/?p=273</guid>

					<description><![CDATA[<p>Installation of Cloudera Manager and small CDH Cluster Lab in Google Cloud As a preparation for the CCA Administration certification we need a workable cluster to do our practice tests. I&#8217;m going to start showing you how to install a CDH cluster in the google cloud. To start with, we need to proceed with the &#8230; </p>
<p>The post <a href="https://www.albertnogues.com/cloudera-manager-installation-in-google-cloud/">Cloudera Manager installation in Google Cloud</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Installation of Cloudera Manager and small CDH Cluster Lab in Google Cloud</p>
<p>As a preparation for the <a href="https://www.cloudera.com/more/training/certification/cca-admin.html">CCA Administration certification</a> we need a workable cluster to do our practice tests.</p>
<p>I&#8217;m going to start showing you how to install a CDH cluster in the google cloud.</p>
<p>To start with, we need to proceed with the cloudera manager installation, which will guide us to the process of setting up our small cluster, to work as a test lab. The cluster will consist in 2 master nodes (we will enable hdfs HA and yarn HA) and 3 workers, as by default hdfs replication is 3 and we will stick to that. We will use one of the workers as a gateway too, to simplify the number of machines we use.</p>
<p>Apart of these 5 machines, we will have the cloudera manager in a separate machine, so in total, we will need 6 machines. The CPU and RAM required for each machine will vary too, but to make it easier, we will use only two types of instances. Let&#8217;s start with the cloudera manager first, in this post and in the following one we will set up the cluster.</p>
<p><strong>Cloudera Manager Installation</strong></p>
<p>Open your google cloud control panel, go to the compute engine section, VM Instances and click on create. A new tab will open with some default values that we need to edit.</p>
<p><a href="https://www.albertnogues.com/wp-content/uploads/2017/12/CM1.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-274" src="https://www.albertnogues.com/wp-content/uploads/2017/12/CM1-1024x876.png" alt="" width="980" height="838" srcset="https://www.albertnogues.com/wp-content/uploads/2017/12/CM1-1024x876.png 1024w, https://www.albertnogues.com/wp-content/uploads/2017/12/CM1-300x257.png 300w, https://www.albertnogues.com/wp-content/uploads/2017/12/CM1-768x657.png 768w, https://www.albertnogues.com/wp-content/uploads/2017/12/CM1-70x60.png 70w, https://www.albertnogues.com/wp-content/uploads/2017/12/CM1.png 1038w" sizes="auto, (max-width: 980px) 100vw, 980px" /></a></p>
<p>I will name the instance Cloudera Manager to simplify things. Choose the appropriate zone based in your geographic location, and as a machine type we will select the n1-highmem-2 which contains 2 virtual cpus and 13 GB of ram, as using the standard n1-standard-2 instance is risky as cloudera manager may not boot because it may not have enough RAM. It requires approximately 8 GB of ram, and having less, causes unexpected errors. SO we are going to play safe.</p>
<p><a href="https://www.albertnogues.com/wp-content/uploads/2017/12/CM2.png"><img loading="lazy" decoding="async" class="alignnone wp-image-275" src="https://www.albertnogues.com/wp-content/uploads/2017/12/CM2.png" alt="" width="402" height="595" srcset="https://www.albertnogues.com/wp-content/uploads/2017/12/CM2.png 451w, https://www.albertnogues.com/wp-content/uploads/2017/12/CM2-203x300.png 203w, https://www.albertnogues.com/wp-content/uploads/2017/12/CM2-41x60.png 41w" sizes="auto, (max-width: 402px) 100vw, 402px" /></a></p>
<p>As a boot disk, we are going to change the default debian for a centos7. Since this will only host the cloudera manager installation,, the disk will only hold that and the OS Files. Just in case we will increase the standard 10 GB of disk to 20 GB to be on the safer side. Leave all the other options by default, even that later we will need to work on the Firewall, to open the cloudera manager port. Once finished, click on CREATE.</p>
<p>After a couple of seconds, we will have our instance created. It will show the private and public IP. As obvious, from the outside, we will need the Public IP to connect through SSH.</p>
<p>Before connecting through ssh, we need to generate a key pair. Follow the google cloud guide for this purpose <a href="https://cloud.google.com/compute/docs/instances/connecting-to-instance#generatesshkeypair">here. </a></p>
<p>Once generated the keys, we can proceed to connect to our machine, we open our ssh client or the one integrated in google cloud (using the web browser) and we will be in:</p>
<p><a href="https://www.albertnogues.com/wp-content/uploads/2017/12/CM3.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-276" src="https://www.albertnogues.com/wp-content/uploads/2017/12/CM3.png" alt="" width="602" height="74"></a></p>
<p>Before installing cloudera manager, let&#8217;s do a few configuration tasks that we may require later. These are to disable selinux and update the system.</p>
<p>To disable selinux, simply do a <em>sudo vi /etc/sysconfig/selinux </em>and set<em> selinux=disabled </em>and <strong>rebot the machine.</strong></p>
<p>then:</p>
<p><strong>sudo yum update &amp;&amp; sudo yum install wget</strong></p>
<p>After installing wget, we can proceed to download the cloudera manager installer:</p>
<p><strong>wget http://archive.cloudera.com/cm5/installer/latest/cloudera-manager-installer.bin</strong></p>
<p><strong>chmod u+x cloudera-manager-installer.bin</strong></p>
<p><strong>sudo ./cloudera-manager-installer.bin</strong></p>
<p>And the installer will start. Then we only need to follow the wizard through the setup process</p>
<p><a href="https://www.albertnogues.com/wp-content/uploads/2017/12/CM4.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-277" src="https://www.albertnogues.com/wp-content/uploads/2017/12/CM4.png" alt="" width="642" height="386"></a></p>
<p>and the download of the java sdk and the cloudera manager will start. The last step, will show us the url of the cloudera manager but note that, first, the url is give using the machine name and with that url we wont be able to get to the server and second, we have to open the port in the firewall so it becomes accessible from the outside.</p>
<p><a href="https://www.albertnogues.com/wp-content/uploads/2017/12/CM5.png"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-278" src="https://www.albertnogues.com/wp-content/uploads/2017/12/CM5.png" alt="" width="643" height="386"></a></p>
<p>So, now, we wait for a couple of seconds and we go back to our google cloud dashboard, click on VPC Network &gt; Firewall Rules, as seen on the image.</p>
<p><a href="https://www.albertnogues.com/wp-content/uploads/2017/12/CM6.png"><img loading="lazy" decoding="async" class="alignnone wp-image-279" src="https://www.albertnogues.com/wp-content/uploads/2017/12/CM6.png" alt="" width="355" height="554"></a></p>
<p>And now, click on create firewall rule, name it cm7180. In the targets select either your instance or all instances in the network (not recommended), and in source ip ranges input either your ip if you connect always from the same place or 0.0.0.0/0 or any other subnet provided by your ISP and on the protocols and ports, select &#8220;specified protocols and ports&#8221; and write <strong>tcp:7180</strong></p>
<p>Of you will still have issues connecting, you can try to disable firewalld which may be blocking the access. At this point, you can either disable it completely, or configure it to give access to the port 7180.</p>
<p>After that, point your browser to <strong>http://&lt;your public ip&gt;:7180</strong> and you should see the cloudera manager login screen. The username and password to log in are <strong>admin/admin</strong> and these should be changed ASAP.</p>
<p><a href="https://www.albertnogues.com/wp-content/uploads/2017/12/CM7.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-280" src="https://www.albertnogues.com/wp-content/uploads/2017/12/CM7-1024x600.png" alt="" width="980" height="574"></a></p>
<p>The screen shows it in spanish because cloudera manager inherits your browser locale configuration. When we login, we can finish the installation of cloudera manager, which basically consists in accepting the license terms, and choosing the license from: Cloudera Manager Express, Cloudera Enterpise 60 day trial or Cloudera Enterprise with license.</p>
<p>At this point we will use the 60 day trial, as we want to perform some tasks in the cluster that are not possible with the express version.</p>
<p>And here it finishes the installation of cloudera manager. In a next post we will cover the installation of CDH which is just the wizard that follows the license selection in cloudera manager.</p>
<p>Stay tuned for next chapter soon!</p>
<p>The post <a href="https://www.albertnogues.com/cloudera-manager-installation-in-google-cloud/">Cloudera Manager installation in Google Cloud</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Business Intelligence Tools for Small Companies: A Guide to Free and Low-Cost Solutions</title>
		<link>https://www.albertnogues.com/business-intelligence-tools-for-small-companies-a-guide-to-free-and-low-cost-solutions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=business-intelligence-tools-for-small-companies-a-guide-to-free-and-low-cost-solutions</link>
		
		<dc:creator><![CDATA[Albert]]></dc:creator>
		<pubDate>Sat, 17 Jun 2017 15:40:17 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[book]]></category>
		<guid isPermaLink="false">http://192.168.1.40/?p=255</guid>

					<description><![CDATA[<p>Juan Valladares and I have finished our book and it is published now. You can get it from major retailers or from the publishers website (Apress): http://www.apress.com/gp/book/9781484225677 Also available from amazon: https://www.amazon.com/Business-Intelligence-Tools-Small-Companies/dp/1484225678 The book: Teaches how to implement and manage the business intelligence/data warehousing (BI/DWH) infrastructure for a small company Provides practice extracting data from any &#8230; </p>
<p>The post <a href="https://www.albertnogues.com/business-intelligence-tools-for-small-companies-a-guide-to-free-and-low-cost-solutions/">Business Intelligence Tools for Small Companies: A Guide to Free and Low-Cost Solutions</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Juan Valladares and I have finished our book and it is published now. You can get it from major retailers or from the publishers website (Apress): <a href="http://www.apress.com/gp/book/9781484225677">http://www.apress.com/gp/book/9781484225677</a></p>
<p>Also available from amazon: <a href="https://www.amazon.com/Business-Intelligence-Tools-Small-Companies/dp/1484225678">https://www.amazon.com/Business-Intelligence-Tools-Small-Companies/dp/1484225678 </a></p>
<p>The book:</p>
<ul>
<li>Teaches how to implement and manage the business intelligence/data warehousing (BI/DWH) infrastructure for a small company</li>
<li>Provides practice extracting data from any enterprise resource planning (ERP) tool</li>
<li>Uses open-source extract-transform-load (ETL) tools to process and integrate BI data</li>
<li>Shows how to query, report, and analyze BI data using open-source visualization and dashboard tools</li>
<li>No previous knowledge is required</li>
</ul>
<p>Learn how to transition from Excel-based business intelligence (BI) analysis to enterprise stacks of open-source BI tools. Select and implement the best free and freemium open-source BI tools for your company’s needs and design, implement, and integrate BI automation across the full stack using agile methodologies.</p>
<p>Business Intelligence Tools for Small Companies provides hands-on demonstrations of open-source tools suitable for the BI requirements of small businesses. The authors draw on their deep experience as BI consultants, developers, and administrators to guide you through the extract-transform-load/data warehousing (ETL/DWH) sequence of extracting data from an enterprise resource planning (ERP) database freely available on the Internet, transforming the data, manipulating them, and loading them into a relational database. These practical insights and skills are particularly advantageous <a href="https://aktien-fur-jedermann.de/blogs/news/die-paypal-aktie-wie-entwickelt-sie-sich-weiter">in this outlook for PayPal</a>, where informed decision-making, data-driven strategies, and insightful analytics are pivotal for navigating and capitalizing on the dynamic landscape of the financial market.</p>
<p>The authors demonstrate how to extract, report, and dashboard key performance indicators (KPIs) in a visually appealing format from the relational database management system (RDBMS). They model the selection and implementation of free and freemium tools such as Pentaho Data Integrator and Talend for ELT, Oracle XE and MySQL/MariaDB for RDBMS, and Qliksense, Power BI, and MicroStrategy Desktop for reporting. This richly illustrated guide models the deployment of a small company BI stack on an inexpensive cloud platform such as AWS.</p>
<p><b>What You&#8217;ll Learn</b></p>
<p>You will learn how to manage, integrate, and automate the processes of BI by selecting and implementing tools to:</p>
<ul>
<li class="active">Implement and manage the business intelligence/data warehousing (BI/DWH) infrastructure</li>
<li>Extract data from any enterprise resource planning (ERP) tool</li>
<li>Process and integrate BI data using open-source extract-transform-load (ETL) tools</li>
<li>Query, report, and analyze BI data using open-source visualization and dashboard tools</li>
<li>Use a MOLAP tool to define next year&#8217;s budget, integrating real data with target scenarios</li>
<li>Deploy BI solutions and big data experiments inexpensively on cloud platforms</li>
</ul>
<p><b>Who This Book Is For</b><br />
Engineers, DBAs, analysts, consultants, and managers at small companies with limited resources but whose BI requirements have outgrown the limitations of Excel spreadsheets; personnel in mid-sized companies with established BI systems who are exploring technological updates and more cost-efficient solutions</p>
<p>The post <a href="https://www.albertnogues.com/business-intelligence-tools-for-small-companies-a-guide-to-free-and-low-cost-solutions/">Business Intelligence Tools for Small Companies: A Guide to Free and Low-Cost Solutions</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introduction to the maths of bookmaking (with python code)</title>
		<link>https://www.albertnogues.com/introduction-to-the-maths-of-bookmaking-with-python-code/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introduction-to-the-maths-of-bookmaking-with-python-code</link>
		
		<dc:creator><![CDATA[Albert]]></dc:creator>
		<pubDate>Sat, 27 Jun 2015 20:12:23 +0000</pubDate>
				<category><![CDATA[Betting]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[betting]]></category>
		<category><![CDATA[prices]]></category>
		<category><![CDATA[probability]]></category>
		<category><![CDATA[python]]></category>
		<guid isPermaLink="false">http://192.168.1.40/?p=180</guid>

					<description><![CDATA[<p>Introduction In this article I will show you how to calculate simple things about the odds the bookmakers offer and how to play with them with the intention of using the real chance of each outcome to model a group of prices. Basically what we will do is the following: retrieve the odds of a &#8230; </p>
<p>The post <a href="https://www.albertnogues.com/introduction-to-the-maths-of-bookmaking-with-python-code/">Introduction to the maths of bookmaking (with python code)</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Introduction</h1>
<p>In this article I will show you how to calculate simple things about the odds the bookmakers offer and how to play with them with the intention of using the real chance of each outcome to model a group of prices. Basically what we will do is the following:</p>
<ul>
<li>retrieve the odds of a horse race</li>
<li>calculate the overround applied</li>
<li>determine the true odds</li>
<li>generate a new set of odds with the desired overround. We will see several techniques, these are:
<ul>
<li>First approach for pricing: Apply the overround linearly</li>
<li>A better approach: Apply the overround based on the chance of winning</li>
<li>The real deal: Apply the overround based on a model</li>
</ul>
</li>
</ul>
<h1>Retrieve the Odds</h1>
<p>For the sample of this article I will be using odds of a horse race held at Doncaster, the 27th of June 2015. This was the last race of the card, a class 4 handicap of 7 runners, but any race or sport should suit.</p>
<p>The odds on offer at the time of writting were the following (got from oddschecker):</p>
<p>Rio Ronaldo <strong>3.25</strong> 3.0 3.0 3.25 3.0 3.25 3.25 3.0 3.0 2.75 3.25 3.25<br />Beau Eile <strong>3.5</strong> 3.25 3.25 3.25 3.5 3.25 3.25 3.25 3.25 3.25 3.5 3.5<br />Bahamian Sunrise <strong>4.0</strong> 4.0 3.75 3.75 4.0 3.75 3.75 3.75 4.0 4.0 3.5 3.75<br />Silver Rainbow <strong>13.0</strong> 13.0 9.0 13.0 12.0 11.0 11.0 13.0 11.0 11.0 10.0 9.0<br />Snow Cloud <strong>15.0</strong> 15.0 12.0 13.0 10.0 12.0 13.0 12.0 12.0 15.0 9.0 12.0<br />Equally Fast <strong>17.0</strong> 17.0 17.0 15.0 17.0 17.0 17.0 17.0 15.0 17.0 13.0 17.0<br />Mc Diamond <strong>67.0</strong> 67.0 41.0 34.0 67.0 51.0 41.0 34.0 51.0 67.0 41.0 41.0</p>
<p>In this article we will choose the best price or joint best price available but any set of ods can be choose.</p>
<p>So we construct our list of best prices with the folowing values: [3.25, 3.5, 4.0, 13.0, 15.0, 17.0, 67.0]</p>
<pre id="block-15d1b0d9-ff9f-4489-a5ee-2b3ec84d1fa8" class="wp-block-code block-editor-block-list__block wp-block is-selected" tabindex="0" role="group" aria-label="Block: Code" data-block="15d1b0d9-ff9f-4489-a5ee-2b3ec84d1fa8" data-type="core/code" data-title="Code"><code class="block-editor-rich-text__editable rich-text" role="textbox" contenteditable="true" aria-multiline="true" aria-label="Code">maxPrices = [3.25, 3.5, 4.0, 13.0, 15.0, 17.0, 67.0]</code></pre>
<h1>Calculate the Overround of a set of outcomes</h1>
<p>To calculate the overround of a set of prices is easy. Basically what needs to be done is to iterate through the list of prices, and calculate the chances of winning each one, accumulate them and see how this number exceeds of 1 (or 100% if we are counting percentages).</p>
<p>To work out the probability of each outcome to win we need to do the following division:</p>
<p>1 / odds</p>
<p>Then we will sum up all these probabilities and will get the overround of the race</p>
<p>overround = 0<br />for price in maxPrices:<br />overround = overround + 1/price<br />print(&#8220;Total overround is&#8221;,overround) </p>
<p>which gives us the following output: Total overround is 1.0607452395424302</p>
<h1>Determine the true odds</h1>
<p>For calculating the fair price we will multiply the current price by the overround we calculated in the previous step. In case we were working with probabilities, the process would be the same.</p>
<p><br />fairPrice = []<br />for price in maxPrices:<br />fairPrice = fairPrice + [price * overround]<br />print(&#8220;fairPrice&#8221;,fairPrice)</p>
<p>The new fair price list without the overround is the following:</p>
<p>fairPrice [3.4474220285128983, 3.7126083383985056, 4.242980958169721, 13.789688114051593, 15.911178593136452, 18.032669072221314, 71.06993104934283]</p>
<h1>Generate a new set of odds</h1>
<p>The following step is generating a new set of odds. These can be generated with different techniques. We cover the following in this article:</p>
<h2>First approach for pricing: Apply the overround linearly</h2>
<p>This solution is not the most usefull one but in some cases it may work. Basically it consists in dividing the total percent of overround equaly amongst all the outcomes. This is usually not a good idea as we can get inflated prices for the favourites against the outsiders. And as we know, money is likely to go for these heading the market. So from a bookmaking point of view, it does not make too much sense.</p>
<p>We have not considered this solution as interesting for the article, so we are not covering it.</p>
<h2>A better approach: Apply the overround based on the chance of winning</h2>
<p>In this paragraph we are presenting a better approach. Instead of dividing the overround in equally parts, we will divide the overround depending on the chance of winning. So, based on the calculated odds, we will apply one part of the overround on the other. This partially compensates the problem with the previous method, and will usually be more than enough, though sometimes it is not yet the perfect solution.</p>
<p>In our sample, we will be applying a 5% of overround on the fair price calculated in the previous step.</p>
<p>appliedOverround5pct = []<br />for price in fairPrice:<br />appliedOverround5pct = appliedOverround5pct + [price/1.05]<br />print(&#8220;appliedOverround 5%&#8221;,appliedOverround5pct)<br /><br /></p>
<p>The new list with a 5% of overround is the folowing. As you can see, prices are slightly higher that they were origially as the overround is 1% less:<br />[3.2832590747741888, 3.5358174651414336, 4.040934245875924, 13.133036299096755, 15.153503422034715, 17.17397054497268, 67.68564861842174]</p>
<h2>The real deal: Apply the overround based on a model</h2>
<p>This solution will entitle in building a model of prices withou overround and winning results. Based on a big number of outcomes we would able to model and predict the overround to apply based on this historical data.</p>
<p>Since this would involve a model creation and usually this means some complexity, and the samples presented are good enough to go, we left this out of the scope of this article.</p>
<p>The full code is here:</p>


<pre class="wp-block-code"><code>def pythonPriceOverround():
maxPrices = &#91;3.25, 3.5, 4.0, 13.0, 15.0, 17.0, 67.0]

print(maxPrices)
overround = 0
for price in maxPrices:
overround = overround + 1/price

print("Total overround is",overround)

fairPrice = &#91;]
for price in maxPrices:
fairPrice = fairPrice + &#91;price * overround]
print("fairPrice",fairPrice)

appliedOverround5pct = &#91;]

for price in fairPrice:
appliedOverround5pct = appliedOverround5pct + &#91;price/1.05]
print("appliedOverround 5%",appliedOverround5pct)

#Check than now the overround is indeed a 5%
overround = 0
for price in appliedOverround5pct:
overround = overround + 1/price

print("Total overround is",overround)</code></pre>



<p></p>



<p></p>
<p>The post <a href="https://www.albertnogues.com/introduction-to-the-maths-of-bookmaking-with-python-code/">Introduction to the maths of bookmaking (with python code)</a> appeared first on <a href="https://www.albertnogues.com">Albert Nogués</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
