📜 ⬆️ ⬇️

We optimize $ 5 VPS (512MB RAM / 1 CPU) so that the wordpress site can handle 42,735,587 hits per day

When you buy a VPS server with 256MB or 512MB of RAM onboard and only a fraction of the processor power, using the default settings for services like MySQL / PHP / Apache is a very bad idea. Currently I have 3 sites launched on the cheapest tariff plan with 512MB RAM / 1 CPU. Not completely sure, but attendance is about 5-10 thousand visitors per day. Next, I want to share instructions on how to optimize LAMP using as little as 512 MB without going to swap. Typically, this setting uses 256 - 378Mb of memory and everything works pretty quickly.

Determine available memory and swap activity.

Before starting the optimization let's take a look at the amount of memory used. To do this, run the following command:

$ free -m 

For. To see a list of running processes and sort them by memory usage, you need to run the following command:
')
 $ ps -eo pmem,pcpu,rss,vsize,args | sort -k 1 -r | less 


We configure the LAMP server to consume a small amount of RAM. Stop, disable unnecessary services.

The first and obvious question that needs to be asked is “what services do I not need to use?”. Recently, I discovered a very handy utility for managing services. It is called " sysv-rc-conf " and manages services using pseudographics and flags. Exits like this:



Here is a list of services that I have changed.



Do not start the X server, turn off all unnecessary services and configure Apache, MySQL, PHP only with the basic functionality required.

Apache

Apache’s biggest problem is the amount of RAM it uses. I will consider the following ways to speed up work and reduce RAM consumption:



Configure Apache to use only the smallest number of running child processes.


Prefork is where real magic happens. This is where we tell Apache to generate a lot of processes. By default, a large number is allocated, which leads to the consumption of server RAM. Make sure that apache2.conf is not configured to run too many servers or has plenty of spare ones. Below is an example:

 <IfModule mpm_prefork_module> StartServers 1 MinSpareServers 1 MaxSpareServers 3 MaxClients 10 MaxRequestsPerChild 3000 </IfModule> <IfModule mpm_worker_module> StartServers 1 MinSpareThreads 5 MaxSpareThreads 15 ThreadLimit 25 ThreadsPerChild 5 MaxClients 25 MaxRequestsPerChild 200 </IfModule> 

Also, be sure to adjust the " KeepAliveTimeout " setting to 10 or 15. In my opinion, 15 seconds is too long for a small page to view and shorter than for a long page view.

Load only the most necessary modules.

The default Apache web server loads too many unnecessary modules. You can check which modules are installed and enabled with the following command:

 # apache2ctl -M 

Below is a list of modules that are required for Wordpress.
 LoadModule dir_module modules/mod_dir.so LoadModule log_config_module modules/mod_log_config.so LoadModule mime_module modules/mod_mime.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule alias_module modules/mod_alias.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule rewrite_module modules/mod_rewrite.so 

You need to comment out the remaining modules to save memory. Or you can enable / disable modules via the command line. To enable, use the command:

 # a2enmod module_name 

To disable:

 # a2dismod module_name 

After the done manipulations you need to restart the Apache web server:

 # service apache2 restart 

Reduce logging

If you want maximum performance, you definitely need to limit logging. On my server, I set the level of "error" (error). Also, if you do not need detailed statistics, you can disable user-agent or the http-referer logging.

 # ErrorLog: The location of the error log file. # If you do not specify an ErrorLog directive within a <VirtualHost> # container, error messages relating to that virtual host will be # logged here. If you *do* define an error logfile for a <VirtualHost> # container, that host's errors will be logged there and not here. # ErrorLog ${APACHE_LOG_DIR}/error.log # # LogLevel: Control the number of messages logged to the error_log. # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. # LogLevel error 

I am satisfied with such settings, but you decide.

MySQL server optimization

Tweaking MySQL to use a small amount of RAM is quite simple.
Next we will consider the following types of MySQL settings:



To optimize MySQL, we need to edit the /etc/mysql/my.cnf file.

Things we need to turn off

Mysql provides several table storage engines. Two of them are the most popular - this is InnoDB and MyISAM . The main differences between them are:


Problems with table level locks are noticeable only on very busy servers. For regular web sites, MyISAM performs better on low-cost servers.

If you decide to use MyISAM tables, then you need to add the following lines to the my.cnf configuration file:

 default-storage-engine=MyISAM default-tmp-storage-engine=MyISAM 

If you only have MyISAM tables, you can disable the InnoDB engine, thereby saving RAM by adding just one line to my.cnf:

 skip-innodb 

If you have used InnoDB in the past, then below I give you a script that automatically converts all InnoDB tables into MyISAM.

 #!/bin/bash MYSQLCMD=mysql for db in `echo show databases | $MYSQLCMD | grep -v Database`; do for table in `echo show tables | $MYSQLCMD $db | grep -v Tables_in_`; do TABLE_TYPE=`echo show create table $table | $MYSQLCMD $db | sed -e's/.*ENGINE=\([[:alnum:]\]\+\)[[:space:]].*/\1/'|grep -v 'Create Table'` if [ $TABLE_TYPE = "InnoDB" ] ; then mysqldump $db $table > $db.$table.sql echo "ALTER TABLE $table ENGINE = MyISAM" | $MYSQLCMD $db fi done done 

Optimizing MySQL server settings

Below are a few parameters that can be adjusted to speed up the MySQL server.

Key buffer size

This is one of the most important parameters affecting memory consumption and performance, which needs to be optimized. MySQL is trying to put everything that is indexed in key buffer, so this parameter brings tremendous performance. The SQL query will be submitted directly from RAM. I cannot say what size you should set for the key buffer, because only you know how much RAM you have free.

The query cache

If you do the same query twice in a row, the result is placed in the query cache, so mysql will not have to do the query again. If you are going to improve performance, then this option can be of great benefit, but memory consumption will increase. Therefore, you need to set this parameter not too huge, but not too small, that is, as much as your website needs.

Below are three variables that affect how your query cache works:

 query_cache_size query_cache_limit query_cache_type 


Maximum Number of Connections

This is an optional parameter. If you have already limited the number of apache processes, then everything is fine. If not, and you need to process thousands of users at the same time, you need to increase the value of this parameter.

The table cache

Each time you access the table, MySQL loads the link to the table as one entry in the table cache. This is done for each parallel access to the table, it is really important for performance, not significant for memory usage. You can constantly increase the cache table, but then you will rest on the limit on the number of open files in your operating system, so keep this in mind. If the table cache is set too small, mysql will barf at you, but you don’t want it.

Below is the correct my.cnf, which I optimized on my VPS with the lowest data plan.
My my.cnf
 [mysqld] port = 3306 socket = /var/lib/mysql/mysql.sock skip-locking key_buffer = 16K max_allowed_packet = 1M table_cache = 4 sort_buffer_size = 64K read_buffer_size = 256K read_rnd_buffer_size = 256K net_buffer_length = 2K thread_stack = 64K # For low memory, InnoDB should not be used so keep skip-innodb uncommented unless required skip-innodb # Uncomment the following if you are using InnoDB tables #innodb_data_home_dir = /var/lib/mysql/ #innodb_data_file_path = ibdata1:10M:autoextend #innodb_log_group_home_dir = /var/lib/mysql/ #innodb_log_arch_dir = /var/lib/mysql/ # You can set .._buffer_pool_size up to 50 - 80 % # of RAM but beware of setting memory usage too high #innodb_buffer_pool_size = 16M #innodb_additional_mem_pool_size = 2M # Set .._log_file_size to 25 % of buffer pool size #innodb_log_file_size = 5M #innodb_log_buffer_size = 8M #innodb_flush_log_at_trx_commit = 1 #innodb_lock_wait_timeout = 50 [mysqldump] quick max_allowed_packet = 16M [mysql] no-auto-rehash # Remove the next comment character if you are not familiar with SQL #safe-updates [isamchk] key_buffer = 8M sort_buffer_size = 8M [myisamchk] key_buffer = 8M sort_buffer_size = 8M [mysqlhotcopy] interactive-timeout 


Third-party MySQL configuration wizards

I found Percona, which provides free MySQL configuration and helps to choose the best MySQL server features for achieving better performance, as well as save time, avoid difficult moments and risks that can arise when self-configuring my.cnf.

MySQL server monitoring

MySQL stores statistics that help determine the best values ​​to use. In addition, there are two handy utilities that you can use to read these statistics and output in a clear format: tuning-primer.sh and mysqltuner.pl .
These scripts will allow you to monitor your MySQL server, and then provide a hint about the parameters that must be configured on your server.

PHP optimization and caching

PHP does not use memory very intensively, so I don’t think I need to worry much about the memory consumption of these processes if your application does not need it, but even if it is necessary to optimize, there will not be a significant reduction in memory consumption. But I researched and then found a few settings for PHP configurations that reduce the memory consumption by the web server.

 ; Limit the memory to 40M should be fine for barebones Wordpress memory_limit = 48M realpath_cache_ttl=300 realpath_cache_size=1M 

Alternative PHP Cache

Install PHP Cache, for example, Alternative PHP Cache. PHP cache will store compiled PHP scripts in such a way that they will be reused without compiling and, accordingly, will not create a load:

 # pecl install apc 

Below is my configured php.ini file.
My php.ini
 [APC] extension=apc.so apc.enabled=1 apc.shm_segments=1 ;32M per WordPress install apc.shm_size=128M ;Relative to the number of cached files (you may need to watch your stats for a day or two to find out a good number) apc.num_files_hint=7000 ;Relative to the size of WordPress apc.user_entries_hint=4096 ;The number of seconds a cache entry is allowed to idle in a slot before APC dumps the cache apc.ttl=7200 apc.user_ttl=7200 apc.gc_ttl=3600 ;Setting this to 0 will give you the best performance, as APC will ;not have to check the IO for changes. However, you must clear ;the APC cache to recompile already cached files. If you are still ;developing, updating your site daily in WP-ADMIN, and running W3TC ;set this to 1 apc.stat=1 ;This MUST be 0, WP can have errors otherwise! apc.include_once_override=0 ;Only set to 1 while debugging apc.enable_cli=0 ;Allow 2 seconds after a file is created before it is cached to prevent users from seeing half-written/weird pages apc.file_update_protection=2 ;Leave at 2M or lower. WordPress does't have any file sizes close to 2M apc.max_file_size=2M ;Ignore files apc.filters = "/var/www/apc.php" apc.cache_by_default=1 apc.use_request_time=1 apc.slam_defense=0 apc.mmap_file_mask=/var/www/temp/apc.XXXXXX apc.stat_ctime=0 apc.canonicalize=1 apc.write_lock=1 apc.report_autofilter=0 apc.rfc1867=0 apc.rfc1867_prefix =upload_ apc.rfc1867_name=APC_UPLOAD_PROGRESS apc.rfc1867_freq=0 apc.rfc1867_ttl=3600 apc.lazy_classes=0 apc.lazy_functions=0 


Static cache

Another thing that might be a good idea for a blog on a small server is to put it in front of a static HTTP-cache, for example, Varnish. What can really increase your scalability. Varnish configuration is a separate large article requiring a separate topic.

Conclusion


I laid out in open access the configuration of my web server to prove that you can achieve high performance even from the cheapest VPS container with 512MB of RAM and 1Ghz CPU. I use Ubuntu 12.04 LTS, LAMP, Varnish, APC Cache to host 3 websites made on Wordpress (not multisite) with attendance of 10k per day. Let's take a look at the test results from Blitz.io:



As you can see, 0.23% of users get Connection Timeout, when my website has 42,735,587 hits per day (WOW), you can still optimize something, but I enjoy the work of my web server. If you’re tired of this tutorial or don’t want to do it yourself, you can use services like PuPHPet or Vagrant.

Source: https://habr.com/ru/post/242011/


All Articles