Home > FMS > Save money with an hybrid FMIS-FMSS cluster

Save money with an hybrid FMIS-FMSS cluster

I client of mine needed to setup a FMS based custom platform for live streaming. They needed to serve several thousands concurrent users with a clustered configuration in complete fail-over. Ok, I said, all that can be done using multiple FMIS installations, leveraging the origin-edge feature of FMIS. The problem was always the same, the budget ! They loved the idea of using FMS but considered too high the price for the six FMIS licenses needed for the specific project (2 origins, 4 edges).

Hardware is every day less expensive, and today the cost of a FMIS license can be almost the double of the dual socket server that will run it. Therefore I needed to squeeze the brain to find a low cost, reliable solution based on FMS, especially today that Microsoft is spreading the word of Silverlight ;-). So I chose to try the setup of an hybrid FMIS – FMSS cluster with an application based failover and load balancing strategy.

As you know, FMIS can re-publish a stream to a different FMS using server side code, while FMSS cannot execute server side code.
Leveraging this features, FMIS can be used as a splitting point to distribute every published stream toward a cluster of FMSS. In this schema, FMIS acts as an origin while several FMSS act as edges.

The final design is shown here:

Every stream is acquired and encoded by a couple of Flash Media Live Encoders (for fail-over on the encoding), when the stream is published on each FMIS, a specific application.onPublish handler split the stream toward the cluster of FMSS (in this case 4). In this design there is no single point of failure because the lost of a FMLE, FMIS or FMSS do not stop the overall live service. The last brick in the wall is the handling of the load-balancing and fail-over on the client side, using a server address in round-robin and a specific netConnection recovery code.

Here You find a simplified extract of the code that split in N every stream published on FMIS:

var nsa1 = {};
var nsa2 = {};
var nca1 = {};
var nca2 = {};
var edge1=”rtmp://remote_server1/live”;
var edge2=”rtmp://remote_server2/live”;

application.onPublish = function( client, myStream ) {

trace(myStream.name + ” is re-publishing to #1″ );

nca1[myStream.name] = new NetConnection();
nca1[myStream.name].onStatus = function (info) {
trace(“Connection Status:” + info.code);
if (info.code == “NetConnection.Connect.Success”) {
trace(“Connection established with #1” );
nsa1[myStream.name] = new NetStream(nca1[myStream.name]);
nsa1[myStream.name].onStatus = function(info) {
trace(“Stream Status: ” + info.code)
if (info.code == “NetStream.Publish.Start”) {
trace(“The stream is now re-publishing”);
}
if (info.code == “NetStream.Publish.BadName” || info.code == “NetStream.Failed” ){
nsa1[myStream.name].publish(myStream.name, “live”); trace(“retry to re-publish : ” + myStream.name);
}
}
nsa1[myStream.name].setBufferTime(1);
nsa1[myStream.name].attach(myStream);
nsa1[myStream.name].publish(myStream.name, “live”);
}
// Auto-recovery
if (info.code == “NetConnection.Connect.Closed” || info.code == “NetConnection.Connect.Failed”) {
trace(“Retry Connecting to #1”);
nca1[myStream.name].connect(edge1 ) //***Reconnection
}
}
nca1[myStream.name].connect( edge1 );

trace(myStream.name + ” is re-publishing to #2″ );

nca2[myStream.name] = new NetConnection();
nca2[myStream.name].onStatus = function (info) {
trace(“Connection Status:” + info.code);
if (info.code == “NetConnection.Connect.Success”) {
trace(“Connection established with #2” );
nsa2[myStream.name] = new NetStream(nca2[myStream.name]);
nsa2[myStream.name].onStatus = function(info) {
trace(“Stream Status: ” + info.code)
if (info.code == “NetStream.Publish.Start”) {
trace(“The stream is now re-publishing”);
}
if (info.code == “NetStream.Publish.BadName” || info.code == “NetStream.Failed” ){
nsa2[myStream.name].publish(myStream.name, “live”); trace(“retry to re-publish : ” + myStream.name);
}
}
nsa2[myStream.name].setBufferTime(1);
nsa2[myStream.name].attach(myStream);
nsa2[myStream.name].publish(myStream.name, “live”);
}
// Auto-recovery
if (info.code == “NetConnection.Connect.Closed” || info.code == “NetConnection.Connect.Failed”) {
trace(“Retry Connecting to #2”);
nca2[myStream.name].connect(edge2 ) //***Reconnection
}
}
nca2[myStream.name].connect(edge2 );
}

Note in the code the handling of the errors that can happen on the NetConnection or the NetStream. This part is very important because if you simply connect the FMIS to the FMSS, it is very probable that you will incur soon or later in a non-handled disconnection.

Concluding, the flexibility of the server side code and of FMIS allowed me to implement a basic low cost clustered FMS based platform for live streaming. This solution is far from the native, enterprise level, origin-edge feature of FMIS, but is sufficient for the requirements of the project. The total cost of licenses is 13.000$ vs 27.000$ of the “standard” configuration, a save of 14.000$, not bad, especially these days…and you certainly know what I mean.

Advertisements
Categories: FMS
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: