2017年7月5日 星期三

Nginx+PHP-FPM+socket 配置優化

1.nginx + php-fpm,連線數一多會發生,502 Bad Gateway 或 504 Gateway Time-out 等問題。
502 Bad Gateway:nginx 連不到 php-fpm。可以增加 php-fpm 連線數量。
或將 nginx 連 php-fpm 等待連接的時間設長一點(fastcgi_connect_timeout)。
504 Gateway Time-out:php-fpm 執行時間,超過 nginx 允許的接收時間。
可以將 nginx 接收時間設長一點(fastcgi_read_timeout)。
影響連線數限制的設定有三個:linux 系統的限制、nginx 的限制、php-fpm 的限制。
修改時,須視執行情況調整,若設的太大,系統負擔太大,會執行的很慢,甚至崩潰。

主要是4個文件設定


修改 Linux 作業系統設定


$ /etc/sysctl.conf

net.ipv4.tcp_syncookies = 1
開啟 SYN Cookies,當出現 SYN 等待隊列溢出時,啟用 cookies 來處理。
net.ipv4.tcp_max_tw_buckets = 6000
timewait 的數量,默認是 180000。
net.core.netdev_max_backlog = 819200
每個網絡接口接收數據包的速率比內核處理這些包的速率快時,允許送到隊列的數據包的最大數目。 不能低于
$  /etc/nginx/sites-available/default
isten 80 default_server backlog=1024;
$ /etc/php/7.0/fpm/pool.d/www.conf
listen.backlog = 2048
net.core.somaxconn = 65535
web 應用中 listen 函數的 backlog 默認會給我們內核參數的 net.core.somaxconn 限製到 128,而 nginx 定義的 NGX_LISTEN_BACKLOG 默認為 511,所以有必要調整這個值。
net.ipv4.tcp_max_orphans = 3276800
系統中最多有多少個 TCP 套接字不被關聯到任何一個用戶文件句柄上。如果超過這個數字,孤兒連接將即刻被復位並打 印出警告信息。這個限制僅僅是為了防止簡單的 DoS 攻擊,不能過分依靠它或者人為地減小這個值,更應該增加這個值 (如果增加了內存之後)。
net.ipv4.tcp_max_syn_backlog = 819200
記錄的那些尚未收到客戶端確認信息的連接請求的最大值。對於有 128M 內存的系統而言,缺省值是 1024,小內存的系 統則是 128。 #不能低于
$  /etc/nginx/sites-available/default
isten 80 default_server backlog=1024;
$ /etc/php/7.0/fpm/pool.d/www.conf
listen.backlog = 2048
net.ipv4.tcp_timestamps = 0
時間戳可以避免序列號的捲繞。一個 1Gbps 的鏈路肯定會遇到以前用過的序列號。時間戳能夠讓內核接受這種“異常”的 數據包。這裡需要將其關掉。
net.ipv4.tcp_synack_retries = 1
為了打開對端的連接,內核需要發送一個 SYN 並附帶一個回應前面一個 SYN 的 ACK。也就是所謂三次握手中的第二次 握手。這個設置決定了內核放棄連接之前發送 SYN+ACK 包的數量。
net.ipv4.tcp_syn_retries = 1
在內核放棄建立連接之前發送 SYN 包的數量。
net.ipv4.tcp_tw_recycle = 1
啟用 timewait 快速回收。
net.ipv4.tcp_tw_reuse = 1
開啟重用。允許將 TIME-WAIT sockets 重新用於新的 TCP 連接。
net.ipv4.tcp_fin_timeout = 1
如果套接字由本端要求關閉,這個參數決定了它保持在 FIN-WAIT-2 狀態的時間。對端可以出錯並永遠不關閉連接,甚 至意外當機。缺省值是 60 秒。2.2 內核的通常值是 180 秒,你可以按這個設置,但要記住的是,即使你的機器是一個輕 載的 WEB 服務器,也有因為大量的死套接字而內存溢出的風險,FIN- WAIT-2 的危險性比 FIN-WAIT-1 要小,因為它最 多只能吃掉 1.5K 內存,但是它們的生存期長些。
net.ipv4.tcp_keepalive_time = 30
當 keepalive 起用的時候,TCP 發送 keepalive 消息的頻度。缺省是 2 小時。
net.ipv4.ip_local_port_range = 1024 65000
允許系統打開的端口範圍。

#不重開機,立即套用設定
$ sysctl -p

完整的優化設置範例:
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 819200
net.core.somaxconn = 65535
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 819200
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000
fs.file-max = 8192

nginx 優化

$ /etc/nginx/nginx.conf

worker_processes 8;
nginx 進程數,建議按照 cpu 數目來指定,一般為它的倍數。
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
為每個進程分配 cpu,上例中將 8 個進程分配到 8 個 cpu,當然可以寫多個,或者將一個進程分配到多個 cpu。
worker_rlimit_nofile 204800;
這個指令是指當一個 nginx 進程打開的最多文件描述符數目,理論值應該是最多打開文件數(ulimit -n)與 nginx 進程數 相除,但是 nginx 分配請求並不是那麼均勻,所以最好與 ulimit -n 的值保持一致。
use epoll;
使用 epoll 的 I/O 模型,這個不用說了吧。
worker_connections 204800;
每個進程允許的最多連接數,理論上每台 nginx 服務器的最大連接數為 worker_processes*worker_connections。
keepalive_timeout 60;
keepalive 超時時間。
client_header_buffer_size 4k;
客戶端請求頭部的緩衝區大小,這個可以根據你的系統分頁大小來設置,一般一個請求的頭部大小不會超過 1k,不過由
於一般系統分頁都要大於 1k,所以這裡設置為分頁大小。分頁大小可以用命令 getconf PAGESIZE 取得。
open_file_cache max=102400 inactive=20s;
這個將為打開文件指定緩存,默認是沒有啟用的,max 指定緩存數量,建議和打開文件數一致,inactive 是指經過多長時
間文件沒被請求後刪除緩存。
open_file_cache_valid 30s;
這個是指多長時間檢查一次緩存的有效信息。
open_file_cache_min_uses 1;
open_file_cache 指令中的 inactive 參數時間內文件的最少使用次數,如果超過這個數字,文件描述符一直是在緩存中打開的,如上例,如果有一個文件在 inactive 時間內一次沒被使用,它將被移除。
fastcgi_connect_timeout 300;
指定連接到後端 FastCGI 的超時時間。#太短可能發生 502 Bad Gateway
fastcgi_send_timeout 300;
向 FastCGI 傳送請求的超時時間,這個值是指已經完成兩次握手後向 FastCGI 傳送請求的超時時間。
fastcgi_read_timeout 300;
接收 FastCGI 應答的超時時間,這個值是指已經完成兩次握手後接收 FastCGI 應答的超時時間。#太短可能發生 504 Gateway Time-out
fastcgi_buffer_size 16k;
指定讀取 FastCGI 應答第一部分需要用多大的緩衝區,這裡可以設置為 fastcgi_buffers 指令指定的緩衝區大小,上面的
指令指定它將使用 1 個 16k 的緩衝區去讀取應答的第一部分,即應答頭,其實這個應答頭一般情況下都很小(不會超過
1k),但是你如果在 fastcgi_buffers 指令中指定了緩衝區的大小,那麼它也會分配一個 fastcgi_buffers 指定的緩衝區大
小去緩存。
fastcgi_buffers 16 16k;
指定本地需要用多少和多大的緩衝區來緩衝 FastCGI 的應答,如上所示,如果一個 php 腳本所產生的頁面大小為 256k,
則會為其分配 16 個 16k 的緩衝區來緩存,如果大於 256k ,增大於 256k 的部分會緩存到 fastcgi_temp 指定的路徑中,
當然這對服務器負載來說是不明智的方案,因為內存中處理數據速度要快於硬盤,通常這個值的設置應該選擇一個你的
站點中的 php 腳本所產生的頁面大小的中間值,比如你的站點大部分腳本所產生的頁面大小為 256k 就可以把這個值設
置為 16 16k,或者 4 64k 或者 64 4k,但很顯然,後兩種並不是好的設置方法,因為如果產生的頁面只有 32k,如果用 4
64k 它會分配 1 個 64k 的緩衝區去緩存,而如果使用 64 4k 它會分配 8 個 4k 的緩衝區去緩存,而如果使用 16 16k 則它
會分配 2 個 16k 去緩存頁面,這樣看起來似乎更加合理。
fastcgi_busy_buffers_size 32k;
這個指令我也不知道是做什麼用,只知道默認值是 fastcgi_buffers 的兩倍。
fastcgi_temp_file_write_size 32k;
在寫入 fastcgi_temp_path 時將用多大的數據塊,默認值是 fastcgi_buffers 的兩倍。
fastcgi_cache TEST
開啟 FastCGI 緩存並且為其製定一個名稱。個人感覺開啟緩存非常有用,可以有效降低 CPU 負載,並且防止 502 錯誤。
但是這個緩存會引起很多問題,因為它緩存的是動態頁面。具體使用還需根據自己的需求。
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
為指定的應答代碼指定緩存時間,如上例中將 200,302 應答緩存一小時,301 應答緩存 1 天,其他為 1 分鐘。
fastcgi_cache_min_uses 1;
緩存在 fastcgi_cache_path 指令 inactive 參數值時間內的最少使用次數,如上例,如果在 5 分鐘內某文件 1 次也沒有被
使用,那麼這個文件將被移除。
fastcgi_cache_use_stale error timeout invalid_header http_500;
不知道這個參數的作用,猜想應該是讓 nginx 知道哪些類型的緩存是沒用的。
以上為 nginx 中 FastCGI 相關參數,另外,FastCGI 自身也有一些配置需要進行優化,如果你使用 php-fpm 來管理

#套用設定
service nginx stop
service nginx start

完整的優化設置範例:
user www-data;
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
pid /run/nginx.pid;
worker_rlimit_nofile 204800;

events {
use epoll;
worker_connections 204800;
}

http {

sendfile on;
tcp_nopush on;
tcp_nodelay on;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
client_body_buffer_size 512k;
server_names_hash_bucket_size 128;

include /etc/nginx/mime.types;
default_type application/octet-stream;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
open_file_cache max=204800 inactive=20s;
open_file_cache_min_uses 1;
open_file_cache_valid 30s;

gzip off;
gzip_disable "msie6";
gzip_min_length 1k;
gzip_comp_level 2;
gzip_buffers 32 4k;
gzip_http_version 1.1;

include /etc/nginx/conf.d/*.conf;
#include /etc/nginx/sites-enabled/*; include /etc/nginx/sites-available/default;
}


[Nginx virtual host 設定] 

重啟後,查看 backlog 設定是否生效。
這邊要注意的是,backlog 這個值不是越大越好,
若程式很耗費資源,當 backlog 太大時,可能耗盡 Server 資源,造成網站卡住所有連線反應都很慢,
這個設定值會受 linux 系統 net.core.somaxconn 設定的限制。

$ /etc/nginx/sites-available/default

server {
    #修改 backlog,多個 virtual host,backlog 只須在其中一個設定
    listen 80 default_server backlog=1024;
    ....
}

$ ss -nlt

State   Recv-Q Send-Q   Local Address:Port    Peer Address:Port

LISTEN    0     1024                *:80                 *:*


php-fpm 優化

/etc/php/7.0/fpm/pool.d/www.conf

常駐的 process 數越多,系統越不用開開關關 process,會較節省 CPU。
但 process 數越多,使用的記憶體也會越大,所以,須視CPU與記憶體使用狀況,取一個平衡。
若設的太小,在 php-fpm.log 會記錄相關的訊息。

listen.backlog = 65535
pm.max_children = 800
pm.start_servers = 200
pm.min_spare_servers = 100
pm.max_spare_servers = 800
pm.max_requests = 4000
rlimit_files = 51200


參考文件
Linux、nginx、php-fpm 連線數優化
nginx 優化突破十萬並行連線數
nginx+php-fpm性能参数优化原则
nginx提示:500 Internal Server Error错误的解决方法

2017年6月16日 星期五

Program use a jave 6 & how to install


  1. download java6  http://download.oracle.com/otn/java/jdk/6u45-b06/jre-6u45-linux-x64.bin
  2. $ chmod u+x jre-6u45-linux-x64.bin
  3. $ ./jre-6u45-linux-x64.bin
  4. $ sudo mkdir -p /usr/lib/jvm
  5. $ sudo mv jre1.6.0_45 /usr/lib/jvm/
  6. $ sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jre1.6.0_45/bin/java" 1
  7. $ sudo update-alternatives --install "/usr/lib/mozilla/plugins/libjavaplugin.so" "mozilla-javaplugin.so" "/usr/lib/jvm/jre1.6.0_45/lib/amd64/libnpjp2.so" 1
  8. $ sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jre1.6.0_45/bin/javaws" 1
  9. java -version
    java version "1.6.0_45"
    Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
    Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mod

2017年6月5日 星期一

MySQL/MariaDB 性能調整和優化重點


※在開始調整前,請不要全然接受所有的建議,每個MySQL/MariaDB設置皆不盡相同,在進行任何修改之前請先確認每一個項目的目的,並依照各自server配置作相對應得調整。
※MySQL/MariaDB 配置文件位於 /etc/mysql/my.cnf,每次更改此文件後需要重新啟動Mysql server,使更改生效。


1.啟用InnoDB 的每張表一個數據文件設置

innodb_file_per_table: 這個不是效能上的優化,而是使 InnoDB 資料表管理更方便。
當設定成 off 時,所有 InnoDB 資料表的資料及索引會儲存在一個 .ibd 檔案,
如果設定成 on, 每個資料表會有一個獨立的 .ibd 檔。
首先,有一個重要的解釋, InnoDB 是一個存儲引擎。MySQL 和MariaDB 使用InnoDB 作為默認存儲引擎。以前,MySQL 使用系統表空間來保存數據庫中的表和索引。
這意味著服務器唯一的目的就是數據庫處理,它們的存儲盤不用於其它目的。
InnoDB提供了更靈活的方式,它把每個數據庫的信息保存在一個.ibd數據文件中。
每個.idb文件代表它自己的表空間。通過這樣的方式可以更快地完成類似“TRUNCATE”的數據庫操作,當刪除或截斷一個數據庫表時,你也可以回收未使用的空間。
這樣配置的另一個好處是你可以將某些數據庫表放在一個單獨的存儲設備。
這可以大大提升你磁盤的I/O 負載。MySQL 5.6及以上的版本默認啟用innodb_file_per_table
該指令看起來是這樣的:

innodb_file_per_table = 1

2.優化使用InnoDB 的緩衝池


innodb_buffer_pool_size: 這個設定是 innodb 儲存引擎資料庫,所使用的資料及索引快取,
根據記憶體的大小䀆量設定大一點,可以減低讀取資料時從硬碟讀取的次數。
如果是獨立的 MySQL 伺服器,可以這樣設定: (約實體記憶體的60~80%)
  1. 系統 8GB 記憶體: 5GB – 6GB 
  2. 系統 32GB 記憶體: 20GB – 25GB 
  3. 系統 128GB 記憶體: 100GB – 120GB
InnoDB 引擎在內存中有一個緩衝池用於緩存數據和索引。這當然有助於你更快地執行MySQL/MariaDB 查詢語句。選擇合適的內存大小需要一些重要的決策並對系統的內存消耗有較多的認識。下面是你需要考慮的: 
  1. 其它的進程需要消耗多少內存。這包括你的系統進程,頁表,套接字緩衝。 
  2. 你的服務器是否專門用於MySQL 還是你運行著其它非常消耗內存的服務。 
如果是Innodb的資料庫,innodb_buffer_pool_size就開的儘可能大點
該參數是用來緩存數據索引以及數據塊的數據,簡單的來說,
當我們操作Innodb資料庫獲取數據的時候,都會在這個內存的區域塊中走一遭,
獲取數據.Innodb_buffer_pool_size 設置了Innodb存儲引擎的內存區域塊的大小,
直接關係到Innodb的存儲引擎性能,因此我們如果有足夠大的內存,
應該將儘可能多的內存設置,從而將儘可能多的數據以及索引發到該內存數據塊中.
我們可以通過 (Innodb_buffer_pool_read_requests – Innodb_buffer_pool_reads) /Innodb_buffer_pool_read_requests * 100% 計算緩存命中率,並根據命中率
來調整 innodb_buffer_pool_size 參數大小進行優化
在一個專用的機器上,你可能會把60-80%的內存分配給innodb_buffer_pool_size。
如果你打算在一個機器上運行更多的服務,
你應該重新考慮專門用於innodb_buffer_pool_size的內存大小。
該指令看起來是這樣的:
  1. innodb_buffer_pool_size = 256M
  2. 預修改innodb_buffer_pool_size,需要stop server,
    並刪除/var/lib/mysql/ib_logfile0, ib_logfile1........ib_logfilen,
    再來必須把預設註解的innodb_log_file_size開啟,
    innodb_log_file_size設定的值為innodb_buffer_pool_size的25%,之後再重啟server即可


3.設置 redo logs 的體積


innodb_log_file_size: 這是 redo logs 的體積,redo logs 可以更快速地寫入,預設值是 2GB,

這個設定可以從 2GB 開始逐步增加,以找到最適合的設定。

MySQL 5.5 最大可以設定成 4GB, 而 MySQL 5.6 開始則沒有這個限制。

對於大量數據集的編寫密集型工作負載非常重要。 較大的尺寸提供更好的性能,

但增加恢復時間,所以要小心。 我通常使用值64M-512M取決於服務器大小。


4.設定資料及快取如果寫入硬碟


innodb_flush_method: 設定資料及快取如果寫入硬碟,

當系統有 RAID 卡及支援電池保護 write-back 快取,建議設定成 O_DIRECT.


5. 設定transactions 的緩存大小


innodb_log_buffer_size: 這是 transactions 的緩存大小,預設值是 1MB,

如果 transactions 的欄位是 blob 或 text,援存很快會用盡,可以逐步增加。

對於具有中等寫入負載和較短事務的許多工作負載,這個默認值是可以的。

如果您有更新活動峰值,或者與blob工作很多,您可能希望增加它。

不要設置太高,因為它會浪費內存 - 它每1秒刷新一次,所以你不需要空間超過1秒的更新。

8MB-16MB通常就夠了。 較小的安裝應使用較小的值。


6.設置MySQL 的最大連接數


max_connections: 如果 MySQL 伺服器經常出現 “Too many connections” 錯誤,

那便表示 “max_connections” 設定太低,如果還遇到 “Too many connections” 問題,

逐步增加測試。 

max_connections指令告訴你當前你的服務器允許多少並發連接。

MySQL/MariaDB 服務器允許有SUPER 權限的用戶在最大連接之外再建立一個連接。

只有當執行MySQL 請求的時候才會建立連接,執行完成後會關閉連接並被新的連接取代。

請記住,太多的連接會導致內存的使用量過高並且會鎖住你的MySQL 服務器。

一般小網站需要100-200 的連接數,而較大可能需要500-800 甚至更多。

這裡的值很大程度上取決於你MySQL/MariaDB 的使用情況。

該指令看起來是這樣的:
  1. max_connections = 300

你可以用以下公式來計算線程池的命中率:
  1. 100 - ((Threads_created / Connections) * 100)

如果你得到一個較低的數字,這意味著大多數mysql連接使用新的線程,而不是從緩存加載。在這種情況下,你需要增加thread_cache_size。

這裡有一個好處是可以動態地改變thread_cache_size而無需重啟MySQL服務。
你可以通過以下方式來實現:
  1. mysql> set global thread_cache_size = 16;


7.在MySQL 中避免使用Swappiness


thread_cache_size指令用來設置你服務器緩存的線程數量。當客戶端斷開連接時,

如果當前線程數小於thread_cache_size,它的線程將被放入緩存中。

下一個請求通過使用緩存池中的線程來完成。

要提高服務器的性能,你可以設置thread_cache_size的值相對高一些。

你可以通過以下方法來查看線程緩存命中率:
  1. mysql> show status like 'Threads_created'; 
  2. mysql> show status like 'Connections';


8.配置MySQL 的查詢緩存容量

如果你有很多重複的查詢並且數據不經常改變–請使用緩存查詢。人們常常不理解

query_cache_size的實際含義而將此值設置為GB級,這實際上會降低服務器的性能。

背後的原因是,在更新過程中線程需要鎖定緩存。通常設置為200-300 MB應該足夠了。

如果你的網站比較小的,你可以嘗試給64M 並在以後及時去增加。

在你的MySQL 配置文件中添加以下設置:

  1. query_cache_type = 1
  2. query_cache_limit = 256K
  3. query_cache_min_res_unit = 2k
  4. query_cache_size = 64M

如果您的應用程序讀取密集,並且沒有應用程序級別的緩存,

這可以幫助您優化MySQL數據庫。

不要設置太大,因為它可能會減慢,因為它的維護可能會變得昂貴。

從32M到512M的值通常是有意義的。 經過一段時間檢查,看看它是否被很好地使用。

對於某些工作負載,緩存命中率低於允許其啟用的理由。

注意:您可以看到所有這些都是全局變量。 這些變量取決於硬件和存儲引擎的混合,

而每個會話變量通常是工作負載特定的。 如果您有簡單的查詢,

即使您有64GB的內存浪費, 也沒有理由增加sort_buffer_size 。

此外,這樣做可能會降低性能。

我可以分析工作負載後,通常將每個會話變量調整到第二步。

query_cache_size/query_cache_type:

Query cache 作用於整個 MySQL Instance,主要用來緩存 MySQL 中的 ResultSet,

也就是一條SQL語句執行的結果集,所以僅僅只能針對select語句。

當我們打開了Query Cache 功能,MySQL在接受到一條select語句的請求後,

如果該語句滿足Query Cache的要求(未顯式說明不允許使用Query Cache,

或者已經顯式申明需要使用QueryCache),

MySQL 會直接根據預先設定好的HASH算法將接受到的select語句以字符串方式進行hash,

然後到Query Cache 中直接查找是否已經緩存。也就是說,如果已經在緩存中,

該select請求就會直接將數據返回,從而省略了後面所有的步驟(如 SQL語句的解析,

優化器優化以及向存儲引擎請求數據等),極大的提高性能。 當然,Query Cache 也有一個致命的缺陷,那就是當某個表的數據有任何任何變化,

都會導致所有引用了該表的select語句在Query Cache 中的緩存數據失效。

所以,當我們的數據變化非常頻繁的情況下,使用Query Cache 可能會得不償失。 Query Cache的使用需要多個參數配合,其中最為關鍵的是 query_cache_size 和 query_cache_type ,

前者設置用於緩存 ResultSet 的內存大小,後者設置在何場景下使用Query Cache。

在以往的經驗來看,如果不是用來緩存基本不變的數據的MySQL資料庫,

query_cache_size 一般 256MB 是一個比較合適的大小。當然,這可以通過計算

Query Cache的命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))來進行調整。

query_cache_type可以設置為0(OFF),1(ON)或者2(DEMOND),

分別表示完全不使用query cache,除顯式要求不使用query cache(使用sql_no_cache)

之外的所有的select都使用query cache,只有顯示要求才使用querycache(sql_cache)。

9.設置binlog_cache_size 


binlog_cache_size (global)Binlog Cache 用於在打開了二進位日誌(binlog)記錄功能的環

境,是 MySQL 用來提高binlog的記錄效率而設計的一個用於短時間內臨時緩存binlog數據的

內存區域。

一般來說,如果我們的資料庫中沒有什麼大事務,寫入也不是特別頻繁,

2MB~4MB是一個合適的選擇。但是如果我們的資料庫大事務較多,

寫入量比較大,可與適當調高binlog_cache_size。同時,

我們可以通過binlog_cache_use 以及 binlog_cache_disk_use來分析設置的binlog_cache_size

是否足夠,是否有大量的binlog_cache由於內存大小不夠而使用臨時文件

(binlog_cache_disk_use)來緩存了

10.innodb_additional_mem_pool_size(global)


這個參數我們平時調整的可能不是太多,很多人都使用了默認值,

可能很多人都不是太熟悉這個參數的作用。innodb_additional_mem_pool_size

設置了InnoDB存儲引擎用來存放數據字典信息以及一些內部數據結構的內存空間大小,

所以當我們一個MySQL Instance中的資料庫對象非常多的時候,

是需要適當調整該參數的大小以確保所有數據 都能存放在內存中提高訪問效率的。

這個參數大小是否足夠還是比較容易知道的,因為當過小的時候,

MySQL 會記錄 Warning 信息到資料庫的 error log 中,

這時候你就知道該調整這個參數大小了。

這個並沒有真正影響性能太多,至少在操作系統與體面的內存分配器。 仍然你可能想要

20MB(有時更大),所以你可以看到Innodb分配多少內存的雜項需求。

11.innodb_log_buffer_size (global)


innodb_log_buffer_size (global)這是 InnoDB 存儲引擎的事務日誌所使用的緩衝區。

類似於 Binlog Buffer,InnoDB 在寫事務日誌的時候,為了提高性能,

也是先將信息寫入 Innofb Log Buffer 中,

當滿足 innodb_flush_log_trx_commit 參數所設置的相應條件(或者日誌緩衝區寫滿)之後,

才會將日誌寫到文件(或者同步到磁碟)中。

可以通過 innodb_log_buffer_size參數設置其可以使用的最大內存空間。

註:innodb_flush_log_trx_commit 參數對 InnoDB Log 的寫入性能有非常關鍵的影響。

該參數可以設置為0,1,2,解釋如下: 0:log buffer中的數據將以每秒一次的頻率寫入到log

file中,且同時會進行文件系統到磁碟的同步操作,

但是每個事務的commit並不會觸發任何log buffer 到log file的刷新或者 文件系統到磁碟的刷新

操作; 1:在每次事務提交的時候將log buffer 中的數據都會寫入到log file,同時也會觸發文件

系統到磁碟的同步; 2:事務提交會觸發log buffer 到log file的刷新,

但並不會觸發磁碟文件系統到磁碟的同步。

此外,每秒會有一次文件系統到磁碟同步操作。 此外,MySQL文檔中還提到,

這幾種設置中的每秒同步一次的機制,

可能並不會完全確保非常準確的每秒就一定會發生同步,還取決於進程調度的問題。

實際上,InnoDB 能否真正滿足此參數所設置值代表的意義正常 Recovery

還是受到了不同 OS 下文件系統以及磁碟本身的限制,

可能有些時候在並沒有真正完成磁碟同步的情況下也會告訴 mysqld 已經完成了磁碟同步。

下面是轉載的一些常用參數的設置: query_cache_type : 如果全部使用innodb存儲引擎,

建議為0,如果使用MyISAM 存儲引擎,建議為2,

同時在SQL語句中顯式控制是否使用gquery cachequery_cache_size:

根據 命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))進行調整,

一般不建議太大,256MB可能已經差不多了,大型的配置型靜態數據可適當調大

binlog_cache_size: 一般環境2MB~4MB是一個合適的選擇,事務較大且寫入頻繁的資料庫環

境可以適當調大, 但不建議超過32MBkey_buffer_size: 如果不使用MyISAM存儲引擎,

16MB足以,用來緩存一些系統表信息等。 如果使用 MyISAM存儲引擎,

在內存允許的情況下,儘可能將所有索引放入內存, 簡單來說就是「越大越好」


12.bulk_insert_buffer_size


如果經常性的需要使用批量插入的特殊語句(上面有說明)來插入數據,

可以適當調大該參數至16MB~32MB,不建議繼續增大,某人8MBinnodb_buffer_pool_size:

如果不使用InnoDB存儲引擎,可以不用調整這個參數,如果需要使用, 在內存允許的情況

下,儘可能將所有的InnoDB數據文件存放如內存中, 同樣將但來說也是「越大越好」


13.innodb_additional_mem_pool_size


一般的資料庫建議調整到8MB~16MB,如果表特別多,可以調整到32MB,

可以根據error log中的信息判斷是否需要增大

14.innodb_log_buffer_size


默認是1MB,系的如頻繁的系統可適當增大至4MB~8MB。當然如上面介紹所說,

這個參數實際上還和另外的flush參數相關。一般來說不建議超過32MB


15.innodb_max_dirty_pages_pct


根據以往的經驗,重啟恢復的數據如果要超過1GB的話,啟動速度會比較慢,

幾乎難以接受,所以建議不大於 1GB/innodb_buffer_pool_size(GB)*100 這個值。

當然,如果你能夠忍受啟動時間比較長, 而且希望儘量減少內存至磁碟的flush,

可以將這個值調整到90,但不建議超過90

16.配置臨時表容量和內存表最大容量


tmp_table_size和max_heap_table_size這兩個變量的大小應該相同,它們可以讓你避免磁盤寫

入。 tmp_table_size是內置內存表的最大空間。如果表的大小超出限值將會被轉換為磁盤上的

MyISAM表。 這會影響數據庫的性能。管理員通常建議在服務器上設置這兩個值為實體記憶

體每GB 內存給64M。

EX:4G -> 256M 8G -> 512M 16G -> 1G
[mysqld]
tmp_table_size= 64M
max_heap_table_size= 64M

17.啟用MySQL 慢查詢日誌


記錄慢查詢可以幫助你定位數據庫中的問題並幫助你調試。

這可以通過在你的MySQL 配置文件中添加以下值來啟用:

slow-query-log = 1
slow-query-log-file = /var/lib/mysql/mysql-slow.log
long_query_time = 1

第一個變量啟用慢查詢日誌,第二個告訴MySQL實際的日誌文件存儲位置。

使用long_query_time來定義完成MySQL查詢多少用時算長。

18.參考文件



19.修改範例

# MariaDB database server configuration file.
#
# You can copy this file to one of:
# - "/etc/mysql/my.cnf" to set global options,
# - "~/.my.cnf" to set user-specific options.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

# This will be passed to all mysql clients
# It has been reported that passwords should be enclosed with ticks/quotes
# escpecially if they contain "#" chars...
# Remember to edit /etc/mysql/debian.cnf when changing the socket location.
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock

# Here is entries for some specific programs
# The following values assume you have at least 32M ram

# This was formally known as [safe_mysqld]. Both versions are currently parsed.
[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0

[mysqld]
#
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc_messages_dir = /usr/share/mysql
lc_messages = en_US
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = 127.0.0.1
#
# * Fine Tuning
#
max_connections = 300
connect_timeout = 5
wait_timeout = 60
max_allowed_packet = 16M
thread_cache_size       = 128
sort_buffer_size = 4M
bulk_insert_buffer_size = 16M
tmp_table_size = 256M
max_heap_table_size = 256M
#
# * MyISAM
#
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched. On error, make copy and try a repair.
myisam_recover_options = BACKUP
key_buffer_size = 128M
#open-files-limit = 2000
table_open_cache = 400
myisam_sort_buffer_size = 512M
concurrent_insert = 2
read_buffer_size = 2M
read_rnd_buffer_size = 1M
#
# * Query Cache Configuration
#
# Cache only tiny result sets, so we can fit more in the query cache.
query_cache_limit = 256K
query_cache_size = 64M
# for more write intensive setups, set to DEMAND or OFF
#query_cache_type = DEMAND
query_cache_type = 1
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
#general_log_file        = /var/log/mysql/mysql.log
#general_log             = 1
#
# Error logging goes to syslog due to /etc/mysql/conf.d/mysqld_safe_syslog.cnf.
#
# we do want to know about network errors and such
log_warnings = 2
#
# Enable the slow query log to see queries with especially long duration
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mariadb-slow.log
long_query_time = 1
#log_slow_rate_limit = 1000
log_slow_verbosity = query_plan

#log-queries-not-using-indexes
#log_slow_admin_statements
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
#       other settings you may need to change.
#server-id = 1
#report_host = master1
#auto_increment_increment = 2
#auto_increment_offset = 1
log_bin = /var/log/mysql/mariadb-bin
log_bin_index = /var/log/mysql/mariadb-bin.index
# not fab for performance, but safer
#sync_binlog = 1
expire_logs_days = 10
max_binlog_size         = 100M
# slaves
#relay_log = /var/log/mysql/relay-bin
#relay_log_index = /var/log/mysql/relay-bin.index
#relay_log_info_file = /var/log/mysql/relay-bin.info
#log_slave_updates
#read_only
#
# If applications support it, this stricter sql_mode prevents some
# mistakes like inserting invalid dates etc.
#sql_mode = NO_ENGINE_SUBSTITUTION,TRADITIONAL
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
default_storage_engine = InnoDB
# you can't just change log file size, requires special procedure
innodb_log_file_size = 640M
innodb_buffer_pool_size = 2560M
innodb_log_buffer_size = 8M
innodb_file_per_table = 1
innodb_open_files = 400
innodb_io_capacity = 400
innodb_flush_method = O_DIRECT
#
# * Security Features
#
# Read the manual, too, if you want chroot!
# chroot = /var/lib/mysql/
#
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
#
# ssl-ca=/etc/mysql/cacert.pem
# ssl-cert=/etc/mysql/server-cert.pem
# ssl-key=/etc/mysql/server-key.pem

#
# * Galera-related settings
#
[galera]
# Mandatory settings
#wsrep_on=ON
#wsrep_provider=
#wsrep_cluster_address=
#binlog_format=row
#default_storage_engine=InnoDB
#innodb_autoinc_lock_mode=2
#
# Allow server to accept connections on all interfaces.
#
#bind-address=0.0.0.0
#
# Optional setting
#wsrep_slave_threads=1
innodb_flush_log_at_trx_commit=0

[mysqldump]
quick
quote-names
max_allowed_packet = 16M

[mysql]
#no-auto-rehash # faster start of mysql but no tab completion

[isamchk]
key_buffer = 16M

#
# * IMPORTANT: Additional settings that can override those from this file!
#   The files must end with '.cnf', otherwise they'll be ignored.
#
!includedir /etc/mysql/conf.d/