Category Archives: Technology

Lamborghini special Event – Los Gatos, CA (March 2014)

March didn’t offer us the best weather for car gatherings, but that didn’t stop the gathering of some of the most unique Lamborghini’s in Northern California in Los Gatos.

What made the day truly special, as a visit by Lamborghini’s former test driver Valentino Balboni! What a treat to meet Supercar royalty.

The Cars

31 new photos added 12-MAY-2014

LG-LAMBO-001

LG-LAMBO-002

LG-LAMBO-003

LG-LAMBO-004

LG-LAMBO-005

LG-LAMBO-006

LG-LAMBO-007

LG-LAMBO-008

LG-LAMBO-009

LG-LAMBO-010

LG-LAMBO-011

LG-LAMBO-012

LG-LAMBO-013

LG-LAMBO-014

LG-LAMBO-015

LG-LAMBO-016

LG-LAMBO-017

LG-LAMBO-018

LG-LAMBO-019

LG-LAMBO-020

LG-LAMBO-021

LG-LAMBO-022

LG-LAMBO-023

LG-LAMBO-024

LG-LAMBO-025

LG-LAMBO-026

LG-LAMBO-027

LG-LAMBO-028

LG-LAMBO-029

LG-LAMBO-030

LG-LAMBO-031

LG-LAMBO-032

LG-LAMBO-033

LG-LAMBO-034

LG-LAMBO-035

LG-LAMBO-036

LG-LAMBO-037

LG-LAMBO-038

LG-LAMBO-039

LG-LAMBO-040

LG-LAMBO-041

LG-LAMBO-042

LG-LAMBO-043

LG-LAMBO-044

LG-LAMBO-045

LG-LAMBO-046

LG-LAMBO-047

LG-LAMBO-048

LG-LAMBO-049

LG-LAMBO-050

LG-LAMBO-051

LG-LAMBO-052

LG-LAMBO-053

LG-LAMBO-054

LG-LAMBO-055

LG-LAMBO-056

LG-LAMBO-057

LG-LAMBO-058

LG-LAMBO-059

LG-LAMBO-060

LG-LAMBO-061

LG-LAMBO-062

LG-LAMBO-063

LG-LAMBO-064

LG-LAMBO-065

LG-LAMBO-066

LG-LAMBO-067

LG-LAMBO-068

LG-LAMBO-069

LG-LAMBO-070

LG-LAMBO-071

LG-LAMBO-072

LG-LAMBO-073

LG-LAMBO-074

LG-LAMBO-075

LG-LAMBO-076

LG-LAMBO-077

LG-LAMBO-078

LG-LAMBO-079

LG-LAMBO-080

LG-LAMBO-081

LG-LAMBO-082

LG-LAMBO-083

LG-LAMBO-084

LG-LAMBO-085

LG-LAMBO-086

LG-LAMBO-087

LG-LAMBO-088

LG-LAMBO-089

LG-LAMBO-090

LG-LAMBO-091

PHP array_shift() not a function for general use

While looking at metrics an monitoring the processing of a CBMHDHS*, I noticed that the active job queue would become quiescent for minutes at a time. Most markedly with the one specific tasklist. My gut told me it was an issue with the way PHP was handling my simple list (700,000 items give or take). So some performance testing was required. What I found was astonishing. PHP’s array_shift is horribly inefficient.

Here is an example to demonstrate this.

When shifting 2500 items (one at a time) off the array (list), it can take 30 or more seconds. Keep in mind this is all in memory! This test is with only 108,000 items:


2013-08-16 18:21:06 # STARTING ARRAY_SHIFT TEST: Q:108581
2013-08-16 18:21:43 # DONE removed 2500 Q:106081

It took 37 seconds, to be exact. To me, that seemed like a long time. Doing a little research I found that when you rewind an array to it’s beginning (using PHP), one of it’s side effects is that it returns the element at that pointer. Reset looks like a scary operation. It does not ‘reset’ the array in the sense of flushing it out, it just resets the pointer to the top. At any rate. the code looked like this:


$element = reset($array);

So, in theory one could use this to get the first element off an array automatically, without removing it. OK, but shift_array does this ANY removes the element. So this is not really the same action. However… (and you know there is a point there), there is another PHP function with a useful side effect. The ‘key() function‘ that returns the key value of at the current pointer (which in this case is the same location we returned the element above). It looks like this:


$key = key($array);

Now, with those two lines of code I have the element (value) and the key at the top of the array. So this is 2 lines of code where array_shift() is just one.. but we’re not even done yet.. we have to perform the most important part (for this exercise) and remove the element. So.. that’s a 3rd line of code like this, right?


unset($array[$key]);

OK.. so taking a line of code right out of the processor, there is a direct comparison. array_shift on the left, reset, key, unset on the right.

Array Shift method Array Reset, Key and Unset method
$key = array_shift($this->QUEUE)) {
$payload = $this->DATA[$key];
$appkey  = reset($this->QUEUE);
$payload = $this->DATA[$appkey];
$key     =  key($this->QUEUE);
unset($this->QUEUE[$key]);

What I didn’t expect to find is how dramatically FASTER the more complex (looking) code is. In The numbers don’t lie.. see for yourself.

Array Shift method.

Total time for 2500 items removed is 37 seconds:


2013-08-16 18:21:06 # STARTING ARRAY_SHIFT TEST: Q:108581
2013-08-16 18:21:43 # DONE removed 2500 Q:106081

Array Reset, Key + Unset method.

Total time for 2500 items removed is <1 second:


2013-08-16 18:21:46 # STARTING ARRAY_RESET TEST: Q:108581
2013-08-16 18:21:46 # DONE removed 2500 Q:106081

Those numbers include getting the payload data out of the 2nd array.

Mind blowing in my opinion. It’s not even a contest. Writing your own is at least 15 times faster than PHP’s native operation, that for all intents, accomplishes the same objective.

The point of all this?

If you are seeing an inexplicable slowdown somewhere in PHP.. and you can narrow it down to 1-2 operations… it’s probably worth your while to try to do it another way, even if that way looks more complex!

I could not believe this when I tried it. When I implement this in the processor, I should be able to remove hours of useless waiting to ‘shift’ items off the list. At some point I’d hope Zend would fix this. Keep in mind I ran this test on PHP 5.5.3 (the latest stable release I could get my mitts on, at the time).

*Cloud Based Massivly Horizontal Distributed Harvesting System

Amazon AWS – spinning up a micro for Gearman Client

Walkthough for spinning up a micro EC2 for use as a GearMan worker node.

This is a preliminary effort, and the steps may very well change over the next few weeks as these are tested out. The documentation I’m presenting here is based on my previous work [HERE] Install Gearman + Gearman-PHP on AWS ec2.

Getting Started

This assumes you already have an AWS account setup. If you don’t you need to go do that now. You can get started [HERE].

Once logged in, go to your dashboard. From here you’ll be selecting the EC2 area.
Screen Shot 2013-06-17 at 10.26.23 AM

Under resources you’ll find a button “Launch Instance”. This is the button you want to click. This is where the fun begins.
Screen Shot 2013-06-17 at 10.27.57 AM

In this case I’m going to use the ‘Classic Wizard’. It’s really not that magical but Wizard is such a super-awesome-cool-name (ala Windoze ’95) you’ll see it used here. Anyhow, I’m going classic:
Screen Shot 2013-06-17 at 10.30.04 AM

I want to keep things EVERY simple here so I’m going use the default Amazon AWS distribution/AMI.
Screen Shot 2013-06-17 at 10.31.52 AM

For this exercise, I’m using an ‘On Demand’ Micro instance:
Screen Shot 2013-06-17 at 10.34.01 AM

No Advanced features should be required, so I’ve left everything on this page set to it’s default settings:
Screen Shot 2013-06-17 at 10.36.20 AM

Next the storage requirements are defined. Since this is a worker that should be able to be spun up on need, and shouldn’t require much in the way of local storage, I’m going to opt out of defining and EBS volume and rely upon Ephemeral storage.
Screen Shot 2013-06-17 at 10.40.43 AM

At this point, I don’t see the need to define any keys for EC2 management, so I’m leaving this area blank:
Screen Shot 2013-06-17 at 10.41.30 AM

Next, select the .ssh key file (it’s stored in a .pem file) that you want to use to access this system. If you don’t have a set of these keys setup already, you’ll want to define them. I’m using one specific to this node class already defined.. you’ll need to handle this step as your policy/needs dictate. It’s not that complex, but word to you, DOWNLOAD THAT KEY, once you create it, there is no known way (according to all places I’ve checked) to download it again. BE WARNED.
Screen Shot 2013-06-17 at 10.47.16 AM

Next step will be do select a security profile for your node. I’ve found that the default one is sufficient for these purposes. You may want to further restrict the number of ports open, as the default opens a few extra things you might not want. This is another area where you’re own needs an policy will need to be carefully considered. Otherwise, start with default and iterate to the optimal configuration.
Screen Shot 2013-06-17 at 10.52.02 AM

Check your settings on this review page, and if everything is to your preference, then you can spin it up!!
Screen Shot 2013-06-17 at 10.55.38 AM

One you click launch, it will take a little while for the instance to go live.
Screen Shot 2013-06-17 at 10.57.20 AM

Once launched, you’ll be able to see your instance in the dashboard! Sorry bout all the greyd out information, but the instance I’m talking about is slightly highlighted in blue.
Screen Shot 2013-06-17 at 11.00.22 AM

NOW, YOU CAN START TO INSTALL YOUR GEARMAN COMPONENTS

Install Gearman + Gearman-PHP on AWS ec2

The fun and games continue!! As with every Gearman implementation I’ve done, there are trick for each environment. Here are the Cliff Notes (originally sourced from [Planet MySQL page] with my own twist) for getting Gearman setup on an Amazon Web Services (AWS) EC2 (Elastic Computing 2) node running the default AWS distribution. As always, your experience may vary.

Install required libraries

First, get all the required libraries installed using yum:

[ec2-user@]$ sudo yum install -y gcc
[ec2-user@]$ sudo yum install -y gcc-c++
[ec2-user@]$ sudo yum install -y gperf
[ec2-user@]$ sudo yum install -y boost
[ec2-user@]$ sudo yum install -y boost-devel
[ec2-user@]$ sudo yum install -y memcached
[ec2-user@]$ sudo yum install -y libuuid
[ec2-user@]$ sudo yum install -y libuuid-devel
[ec2-user@]$ sudo yum install -y libevent-devel
[ec2-user@]$ sudo yum install -y php-devel
[ec2-user@]$ sudo yum install -y php-xml

Compile Gearmand from Source

Very straight forward config and build.

[ec2-user@]$ cd gearmand-1.1.9
[ec2-user@]$ sudo ./configure --with-boost=/usr/include --prefix=/usr
[ec2-user@]$ sudo make
[ec2-user@]$ sudo make install

Compile Gearman PHP Library from Source

Fairly simple build, but you must first phpize.

[ec2-user@]$ cd gearman-1.1.1
[ec2-user@]$ sudo phpize
[ec2-user@]$ sudo ./configure --prefix=/usr
[ec2-user@]$ sudo make
[ec2-user@]$ sudo make install

Run ldconfig to Reload Dynmaic Library Cache

If you don’t run ldconfig, you’re going to get errors when you edit the php.ini file (last step).


bad:
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/gearman.so' - libgearman.so.8: cannot open shared object file: No such file or directory in Unknown on line 0

[ec2-user@]$ sudo ldconfig

Edit the PHP ini file

This is the last step.

finding location of your php.ini file
[ec2-user@]$ php -i | grep php.ini
Configuration File (php.ini) Path => /etc
Loaded Configuration File => /etc/php.ini

Edit your config file, adding these lines:

[ec2-user@]$ sudo vi /etc/php.ini
[Gearman]
; Add Gearman shared object to config
extension="gearman.so"

Now your install is complete!!

Installing HomeBrew for OSX

Installing Homebrew

This process appeared to be fairly trivial. Run the following command. The script will tell you want it wants to do. I stuck with the default responses and let it do it’s worst. You will probably want to read the HomeBrew page [HERE] first, before just trusting me.


david$ ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"

Next step was to run the Brew Doctor and address any major issues raised there, of which I had a few. The most pressing of which was this:

Warning: Xcode is installed to a directory with a space in the name.
This will cause some formulae to fail to build.

I deleted XCode 4.3.3 (my latest installed version) and re-installed which gave me version 4.6.2. Next I had to install the ‘Command Line Tools’ (no longer embeded in XCode). That can be found in the XCode Preferences -> Downloads.

I had a few other issues, stray libraries from botched builds past. I worked through my issued and then tried to installing components.

Since Boost seems to be very commonly referenced, I went ahead and installed it with Brew as it’s first task:

Installing Boost using Brew

Then went about installing boost with HomeBrew, since it did not seem to get all the components I needed when installed via MacPorts/Fink.


david$ brew install boost

This appears to have installed boost-1.53.0

* DONE *

Now, you may Brew!

Installing Gearman PHP components for OSX- (less fun that it should be)

gearmanlogo

NOTES: Installing Geaman’s PHP components on OSX is a frustrating and rather complex task. Know this going in. The only way I was finally able to do this was by reading this page here, from one of PHP’s own engineers, got me pretty close but it was still not a full solution. [HERE]. YOU HAVE BEEN WARNED!!

FIRST THINGS FIRST — Get the right versions!!

Do not use gearman.1.1.7!
As of this writing (7-JUN-2013) the current version of gearmand (gearmand-1.1.7) has a bug that prevents it from properly building on OSX. I waste probably 2 days before in a deep corner of the mind I thought.. “If 1.1.7 has a known bug in OSX, and they have not fixed it yet.. let’s try 1.1.6!, and that worked!! The main Gearman download page has multiple versions so just avoid 1.1.7.

Get the lateset PHP source, (gearman-1.1.2) NOT the one linked off the Gearman page!
Yes.. this wasted even more time. The Gearman page didn’t have a quick easy link to the full set of available versions, and the linked version from the page was very much out of date. There is another build bug regarding PHP. One of the engineers decided to get fancy and change the privacy of the objects members somewhere in 1.0.x tree. This BREAKS build on OSX. They did as recently as this year release a FIX for this which is version gearman-1.1.2. All of them can be had on this page [HERE].

Getting Library Dependancies Worked Out

After fighting with source code, screaming at the screen, and even getting completely frustrated with what I was able to (or not able to) install with MacPorts.. I decided to install HomeBrew and give that a run. It’s not a big deal but I moved that to it’s own page located [HERE].

libevent must be built/installed

You’re going to need libevent, and installing it straight up from brew (nor Mac Ports) did the job for me. Check out my previous pages on installing libevent located [HERE] for details on that exciting exercise.

You Must Install Gearmand (sever) regardless

Regardless of how you plan to user Gearman with PHP, you must have the GearmanD server compiled to create the required libraries. There are no two ways about it, just resign yourself to that and keep moving forward!

First, obtain the Gearmand source code for compile from [HERE]. I dropped min in /usr/local

Unball the file and cd into source code directory, configure and build with the following commands:

david$ cd gearmand-1.1.12/
david$ ./configure -disable-shared -prefix=/usr/local
david$ make && make install

A couple of adjunct notes

If you are having problems location the libevent.. or basically seeing this error:

checking test for a working libevent… no
configure: error: Unable to find libevent

Try setting these two environment variables, to tell the configurator exactly where to locate these libraries, if you’ve managed to build libevent from source:

[gearmand]$ export CPPFLAGS=’-I/usr/local/include’
[gearmand]$ export LDFLAGS=’-L/usr/local/lib’

Gearman — Starting the Java-Gearman-Service process

gearmanlogo
These notes apply to testing on a MAC OSX portable, and may or may not apply to your implementation. They are provided as an adjunct to my main Getting Gearman Going post elsewhere in this blog.

The project page for Java-Gearman-Service is located [HERE] on Google Code.

The full set of instructions for staring up Gearman’s Java-Gearman-Service were not clearly linked to the main Gearman project page, so I’m including the link [HERE] to save you the few Google dorkings I did to find it.

Starting up the Java service should be as simple as this:


java -jar java-gearman-service-0.6.6.jar

HOWEVER, I received this instead.. an error:


david$ java -jar java-gearman-service-0.6.6.jar
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/gearman/impl/Main : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

Checking my version shows that I am on 1.6 not 1.7 as I had thought;


david$ java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06-451-11M4406)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01-451, mixed mode)

To get the proper version, I navigated to the Oracle page located [HERE], agreed to their terms (do I really have a functional choice… not if I want/need to use Java…) and pushed forward.

If you are running the install for 1.7, you should see a dialog like this:
Screen Shot 2013-06-03 at 2.12.16 PM

That has at least resolved this part of the issue, and will attempt to restart the server.


david$ java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b12)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)

Now I’m going to restart, specific a custom port and get it kicked off in the background:


david$ java -jar java-gearman-service-0.6.6.jar -p6315 &

At this point the process is running on my Job Service box and next step will be to craft some code to see how it all works.

Deploying Java Gearman Job Server

gearmanlogo
OK, after more than a year it’s time to get down to really building out a Gearman system.

I’ve recently taken on a project that I believe to be the perfect fit for the pipelined distributed work manager of Gearman. I’m of course, not at liberty to discuss the various details of this project, but I can provide some high-level description for the purposes of justification.

The Project – distributed harvesting

The objective of the project is to provide a distributed method of web page scraping and parsing. This project requires that the scraping and profiling occur for 2,000,000+ websites in under 18 hours. No small feat for certain. The good news is that I’ve built a systems in the past (circa 2006) that did just this using MySQL as the task manager. It worked, but it had it’s issues, and almost every single one of them can be mitigated by using Gearman. The rest will be mitigated with the application of NoSQL solutions for site list management.

What is Gearman

Here is the synopsis from the Gearman.org main page.

Gearman provides a generic application framework to farm out work to other machines or processes that are better suited to do the work. It allows you to do work in parallel, to load balance processing, and to call functions between languages. It can be used in a variety of applications, from high-availability web sites to the transport of database replication events. In other words, it is the nervous system for how distributed processing communicates.

The Job Server — implementing in Amazon’s ES2 environment

For the project I’m working on, I’ve opted for the Java implementation of the Job Server. This implementation’s main page is located [HERE].

Information about the Java Job Server:

Java Gearman Service is an easy-to-use distributed network application framework implementing the gearman protocol used to farm out work to other machines or processes that are better suited to do the work. It allows you to do work in parallel, to load balance processing, and to call functions between languages.

04-23-2012 java-gearman-service v0.6 has been released. [DOWNLOAD]

  • The service now uses the slf4j logging facade, allowing the user to have better control over logging
  • Persistent background jobs are now supported though an application hook
  • The API has been updated to be more user friendly, and it makes it easier to create divide-and-conquer/mapreduce applications (breaks the code of previous versions)
  • A .properties file now may be used to set property values and fine-tune the application.
Requirements to deploy the Java job server:
  • Java SE 7
  • slf4j 1.6.4+

For my implementation, I’ve extracted the zip into a vendor directory form where I’ll plan to launch the .jar. Development is occurring on an Apple OSX portable, then deployed to the AWS EC2 cluster for production. It’s expected that some library pathing and configuration will be required to make this all work.

Starting up the Java Gearman Service

It took a little time to locate the instructions for Starting up the Java implementation of the Gearman Service. It is located [HERE].

Instructions on how I started the GearMan server on my OSX development machine are located [HERE].

Once started, you should be able to communicate with it with your Client and Worker code!!

Next steps:

Installing Gearman PHP components

Build a GearMan Client Demonstrator

Build a GearMan Worker Demonstrator

macports.conf points to a non-existing directory.

QUICK TIP:

If you receive the following error while attempting to install MacPorts, there is a quick and easy fix:

Warning: Your developer_dir setting in macports.conf points to a non-existing directory. Since this is known to cause problems, please correct the setting or comment it and let macports auto-discover the correct path.

The following commands will let you locate the current path, then set this into the macport.conf file, making installation of your MacPorts package more robust.

First, determine the actual path on your machine. Your path may vary. The path shown below is for my OSX 10.7 box.


xcode-select --print-path
/Applications/Xcode 4.3.3.app/Contents/Developer

Next, edit the macports.conf file, replacing the current entry with the one you just found above:


sudo vi /opt/local/etc/macports/macports.conf

[...]

# Directory containing Xcode Tools
#developer_dir /Developer
developer_dir /Applications/Xcode 4.3.3.app/Contents/Developer

[...]

Once you have done that, when you run the installation command, you’ll no longer see that annoying warning, and your MacPorts should be installed, ready for you to enjoy!


sudo port -c install coreutils +with_default_names

Dash Cam Test Run – Santa Cruz to SJC, CA

Sunday afternoon, I mounted my new $25 dash cam (purchased 2 of them from Amazon, $25 each to my door, I figured why not!) inside the windshield of my 2002 BMW ///M3 Convertible, and drove from Santa Cruz to San Jose (SJC airport) California.

Highway 17, has earned this dubious distinction as the most dangerous highway in California. With it’s steep decent from it’s 1800′ Santa Cruz Mountains summit to the Santa Clara Valley Floor below, it’s often this site of injury and fatality crashes.

Audio in the clip is horrible, and unedited. Wind noise due to the top on car being down, plus the fact I was wasting no time on “The Hill“.

While growing up in “The Valley”, heading over the hill to Santa Cruz always seemed like such a journey. Families would pack up food and drink to make it over the mountain. In reality, it’s a fairly short dive (about 20 miles) but back in the 70’s when I grew up, summer time temps well into the 90’s, combined with the fairly steep ascent to the summit (at 1800′) meant there was a pretty good chance you’d be taking a break in one of the turnouts while the car’s radiator cooled off enough to continue the drive. Using A/C on the hill was basically an impossibility, unless you enjoyed being temporarily stranded on the side of the highway while possibly awaiting a tow hook.

As I grew older, cars were built better, and I was able to afford these better cars, the drive to the beach became less and less an practice of gambling upon one’s luck, and simply being able to afford a 1/2 tank of gas on a high school or college student’s budget.