I am building a website on Django hosted at Heroku. I think at the peak time about 500-600 users can use it simultaneously. I can't figure out what is the best postgres plan.
According to this: https://elements.heroku.com/addons/heroku-postgresql#details
heroku-postgresql:standard-0 has a connection limit of 120, and
heroku-postgresql:standard-2 has a connection limit of 400.
Is it enough to have connections of 120 for about 500 users? Or it is entirely irrelevant?
Is it enough to have connections of 120 for about 500 users?
This isn't something that can be answered with certainty by anyone other than you but there's some general understanding that might be helpful here.
In most cases for basic web applications, one user on your website != one connection used for as long as they're using the app. For instance, that user might need a connection while they log in and load their profile, but not while they're simply viewing the content. While they're idling on a page, those database connections can service other users. With sensible defaults and connection pooling, 120 connections should be plenty for 500 concurrent users.
All that being said, it's on the application developer to manage database connections and pooling to ensure that this behavior is enforced. Also, this position only represents an average web app and there are certainly apps out there whose users require longer-lived connections.
Related
I just took over a project and noticed that they are using a DB profile as such for service accounts used for connection caching
ALTER PROFILE APP_PROF LIMIT
SESSIONS_PER_USER 100
CONNECT_TIME 640
IDLE_TIME 15
...
I believe that is why we are sometimes getting stale connections, and the "ORA-02399: exceeded maximum connect time, you are being logged off".
My question will be: For middle-tiered applications where connections are cached, are there any good reasons why such a profile would be used for service accounts with such limits ?
Personally, I'd be hard-pressed to imagine a situation where I'd want to have a middle tier service account with a connect_time or idle_time set. I suppose it's possible that someone somewhere has a reasonable reason to use such a configuration-- maybe forcing connections to be frequently recycled is the least painful way to quickly put a band-aid on a resource leak, for example, while you looked to fix the underlying code issue. But those would certainly be settings I'd look at carefully.
I've seen and heard of cases where someone wanted to set sessions_per_user for a middle tier service account where the relationships between the middle tier app server admins and the database admins were strained. Normally, the middle tier admins set a cap for the size of the connection pool in the middle tier in consultation with the DBA team that makes sure that the database can handle connection_pool_max * number_of_app_servers connections. If the middle tier admins have a history of spinning up new app server farms or bumping up the number of allowed connections in the connection pool without talking to the DBA team, the DBA team may want to set their own limit to protect the database. I'd much rather solve the communication problem than have a separate database limit.
I'm just configuring a system for production and we have chosen Heroku's Postgres Standard-0 as the database. This states the maximum connections is 120 but I am aware that this does not mean I can set Sequelize's POOL_MAX to 120 as there are other considerations.
From experience, what would be an upper POOL_MAX setting?
Since Heroku needs to occasionally connect to your database to perform health-checks and various other tasks, I wouldn't recommend setting POOL_MAX to 120 as you've already intuited. A figure around 110 seems more appropriate as it will leave room for Heroku to monitor the database and allow a couple extra connections in case you need to connect to the database in a pinch. If you add more dynos or have other clients connecting to the database regularly, you'll want to adjust the POOL_MAX setting downward to account for the additional connections.
Reading this article: http://go-database-sql.org/accessing.html
It says that the sql.DB object is designed to be long-lived and that we should not Open() and Close() databases frequently. But what should I do if I have 10 different MySQL servers and I have sharded them in a way that I have 511 databases in each server for example the way Pinterest shards their data with MySQL?
https://medium.com/#Pinterest_Engineering/sharding-pinterest-how-we-scaled-our-mysql-fleet-3f341e96ca6f
Then would I not need to constantly access new nodes with new databases all the time? As I understand then I have to Open and Close the database connection all the time depending on which node and database I have to access.
It also says that:
If you don’t treat the sql.DB as a long-lived object, you could
experience problems such as poor reuse and sharing of connections,
running out of available network resources, or sporadic failures due
to a lot of TCP connections remaining in TIME_WAIT status. Such
problems are signs that you’re not using database/sql as it was
designed.
Will this be a problem? How should I solve this issue then?
I am also interested in the question. I guess there could be such solution:
Minimize number of idle connection in pool db.SerMaxIdleConns(N)
Make map[serverID]*sql.DB. When you have no such connection - add it to map.
Make Dara more local - so backends usually go to “their” databases. However Pinterest seems not to use it.
Increase number of sockets and files on backend machines so they can keep more open connections.
Provide some reasonable idle timeout so very old unused connections could be closed.
I'm using Laravel5 and, I want to create a notification system for my (web) project. What I want to do is, notifying the user for new notifications such as;
another user starts following him,
another user writes on his wall,
another user sends him a message, etc,
(by possibly highlighting an icon on the header with a drop-down menu. The ones such as StackOverflow).
I found out the new tutorials on Laracast: Real-time Laravel with Socket.io, where a kind of similar thing is achieved by using Node, Redis and Socket.io.
If I choose using socket.io and I have 5000 users online, I assume I will have to make 5000 connections, 5000 broadcastings plus the notifications, so it will make a lot of number of requests. And I need to start for every user on login, on the master blade, is that true?
Is it a bad way of doing it? I also think same thing can be achieved with Ajax requests. Should I tend to avoid using too many continuous ajax requests?
I want to ask if Socket.io is a good way of logic for creating such system, or is it a better approach to use Ajax requests in 5 seconds instead? Or is there any alternative better way of doing it? Pusher can be an alternative, however, I think free is a better alternative in my case.
A few thoughts:
Websockets and Socket.io are two different things.
Socket.io might use Websockets and it might fall back to AJAX (among different options).
Websockets are more web friendly and resource effective, but they require work as far as coding and setup is concerned.
Also using SSL with Websockets for production is quite important for many reasons, and some browsers require that the SSL certificate be valid... So there could be a price to pay.
Websockets sometimes fail to connect even when supported by the browser (that's one reason using SSL is recommended)... So writing an AJAX fallback for legacy or connectivity issues, means that the coding of Websockets usually doesn't replace the AJAX code.
5000 users at 5 seconds is 1000 new connections and requests per second. Some apps can't handle 1000 requests per second. This shouldn't always be the case, but it is a common enough issue.
The more users you have, the close your AJAX acts like a DoS attack.
On the other hand, Websockets are persistent, no new connections - which is a big resources issue - especially considering TCP/IP's slow start feature (yes, it's a feature, not a bug).
Existing clients shouldn't experience a DoS even when new clients are refused (server design might effect this issue).
A Heroku dyno should be able to handle 5000 Websocket connections and still have room for more, while still answering regular HTTP requests.
On the other hand, I think Heroku imposes an active requests per second and/or backlog limit per dyno (~50 requests each). Meaning that if more than a certain amount of requests are waiting for a first response or for your application to accept the connection, new requests will be refused automatically.... So you have to make sure you have no more than 100 new requests at a time. For 1000 requests per second, you need your concurrency to allows for 100 simultaneous requests at 10ms per request as a minimal performance state... This might be easy on your local machine, but when network latency kicks in it's quite hard to achieve.
This means that it's quite likely that a Websocket application running on one Heroku Dyno would require a number of Dynos when using AJAX.
These are just thoughts of things you might consider when choosing your approach, no matter what gem or framework you use to achieve your approach.
Outsourcing parts of your application, such as push notifications, would require other considerations such as scalability management (what resources are you saving on?) vs. price etc'
I see these kinds of messages on twitter and other places.... how do they work? Is it MySQL connections?
You can measure response time of each request (or a given fraction of the requests). If the response time goes up above a threshold you start rejecting requests.
If you measure SQL connection etc you need to know where your bottle necks are at a given moment. If your application is limited by bandwidth between your servers or something else counting SQL connections will not help you.
It might be shown if the database refused a connection or if the system load (read from /proc/loadavg) is too high. It could also be shown if too many users are logged in - but that's only likely for web applications where logged in users are expensive.. certain games for example where lots of state information must be kept while someone is logged in.