小内存vps lnmp 优化

来自linuxsa wiki
跳转到导航 跳转到搜索

优化方向

真正开启 Cache Everything

docker stats

docker composet mediawiki

#apach
cat docker-compose.yml
# MediaWiki with MariaDB
#
# Access via "http://localhost:8080"
#   (or "http://$(docker-machine ip):8080" if using docker-machine)
services:
  mediawiki:
    image: mediawiki:lts
    container_name: mediawiki
    restart: always
    ports:
      - "127.0.0.1:8080:80"
      #- 8080:80
    links:
      - db
      - memcached
    volumes:
      #- mediawiki_data:/data/www/wiki
      # After initial setup, download LocalSettings.php to the same directory as
      # this yaml and uncomment the following line and use compose to restart
      # the mediawiki service
      #- ./mediawiki_data/html:/var/www/html #这个是not found
      #- ./mediawiki_data/images:/var/www/html/images 
      - .images:/var/www/html/images 
      - ./LocalSettings.php:/var/www/html/LocalSettings.php
      - ./mpm_prefork.conf:/etc/apache2/conf-enabled/99-custom-mpm.conf
      #- ./change-your-log.svg:/var/www/html/resources/assets/change-your-logo.svg
      #    # 资源限制(适用于 docker-compose)
      #    deploy:
      #      resources:
      #        limits:
      #          cpus: '0.3'
      #          memory: 200M      
      #    #mem_limit: 300m
      #    #cpus: 0.5
      

    depends_on:
      - db
      - memcached
  db:
    image: mariadb:11.8
    container_name: mariadb
    restart: always
    ports:
      #- "3306:3306"
      - "127.0.0.1:3306:3306"
    environment:
      # @see https://phabricator.wikimedia.org/source/mediawiki/browse/master/includes/DefaultSettings.php
      # random root pasword 注意  t9j3Ad^ZdYUZt[+M*U1]f4q<kfL[GqQ5
      #MYSQL_ROOT_PASSWORD: 'evan281FreeBsdrTyt'
      MYSQL_DATABASE: my_wiki
      MYSQL_USER: evan 
      #successed
      MYSQL_PASSWORD: 'evan22'
      MYSQL_ROOT_PASSWORD: '36'
      #MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
    volumes:
      - ./db_data:/var/lib/mysql
      - ./mysql.cnf:/etc/mysql/conf.d/custom.cnf:ro

        #    # 资源限制(适用于 docker-compose)
        #    deploy:
        #      resources:
        #        limits:
        #          cpus: '0.2'
        #          memory: 200M      
        #
        #
  memcached:
    image: memcached:1.6.38-alpine
    container_name: memcached
    restart: always
    ports:
      - "127.0.0.1:11211:11211"

        #  memcached:
        #    image: bitnami/memcached:1.6.38
        #    container_name: memcached
        #    restart: always
        #    environment:
        #      - MEMCACHED_USERNAME=mediawiki
        #      - MEMCACHED_PASSWORD=s
        #    ports:
        #      - "11211:11211"


cat mpm_prefork.conf 
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxRequestWorkers: maximum number of server processes allowed to start
# MaxConnectionsPerChild: maximum number of requests a server process serves

#at least is MaxRequestWorkers 5
StartServers            2
MinSpareServers         2
MaxSpareServers         3
MaxRequestWorkers       5
MaxConnectionsPerChild   200 


爬虫导致504

docker exec -it wiki ps aux | grep apache2 
 
 docker logs wiki --tail 50
172.18.0.1 - - [23/Feb/2026:03:51:53 +0000] "GET /index.php?title=%E7%89%B9%E6%AE%8A:%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95&returnto=%E7%89%B9%E6%AE%8A%3A%E6%9C%80%E8%BF%91%E9%93%BE%E5%87%BA%E6%9B%B4%E6%94%B9&returntoquery=hidebots%3D1%26days%3D30%26limit%3D100%26from%3D20251116110116%26target%3D%25E5%2588%2586%25E7%25B1%25BB%253ADevops HTTP/1.1" 200 5466 "-" "meta-externalagent/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)"
172.18.0.1 - - [23/Feb/2026:03:51:54 +0000] "GET /index.php?title=%E7%89%B9%E6%AE%8A:%E6%9C%80%E8%BF%91%E9%93%BE%E5%87%BA%E6%9B%B4%E6%94%B9&from=20250714094735&fromFormatted=2025%E5%B9%B47%E6%9C%8814%E6%97%A5+%28%E4%B8%80%29+09%3A47&userExpLevel=registered&hidemyself=1&hidebots=0&days=14&target=%E5%88%86%E7%B1%BB%3APython HTTP/1.1" 404 9051 "-" "meta-externalagent/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)"
172.18.0.1 - - [23/Feb/2026:03:51:55 +0000] "GET 

优化 nginx php mysql and redis

nginx

1、nginx运行的进程数,一般设置成和CPU的核数相同。
worker_processes 1;

2、worker_rlimit_nofile是nginx能打开文件的最大句柄数。 位置就跟在worker_processes后面就好了 
worker_rlimit_nofile 40960;

3、nginx进程所允许的最大的连接数,max_clients = worker_processes * worker_connections。
worker_connections 10240; 

4、设置连接超时时间为60。
keepalive_timeout 60;

5、该指令用于开启或关闭gzip模块(on/off)
gzip on;

6、设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是0,不管页面多大都压缩。建议设置成大于1k的字节数,小于1k可能会越压越大。
gzip_min_length 1k;

7、设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。4 16k代表以16k为单位,安装原始数据大小以16k为单位的4倍申请内存。
gzip_buffers 4 16k;

8、识别http的协议版本(1.0/1.1)
gzip_http_version 1.1;

9、gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu)
gzip_comp_level 2;

10、匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的。
gzip_types text/xml text/css text/javascript application/x-javascript application/xml;

11、和http头有关系,加个vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩
gzip_vary on;


 service nginx restart
 
 nginx优化效果如下 
优化前
29508K  3976K kqread   0:13   0.01% nginx

优化后 
7672K kqread   0:00   0.45% nginx
 

mysql

# mysql.cnf
[mysqld]
# 基础设置
max_connections = 20
thread_cache_size = 4
query_cache_size = 0
query_cache_type = 0

# InnoDB 优化(小内存)
innodb_buffer_pool_size = 64M
innodb_log_file_size = 16M
innodb_log_buffer_size = 4M
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table = 1

# 性能优化
table_open_cache = 64
sort_buffer_size = 512K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
join_buffer_size = 512K
tmp_table_size = 16M
max_heap_table_size = 16M

# 禁用性能模式
performance_schema = OFF


#docker-compose.yml 
db:
  volumes:
    - ./db_data:/var/lib/mysql
    - ./mysql.cnf:/etc/mysql/conf.d/custom.cnf:ro

1、key_buffer 是优化性能的重要参数,用来缓存 tables keys 和 indexes,增加这个值可以更好的处理索引,读和写都需要索引。这里设设置成 256K 足够了
key_buffer = 16k

2、table_cache 是所有线程打开的表的数量,增加值可以增大 MySQL 的文件描述符数量,避免频繁的打开表,原始 my-small.cnf 中 table_cache 设置成4有点小,
#一个 wordpress 的页面通常会涉及到10个左右的表,其他的程序比如 Drupal,MediaWiki 会涉及到更多,将table_cache改为8。
table_cache = 8

3、max_connections 是数据库最大的连接数量,可以根据自己博客/网站的访问量来定这个值。如果博客/网站经常出现:Too many connections 错误的信息说明需要增大 max_connections 的值。
max_connections = 16

4、hread_concurrency 是最大并发线程数,通常设置为 CPU核数量×2,在 VPS 宿主机上如果服务器有2颗物理 CPU,而每颗物理 CPU 又支持 H.T 超线程(一个处理器上整合了两个逻辑处理器单元),所以实际取值为4 × 2 = 8。
thread_concurrency = 2

5、对于博客/新闻网站来说,用得最多的就是查询,所以需要加入 query cache 的设置。query_cache_size 是执行查询所使用的缓冲大小。
query_cache_limit = 256K
query_cache_size = 4M

6、thread_stack 用来存放每个线程的标识信息,如线程 id,线程运行时环境等,可以通过设置 thread_stack 来决定给每个线程分配多大的内存。
thread_stack = 64K

7、sort_buffer_size是每个需要排序的线程分配的缓冲区大小,增加该值可以加速 order by 和 group by 的操作。注意:该参数是以每个连接分配内存,也就是说,如果有16个连接,sort_buffer_size 为 64K,
那么实际分配的内存为:16 × 64K = 1MB。如果设置的缓存大小无法满足需要,MySQL 会将数据写入磁盘来完成排序。因为磁盘操作和内存操作不在一个数量级,所以 sort_buffer_size 对排序的性能影响很大。
sort_buffer_size = 256K

8、read_buffer_size 是顺序读取数据时的缓冲区大小,与 sort_buffer_size 一样,该参数分配的内存也是以每连接为单位的。read_buffer_size 是用来当需要顺序读取数据的时候,如无发使用索引的情况下的全表扫描,
#全索引扫描等。在这种时候,MySQL 按照数据的存储顺序依次读取数据块,每次读取的数据快首先会暂存在 read_buffer_size 中,当 buffer 空间被写满或者全部数据读取结束后,再将 buffer 中的数据返回给上层调用者,以提高效率。
read_buffer_size = 256K

9、read_rnd_buffer_size 是随机读取数据时的缓冲区大小,与顺序读相对应。

read_rnd_buffer_size = 256K

10、net_buffer_size 用来存放客户端连接线程的连接信息和返回客户端的结果集的缓存大小。当 MySQL 接到请求后,产生返回结果集时,会在返回给请求线程之前暂存在在这个缓存中,等积累到一定大小的时候才开始向客户端发送,
#以提高网络效率。不过,net_buffer_size 所设置的仅仅只是初始大小,MySQL 会根据实际需要自行申请更多的内存,但最大不会超过 max_allowed_packet。

net_buffer_length = 2K


其它以前的优化 

key_buffer = 16K # or10M
max_allowed_packet = 1M
thread_stack = 64K
table_cache = 4
sort_buffer = 64K
net_buffer_length = 2K


这个不能改 很多时候是用innodb的啦 
如果你不使用InnoDB表,就在文件底部禁用InnoDB:

skip-innodb

service mysql-server restart  

php

因为是php7  所以我的是以 Php7性能优化技巧 为准 
多一点PHP配置优化
1、开启php gzip压缩。这里和nginx gzip压缩的东西不同,nginx是压缩html,css,javascript。php gzip是用来压缩php。
; http://php.net/zlib.output-compression
zlib.output_compression = On

; http://php.net/zlib.output-compression-level
zlib.output_compression_level = 5

2、修改php脚本使用的最大内存数。
memory_limit = 32M


其它

确保以下的参数已经设置好,主要要去掉前面的注释符号“;”

max_execution_time = 30
memory_limit = 64M
error_reporting = E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR
display_errors = Off
log_errors = On
error_log = /var/log/php.log
register_globals = Off
注意:这里的64M设置对大部分站点都适用,如果是更大的站点,你需要改成128M或者更大。
pm.min_spare_servers=2  如果=3 load就会超过1 
service  php-fpm restart

redis



 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes



分析可以看出redis实际上的内存管理成本非常高,即占用了过多的内存,作者对这点也非常清楚,所以提供了一系列的参数和手段来控制和节省内存,我们分别来讨论下。

首先最重要的一点是不要开启Redis的VM选项,即虚拟内存功能,这个本来是作为Redis存储超出物理内存数据的一种数据在内存与磁盘换入换出的一个持久化策略,但是其内存管理成本也非常的高,并且我们后续会分析此种持久化策略并不成熟,所以要关闭VM功能,请检查你的redis.conf文件中 vm-enabled 为 no。

其次最好设置下redis.conf中的maxmemory选项,该选项是告诉Redis当使用了多少物理内存后就开始拒绝后续的写入请求,该参数能很好的保护好你的Redis不会因为使用了过多的物理内存而导致swap,最终严重影响性能甚至崩溃。

另外Redis为不同数据类型分别提供了一组参数来控制内存使用,我们在前面详细分析过Redis Hash是value内部为一个HashMap,如果该Map的成员数比较少,则会采用类似一维线性的紧凑格式来存储该Map, 即省去了大量指针的内存开销,这个参数控制对应在redis.conf配置文件中下面2项:



 service redis restart 
 service shadowsocks_libev start

不太好优化  我如果不  maxmemory=0  就会整个站打开都慢

Redis内存使用优化与存储

关于redis性能问题分析和优化

心得

优化nginx php mysql 得到的内存给redis 用 哈哈

参考

512内存VPS的MySql和Php优化设置

小内存VPS LNMP配置优化

小内存VPS Mysql优化配置 图文教程

nginx 配置高并发

nginx 调优 linuxchina