Sunday, May 24, 2009

Yes Deletion is not write behind

There are a few critical words that Coherence or any similar distributed mechanisms are built around. Coherency, Consistency and Availability are a few. In a room if you ask a question to anyone about something and irrespective of who you ask you get the same reply we have a coherent system. They don't have to speak the truth but as long as they all tell the same answer it is a coherent system. Consistency is across the boundaries of a single data source. If the answer against a Coherence cluster is same as what say a relational database tells at a given time then these two systems are consistent systems. Availability is when applications have an ability to find the data irrespective of failures and unavailability. Coherence cache like any database supports Entry Insert, Update and Delete operations. While the Cache itself is coherent, Entry Insertion and Updates are about data availability while Delete is a peculiar use case and is about data consistency. Coherence write-behind is a mechanism that allows asynchronous/delayed persistence of changes in the Cache to an external data source like a Database. While inserts and updates can be delayed Entry deletion is not write-behind. Why?
Applications quite often confuse data eviction with data deletion. A poor analogy of eviction is like if someone moves from Phoenix, AZ to LA. If someone lives in Arizona and decides to leave it is similar to data eviction. Application looking at AZ data would not find him but there could be a way to find him if need be (barring a fact that its not the same object that lives at two places in real life but it does in two systems). Deletion is like that person dies. You cannot die in Arizona and live in Los Angeles. If thats the case probably LAPD has to get involved ;). Data deletion has to be conservative and needs to make sure it is consistent across all the data sources. This is why Coherence write-behind mechanism makes Entry deletion a synchronous process even if there is a delay set. The good thing is API contract is just to an extent of calling erase() method of the configured CacheStore. Even though not recommended but If your application mandates that all CRUD operations are of equal priority can be done by using some Timer service inside the erase () erase process still can offload the deletion steps to a separate thread that deletes data after a write-behind delay.

Sunday, May 17, 2009

इक शेर

आवाजें दूर की गुजरां करें मेरे कानो के साए से,
सुनाई कुछ भी ना दे बस जगाती हैं इक आहट सी।
पुकारें चुप सी रहती हैं लगे बहती आखों से किसी के,
बुलाते खींचते अपनी तरफ़, ये धागे गुम हवाओं सी।
कि आजा पास अब ये दूरियां नागवार होती हैं,
करें क्या? बंधीं हैं बेड़ियों सी नागिनें पैरों में चाहत सी।
कहाँ जायें किधर जायें किधर जायें कहाँ जायें?
ये राहें काटती पैरों को, बुला के पास काटों सी।

Friday, May 15, 2009

What BJP does not understand again and again

So it came out true what I had predicted - A win for UPA and rejection of Left and Third front. For BJP it must hurt with two consecutive defeats with people rejecting its leader and its policies. BJP and NDA will sure analyze what went wrong but it does not matter if they do not learn from it. They did not learn the last time either. If they want to get their acts together they have to go back and do major overhaul on what they actually stand for and how they see their future as. Following are simple reasons why BJP failed and is ironic why they couldn't see it.

  1. Personal attacks on leaders does not work. People have rejected it in the past and they will in the future.
  2. Indians have already accepted Sonia Gandhi as an Indian, projecting her as an outsider does not strike a cord with common masses.
  3. An absolute absence of young leaders in the age group of 35-45. A wave of Omar Abdullas, Sachin Pilots, Jyotir Adityas and Rahul Gandhis are coming to crush you.
  4. Absence of any credible presence in South or strong alliance. Banking on post-election alliances would not work.
  5. Retaining the states. They keep losing some key northern states. The states they have won is because how the state government has performed not because of Advani's appeal.
  6. L.K Advani is not an accepted leader of common Indians and he has been rejected in 2009 elections. Sooner he retires the better.
  7. Growth is what will bring them back. There has to be BJP in every state winning local elections. Grass root presence is key to revival.
  8. Up till 1991 BJP was seen as a party not hungry for power. If they have to win then do not project themselves as an alternative of Congress but a party that has concrete beliefs on issues.
  9. BJP is a company that can not build themselves by acquisitions (alliances) alone, they need to generate products.

A tale of two cell phones - why reliability is important

I loved my Palm Treo when I bought it. At that time iPhone was not available and getting a smart phone with a touch screen was all I wanted. And then I broke its screen (thanks for tossing a TV remote on the Bed). I was sad but resilient to fix it instead of buying a new one. Thanks to eBay bought a Palm touch screen and replaced it. While doing so I dropped its mic and for the sake of not taking any more risks I decided to buy a Bluetooth headset so I could continue using the phone. I so loved the phone that I also configured twitter with it. And then one day it decided to breach my trust and apathy. The phone decided to divorce the bluetooth headset. Even though there was a problem with the headset as well but even after getting a replacement it just did not work. I so wanted an iPhone. The price and thanks to the economy I decided to buy a $50 3G Samsung flip phone instead. Moving back to a non-touch-screen phone was hard. 3G was good but my current plan does not have an unrestricted data plan so watching ESPN on phone was not something that I could do. Good enough phone and except a few times going to Apple website to watch an iPhone I decided to settle down. It was like after a failed relationship while on the bounce unable to get any attention from that darn rich beauty deciding to get married to somebody else. The Samsung phone just worked with nice handy features. I stayed happy till the day when I needed reliability more than features. Had to be on a conference call all day for 12 hrs, I plugged the phone with a charger hoping the battery will remain available while I talk. No it did not. It failed the reliability test. The battery died in the middle while I was talking. The charger should have worked while the phone was busy, or at least that what I assumed. Then my old Palm saved the day. Flipped the SIM hooked a cheap Walmart wired headset and I was ready to go. The best thing while I talked, the phone charger continued to charge the battery and for the entire session the battery signal remained green. Features, bluetooth, touch screen was not on my mind. When it comes to saving the day its the battery that matters.

Wednesday, May 06, 2009

Mac Ad

It took humans thousands of years to Mechanize.. Isn't it time to Mac-anize?

Monday, April 27, 2009

My Sis' reasons why BJP is better

Nuclear deal:
The stage was set by Atal. Anyone could have done it. It was done because US was willing to do it. Congress did not do anything special that BJP could not have done.
Kandahar episode:
Did anyone ask Congress what would they have done if Rahul Baba was in the same plane?
Mumbai terror attack:
No one suppose to talk about CS Station where 57 people died. Everyone is talking about Taj which was at the center of international attention. Are lives of common people cheaper? What was their preparedness? How come a few terrorists walked free for so many hours and held the entire nation hostage for three days? Why was response so late?
Kasab/Afjal Guru:
Why is Afjal not hanged yet when Supreme Court has already convicted him? Why is plea bargain still pending? Why has home ministry not forwarded anything to the President's office yet? About Kasab - He is captured on video. If he is found to be 17 would they keep him in a juvenile detention center?
Zero leadership:
India needs a strong leadership. South Asia is in mess. India needs a leader like Indira Gandhi an internationally aggressive personality not a weak person who seeks permission from a family to do anything.
Rahul as PM - You kidding me?
Congress is trying to project Rahul or Priyanka as a Prime Ministerial candidate. This cannot be accepted.
National progress:
BJP and Congress are the only two parties who would not slow down the national progress. Its about the speed of it. Third front is a mess. They don't fight on issues but do seat calculations. Third front has stronger allies of Congress and they impede our progress.

Wednesday, April 22, 2009

Push Replication - You know it alright

So you have heard about it alright here, here, here, this one too, here and even here and of course a hero of numerous talks at NYSIG, UKSIG and more. I have had opportunities to work on multi-cluster Coherence solutions at many client locations and also be part of a project whose one member is an active contributor to Push Replication. So what new do I have to bring on table? A working example for Incubator junkies for one. If you have followed Brian Oliver's write-up at Push Replication page I am sure you already know how to set this up and get running in just a few minutes. So I thought to spice it up a little. So lets build the following:
Setting up Active-Activen clusters
Active/Active is pretty similar to how we set up Active/Passive clusters but it needs some special classes to be used. First, make sure SafePublishingCacheStore is configured in the cache config and as we register a publisher we use SafeLocalCachePublisher instead of LocalCachePublisher.

Making use of introduce element in cache configuration

Start using introduce tag while writing coherence cache config. This is one of the very useful features introduced in coherence common incubator pattern. introduce tag allows us re-use of common cache configurations and is as simple as:
<cache-config>
<introduce-cache-config file="coherence-pushreplicationpattern-cache-config.xml"/>
</cache-config>


Dynamic subscription of subscriber clusters
One architecture that Push replication supports and possibly the most popular one as well, is a hub-n-spoke model. In the hub-n-spoke model not only the spoke clusters know about the hub but the hub knows about all the clusters on the spokes as well at least at the time of deployment. This "knowledge" of the other cluster is in shape of a set of remote-cache-schemes. Recently I came across a requirement where the number of spoke clusters were not known at the time of deployment. This ever expanding subscriber cluster introduces new challenges to Push replication deployments. Coherence is all about 100% up time and stopping the hub every time a new subscriber cluster joins, is not a preferable deployment. So lets introduce how new clusters can dynamically join the hub so that hub does not know about the subscriber but subscriber knows about the hub.

Lets start with some cache configurations and how it will look in a production environment. The following samples are part of a proof of concept and there is a scope of a few tweakings.

Coherence Cache Configuration on the hub
<?xml version="1.0" encoding="windows-1252" ?>
<!DOCTYPE cache-config SYSTEM "cache-config.dtd">
<cache-config>
 <introduce-cache-config file="coherence-pushreplicationpattern-cache-config.xml" />
  <caching-scheme-mapping>
  </caching-scheme-mapping>
 <caching-schemes>
     <proxy-scheme>
         <scheme-name>proxy-scheme</scheme-name>
         <service-name>ProxyCacheScheme</service-name>
         <acceptor-config>
             <tcp-acceptor>
                 <local-address>
                     <address>localhost</address>
                     <port>20000</port>
                     <reusable>true</reusable>
                 </local-address>
                 <keep-alive-enabled>true</keep-alive-enabled>
             </tcp-acceptor>
          </acceptor-config>
         <autostart>true</autostart>
     </proxy-scheme>            
 </caching-schemes>
</cache-config>
Hmm... The only configuration the hub cache config has is proxy-scheme. The hub does not know anything about who the subscribers will be. Will explain later how it will be done, scroll down.

coherence-pushreplicationpattern-cache-config.xml
Its pretty much the same as seen when you download the push replication project, just replace PublishingCacheStore with SafePublishingCacheStore.

Subscriber Cluster Cache Configuration
Cache configuration deployed on the subscriber cluster looks a little more complete as subscriber knows about which hub it has to connect to. The configuration looks like:
<cache-config>
 <introduce-cache-config file="coherence-pushreplicationpattern-cache-config.xml" />
 
 <caching-scheme-mapping>
 </caching-scheme-mapping>
 <caching-schemes>
     <proxy-scheme>
         <scheme-name>proxy-scheme</scheme-name>
         <service-name>ProxyCacheScheme</service-name>
         <acceptor-config>
             <tcp-acceptor>
                 <local-address>
                     <address>localhost</address>
                     <port>9099</port>
                     <reusable>true</reusable>
                 </local-address>
                 <keep-alive-enabled>true</keep-alive-enabled>
             </tcp-acceptor>            
         </acceptor-config>
         <autostart>true</autostart>        
     </proxy-scheme>    
 
     <remote-invocation-scheme>
         <scheme-name>RemoteSiteInvocationService</scheme-name>
         <service-name>RemoteSiteInvocationService</service-name>
         <initiator-config>
             <tcp-initiator>
                 <remote-addresses>
                     <socket-address>
                         <address>localhost</address>
                         <port>20000</port>
                     </socket-address>
                 </remote-addresses>
             </tcp-initiator>
         </initiator-config>    
     </remote-invocation-scheme>
 
     <invocation-scheme>
         <scheme-name>invocation-scheme</scheme-name>
         <service-name>InvocationService</service-name>
         <autostart>true</autostart>
     </invocation-scheme>
 </caching-schemes>

</cache-config>


Dynamic Registration of Subscriber Cluster
The following example is a very scaled down sample tuned to be run on a single machine. Change it as needed. Also the following class should be made a MBean so that it can be executed from a JMX console.
Run:
java -Dtangosol.coherence.distributed.localstorage=false -Dtangosol.coherence.clusteraddress=<subscriber-multicast-ip> -Dtangosol.coherence.cacheconfig=subscriber-cache-config.xml PushReplicationClient <proxy-port> <subscriber-name>
public class PushReplicationClient implements Serializable {

 public PushReplicationClient() {
 }

 public static void main(String[] args) {
     PushReplicationClient pC = new PushReplicationClient();
     String cacheName = "publishing-cache";
     String remoteServiceName = args[1];
     NamedCache nCache = CacheFactory.getCache(cacheName);
     PublisherRegistrationTask rTask =
                          pC.new PublisherRegistrationTask(cacheName,
                                        remoteServiceName, remoteServiceName);
     InvocationService iS =
         (InvocationService) CacheFactory.getService("RemoteSiteInvocationService");
     iS.query(pC.new SubscriberTask(remoteServiceName, Integer.parseInt(args[0])),
              null);
     iS.query(rTask, null);
     Member sM = CacheFactory.getCluster().getOldestMember();
     InvocationService isLocal =
         (InvocationService) CacheFactory.getService("InvocationService");
     rTask = pC.new PublisherRegistrationTask(cacheName,
                          "RemoteSiteInvocationService", remoteServiceName);
                                                                              
     isLocal.execute(rTask, new HashSet(Collections.singletonList(sM)), null);

 }

 private class PublisherRegistrationTask implements Invocable {

     private String cacheName;
     private String serviceName;
     private String publisherName;

     public PublisherRegistrationTask(String cacheName, String serviceName,
                                      String publisherName) {
         this.cacheName = cacheName;
         this.serviceName = serviceName;
         this.publisherName = publisherName;
     }

     public void init(InvocationService invocationService) {

     }

     public void run() {
         PushReplicationManager pM =
             DefaultPushReplicationMananger.getInstance();
         BatchPublisher batchPublisher =
             new RemoteInvocationPublisher(serviceName,
                                           new BatchPublisherAdapter(
                                           new SafeLocalCachePublisher(cacheName)),
                                           true, 10000, 100, 10000, 5);
         pM.registerBatchPublisher(cacheName, publisherName,
                                   batchPublisher);
     }

     public Object getResult() {
         return null;
     }

 }

 private class SubscriberTask implements Invocable {

     private String serviceName;
     private int port;

     public SubscriberTask(String serviceName, int port) {
         this.serviceName = serviceName;
         this.port = port;
     }

     public void init(InvocationService invocationService) {

     }

     public void run() {
         ConfigurableCacheFactory factory =
             CacheFactory.getConfigurableCacheFactory();
         XmlElement root = factory.getConfig();
         XmlElement cS = root.findElement("caching-schemes");
         XmlElement riS = cS.addElement("remote-invocation-scheme");
         riS.addElement("scheme-name").setString(serviceName);
         riS.addElement("service-name").setString(serviceName);
         XmlElement iC = riS.addElement("initiator-config");
         XmlElement tI = iC.addElement("tcp-initiator");
         XmlElement rA = tI.addElement("remote-addresses");
         XmlElement sA = rA.addElement("socket-address");
         sA.addElement("address").setString("localhost");
         sA.addElement("port").setInt(port);
         factory.setConfig(root);
         System.out.println(cS);
     }

     public Object getResult() {
         return null;
     }

 }

}

There are three parts of this class:
  1. Updates the cache configuration deployed on the hub to register itself.
  2. Registers a Publisher on the hub so that changes made in the hub is pushed to this subscriber cluster.
  3. Registers a publisher in the local cluster so that the replication is in Active-Active mode. Changes made in the subscriber cluster also is pushed to the hub's cache and thereafter to other subscriber clusters.
Execute this program for each subscriber cluster that needs to join the hub. Change the subscriber cache configuration accordingly. While I was developing this sample I found an issue in SafeLocalCachePublisher as it was missing a default constructor. A JIRA has been opened and will be fixed in the next Incubator release. In the meantime download the push replication source code and add a default constructor in SafeLocalCachePublisher. So thats pretty much it. Running geographically distributed dynamically subscribed multi-clusters in a hub-n-spoke architecture in less than 10 minutes and then staying up 100% of the time. A complete project with an MBean can be downloaded from Dynamic Push Replication Subscription page. Enjoy!