Archived

This forum has been archived. Please start a new discussion on GitHub.

Is IceGrid load balancer fully transparent for the clients?

Hello Ice Team!

I was wondering whether the IceGrid load balancer is able to be fully transparent to clients. From what I understand communication with IceGrid works as follows (taken from cpp/demo/IceGrid/simple/Client.cpp):

IceGrid::QueryPrx query = IceGrid::QueryPrx::checkedCast(communicator()->stringToProxy("DemoIceGrid/Query"));
hello = HelloPrx::checkedCast(query->findObjectByType("::Demo::Hello"));

Here are some thoughts:
- clients must be aware of IceGrid interface and it has to be written to handle it (it is not possible to use IceGrid features for "old" clients)
- communication overhead is theoretically large, each time there are at least three remote calls instead of one, I mean now it is:

2 calls for: hello = HelloPrx: checkedCast (query->findObjectByType (":: Demo:: Hello")); //findObjectByType and checkedCast are remote calls
1 call for hello->sayHello()

and it could have been:
1 call for hello->sayHello()

I mean LoadBalancer could be fully transparent for the clients eg. it could dispatch requests among nodes according to defined rules instead of just returning proxy. It could be very important for systems where there is a must to partition data among nodes and there is a possibility that some data may be moved from one node to other node at any time. In such systems LoadBalancer must store current mapping and each remote call from client should go through LoadBalancer (no caching possible).

Here is some simple workaround which comes into my mind: one can create HelloLoadBalancer Ice object which will accept "sayHello" method (or whatever possible), HelloLoadBalancerI will implement sayHello in such way that it will make remote call to one of HelloPrxy proxy object located on one of the nodes. Here is some pseudo code:

//client
HelloLoadBalancerPrxy prxy = HelloLoadBalancerPrxy::checkedCast(communicator()->stringToProxy("HelloLoadBalancerPrxy"));//initialization
//...
while(there_are_some_requests)
hello->sayHello(some_input);
//..

//HelloLoadBalancerI
void sayHello(some_input,...)
{
HelloPrxy prxy=getProxyForInput(some_input);
prxy->sayHello();
}

Of course no IceGrid features will be used at all, but then:
- clients does not have to be aware of load balancer existence (it's just a names, "HelloLoadBalancer" may still have name "Hello", and it will call "HelloPerNode" objects or whatever)
- each call will go through LB which guarantees that current partition mapping for data shall be used
- communication overhead from client to Ice node will be much smaller (which could be useful for Internet calls)
- it is possible to implement custom load balancing based on user input
- very easy to implement (?)
- similarity to existing HTTP load balancers

Here are some drawbacks which comes into my mind:
- load balancer node may be overloaded easily (whether it will be possible if AMD and AMI calls will be used?)
- single point of failure (how it could be eliminated?)
- scalability (how to extend it if we have single node with mapping?)
- potential deadlocks or other threading issues (nothing particular has come int my mind yet)

Please correct me if I'm wrong, maybe IceGrid is able to work in a such way but I couldn't find any information about it. Thanks for any advice.

Przemek

Comments

  • benoit
    benoit Rennes, France
    Hi and welcome to the forums!

    Yes, IceGrid has support for this already with replica groups. I recommend checking out the IceGrid chapter in the manual, it explains step by step the IceGrid features through a simple example.

    You can also try out replica groups with the simple demo by deploying multiple servers using the application_with_replication.xml deployment descriptor (see the README file for a description of this deployment file). When using this deployment, the simple client won't be calling findObjectByType, it will just use the proxy returned by:
        hello = HelloPrx::checkedCast(communicator()->stringToProxy("hello"));
    

    This proxy will point to one of the three replicated servers.

    Cheers,
    Benoit.
  • Hello again,

    Thanks for quick reply, I will investigate replica groups more deeply now. But I'm afraid that this will not give ma a chance to implement custom load balance algorithm according to some arbitrary user data assigned to each request, am I right? It seems to be important for me because I want to implement some kind of database cache on each of the nodes and sharing of data is not allowed.
    My main goal is to partition requests from outer system among nodes as fast as possible. It would be great to add some kind of hint (part of request like for example "client id") per each remote call which could be used by load balancing algorithm.

    BTW what do you think about proposed workaround, I mean HelloLoadBalancer etc.? I'm sure that it's not very clean solution, other problems may arise (eg. marsaling and umarshaling data in the load balancer may be unnecessary when dealing with large structs) but it will certainly work according to my needs.

    Best regards
    Przemek
  • benoit
    benoit Rennes, France
    What you are describing sounds complex. Is it too complex or necessary? I'm afraid I can't answer these questions without knowing a lot more about the system you want to develop. Perhaps it's fine if your application is required to handle many clients and very high loads. But if you are in the early design phase of your application, I would recommend to first try a simpler approach.

    To answer your questions:
    • Yes, replica groups don't allow implementing custom load balancing. We had requests for this feature in the past. This is a feature you could sponsor if you are interested and would like to see this added to IceGrid soon.
    • You can pass some extra information with each Ice requests using the Ice::Context parameter. See here for more information.
    • Implementing a load balancer service that intercepts requests from clients and decide to which server to forward the request is certainly an option. An option that could for sure provide lots of flexibility. It's possible that you could use blobjects to implement this service as well to make it generic (not tight to few application interfaces). However, this adds an extra layer of complexity with its own set of issues (can you replicate this service to provide high availability? etc).

    Cheers,
    Benoit.