I have read a lot on scaling out in signalr and the favourites seem to be those mentioned in :
http://www.asp.net/signalr/overview/signalr-20/performance-and-scaling/scaleout-in-signalr
Namely the following service buses:
- SQL
- Redis
- Azure
The problem is is even stated in the text however:
"Using a backplane, the maximum message throughput is lower than it is when clients talk directly to a single server node. That's because the backplane forwards every message to every node, so the backplane can become a bottleneck."
I am creating...wait for it... YEP! A chat application. And I want to be able to scale it out to MILLIONS of users. Regardless of whether I make it big (ha!) or not, I plan on documenting the step by step process. Now I have most of the app ready, and I am wondering about this scale out issue. I watched this, highly useful video:
http://channel9.msdn.com/Events/Build/2013/3-502
Skip to 55 minutes. "Custom scale-out". And the other ideas such as filtering the message bus.
Now hopefully you're excited and not contemplating suicide over the boredom I am ushering unto you...
My idea is to do as follows:
- per popular rooms give a single server
- each room therefore can easily cope with the traffic and signalr can work nicely broadcasting to the clients and storing the message log to a GROUPS server (ie holds all group messaging per group)
- Then private messaging will need to either use a backplane or server push
- the user connections will therefore need to be updated in a sql server DB (easy enough) and the data posted via ajax rather than signalr
However, I want to explore all options. (Please post any better ideas if you have them) I want to also try testing REDIS for the private messaging. WHY?!! Because what if I want the users to be able to have private messaging groups... and users 1,2 and 3 are all highly annoying and are on servers 1,2 and 3. (Ah you little ...!) For better performance though, I will want to implement a Redis message filter to only send to the servers with the clients on them!
So, what exactly am I looking for? Basically I need resources. I can't find any useful Redis message bus examples (asp.net example has no filter. yes, I can add the AddResolverblabla line! :) )
I also need examples of the following:
- server to server ajax post: I am a server noobie!
- a load balancer example to specify a certain room per chat room (or just some page)
- how many messages can the Redis message bus handle? Will it easily be a bottle neck even with the filter? I cant find any example of performances WITH a filter
Finally I need your brains! ;) If you are sat there thinking there's a better way, please let me know.
Many thanks to all who read this essay, I look forward to your replies. (Please up-vote this if you find it useful! There's a lot of forums with similar questions, but no proper answers)
I plan to start answering this as I find documentation. Hopefully more will join!
1.
How to define a connection string to a SQL Server 2008 database?
2.
SQL Server filter:
http://msdn.microsoft.com/en-us/library/windowsazure/microsoft.servicebus.messaging.sqlfilter.aspx
3. web farm
http://weblogs.asp.net/scottgu/archive/2010/09/08/introducing-the-microsoft-web-farm-framework.aspx
4. WF tutorials:
http://www.asp.net/web-forms/tutorials/deployment/configuring-server-environments-for-web-deployment/creating-a-server-farm-with-the-web-farm-framework
3/12/2014
A possible better solution is to use memecache - what facebook is based on
still need to find whether you can specify: use signalr or use redis message bus.
still need to find redis filter tutorials
14/03
GlobalHost.DependencyResolver.UseRedis("server", port, "password", "AppName");
Defines the servers to use redis. Need a filter
6/10/2014
After more research on scaling out, a possibleanswer is to not think of servers as a web of communications, but self-contained. The server uses sends to update the DB and using a timer you can get all the required information (messages etc) each loop from the DB for the users CURRENTLY logged in to that server. As such, it will scale out much easier. Not cheaply however.
Related
we are in a situation where millions of connections (approximately 30 million) will be connected to application. (SignalR Hubs)
however 90% of them will be idle and main operation is server push to specific client thus i need to implement a scale out mechanism.
so i came across this fantastic talk on channel 9 by Damian Edwards where he states that current implementations of backplanes for SignalR is very limited and in scenarios like mine a Custom scale out is needed specifically in server push situation. (at 58:29 of above talk)
after spending many hours in web, i could not find any clear guidance on how to implement a custom backplane which suits my need.
i would like to know how signalR back plane internally works and basically how a backplane works in general. so i can implement my own one.
any help, blog post etc.. is highly appreciated.
Please read this piece of documentation, specifically the piece regarding Implementation.
TL;DR -
When a message is sent, it goes to the backplane, and the backplane sends it to every server. When a server gets a message from the backplane, it puts the message in its local cache. The server then delivers messages to clients from its local cache.
I am using C# ASP.NET MVC 4 Razor
I have a Grid in ASP.NET MVC Razor View that displays the user records. Is there any way to show the new users in Grid without sending the async request to server after each 1 min ?
I searched on Google a lot. Now, finally I am posting the query here to get any clue for this solution to avoid Traffic on Server. As this page will be visible to at least 20,000 users
#Christos approach is the right one!, Just to add more info about it for an ASP.NET solution I would it use SignalR, that lets you implement a simple server/client communication and it's cross browser (it has several polyfills that if it cannot use web sockets it will use server-sent event, and so on), and the best part is that you don't need to worry about that implementation.
Once your clients are connected to the signalR server you can notify them everytime you need to add a new item to the grid.
http://www.asp.net/signalr/overview/getting-started/tutorial-server-broadcast-with-signalr
I hope it helps!
You could make use of the the publish/subscriber pattern. This can be done using for instance a redis server.
In software architecture, publish–subscribe is a messaging pattern
where senders of messages, called publishers, do not program the
messages to be sent directly to specific receivers, called
subscribers. Instead, published messages are characterized into
classes, without knowledge of what, if any, subscribers there may be.
Similarly, subscribers express interest in one or more classes, and
only receive messages that are of interest, without knowledge of what,
if any, publishers there are.
Please have a look here.
Doing so, the first time a client requests data from the server will subscribe to the server for taking any updates. Once any update arrives, the server will push the update to the clients that have subscribed, without requiring from the client to make any other request to the server.
As for implementation details, please have a look here.
I have a scenario that requires me to export a large mailing list (> 1m customers) to an external email system. I have source code and control over both applications.
I need a mechanism for transferring the data from one system to another that is:
Robust
Fast
Secure
So far, I have set up a standard MVC controller method that responds to a request (over https), performs some custom security checks, and then pulls the data from the DB.
As data is retrieved from the DB, the controller method iterates over the results, and writes response in a plain text format, flushing the response every 100 records or so. The receiver reads each row of the response and performs storeage and processing logic.
I have chosen this method because it does not require persisting user data to a permanent file, and a client built in any language will be able to implement receiver logic without a dependency on any proprietary technology (e.g. WCF).
I am aware of other transport mechanisms that I can use with .NET, but none with an overall advantage, given the requirements listed above.
Any insight into which technologies might be better than my request / response solution?
Two suggestions come to mind, we had something similar to this happen at our company a little while ago (acquired website with over 1 million monthly active users and associated data needed a complete datacenter change, including 180gb db that was still active).
We ended up setting up a pull replication to it over SSH (SQL Server 2005), this is black magic at best and took us about a month to set up properly between research and failed configurations. There are various blog posts about it, but the key parts are:
1) set up a named server alias in SQL Server configuration manager on the subscriber db machine, specifying localhost:1234 (choose a better number).
2) set up putty to make a ssh tunnel between your subscriber's localhost:1234 from step 1 and publish db's port 9876 (again, choose a better number). Also make sure you have ssh server enabled on the publisher. Also keep the port a secret and figure out a secure password for the ssh permissions.
3) add a server alias on publisher for port 9876 for the replicated db.
4) if your data set is small enough, create the publications and try starting up the subscriber using snapshot initialize. If not, you need to create a publication with "initialize from backup" enabled, and restore a partial backup at the subscriber using ftp to transfer the backup file over. This method is much faster than snapshot initialization for larger datasets.
Pros: You don't need to worry about authentication for the sql server, "just" the ssh tunnel. Publication can be easily modified in case you realize you need more columns or schema changes. You save time writing an api that may be only temporary and might have more security issues.
Cons: It's weird, there's not much official documentation and ssh on windows is finicky. If you have a linux based load balancer, it may be easier. There are a lot of steps.
Second suggestion: use ServiceStack and protobuf.NET to create a very quick webservice and expose it over https. If you know how to use ServiceStack, it should be very quick. If you don't, it would take a little time because it operates on a different design philosophy from Web API and WCF. Protobuf.NET is the most compact and fastest serialization/deserialization wire format widely available currently. Links:
ServiceStack.NET
Protobuf.NET
Pros: You can handle security however you like. This is also a downside since you then have to worry about it. It's much better documented. You get to use or learn a great framework that will speed up the rest of your webservice-related projects for the rest of your life (or until something better comes along).
Cons: You have to write it. You have to test it. You have to support it.
I'm working on implementing a game server on AppHarbor for a tournament style game. I'm planning on using WCF and C#. I want the server to generate new "levels" every 5 minutes and send it out to all the clients that are online at the time. The clients would then after 3 minutes send back the results of the level (how the player did) and the server will analyze the results and send back the universal results to each client (leaderboards, statistics, etc). And this cycle would repeat.
I'm not sure where I should start. I was looking into making a WCF service application with REST services to get the information, but I don't know who to make the server do calculations and generations independent of the clients.
I would greatly appreciate any help that you all could give me.
Thank you.
You can use SignalR to create independent persistent connections to your clients. At this point SignalR doesn't scale that well as it is only possible to run it on one worker/server out of the box. There is a feature request for scaling but it's not done yet. Depending on how many users you are counting on getting the first months, I would say SignalR is the way to go and then when you need scaling you can improve SignalR to be scaleable as it is open source. :)
I'm writing a simple accounting program consists of several C# winform clients and a java server app that read/write data into a database. One of the requirement is that all C# clients should receive updates from the server. For example, if user a create a new invoice from his C# client, other users should see this new invoice from their client.
My experience is mainly on web development and I don't know what's the best way to fulfill this requirement with C#s client and Java servlet server.
My initial though is to run ActiveMQ with Glassfish and use messaging pub/sub method so that updates can be pushed to C# client. I will create different topics like newInvoice, cancelInvoice, etc in order to differentiate the message type. Each message will simply contains the object encoded in JSON.
But it seems to me that this involves quite a lot of work. Given that my user base is very small ( just 3 or 4 concurrent user), it seems to me that there should be some simpler solutions. (I'm not familiar socket programming :) )
I know this is a client-server programming 101 questions but would be great if any experienced programmer can point me to some simple solutions.
The simplest approach here is often to simply use a poll - i.e. have the clients query for data every (your time interval). That avoids a whole family of issues (firewalls, security, line-of-sight, resolution, client-tracking, etc).
With WCF, you can have callbacks on duplex channels (allowing the server to actively send a message to clients), but this is more complex. I value simplicity, so I usually just poll.
Tricks that help here are designing the system to have an inbuilt mechanism for querying "changes since x" - for example, an audit table, perhaps fed by database triggers. The exact details vary per project, of course.
Another option that you might want to look at is ADO.NET Sync Services; this does much of what you ask for, for keeping a local copy of the database up to date with the server - but has a few complexities of its own. This is available (IIRC) in the "Local Database Cache" VS template.
Rather than pushing information from the server to 1:N Clients, would it not be easier to have the clients Poll the server for updates every so often ? Or when the client launches and creates a connection to the server, the server could dynamically generate a new Message Queue for that Client Connection, which the client could then poll for updates?
There are several push technologies available to you, like ActiveMQ (as you mentioned), or XMPP. But if you only have 3 or 4 clients to concern yourself with, polling would be the simplest solution. It doesn't scale well, but that isn't really a concern in your case, unless your server is an 8086 or something 8-)
You may want to take a look at StreamHub Push Server - its a popular Comet server written in Java that has a .NET Client SDK for receiving updates from the server in C#. It also has a Java Client SDK and the usual Ajax/Comet web browser support giving you more flexibility in the future to push data to web, Java and C# clients.