Wednesday, May 13, 2015

pyspark + ipython = tab-completing python shell for spark

Update (2015-06-21): The new version of Spark (1.4.0) resolved the naming issue for environment variables, so that environment variables in Windows and Linux have the same names. Big thank-you to Aviad "Jo" Cohen for pointing this out to me!

<tldr>
How to run pyspark via IPython/IPython Notebook in Windows/Mac/Linux, and how to turn off its log messages.
</tldr>

Big-data is a lie - that we all know. To make it more believable, a shift was made from disk-based Map-Reduce (aka: Map-Reduce) to RAM-based Map-Reduce (aka: Spark). The immediate benefit is that Pig, which uses disk-based Map-Reduce, now has a fork called Spork (Pig over Spark). Just say that: spork!!! The joy is boundless.

Spark is fun if you like writing in Scala. (I am of course ignoring Java completely, just like everyone else should.) In case you are like me - trapped in the belly of Python, with no intention to ever leave these cozy intestines, you'll be working with the Python port of spark, dubbed PySpark. I call this a 'port' rather than a version or a driver since some parts available in the Scala/Java versions of Spark are not available in Python (for instance, their graph toolkit, GraphX). However, it's still useful for many.

When you downloaded a pre-built binary version of Spark (from here), the versions > 1.3 support integration with ipython. This is based on having ipython in your PATH and adding some environment variables. Here's how to achieve it:

0) Make sure python is installed: from the Windows cmd or Linux shell, type in:
$ python
(you should get a Python shell, exit() the shell.)
$ pip
(you should see that pip is installed.)

Windows users: to make the best out of pyspark you should probably have numpy installed (since it is used by MLlib). It's is a pain to install this on vanilla Python, so my advice is to download Anaconda Python, a distribution of python - which means Python + tons of packages already installed (numpy, scipy, pandas, networkx and much more). This is also good for installing 64-bit Python (rather than the usual 32-bit version). Get Anaconda from here:
http://continuum.io/downloads


1) Install ipython, pyradline:

$ pip install ipython
$ pip install pyreadline


2) Make sure that the ipython executable is in your path (if you can run pip with no problems, that should be ok as well).


3) Set the proper environment variables:
On Windows:


$ set PYSPARK_DRIVER_PYTHON="ipython"
(or set it permanently in the control panel)

On Mac/Linux:
$ declare -x PYSPARK_DRIVER_PYTHON="ipython"
(or add it to your ~/.bash_profile or ~/.bashrc file)

On Windows + Spark < 1.4.0:


$ set IPYTHON=1


4) Run pyspark, and you'll get it in IPython with auto completion working! Now you'll never mistake spelling sc.paralelize sc.parrallelize sc.parallelize again!


Bonus rounds:

5) If you want to use pyspark and IPython Notebook, you can install IPython Notebook, and then make pyspark use it:
On Windows:
$ set PYSPARK_DRIVER_PYTHON_OPTS=notebook
(or set it permanently in the control panel)

On Mac/Linux:
$ declare -x PYSPARK_DRIVER_PYTHON_OPTS="notebook"
(or add it to your ~/.bash_profile or ~/.bashrc file)

On Windows + Spark < 1.4.0:


$ set IPYTHON_OPTS=notebook

In the next IPython Notebook, the sc object will be available right from the start (no need to define it) as well as the pyspark module.


6) Last but not least, like any good Java program Spark makes a big drama out of its execution by printing out lots and lots of lengthy log messages. You can turn them off by following this StackOverflow answer:
http://stackoverflow.com/questions/25193488/how-to-turn-off-info-logging-in-pyspark


Enjoy Sparking!

Sunday, May 3, 2015

How to install IPython Notebook + matplotlib + GraphLab Create

tl;dr: these instructions *work*. I'm publishing them here mainly to make them quickly accessible for my own use.

Install the following to get a fully working IPython Notebook:

$ sudo apt-get install python-dev
$ sudo apt-get install libzmq3-dev
$ sudo pip install pyzmq
$ sudo pip install jinja2
$ sudo pip install pygments
$ sudo pip install tornado
$ sudo pip install jsonschema
$ sudo pip install ipython
$ sudo pip install "ipython[notebook]"


If you want to use this machine as a server, follow these instructions:

These instructions including creating an SSL key pair so that you can access the IPython server via https from a remote machine.


Additionally, install this to get a fully working matplotlib:

$ sudo apt-get install libpng-dev
$ sudo apt-get install libfreetype6
$ sudo apt-get install libfreetype6-dev
$ sudo apt-get install g++
$ sudo pip install matplotlib


And finally, install GraphLab Create:

$ pip install graphlab-create

Note: for GraphLab Create to work, your Python instance should be built with the UCS4 flag. To check if that was the case:

(Taken from: http://stackoverflow.com/questions/1446347/how-to-find-out-if-python-is-compiled-with-ucs-2-or-ucs-4 )

When built with --enable-unicode=ucs4:
>>> import sys
>>> print sys.maxunicode
1114111
When built with --enable-unicode=ucs2:
>>> import sys
>>> print sys.maxunicode
65535



GraphLab Create Product Key Setup

After GraphLab is installed, you need to get a product key from dato.com (for free, after a simple and short registration). When you register, you receive the product key within a script for installing it into the appropriate directory. In case you lost the script and only have the product key, you can also set it via GraphLab itself.

$ python
>>> import graphlab as gl
>>> gl.product_key.set_product_key("PRODUCT KEY OBTAINED FROM DATO AFTER REGISTRATION")

Tuesday, March 10, 2015

Resizing a VirtualBox vm's disk using gparted - by Derek Molloy

Had to place a link somwhere to this awsome post by Derek Molloy, about how to resize the disk for a VirtualBox VM:
http://derekmolloy.ie/resize-a-virtualbox-disk/

If you install Ubuntu Desktop (like I did), reserve more than 8GB for disk space... This process is a bit lengthy and annoying, but Derek's post makes it a bit better with it's clear explanations.

Tuesday, January 27, 2015

Compiling GCC 4.9.2 from scratch on CentOS 6.5

I required GCC 4.8+ to compile the GraphLab Create SDK:
https://github.com/graphlab-code/GraphLab-Create-SDK

The machine runs CentOS 6.5 (for which yum does not yet offer the latest version of GCC), so I had to compile it on my own. Luckily, I have root access on this machine.

To compile it from scratch, GMP, MPFR and MPC should be installed:

yum install gmp-devel mpfr-devel libmpc-devel

Afterwards, the official installation instructions may be followed:
https://gcc.gnu.org/wiki/InstallingGCC

Monday, December 29, 2014

Installing python-igraph 0.7 (when cannot compile against libxml2.a)

Scientific Linux 6.5 (SL6.5), trying to install python-igraph, but getting error documented here:
https://github.com/igraph/igraph/issues/640. When trying to pip install python-igraph, version 0.7 yields the following error:

/usr/lib64/gcc/x86_64-suse-linux/4.3/../../../../x86_64-suse-linux/bin/ld: /usr/lib64/libxml2.a(entities.o): relocation R_X86_64_32 against `.text' can not be used when making a shared object; recompile with -fPIC

/usr/lib64/libxml2.a: could not read symbols: Bad value

collect2: ld returned 1 exit status
The server is not mine, so I am not a sudoer or anything.

The solution is mentioned in the github issue:


I modified the setup.py as follows:
I changed the line
variants = ["lib{0}.a", "{0}.a", "{0}.lib", "lib{0}.lib"]
to
variants = ["lib{0}.so", "{0}.so"]
I downloaded Python 2.7.9's source code and compiled it on a local directory. I then added it to my PATH so that my newly compiled version would be the one I use by default. I logged out, logged in, downloaded the python-igraph source code, and modified the variants in the setup.py and used Python to install igraph:

python setup.py install

I then tried to import igraph from Python, but got an ImportError:

ImportError: libigraph.so.0: cannot open shared object file: No such file or directory

So I looked it up and found that in the igraph source code directory (where it was built) and found the libigraph.so.0 file. On the GitHub link, they say you should copy it to the /lib folder under your Python installation. That did not work for me (maybe because I don't use Anaconda like they do, but who knows). So I added that

setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:/path/to/build/source/of/python-igraph-0.7/igraphcore/lib

and now igraph could be imported from my own Python installation.


I am writing this post because:

  1. I almost resorted to using the crappy C API of igraph; such desperation is surely worth of a post.
  2. The answer supplied by the igraph team here: http://lists.nongnu.org/archive/html/igraph-help/2014-09/msg00041.html
    is misleading and did not help me, so I thought it'd be worth to upvote the GitHub issue answer by a link.

That's it.

Thursday, February 27, 2014

Getting logs for jobs / tasks in Hadoop 2

tl;dr

mapred job -list all | grep <username> #get your job-id
mapred job -events <job-id> # print attempts
mapred job -logs <job-id> [<attempt-id>] #all/just for attempt

That's it. I'm not going to spend another word discussing this. Grab the shell terminal and try it yourself, and everything will be clear.

tl;dr+

#here's the same example and some outputs with:

  • <username> = reuts
  • <job-id> = job_1392731301770_0015
  • <attempt-id> = attempt_1392731301770_0015_m_000001_0

[root@hadoopb home]# mapred job -list all | grep reuts #all the 
14/02/27 17:20:00 INFO service.AbstractService: Service:org.apache.hadoop.yarn.client.YarnClientImpl is inited.
14/02/27 17:20:00 INFO service.AbstractService: Service:org.apache.hadoop.yarn.client.YarnClientImpl is started.
 job_1392731301770_0022     FAILED       1393505972362         reuts         default        NORMAL                    0               0       0M              0M                0M      hadoopb-w02:8088/proxy/application_1392731301770_0022/jobhistory/job/job_1392731301770_0022
 job_1392731301770_0021     FAILED       1393504180159         reuts         default        NORMAL                    0               0       0M              0M                0M      hadoopb-w02:8088/proxy/application_1392731301770_0021/jobhistory/job/job_1392731301770_0021
 job_1392731301770_0016     FAILED       1393455977860         reuts         default        NORMAL                    0               0       0M              0M                0M      hadoopb-w02:8088/proxy/application_1392731301770_0016/jobhistory/job/job_1392731301770_0016

#... many more failures after that! I picked one of the last which is not shown here - job_1392731301770_0015

[root@hadoopb home]# mapred job -events job_1392731301770_0015 #the high-level events.
Usage: CLI [-events <job-id> <from-event-#> <#-of-events>]. Event #s start from 1.
[root@hadoopb home]# mapred job -events job_1392731301770_0015 1 100
14/02/27 17:19:44 INFO service.AbstractService: Service:org.apache.hadoop.yarn.client.YarnClientImpl is inited.
14/02/27 17:19:44 INFO service.AbstractService: Service:org.apache.hadoop.yarn.client.YarnClientImpl is started.
14/02/27 17:19:45 INFO mapred.ClientServiceDelegate: Application state is completed. FinalApplicationStatus=FAILED. Redirecting to job history server
Task completion events for job_1392731301770_0015
Number of events (from 1) are: 6
FAILED attempt_1392731301770_0015_m_000001_0 hadoopb-w07:59031/tasklog?plaintext=true&attemptid=attempt_1392731301770_0015_m_000001_0
FAILED attempt_1392731301770_0015_m_000001_1 hadoopb-w06:45315/tasklog?plaintext=true&attemptid=attempt_1392731301770_0015_m_000001_1
FAILED attempt_1392731301770_0015_m_000000_1 hadoopb-w05:48979/tasklog?plaintext=true&attemptid=attempt_1392731301770_0015_m_000000_1
FAILED attempt_1392731301770_0015_m_000001_2 hadoopb-w07:59031/tasklog?plaintext=true&attemptid=attempt_1392731301770_0015_m_000001_2
FAILED attempt_1392731301770_0015_m_000000_2 hadoopb-w06:45315/tasklog?plaintext=true&attemptid=attempt_1392731301770_0015_m_000000_2
FAILED attempt_1392731301770_0015_m_000001_3 hadoopb-w06:45315/tasklog?plaintext=true&attemptid=attempt_1392731301770_0015_m_000001_3

[root@hadoopb home]# mapred job -logs job_1392731301770_0015 #that'd spit all the logs, so lets specify an attemptID.
[root@hadoopb home]# mapred job -logs job_1392731301770_0015 attempt_1392731301770_0015_m_000001_0
14/02/27 17:21:18 INFO service.AbstractService: Service:org.apache.hadoop.yarn.client.YarnClientImpl is inited.
14/02/27 17:21:18 INFO service.AbstractService: Service:org.apache.hadoop.yarn.client.YarnClientImpl is started.
14/02/27 17:21:19 INFO mapred.ClientServiceDelegate: Application state is completed. FinalApplicationStatus=FAILED. Redirecting to job history server

LogType:stderr

LogLength:250
Log Contents:
Traceback (most recent call last):
  File "/mnt/disk2/hadoop/yarn/usercache/reuts/appcache/application_1392731301770_0015/container_1392731301770_0015_01_000003/./mapper.py", line 11, in <module>
    import config
ImportError: No module named config

LogType:stdout

LogLength:0
Log Contents:

LogType:syslog

LogLength:11461
Log Contents:
2014-02-27 01:01:50,943 WARN [main] org.apache.hadoop.conf.Configuration: job.xml:an attempt to override final parameter: mapreduce.job.end-notification.max.retry.interval;  Ignoring.
2014-02-27 01:01:50,944 WARN [main] org.apache.hadoop.conf.Configuration: job.xml:an attempt to override final parameter: mapreduce.job.end-notification.max.attempts;  Ignoring.
2014-02-27 01:01:51,062 INFO [main] org.apache.hadoop.metrics2.impl.MetricsConfig: loaded properties from hadoop-metrics2.properties