I am planning to build a web app running on a single computer and exploit the hardware resources as efficient as possible. The logic of app will not be complex. The following is my design:
OS: Linux (CentOS 5)
Web Server: Nginx
Web script: PHP
Database: Tokyo cabinet + Tokyo Tyrant
Index: Sphinx
I am not going to use RDBMS such as MySQL, cause I think a key-value store (Tokyo cabinet) with a indexer (Sphinx) will meet all the needs to deploy a normal web app, also with better performance than MySQL.
My question is: is this design to be the an efficient architecture for a single computer? Or how to improve it?
(I know this question might to be subjective but I really need your help)
Thank you very much~
EDIT:
The computer I am going to host my app on, is a normal PC, like 8GB~16GB memory, 500G~1TB Hard disk, etc. I think it won't need to consider the "scalability". Every first step of a web app is started from one machine and it will always the beginning.
Choice of DB
I think that the choice of type of database you make depends less on how many computers the system is hosted on. I think this should be more a function of the quality of data that you want/need to preserve.
For example, if you need to store the shipping addresses for a customer, you will need to account for that in your storage structure. A name value pair may seem an easy enough structure to begin with, but if you foresee any of the following, you should consider moving to a standard database system
keeping track of changes
reporting activity / reports
concurrent users
Performance
This is dependent on your code, images, content, caching, etc just as much as it is on your database.
well, one way to see is to load test it:
http://grinder.sourceforge.net/
I've never worked with Tokyo cabinet, but if it's functionally sufficient, then it will probably be significantly faster then a DB.
In the long run though, any savings you realize by tuning your app to work on one box will be quickly lost when you start to scale beyond that box. trying to add a lot of caching, and hacks to get the app to be faster will only go so far. More importantly you should try to think about how easily you can decouple the various layers.
Related
I wanted to know that if 1000 users are concurrently using a website built with laravel 5 and also querying database regularly then how does laravel 5 perform ?
I know it would be slow but will it be highly slow that it would be unbearable ?
Note that i am also going to use ajax a lot.
And lets assume i am using digital ocean cloud service with following configurations
2GB memory
2 vCPU
40GB SSD
I don't expect completely real figures as it is impossible to do so but at least provide some details whether i should go with laravel with some considerable performance.
Please also provide some some tools through which i can check the speed of my laravel 5 application as well as how it will perform when there is actual load as well as other tools through which i can test speed and performance.
And it would be great if someone has real experience of using laravel especially Laravel 5.
And what about Lumen does that really make application faster than laravel and how much ?
In short, yes. At least newer versions of Laravel are capable (Laravel 7.*).
That being said, this is really a three part conundrum.
1. Laravel (Php)
High Concurrency Architecture And Laravel Performance Tuning
Honestly, I wouldn't be able to provide half the details as this amazing article provides. He's got everything in there from the definition of concurrency all the way to pre-optimization times vs. after-optimization times.
2. Reading, Writing, & Partitioning Persisted Data (Databases)
MySQL vs. MongoDB
I'd be curious if the real concern is Php's Laravel, or more of a database read/write speed timing bottleneck. Non relational databases are an incredible technology, that benefit big data much more than traditional relational databases.
Non-relational Databases (Mongo) have a much faster read speed than MySql (Something like 60% faster if I'm remembering correctly)
Non-relational Databases (Mongo) do have a slower write speed, but this usually is not an inhibitor to the user experience
Unlike Relational Databases (MySQL), Mongo DB can truly be partitioned, spread out across multiple servers.
Mongo DB has collections of documents, collections are pretty synonymous to tables and documents are pretty synonymous to rows.
The difference being, MongoDB has a very JSON like feel to it. (Collections of documents, where each document looks like a JSON object).
The huge difference, and benefit, is that each document - AKA row - does not have have the same keys. When using mongo DB on a fortune 500 project, my mentor and lead at the time, Logan, had a phenomenal quote.
"Mongo Don't Care"
This means that you can shape the data how you're wanting to retrieve it, so not only is your read speed faster, you're usually not being slowed by having to retrieve data from multiple tables.
Here's a package, personally tested and loved, to set up MongoDB within Laravel
Jessengers ~ MongoDB In Laravel
If you are concerned about immense amounts of users and transferring data, MongoDB may be what you're looking for. With that, let's move on to the 3rd, and most important point.
3. Serverless Architecture (Aka Horizontal scaling)
Aws, Google Cloud, Microsoft Azure, etc... I'm sure you've hear of The Cloud.
This, ultimately, is what you're looking for if you're having concurrency issues and want to stay within the realm of Laravel.
It's a whole new world of incredible tools one can hammer away at -- they'er awesome. It's also a whole new, quite large, world of tools and thought to learn.
First, let's dive into a few serverless concepts.
Infrastructure as Code Terraform
"Use Infrastructure as Code to provision and manage any cloud, infrastructure, or service"
Horizontal Scaling Example via The Cloud
"Create a Laravel application. It's a single application, monolithic. Then you dive Cloud. You discover Terraform. Ahaha, first you use terraform to define how many instances of your app will run at once. You decide you want 8 instances of your application. Next, you of course define a Load Balancer. The Load Balancer simply balances the traffic load between your 8 application instances. Each application is connected to the same database, ultimately sharing the same data source. You're simply spreading out the traffic across multiples instances of the same application."
We can of course top that, very simplified answer of cloud, and dive into lambdas, the what Not to do's of serverless, setting up your internal virtual cloud network...
Or...we can thank the Laravel team in advance for simplifying Serverless Architecture
Yep, Laravel Simplified Serverless (Shout out Laravel team)
Serverless Via Laravel Vapor
Laravel Vapor Opening Paragraph
"Laravel Vapor is an auto-scaling, serverless deployment platform for Laravel, powered by AWS Lambda. Manage your Laravel infrastructure on Vapor and fall in love with the scalability and simplicity of serverless."
Coming to a close, let's summarize.
Oringal Concern
Ability to handle a certain amount of traffic in a set amount of time
Potential Bottlenecks with potential solutions
Laravel & Php
(High Concurrency Architecture And Laravel Performance
Tuning
Database & Persisting/Retrieving Data Efficiently
Jessengers ~ MongoDB In Laravel
Serverless Architecture For Horizontal Scaling
Serverless Via Laravel Vapor
I'll try to answer this based on my experience as a software developer. To be honest I definitely will ask for an upgrade whenever it hits 1000 concurrent users at the same time because I won't take a risk with server failure nor data failure.
But let's break it how to engineer this.
It could handle those users if the data fetched is not complex and there are not many operations from Laravel code. If it's just passing through from the database and almost no modification from the data, it'll be fast.
The data fetched by the users are not unique. Let's say you have a news site without user personalization. the news that the users fetched mostly will be the same. You cached the data from memory (Redis, which I recommend) or from the web server(Nginx, should be avoided), your Laravel program will run fast enough.
Querying directly from the database is faster than using Laravel ORM. you might consider it if needed, but I myself will always try to use ORM because it will help code to be more readable and secure.
Splitting database, web server, CDN, and cache server is obviously making it easier to monitor server usage.
Try to upgrade it to the latest version. I used to work with a company that using version 5, and it's not really good at performance.
opcode caching. cache the PHP file code. I myself never use this.
split app to backend and frontend. use state management for front end app to reduce requests data to the server.
Now let's answer your question
Are there any tools for checking performance? You can check Laravel debug bar, these tools provide for simple performance reports. I myself encourage you to make a test for each of the features you create. You can create a report from that unit test to find which feature taking time to finish.
Are lume faster than laravel? Yeah, Lumen is faster because they disabled some features from Laravel. But please be aware that Taylor seems gonna stop Lumen for development. You should consider this for the future.
If you're aware of performance, you might not choose Laravel for development.
Because there is a delay between each server while opening a connection. Whenever a user creating a request, they open a connection to the server. server open connections to the cache server, database server, SMTP server, or probably other 3rd parties as well. It's the real bottleneck that happened on Laravel. You can make keep-alive connections with the database and cache server to reduce connection delay, but you wouldn't find it in Laravel because it will dispose the connection whenever the request finish.
It's a typed language, mostly compiled language are faster
In the end, you might not be able to use Laravel with that server resources unless you're creating a really simple application.
A question like this need an answer with real numbers:
luckily this guy already have done it in similar conditions as you want to try and with laravel forge.
with this php config:
opcache.enable=1
opcache.memory_consumption=512
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.save_comments=1
opcache.fast_shutdown=1
the results:
Without Sessions:
Laravel: 609.03 requests per second
With Sessions:
Laravel: 521.64 requests per second
so answering your question:
With that memory you would be in trouble to get 1000 users making requests, use 4gb memory and you will be in better shape.
I don't think you can do that with Laravel.
I tried benchmarking Laravel with an 8 core CPU, 8 GB RAM and 120GB HDD and I just got 200-400 request per second.
I run a website that uses a database, but not intensively, on a WAMP configuration. I currently use MS Access: We have a small database, < 4MB max, that can be downloaded for easy backup and emailed to organization members for completing tasks in the MS Access software (like generating reports, etc.). However, it requires MS Office software and isn't exactly standard use with PHP.
On the other hand, our host provides MySQL, which is typical with PHP, generally more powerful, has a greater availability of software and support, but backup can be a little messier.
But, MySQL is not hosted on the local host. So, I copied the information to MySQL, and made a copy of the site using the MySQL database. I proceeded to run some benchmarks, and surprisingly, MS Access was faster, marginally.
I am not sure which is the best direction to take at this point. Hoping the community can give some pros and cons that I haven't though about.
Since Access is way simpler, it's not surprising that rough benchmarking reveals it's faster. The difference comes when you have to deal with concurrent sessions and large data sets. Desktop apps are normally used by a single process at a time but in web applications concurrent queries are the norm.
Said that, if you've been using Access for a while and you didn't find issues, I don't think that switching to MySQL is going to make any difference regarding performance. I'd think about other considerations:
Would you like to have Linux hosting as an option?
Are you proficient enough with MySQL as to migrate code in a reasonable timespan and with reasonable quality?
Can you replace those reports with plain HTML listings?
BTW, MySQL backups can be automated with a simple command line script, it should not be messy at all.
One pro that MS Access is already offering you is a client interface. You've mentioned users that are "generating reports, etc.". Unless you already have an alternative in place that will do everything they need, switching to MySQL will likely be a no-win situation.
I'd stick with Access database for such a small scale project! There's no need to move onto a bigger technology for the hell of it - put it this way, if you had 4 kids, and a bus came up for sale, would you buy the bus because you can fit your 4 kids in it?
One big advantage of MySQL IMO is that PHP has built in support for MySQL. You can use ODBC with PHP to connect to MS Access but it's one more thing to set up and one more thing to 'break' at some point.
Could you set up MySQL on the host? Is it likely that your database would grow and become more complex in the near future?
Access is ideal for us: several accountants using it in our accounting work in the same room but not through the internet, and none of us is programmer. The only thing to think about is the fee for Access copy-wright.
Mysql is free, yes, that is great, but Mysql lacks stored queries, forms and reports, and the quick "on_click, on_doubleclick..." functions that are extremely useful and easy to handle in Access. Are there ways to solve this problem. Thank you.
I need to run Linux-Apache-PHP-MySQL application (Moodle e-learning platform) for a large number of concurrent users - I am aiming 5000 users. By concurrent I mean that 5000 people should be able to work with the application at the same time. "Work" means not only do database reads but writes as well.
The application is not very typical, since it is doing a lot of inserts/updates on the database, so caching techniques are not helping to much. We are using InnoDB storage engine. In addition application is not written with performance in mind. For instance one Apache thread usually occupies about 30-50 MB of RAM.
I would be greatful for information what hardware is needed to build scalable configuration that is able to handle this kind of load.
We are using right now two HP DLG 380 with two 4 core processors which are able to handle much lower load (typically 300-500 concurrent users). Is it reasonable to invest in this kind of boxes and build cluster using them or is it better to go with some more high-end hardware?
I am particularly curious
how many and how powerful servers are
needed (number of processors/cores, size of RAM)
what network equipment should
be used (what kind of switches,
network cards)
any other hardware,
like particular disc storage
solutions, etc, that are needed
Another thing is how to put together everything, that is what is the most optimal architecture. Clustering with MySQL is rather hard (people are complaining about MySQL Cluster, even here on Stackoverflow).
Once you get past the point where a couple of physical machines aren't giving you the peak load you need, you probably want to start virtualising.
EC2 is probably the most flexible solution at the moment for the LAMP stack. You can set up their VMs as if they were physical machines, cluster them, spin them up as you need more compute-time, switch them off during off-peak times, create machine images so it's easy to system test...
There are various solutions available for load-balancing and automated spin-up.
If you can make your app fit, you can get use out of their non-relational database engine as well. At very high loads, relational databases (and MySQL in particular) don't scale effectively. The peak load of SimpleDB, BigTable and similar non-relational databases can scale almost linearly as you add hardware.
Moving away from a relational database is a huge step though, I can't say I've ever needed to do it myself.
I'm not so sure about hardware, but from a software point-of-view:
With an efficient data layer that will cache objects and collections returned from the database then I'd say a standard master-slave configuration would work fine. Route all writes to a beefy master and all reads to slaves, adding more slaves as required.
Cache data as objects returned from your data-mapper/ORM and not HTML, and use Memcached as your caching layer. If you update an object then write to the db and update in memcached, best use IdentityMap pattern for this. You'll probably need quite a few Memcached instances although you could get away with running these on your web servers.
We could never get MySQL clustering to work properly.
Be careful with the SQL queries you write and you should be fine.
Piotr, have you tried asking this question on moodle.org yet? There are a couple of similar scoped installations whose staff members answer that currently.
Also, depending on what your timeframe for deployment is, you might want to check out the moodle 2.0 line rather than the moodle 1.9 line, it looks like there are a bunch of good fixes for some of the issues with moodle's architecture in that version.
also: memcached rocks for this. php acceleration rocks for this. serverfault is probably the better *exchange site for this question though
I am new in the website scalability realm. Can you suggest to me some the techniques for making a website scalable to a large number of users?
Test your website under heavy load.
Monitor all statistics
Find bottleneck
Fix bottleneck
Go back to 1
good luck
If you expect your site to scale beyond the capabilities of a single server you will need to plan carefully. Design so the following will be possible:-
Make it so your database can be on a separate server. This isn't normally too hard.
Ensure all your static content can be moved to a CDN, as this will normally pull a lot of load off your servers.
Be prepared to spend a lot of money on hardware. More RAM and faster disks help a LOT.
It gets a lot harder when you need to split either the database or the php from a single server to multiple servers, so optimise everything, from your code, your database schema, your server config and anything else you can think of to put this final step off for as long as possible.
Other than that, all you can do is stress test your site, figure out where the bottlenecks are and try and design them away.
Check out this talk by Rasmus Lerdorf (creator of PHP)
Specially Page 8 and beyond.
You might want to look at this resource- highscalability.com.
A number of people have mentioned tools for identifying bottlenecks, and that is of course necessary. You can't spend productive time speeding something up without knowing where it's slow. But the other thing you need to know is where your target scalability lies. Is it value for money to spend a couple of months making your site scale to the same number of users as Twitter if it's going to be used by three people in HR? Do you have a known rate of transactions, or response latency, or number of users, in the requirements of the product? If so, target those numbers with your optimisation strategy. If not, find those out before chasing the performance rat down the hole.
Very similar: How Is PHP Done the Right Way?
Scalability is no small subject and certainly more material than can be reasonably covered in a single question.
For instance, with some kinds of applications, joins (in SQL) don't scale, which brings up all sorts of caching and sharding strategies.
Beanstalk is another scalability and performance tool in high-performance PHP sites. As is memcache (different kind).
The biggest problem for scalability is usually shared resources like DBMS's. The problem arises because DBMS's usually have no way to relax consistency guarantees.
If you want to increase scalability when you use something like MySQL you have to change your schema design to relax consistency.
For instance, you can separate your database schema to have your normalized data model for writes, and a replicated read only denormalized part for the 90% of read operations. The read only data can be spread over several servers.
Another way to increase scalability of a database is to partition the data, e.g. separate the data into a database for every department and aggregate them either in the ORM or in the DBMS.
In order of importance:
If you run PHP, use an opcode cache like APC. (This is important enough to be built-in in the next generation of PHP.)
Use YSlow or Google Page Speed to identify bottlenecks. (This will reveal structural problems with your website that affect both client and server performance.)
Ensure that your web server sends a proper Expires header for static content (images, Javascript, CSS), such that the browser can cache it properly. (YSlow will warn you about this, too.)
Use an HTTP accelerator, such as Varnish. (This picture says it all – and they already had an HTTP accelerator in place.)
Develop your site using solid OOP techniques. You will need your site to be modular as not all performance bottlenecks are obvious at the start. Be ready to refactor parts of your site as traffic increases. The first sentence I wrote will help you do it more easily and safely. Also, use test driven development, As refactor means new introduced bugs, and good TDD is good in catching them before they go into production.
Separate as much as possible client side code from server side code, as they will likely to be served from different servers, if your site traffic justify this.
Read articles (read the YSlow tips for instance).
GL
In addition to the other suggestions, look into splitting your sites into tiers, as in multitier architecture. If done right, you can then use one server per tier.
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I want to know when building a typical site on the LAMP stack how do you optimize it for the best possible load times. I am picturing a typical DB-driven site.
This is a high-level look and could probably pull in question and let me break it down into each layer of the stack.
L - At the system level, (setup and filesystem) can you do to improve speed? One thing I can think of is image sizes, can compression here help optimize anything?
A - There have to be a ton of settings related to site speed here in the web server. Not my Forte. Probably depends a lot on how many sites are running concurrently.
M - MySQL in a database driven site, DB performance is key. Is there a better normalization approach i.e, using link tables? Web developers often just make simple monolithic tables resembling 1NF and this can kill performance.
P - aside from performance-boosting settings like caching, what can the programmer do to affect performance at a high level? I would really like to know if MVC design approaches hit performance more than quick-and-dirty. Other simple tips like are sessions faster than cookies would be interesting to know.
Obviously you have to get down and dirty into the details and find what code is slowing you down. Also I realize that many sites have many different performance characteristics, but let's assume a typical site that has more reads then writes.
I am just wondering if we can compile a bunch of best practices and fully expect people to link other questions so we can effectively workup a checklist.
My goal is to see if even in addition to the usual issues in performance we can see some oddball things you might not think of crop up to go along with a best-practices summary.
So my question is, if you were starting from scratch, how would you make sure your LAMP site was fast?
Here's a few personal must-dos that I always set up in my LAMP applications.
Install mod_deflate for apache, and
do not use PHP's gzip handlers.
mod_deflate will allow you to
compress static content, like
javascript/css/static html, as well
as the usual dynamic PHP output, and
it's one less thing you have to worry
about in your code.
Be careful with .htaccess files!
Enabling .htaccess files for
directories in your app means that
Apache has to scan the filesystem
constantly, looking for .htaccess
directives. It is far better to put
directives inside the main
configuration or a vhost
configuration, where they are loaded
once. Any time you can get rid of a
directory-level access file by moving
it into a main configuration file,
you save disk access time.
Prepare your application's database
layer to utilize a connection manager
of some sort (I use a Singleton for
most applications). It's not very
hard to do, and reducing the number
of database connections your
application opens saves resources.
If you think your application will
see significant load, memcached can
perform miracles. Keep this in mind
while you write your code... perhaps
one day instead of creating objects
on the fly, you will be getting them
from memcached. A little foresight
will make implementation painless.
Once your app is up and running, set
MySQL's slow query time to a small
number and monitor the slow query log
diligently. This will show you where
your problem queries are coming from,
and allow you to optimize your
queries and indexes before they
become a problem.
For serious performance tweakers, you
will want to compile PHP from source.
Installing from a package installs a
lot of libraries that you may never
use. Since PHP environments are
loaded into every instance of an
Apache thread, even a 5MB memory
overhead from extra libraries quickly
becomes 250MB of lost memory when
there's 50 Apache threads in
existence. I keep a list of my
standard ./configure line I use when
building PHP here, and I find it
suits most of my applications. The
downside is that if you end up
needing a library, you have to
recompile PHP to get it. Analyze
your code and test it in a devel
environment to make sure you have
everything you need.
Minify your Javascript.
Be prepared to move static content,
such as images and video, to a
non-dynamic web server. Write your
code so that any URLs for images and
video are easily configured to point
to another server in the future. A
web server optimized for static
content can easily serve tens or even
hundreds of times faster than a
dynamic content server.
That's what I can think of off the top of my head. Googling around for PHP best practices will find a lot of tips on how to write faster/better code as well (Such as: echo is faster than print).
First, realize that performance is an iterative process. You don't build a web application in a single pass, launch it, and never work on it again. On the contrary, you start small, and address performance issues as your site grows.
Now, onto specifics:
Profile. Identify your bottlenecks. This is the most important step. You need to focus your effort where you'll get the best results. You should have some sort of monitoring solution in place (like cacti or munin), giving you visibility into what's going on on your server(s)
Cache, cache, cache. You'll probably find that database access is your biggest bottleneck on the back end -- but you should verify this on your own. Fortunately, you'll probably find that a lot of your traffic is for a small set of resources. You can cache those resources in something like memcached, saving yourself the database hit, and resulting in better backend performance.
As others have mentioned above, take a look at the YDN performance rules. Consider picking up the accompanying book. This'll help you with front end performance
Install PHP APC, and make sure it's configured with enough memory to hold all your compiled PHP bytecode. We recently discovered that our APC installation didn't have nearly enough ram; giving it enough to work in cut our CPU time in half, and disk activity by 10%
Make sure your database tables are properly indexed. This goes hand in hand with monitoring the slow query log.
The above will get you very far. That is to say, even a fairly db-heavy site should be able to survive a frontpage digg on a single modestly-spec'd server if you've done the above.
You'll eventually hit a point where the default apache config won't always be able to keep up with incoming requests. When you hit this wall, there are two things to do:
As above, profile. Monitor your apache activity -- you should have an idea of how many connections are active at any given time, in addition to the max number of active connections when you get sudden bursts of traffic
Configure apache with this in mind. This is the best guide to apache config I've seen: Practical mod_perl chapter 11
Take as much load off of apache as you can. Apache's too heavy-duty to serve static content efficiently. You should be using a lighter-weight reverse proxy (like squid) or webserver (lighttpd or nginx) to serve static content, and to take over the job of spoon-feeding bytes to slow clients. This leaves Apache to do what it does best: execute your code. Again, the mod_perl book does a good job of explaining this.
Once you've gotten this far, it's largely an issue of caching more, and keeping an eye on your database. Eventually, you'll outgrow a single server. First, you'll probably add more front end boxes, all backed by a single database server. Then you're going to have to start spreading your database load around, probably by sharding. For an excellent overview of this growth process, see this livejournal presentation
For a more in-depth look at much of the above, check out Building Scalable Web Sites, by Cal Henderson, of Flickr fame. Google has portions of the book available for preview
I've used MysqlTuner for performance analysis on my mysql servers and its given a good insight into further issues for googling, as well as making its own recommendations
A resource you might find helpful is the YDN set of performance rules.
Don't forget the fact that your users will be thousands of miles away from your server, and downloading dozens of files to render a single page. That latency, and the overhead of rendering the page in their browsers can be larger than the amount of time that you spend collecting the information, and generating the page.
See the pages at Yahoo Developer Network about Best Practices for Speeding Up Your Web Site, and the YSlow tool for seeing what part of the downloading of the site is taking time.
Don't forget to turn off atime for your filesystem!
I'd recommend using Jet Profiler for MySQL to find any bad queries. I've successfully used it on a couple of my sites. Really helpful, and much easier to digest than the slow query log.
I'd recommend starting with http://highscalability.com/
As for your suggestions:
Compression for images, definitely no. Type of files system tunning, yes, that could have some effect, but minimal. But actually the best is to use in-memory reverse proxy, or even better CDN.
For Apache basically only load the modules you need. Do not load anything else. As with PHP you can only use forking MPM, it's important to keep it slim. As for optimal settings, well you have to fine tune them to specific application, hardware etc. If you have enough CPU, it's recommendable that you use mod_deflate. Faster the server can send data to the client, faster it can start processing next request.