Hello Filip,
thank you for your example. Comments below.
> So this is the scenario where information could be shared in the JNDI tree
> for other purposes than just storing references to home interfaces.
>
> =======================================================================
> | NODE 1 | NODE 2 | NODE3 |
> =======================================================================
> JNDI |App1/BeanAHome |App1/BeanAHome |App1/BeanAHome |
> SPACE |App1/BeanA |App1/BeanA |App1/BeanA |
> |App2/BeanBHome |App2/BeanBHome |App2/BeanBHome |
> |App2/BeanB |App2/BeanB |App2/BeanB |
> |myapp.Snapshot |myapp.Snapshot | |
> =======================================================================
> EJB | | | |
> SERVER | App1 running | App1 running | App1 running |
> | App2 deployed but | App2 running | |
> | in standby backup | | |
> =======================================================================
> CACHE | | | |
> DATA | Data {A,B} | Data {B,C} | Data {D,E} |
> =======================================================================
>
> I have made a monitor system built into my app. This monitor
> system consist
> of an internal measurement/snapshot component that sits inside the EJB
> application and an external report/analysis component.
> The internal snapshot component gathers information about the EJB app
> statistics and publishes them into an object into the JNDI tree.
> In a non-clustered environment, the external report/analysis
> component will
> go to each server and take the latest snap shot and compile the
> information
> and produce a report. The snapshot is bound to the name myapp.Snapshot.
>
> So far so good, the monitoring works great with my 3 different
> server nodes.
>
> No client transparent fail-over has become a requirement from the
> EJB client
> app (another app that accesses the EJB server, not the monitor
> report app).
>
> The developers thought they could do this seamlessly, but as it turns out,
> all the content in the JNDI tree gets replicated between the
> cluster nodes.
> This means that object bound to the name "myapp.Snapshot" represents the
> latest snapshot of each of the individual servers. But what
> happens if NODE
> 2 gets restarted, and a snapshot has not been performed (bound to the JNDI
> tree)? Now there is a risk that a snapshot from NODE 1 or 3 gets
> replicated
> into the JNDI tree of NODE 2 and the report component is
> accessing incorrect
> data.
The goal of clustering is to have a set of nodes presented to the client as
a single entity : the cluster. Consequently, this means that every active
replicat in the cluster represent (i.e. work for) exactly the same entity.
For example, when an entity bean stores something in the database, it knows
that it is just a bean class instance representing a particular EB and that
after the invocation, it won't be able to rely on any particular data it
keeps secret because the next invocation may be delegated to another bean
class instance.
In your example, it is not the case: your 3 nodes work EACH for their own
node (collecting data for their own node) and publish it under the SAME
name. If you want to cluster your example, you need to cluster all 3
different applications (i.e. one for each target), and that each one writes
on its own name. On the contrary, if you only want to monitor a single
target, it is ok that your beans write to the same name because they will
not do it at the same time (only one replicat answer a particular request,
see below)
> Also, lets say that the client is reading snapshot data as well and
> collecting a history on client machine, so when NODE 2 fails, the request
> gets automatically redirected to NODE 1 and the client data doesn't make
> sense anymore :)
Yes, because in your example the three nodes do not work as a replicat for a
same target: each replicat does its own duty.
> Now this is clearly a design that was not made with clustering
...
> to use JNDI for shared caching :) I'm sure similar scenarios actually do
> exist.
>
> Just trying to point out two things here
> 1. You will have name conflicts when replicating JNDI objects
No because this would assume that some sort of client would talk to a
particular JNDI node instead of the JNDI cluster. As said before on the
group communication topic: if a correct JNDI node deliver a binding, then
all correct node will also receive it.
> 2. If you have a strategy of resolving those name conflicts by
> applying some
> FIFO overwrite rule, you may end up overwriting data that applications
> depend upon.
if more than one client try to write to the same place it is either because
the represent the same entity (the clustering case => no problem) or because
two applications use the same name => configuration problem.
> 3. When a client gets transparently redirected to another NODE,
> they may see
> unexpected data in the JNDI tree from what they say in their previous call
No, not if every replicat work for the same entity. What you tell me is like
if you said: "Entity bean A is loaded from DB in a bean class instance i1
for a first method invocation. For the second method invocation, a new
instance i2 is created and linked to this EB identity. But there is a
problem if i1 has kept some kind of instance variable regarding our EB
because i2 does not know about this". We can no more rely on locally cached
data (without sharing this information with other replicat)
I think we need to differentiate two cases:
1) invocation clustering : a client performs an invocation. It can be
handled by any replicat as long as all modifications resulting from the call
are visible to all other replicats. The unit of work can be as low as the
invocation.
2) process clustering : a node performs "continuously" some work on a
singleton target/material. In this case, not two instances can work together
because we would have each invocation performed twice (or more) on the same
target/material. In this case, a single node work and others are in backup
mode.
I think our case is strictly number 1).
Some other services, would be case 2. For example, the JMX timer service
could be such a case. Some beans register to it and wait to be invoked. We
do not want that each node wakes up a same replicat (each node has its
service). On the other hand, we do not want to have a single service
somewhere but rather that this service be HA. This time the case is 2)
because only one service should work on the target material (list of time
and target) at a particular time but some backup should be available in case
the primary dies.
Hopefuly, AFAIK, every EJB bean is 1)-compliant (and 2-cases could be
managed through a generic primary-backup scheme)
And for a less important point, as we were speaking about a CORBA
interoperable NS, it is a naming service, not a directory (such as LDAP).
Consequently, we wouldn't be able to store objects in it, only references
(this does not change the reason of our discussion nevertheless)
Some pairs of fresh eyes are welcome (in case I would not see the wall in
front of me).
Cheers,
Sacha