Friday, February 22, 2013

What is messaging and why should you care?


I drew the following diagram for wso2con talk. Through the diagram, I am trying to explain “what is messaging” and “why should you care”? Here are some thoughts.



When we build systems, often we use some form of RPC: like UNIX RPC, RMI, Web Services and Thrift etc. Yes, each has its unique traits, yet fundamentally all let users invoke a procedure call living in a remote server and has three properties.
  1. Request/response (a.k.a. two way messaging)
  2. Synchronous (client wait for the server to return)
  3. Transient (message is not stored)
Although, we often take these properties as granted, there is a flip side to each. For example, there are one-way interactions, asynchronous interactions, and persistent interactions.

As shown by the figure, those properties can be combined into eight possibilities, and RPC is just one of the eight. We use messaging to mean a superset of RPC interactions that allow users the flexibility of choosing above properties. Messaging systems (e.g. JMS) support Distributed Queues (see [2]) and Publish/Subscribe (see [1]) models.

Messaging may provide all or some of the following advantages.
  1. Reliability – via transactions or persistence 
  2. Performance – enable us to do SEDA like event driven non-blocking architecture that can provide higher throughput than blocking architectures. 
  3. Loose coupling – participants joining the interaction may loosely coupled in one of the following three dimensions (read the paper “Many faces of Publish Subscribe” for more information. )
    • Space – server and client do not need to know each other.
    • Time – server and client do not have to be online at the same time.
    • Synchronization –client does not have to wait for the message to be delivered.
References
  1. Eugster, Patrick Th, et al. "The many faces of publish/subscribe." ACM Computing Surveys (CSUR) 35.2 (2003): 114-131.
  2. Scalable Persistent Message Brokering with WSO2 Message Broker slide deck
.

Wednesday, January 30, 2013

Our book, "Hadoop MapReduce Cookbook" is online



Myself and Thilina has been working on a Book on Hadoop, and it is now online! You can find the book from http://www.packtpub.com/hadoop-mapreduce-cookbook/book or from Amazon at http://www.amazon.com/Hadoop-MapReduce-Cookbook-ebook/dp/B00B71KZRE/. It is available under both paperback as well as in the e-book format. 

Hadoop is an implementation of the MapReduce pattern first introduced by Goolge in their seminal paper MapReduce: Simplified Data Processing on Large Clusters . It provide a programming model for users to process large dataset using many computers. 

For example, let us consider there are few giga bytes of log files that contains access logs for a server. If you want to read those log files and count the number of hits received by each web page in the server. It is possible for the user to write a program that walks though the log file and process them. However, if the log files are large, users would need to process the log files using many computers. Writing a system that process such log files using many computers would be a significant undertaking. 

However, toolkits like Hadoop that support MapReduce framework would let users to write two functions called "map" and "reduce", and the framework will take care of the details of processing the log files. Furthermore, Hadoop will handle details like communication between nodes, scheduling sub-tasks, handling failures, and debugging. 

Log processing is only a trivial examples that can be implemented with MapReduce paradigm. It can and it is being used to implement many simple and complex data processing tasks around the world. Users can extend in many ways to handle different message formats. 

The book starts with simple introductory level details, but goes into many map reduce patterns like analytics, clustering, and recommendations etc. Each one is explained using a recipe and accompanied with code samples. We believe it has recipe that would help beginners as well as experienced MapReduce developers. 

Some important information. 
  1. Book uses Hadoop 1.0.x releases 
  2. Table of content is at http://www.amazon.com/Hadoop-MapReduce-Cookbook-ebook/dp/B00B71KZRE/ (click on the image)
  3. The sample chapter that talks about Analytics using MapReduce from https://www.packtpub.com/sites/default/files/9781849517287_Chapter_06.pdf  


This finishes about a year long process of writing editing, and re-editing. It took lot of time, but it was of course a great experience. I would like to thank the editorial team for all the help and feedback. We hope the book will be be useful for Hadoop developers. 

Enjoy!!



Wednesday, October 31, 2012

Do you need to match few 100k events per second? Siddhi Open source CEP Engine and WSO2 CEP Server 2.0 Released

I have written about Siddhi, a new open source java Complex Event Processing engine available under Apache License we were working on. At last, it has emerged, and we have out first production grade release of Siddhi.

Now Siddhi has become the runtime for WSO2 CEP server, and we have just released the WSO2 CEP 2.0 and Siddhi 2.0 comes bundled with it.

WSO2 CEP adds network support for Siddhi, and now you can use it with Thrift, HTTP, SOAP, and JMS.  Siddhi/WSO2 CEP 2.0 has several cool (new) features, but let me briefly list few things I believe are the key.

 1) Very fast (can do 1-2.5 Million events/ sec as a jar library)
 2) Fast across the network too (about 0.25 million event/sec over thrift calls)
 3) New Siddhi Query language (supports Filters, Windows, Pattern, Sequences, Joins). You can find the specification from http://docs.wso2.org/wiki/display/CEP200/Siddhi+Language+Specification
 4) Supports Hazzlecast based highly available deployments and large working memories
 5) Supports periodic snapshots of CEP state so it can recover the state in case of a failure
 6) Integrate closely with WSO2 BAM. Basically you can setup a system where you collect data from many event sources and send them to both BAM and CEP using the same thrift transport so that the former can do batch style hadoop/hive based processing and the latter can do real time processing.

 You can download the server from http://wso2.com/products/complex-event-processor.

 If you are looking for Siddhi jar to be used with your java code, it is in the .zip file. Alternatively you can get the jar from http://dist.wso2.org/maven2/org/wso2/siddhi/siddhi-distribution/1.0.0-wso2v2/.

 We have moved the code and mailing list to WSO2.

 You can find the code from https://svn.wso2.org/repos/wso2/carbon/platform/branches/4.0.0/dependencies/commons/siddhi/1.0.0-wso2v3/.

 You can find documents and samples from http://docs.wso2.org/wiki/display/CEP200/Complex+Event+Processor+Documentation.

 Any questions, you can ask at http://stackoverflow.com/questions/tagged/wso2/.

 I will soon write more about architecture and how some of the Siddhi/CEP features are implemented.













Wednesday, October 3, 2012

Offline Profiling with JProfiler


We use offline profiling when we want to run the profiling in the headless mode (without UI). Another option is to profile by connecting remotely using JProfiler GUI, which is great.  However, sometime even that option is not available if the network is slow or only allow SSH connection.

Following are quick instructions for offline profiling. For more details, refer to the "JProfiler Manual".
  1. Create a JProfile session and configure the triggers. Make sure you add a "save snapshot trigger with a timer", else you will not get anything. Do this like every 5-10 minutes. You can also give the target snapshot file location when you configure. 
  2. Copy local .jprofiler7/config.xml and JProfiler binaries or agent code to the remote machine 
  3. Add following before the java command.
    -agentpath:JPROF_LOCATION/bin/macos/libjprofilerti.jnilib=offline,id=SESSION_ID,config=/Users/srinath/.jprofiler7/config.xml 
    Here replace the configuration file and JProfiler location with your machine's values. SESSION_ID is the session ID of the session you created with JProfiler UI.  Here ~./jprofiler7/config.xml file has settings for all sessions creates by jprofiler, and it will pick up the right value.  If you are profiling in a remote machine copy your local configs to the remote host. 
  4. Start and run the program, and it will print  the following
  5. JProfiler> Using JVMTI
    JProfiler> JVMTI version 1.1 detected.
    JProfiler> 64-bit library
    JProfiler> Offline profiling mode.
    JProfiler> Using config file /Users/srinath/.jprofiler7/config.xml (id: 194)
    JProfiler> Listening on port: 8849.
    JProfiler> Instrumenting native methods.
    JProfiler> Can retransform classes.
    JProfiler> Can retransform any class.
    JProfiler> Native library initialized
    JProfiler> VM initialized
    JProfiler> Using dynamic instrumentation
    JProfiler> Time measurement: elapsed time
    JProfiler> CPU profiling enabled
    JProfiler> Hotspot compiler enabled

  6.  Open the snapshot file and analyze using JProfiler UI. 



Tuesday, July 3, 2012

Slides for Cloud Hands-on Tutorial in IEEE Cloud 2012

Following are the slides I used for the tutorial. As the sample, we deployed a Web Service and a Web Application. When deployed, users access the web application, which will do a call to the Web Service and show the results.

Hands on deployed the service and webapp in three setup.
  1. In the local machine
  2. In the Amazon EC2 (IaaS)
  3. In the WSO2 Stratos (PaaS)
The script for the demo can be found below. Please note it is only  a rough script. 




Abstract

When cloud computing was introduced a few years ago, it promised many advantages including self-service, elasticity, pay as you go, improved accessibility to computation resources, and full deployment automation. Few years down the line, now we can see many ideas, architectures, and systems shaping up providing more clarity and understanding into cloud computing landscape. Among them, there are many cloud computing systems that enable users to build systems in the cloud with minimal effort. Understanding those systems could provide great insights and understanding into both “cloud promise” and “cloud reality”. This tutorial will provide a brief introduction to the cloud, and discuss how to use some of the existing cloud computing systems with hands-on. We will demonstrate how to develop and run a SOA application in an Infrastructure as a Service platform (IaaS) as well as in a Platform as a Service Platform (PaaS).

Script 


As a demo, we will deploy a Web Service and a Web Application. When deployed, users access the web application, which will do a call to the Web Service and show the results. You can download the sample code from http://people.apache.org/~hemapani/dist/clouddemo/HelloStratos.zip. Download and unzip the distribution.
  1. webapp folder will have the Web app, and you can build the HelloStratosWebapp.war file by running the ant command from the webapp folder.
  2. services folder has the Web service, and you can build theHelloStratos-1.0.aar file by running mvn clean install

Local Hello Stratos Demo

  1. Edit the webapp/src/main/resources/index.jsp to do the service call to 127.0.0.1. Rebuild the webapp by running ant from webapp directory.
  2. Download WSO2 AS
  3. Running following commands to install WSO2 AS
    unzip wso2as-4.1.2.zip
    cd /Users/srinath/playground/cloud-2012-tutorial/wso2as-4.1.0
    cp /Users/srinath/playground/cloud-2012-tutorial/HelloStratos/webapp/target/HelloStratosWebapp.war repository/deployment/server/webapps/
    cp /Users/srinath/playground/cloud-2012-tutorial/HelloStratos/service/target/HelloStratos-1.0.aar repository/deployment/server/axis2services/
    
    
    
  4. Start the WSO2 AS via following commands.
    cd bin/
    ./wso2server.sh
    
    
    
  5. Go to the admin console and login via https://127.0.0.1:9443/carbon/admin/login.jsp, username password are admin, admin.
  6. Try out the service. 
  7. Show soap traces.
  8. Show Web app.
  9. Try out the Web app 

EC2 Demo

  1. Create AWS account
  2. Go to management console
  3. Create instance(Base AMI ami-2ab91843 and AMI with all setup AMI: Unnamed (ami-5805a731)) Create key pair in the process, save the key pair
  4. Connect to instance (srinath-2012.pem is the keypair in this case)

  5. ssh -i ~/.ssh/ec2/srinath-2012.pem ubuntu@ec2-23-22-125-63.compute-1.amazonaws.com

  6. Create a folder ieee-clouddemo
  7. Download WSO2 AS and install following command

  8. wget http://people.apache.org/~hemapani/dist/wso2as-4.1.2.zip
    sudo apt-get install unzip  
    
    Unzip WSAS distribution
    
    wget http://download.java.net/jdk6/6u34/promoted/b03/binaries/jdk-6u34-ea-bin-b03-linux-amd64-20_jun_2012.bin (direct link http://jdk6.java.net/download.html)
    
    ./jdk-6u34-ea-bin-b03-linux-amd64-20_jun_2012.bin
    
    export JAVA_HOME=/home/ubuntu/jdk1.6.0_34
    

  9. Edit Host name in carbon.xml
  10. Access Admin console via https://ec2-107-20-54-230.compute-1.amazonaws.com:9443/carbon/admin/login.jsp
  11. Upload the service via admin console
  12. tryout the service
  13. Download the HelloStratosWebapp.war from
  14. Upload the war file
  15. try out the war file
  16. Save the AMI

Stratos Demo

  1. Create an account from https://stratoslive.wso2.com/
  2. Login to Application Service in Stratos https://stratoslive.wso2.com/t/ieeecloud1.org/carbon/ (replace the ieeecloud1.org with your tenant.)
  3. Show services and compare with the standalone version
  4. Upload the service to stratos
  5. try it out
  6. Login to windows VM and upload the Web app
  7. Try the demo
  8. Enable security via uncommenting commented parts in web.xml
  9. Re-upload the services
  10. Try the Web app, it will ask for passwords. Login via admin admin.

Wednesday, June 6, 2012

Few thought on debugging

If you a developer who works on Distributed system, there is one thing you learn well. That is how to debug, and how to avoid having to debug. Following are some of my thoughts and somethings I generally do.

Debugging a Local Java Program

  1. If you write your program well, generally you will have a stack trace when you have a problem. (This does not apply well with performance problems and memory leaks. I will write a separate note about those. )
  2. Look at the trace; go to where the error happened. Try to figure out what happened. The best way to do this is by walking through the logic again.
  3. If that did not work, copy and paste your stack trace in to Google. About 80% of the time, you will find the answer there. Pay special attention to JIRA bug reports for the projects you are using and online forums like stackoverflow.com.
  4. If that did not work, you will have to debug. You can debug by running the code from your IDE (e.g. Eclipse) or by connecting to a server through a remote debugger. Walk through the logic using the debugger that generally tells what happened. For example, the article explains how to debug with eclipse and how to connect to a remote server.
  5. If none of these worked, now it is the time to go and ask for someone to help. There are some bugs that are very hard for the author of the code to see. However, you should go for help with problem recreated, debugger attached, and ready to let him step through the execution.
  6. If you have trouble with a specific tool, you can ask for help as user lists, forums, or general developer forums like stackoverflow.com.

Debugging a Distributed System

  1. Debugging distributed systems are hard. So best approach is to not to have to debug them. You can almost get there by writing unit tests and tests what you write in small steps. My preferred approach is to make one path work end to end, and do small changes while testing each change.
  2. Distributed system will have multiple Processors (JVMs). So it is tricky to debug them. If it is at all possible, find a way to run whole your distributed system within the same process (JVM). This will need some imagination from your end, but it will save you lot of trouble later.
  3. If you are debugging a distributed system, it is often useful to capture messages that are sent and received. You can do this via tools like TCP Monitor, SOAP Monitor, or Wireshark.
  4. It is doubly important to log all exception that can happen in your code. Otherwise, you will have no idea whether system worked or not. 
  5. I often append the timestamp and the name of process or host to each log line. One way to do this is by writing a Log4j appender. Time stamp and process or host name let me merge sort all the logs into one file and read the execution of the system in one read.
  6. It is likely that your distributed system process lot of messages. So it is very hard to read and understand the log. One way out of this is to trace every 1000th messages. I do this by having a message count and using.
    if(1000%messageCount=1){
       log.info(….);
    }
    
  7. If you running a complex system that has more than five nodes, you should invest in some mechanism to collect the logs using something like FLUME and automate their processing to find stack traces etc.

Tuesday, June 5, 2012

Scaling WSO2 Stratos

WSO2 Stratos is a Platform as a Service (PaaS) that offers middleware technologies like Web Services, Workflows, Messaging etc as a Service.

PaaS environments bring together many users and could potentially attract a large number of users. Therefore, scaling up is a major consideration for a PaaS. This post explain our experiences and some thoughts on scaling Stratos.

Problem

Stratos is multi-tenanted. In other words, there are many tenants. Each tenant generally represents an organization and isolated from other tenants, where each tenant has his own users, resources, and permissions. Stratos supports multiple PaaS services. Each PaaS service is actually a WSO2 Products (e.g. AS, BPS, ESB etc.) offered as a service. Using those services, tenants may deploy their own Web Services, Mediation logic, Workflows, and Gadgets etc.
  1. WSO2 Stratos runtime provides servers where each can support multiple tenants and provide a PaaS service. For example, there are multi-tenanted AS, BPS, ESB etc.
  2. Stratos can provision (add/remove) resources (computing nodes) as needed on demand.
  3. Problem is to build a system that scale up and down without end users realizing it.

Answers

Following describes a series of solutions while each solution adds a new feature to solve a specific problem. It explains the rationale and thought process behind the final design.

Solution 1
WSO2 Stratos consists of a multi-tenanted server of each type (e.g. ESB, BPS etc.). Users first talks to an Identity Server (IS), gets a SSO (single sign-on) token, and log in to any server. We stored all tenants data in a registry. Each server loads all tenants at the startup and can support any tenant when they receive a request.

Solution 2
Solution 1 does not scale at all. So we started running multiple instances of each server and put a load balancer (LB). LB load balances the requests to different servers. When load on the server instances are high, LB starts new server instances and when the load is low, LB shuts down some instances. We call this auto-scaling.

Solution 3
When Stratos had several hundred tenants and many tenants with tens of services, it took a long time to load all tenants at the startup. Start up took 15-30 minutes. Furthermore, most tenants stays inactive most of the time. However, since each node has to hold all tenants, Stratos spends resources for inactive tenants as well.

To avoid above problems, solution 3 added lazy loading. All information about tenants is stored in a central registry. Tenants are loaded into memory only when they are needed. Tenants get unloaded when they have been idle for more than a given timeout. You can find more information about Lazy loading from Azzez’s blog entry “Lazy Loading Deployment Artifacts in a PaaS Deployment”.

Solution 4
When tenants have several artifacts, loading them takes time. So if the tenant is accessed while it has not been loaded in solution 3, first request or two to the tenant will timeout.

Solution 4 added ghost deployer to solve the above problem. Ghost deployer does not load all information about tenants, but just loads the metadata. Actual artifacts are loaded on demand. As a result, loading a tenant has become a much simpler in Solution 4. So this avoids requests from timing out while loading the tenant. You can also find more information about Lazy loading from Azzez’s blog entry “Lazy Loading Deployment Artifacts in a PaaS Deployment”.

Solution 5
However in the solution 4, LB does not scale to handle a large number of requests. So we replace the LB with multiple LBs that have same metadata in all nodes. Therefore, all LB will take the same decision when it received a request. We can use this model to scale Stratos by placing a hardware Load balancer or setting up DNS round robin to distributed requests among LBs.

To synchronize the metadata across all LBs, we can use group communication. That is a MXM communication, which is heavy. Instead,  LBs in Stratos are designed to send updates as batches to a single decision service, and the decision service takes auto-scaling decisions. We enforce High Availability by running a replica of the decision service and keeping it up-to-date via state replication through group communication.

Solution 6
However, in Solution 5, LB instances are not aware of tenants. Due to lazy loading, all requests will work even through LBs route messages arbiterly. However, this might lead to a scenario where a single node has to load too many tenants.

To avoid this, in the solution 6, LBs are aware of tenants and allocate only a subset of tenants to each LB. You can find more information from the Sajeewa’s blog entry, WSO2 Tenant Aware Load balancer.

Solution 7
Upcoming Stratos release will follow the solution 6. However, the next potential problem is that Registry which holds the configurations and resources of all tenants could not scale to handle a large number of tenants. Hence the registry needs to be partitioned across multiple users.