Wishlist 0 ¥0.00

Dynamic IP Restrictions: 保護 IIS 網站的流量守門員

本文將介紹一個可以防止 IIS 網站受到 DDoS(分散式阻斷服務)或是惡意產生大量並行流量的用戶端攻擊的一個擴充套件:Dynamic IP Restrictions,它可以設定強制將大量並行流量的用戶的要求捨棄,並且在發生 DDoS 時將特定的 IP 網段的要求全部捨棄,以保護網站不因為這種大量流量的攻擊而中斷服務。

 

阻斷服務攻擊:網站經營者的夢魘

顧名思義,阻斷服務攻擊(Denied of Service, DoS)是一種讓目標服務(或伺服器)無法正常提供服務的一種攻擊手段,它的目的只有一個,即讓目標服務停擺。DoS 攻擊的案例非常多,台灣的很多知名網站以及主機供應商都吃過 DoS 的苦頭,現階段 DoS 的防治仍然非常困難,因為攻擊的來源可能有很多,DoS 是只有一台電腦或一個群組的電腦發動的攻擊,另一種 DDoS(Distributed Denied of Service)則是由網路上無法估計的許多電腦一起發動的,而這些電腦的使用者通常對自己被當做攻擊者是渾知不知的,實際發動攻擊封包的電腦被稱為殭屍(Zombie),它們通常都被駭客(cracker)植入了具有遠端遙控(remote control)性質的木馬程式,當駭客下指令發動攻擊時,這些殭屍電腦即會針對特定的目標發動巨大流量的封包,當目標伺服器沒有做防護(防火牆流量偵測、入侵防禦系統等)時,通常都是照單全收,當封包要求超出伺服器負荷時,伺服器會呈現 CPU 100% 或是記憶體被佔滿的現象,導致服務速度變慢甚至於整個服務完全中斷。

當 DDoS 發生時,受影響的可能不只是目標伺服器,若受攻擊的目標是主機供應商的其中一個客戶的網站時,其他掛在相同網段中的主機服務也會因為網路流量過大而受到影響,雖然伺服器沒有被攻擊,但是因網路頻寬被大量吃光而速度變慢,回應的封包也可能會因為網路壅塞而被路由器捨棄,用戶端收不到回應的封包,以為服務被遠端中斷。

DDoS 攻擊的手法有很多,其中知名的兩種是死亡之 ping(Death of ping)以及 SYN 洪流(SYN Flood),這兩種攻擊手段都是利用TCP的三方交握機制(3-way handshake)的流量發動的。

DDoS 目前因為駭客不是實際的發動攻擊者,所以在追查上困難很多,因此各大廠商在防治 DDoS 的攻擊上大多都是採取消極的防禦措施,例如異常流量的偵測以及可能的攻擊因素發生時將連線中斷的方式,來防止 DDoS 攻擊成功。本文所要介紹的,就是內置於 IIS 7.0 中,防止大量異常流量進入 IIS 處理的套件:Dynamic IP Restrictions。

Dynamic IP Restrictions 介紹

Dynamic IP Restrictions 是一個基於 IIS 核心層次上的一個模組,提供 IIS 核心針對網路上的異常通訊與要求進行封鎖處理,它會和 IIS 本身的『IP 與網域限制』的功能整合,以支援管理人員所需要的網站安全原則管理。讀者也可以將它視為 『IP 與網域限制』的加強版本,內建的『IP 與網域限制』是靜態的,不會針對用戶端的活動做動態的監控,只能被動的在 IP 與網域封鎖清單中加入要封裝的IP與網域,但 Dynamic IP Restrictions 模組可以實施動態的用戶端流量監測,只要用戶端發出的要求超過 Dynamic IP Restrictions 設定的限制時,它就會將要求擋下來,並且回傳指定的 HTTP 錯誤碼,讓用戶端在一段時間內無法再向 IIS 提出要求。

Dynamic IP Restrictions 具有下列功能:

  • 以並行要求次數為主的 IP 流量管理原則(Blocking of IP addresses based on number of concurrent requests),若用戶端 IP 位址發出了太多的並行要求(concurrent requests),IIS 會將它封鎖。
  • 以週期時間為主的 IP 流量管理原則(Blocking of IP address based on number of requests over a period of time),若在一定的週期時間內有大量的用戶端連線要求時,IIS 會將超過的用戶端要求封鎖,並且在一定時間內解除鎖定,這樣可以保證至少有一定數量的用戶端可以存取服務。
  • 允許管理人員自訂回應的方式,目前支援 HTTP 403, 404 以及捨棄連線三種。
  • 在發生封鎖的狀況時,會將當時被封鎖的 IP 顯示在 IIS 上,並且會產生 W3C 的記錄檔。
  • 支援 IPv6。

目前 Dynamic IP Restrictions 模組是處於 Beta 測試狀態,微軟希望它可以在符合可阻絕大多數惡意的大流量攻擊時,才會將它正式釋出,未來當然也有可能包裝在 Service Pack 或是下一個版本的 IIS 中釋出。

使用 Dynamic IP Restrictions

Dynamic IP Restrictions 可以透過 Web Platform Installer 2.0 來安裝,安裝完成後在 IIS 中會產生一個「Dynamic IP and Domain Restriction」的項目,在該圖示上按兩下即可進入主畫面:

 

在預設的情況下,Dynamic IP Restriction 的功能是不啟用的,必須要勾選要封鎖的類型的核取方塊,並且套用其設定後它才會生效,而設定的欄位說明如下:

欄位 說明
Deny IP address based on the number of concurrent requests
Maximum number of concurrent requests 設定用戶端的最大並行要求,若超出時執行Action Type所指定的動作。
Deny IP addresses based on number of requests over a period of time
Maximum number of requests 設定要求允許進入IIS的最大數量。
Time period (in seconds) 設定要求最大數量的監測週期時間。
Deny for time period (in seconds) 設定超出要求最大數量時,封鎖要求的時間週期。
Deny Action
Action type 當發生必須封鎖的動作時,要執行的動作。

首先,我們先來模擬並行要求過多的用戶端,以測試 Dynamic IP Restrictions 的功能。我們在預設的網站上建立一個 Concurrence.aspx,並加入下列的內容:

[HTML] <%@ Page Language="C#" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Dynamic IP Restrictions Test</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Hello World!</h1>
</div>
</form>
</body>
</html>

然後在 Dynamic IP Restrictions 的限制設定中,設定只允許 2 個並行要求:

 

所謂的並行要求(concurrence requests)是指同一個用戶端在伺服器尚未回傳結果前又再次發出的服務要求,如果伺服器程式會執行長時間時,用戶端未被處理完的要求會一直累積,可能會造成資料錯誤或是伺服器記憶體耗盡(要求暫存需要花費記憶體空間)的問題。

接著將瀏覽器打開,並且瀏覽預設網站的 Concurrence.aspx,此時應該是正常的,但若連續按重新整理 3 次,就會看到下列的錯誤訊息:

 

這表示 Dynamic IP Restrictions 偵測到了用戶端發出了超過2次的要求訊息,因此發出 HTTP 403 的回應,以拒絕用戶端的存取要求。

接著我們再來展示另外一個封鎖行為,就是在週期時間(Time period)內如果連線要求超出設定的範圍時,就會將拒絕連入要求一定的時間。為了要展現這個效果,我們先將 Concurrence requests 的部份關閉,並且開啟 Requests over the period time 的設定,將要求數設為 2,週期時間設為 10 秒:

所謂的要求(request)泛指向伺服器要求各種資源的 HTTP 指令,不論是要求 HTML 網頁,或是 CSS、圖檔、JavaScript 或其他連結在網頁上的資源都一樣,所以可能用戶端瀏覽網頁時可能會引發數十個要求,端看網頁的複雜程度以及是否有快取而決定。

 

接著一樣使用前面說明的測試方式,只要在 10 秒鐘內重新整理超過 2 次時就會出現下列錯誤訊息:

 

而當 IIS 進行封鎖行為的時候,管理人員可以利用在 Dynamic IP Restrictions 功能區右方的『Show Blocked Addresses…』來瀏覽目前被封鎖的 IP 位址清單:

 

在封鎖的同時,Dynamic IP Restrictions 會將封鎖的 IP 資料寫入到記錄檔中(預設路徑是 %SYSTEMDRIVE%\inetpub\logs\IPRestrictions),以利管理人員的後續追踪:

 

結語

Dynamic IP Restrictions 模組提供了動態的用戶端流量監控服務,以防止來自網路不明的大流量讓網站停擺的問題,管理人員可以善用這個模組來保護 IIS 網站或伺服器,以解除來自網路上可能的 DDoS 的威脅。

【转载】IIS6、IIS7、IIS7.5设置拒绝一组计算机(IP段)访问网站的方法

IIS6设置方法:

1、打开IIS管理器,右键点击网站,选择“属性”

2、把标签切换到“目录安全性”,点击“IP地址和域名限制”的编辑按钮,如下图:

IP地址和域名限制

IP地址和域名限制

3、选择“授权访问”,然后点击“添加”按钮,如图:

授权访问

授权访问

4、拒绝访问设置,选择“一组计算机”,下面重点说明如何填写“网络标识”和“子网掩码”。

IP地址按照IPV4的标准来分,分为A类地址、B类地址、C类地址,一般我们是屏蔽C类或者B类地址。

A类地址:如 202.*.*.*         子网掩码 255.0.0.0
B类地址:如 202.96.*.*       子网掩码 255.255.0.0
C类地址:如 202.96.128.*     子网掩码 255.255.255.0

如上,若屏蔽C类地址,只会屏蔽255个IP;若屏蔽B类地址,将会屏蔽255X255=65025个IP地址。如果需要屏蔽的是个固定IP,建议只屏蔽该IP,不确定是否为固定IP,建议屏蔽C类地址,因此屏蔽掉B类地址影响会比较大。A类型更是如此!

此处我们以屏蔽一个C类地址为例,我们要屏蔽202.96.128.*这段地址,类型选择“一组计算机”,网络标识将*换成0,填写202.96.128.0,子网掩码 255.255.255.0。

拒绝访问

拒绝访问

下面是屏蔽B类和A类地址的IP填写方法

1)如果你要屏蔽的IP段是:202.96.0.0 至 202.96.255.255,那么网络标识就填202.96.0.0,子网掩码就填255.255.0.0。

2)如果你要屏蔽的IP段是:202.0.0.0 至 202.255.255.255,那么网络标识就填202.0.0.0,子网掩码就填255.0.0.0。

这样,就可以拒绝一组计算机(IP段)访问了。无需重启IIS。

IIS7、IIS7.5设置方法

1、打开IIS管理器(如果你已经打开,则要关闭重新打开),会看到“IP 地址和域限制”的图标,如下图所示:

IP 地址和域限制

IP 地址和域限制

2、双击“IP 地址和域限制”图标进入设置界面,点击右侧的“添加拒绝条目...”,如下图:

 

添加拒绝条目

添加拒绝条目

3、然后输入IP地址范围和掩码,如下图:

输入IP地址范围和掩码

输入IP地址范围和掩码

解释:

IP地址范围: 122.226.16.0
掩码或前缀: 255.255.255.0
拒绝的IP段是: 122.226.16.*

如果要拒绝的IP段是: 122.226.*.*,则要这样填写:

IP地址范围: 122.226.0.0
掩码或前缀: 255.255.0.0

此外,

如果要拒绝的IP段是: 122.226.16.1 - 122.226.16.127,则要这样填写:

IP地址范围: 122.226.16.0
掩码或前缀: 255.255.255.128

如果要拒绝的IP段是: 122.226.16.128 - 122.226.16.254,则要这样填写:

IP地址范围: 122.226.16.128
掩码或前缀: 255.255.255.128

你要了解的相关知识

1、为什么ip地址的最后一位不可以是255或者0呢?

并非IP地址的最后一位永远不可以是255或0,这是有条件的。例如:当一个网段的掩码为255.255.255.0的时候,通常IP地址的最后一位不可以是255或0。因为这种掩码的网段,最后一位是0的IP是网段的网络地址,而最后一位是255的IP是网段的广播地址,不能分配给主机。假设一个网段为172.16.0.0,它的掩码是255.255.254.0,那么它的主机可用地址范围是172.16.0.1到172.16.1.254,即172.16.1.0和172.16.0.255这两个地址是可用的。

2、子网掩码255.255.255.0和255.255.0.0有什么区别?

子网掩码决定可用的主机数量多少,以及ip是否在同一个网段,举两个例子。

以网段192.168.0.0为例:

  • 子网掩码为255.255.255.0时,可用IP为192.168.0.1-192.168.0.254(255为广播地址)。
  • 子网掩码为255.255.0.0时,可用IP为192.168.0.0-192.168.255.254。

以192.168.10.1和192.168.100.1为例:

  • 子网掩码为255.255.255.0时,他们不在一个网段;
  • 子网掩码为255.255.0.0时,他们在一个网段。

综上所述,多个IP地址是否在同一个网段以及该网段有多少两个可用的IP地址,由子网掩码决定。

名词解释:广播地址

广播地址(Broadcast Address)是专门用于同时向网络中所有工作站进行发送的一个地址。在使用TCP/IP 协议的网络中,主机标识段host ID 为全1 的IP 地址为广播地址,广播的分组传送给host ID段所涉及的所有计算机。例如,对于10.1.1.0 (255.255.255.0 )网段,其广播地址为10.1.1.255 (255 即为2 进制的11111111 ),当发出一个目的地址为10.1.1.255 的分组(封包)时,它将被分发给该网段上的所有计算机。

◆广播地址主要有两类

广播地址应用于网络内的所有主机

1) 受限广播

  • 它不被路由发送,但会被送到相同物理网络段上的所有主机
  • IP地址的网络字段和主机字段全为1就是地址255.255.255.255

2) 直接广播

    • 网络广播会被路由,并会发送到专门网络上的每台主机
    • IP地址的网络字段定义这个网络,主机字段通常全为1,如 192.168.10.255

MySQL之thread cache

最近突然对MySQL的连接非常感兴趣,从status根据thread关键字可以查出如下是个状态

复制代码
show global status like 'thread%';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_cached    | 57    |
| Threads_connected | 1268  |
| Threads_created   | 31715 |
| Threads_running   | 1     |
+-------------------+-------+
复制代码

Thread_cached:The number of threads in the thread cache

Thread_connected:The number of currently open connections.

Thread_created:The number of threads created to handle connections.

Thread_running:The number of threads that are not sleeping.

 

  以上是这4个状态的含义,thread_connected等于show processlist,thread_running代表真正在运行的(等于1一般就是这个show status命令本身),thread_cached代表mysql管理的线程池中还有多少可以被复用的资源,thread_created代表新创建的thread(根据官方文档,如果thread_created增大迅速,需要适当调高thread_cache_size)。

  我们先来实际看下这4个状态之间的直观关系。

  从上面这个图,我们可以总结出来一个公式:running和其他三个状态关系不大,但肯定不会超过thread_connected

  (new_con-old_con)=create+(old_cache-new_cache)

  从上面公式可以看出,如果create等于0,那么thread_connected减少的和thread_cached增加的相等,thread_connected增加的和thread_cached减少的相等。(其实这也就是thread_cached存在的意义,资源可以复用)

 

  我们来看眼影响thread_cached的参数thread_cache_size

1
How many threads the server should cache for reuse. When a client disconnects, the client's threads are put in the cache if there are fewer than thread_cache_size threads there. Requests for threads are satisfied by reusing threads taken from the cache if possible, and only when the cache is empty is a new thread created. This variable can be increased to improve performance if you have a lot of new connections. Normally, this does not provide a notable performance improvement if you have a good thread implementation. However, if your server sees hundreds of connections per second you should normally set thread_cache_size high enough so that most new connections use cached threads. By examining the difference between the Connections and Threads_created status variables, you can see how efficient the thread cache is. For details, see Section 5.1.6, “Server Status Variables”.

  众所周知,mysql建立连接非常消耗资源,所以就有了thread_cache,当已有连接不再使用之后,mysql server不是直接断开连接,而是将已有连接转入到thread_cache中,以便下次在有create thread的需求时,可以在cache中复用,提高性能,降低资源消耗。  

  当然,如果已经有了中间件或者其他的连接池管理,那么这个参数就没有那么重要了,但是如果没有其他的连接池管理,那么优化这个参数还是可以得到不错的回报的。

MySQL内存体系架构及参数总结

内存结构:
Mysql 内存分配规则是:用多少给多少,最高到配置的值,不是立即分配
图只做大概参考
全局缓存包括:
global buffer(全局内存分配总和) =
   innodb_buffer_pool_size                      -- InnoDB高速缓冲,行数据、索引缓冲,以及事务锁、自适应哈希等
+innodb_additional_mem_pool_size    -- InnoDB数据字典额外内存,缓存所有表数据字典
+innodb_log_buffer_size                      -- InnoDB REDO日志缓冲,提高REDO日志写入效率
+key_buffer_size                                   -- MyISAM表索引高速缓冲,提高MyISAM表索引读写效率
+query_cache_size                                -- 查询高速缓存,缓存查询结果,提高反复查询返回效率
+thread_cache_size                               --Thread_Cache 中存放的最大连接线程数
+table_cahce                                         -- 表空间文件描述符缓存,提高数据表打开效率
+table_definition_cache                        -- 表定义文件描述符缓存,提高数据表打开效率
会话缓存包括:
 total_thread_buffers= max_connections  * (
  read_buffer_size             -- 顺序读缓冲,提高顺序读效率
+read_rnd_buffer_size   -- 随机读缓冲,提高随机读效率
+sort_buffer_size           -- 排序缓冲,提高排序效率
+join_buffer_size           -- 表连接缓冲,提高表连接效率
+binlog_cache_size       -- 二进制日志缓冲,提高二进制日志写入效率
+tmp_table_size            -- 内存临时表,提高临时表存储效率
+thread_stack                -- 线程堆栈,暂时寄存SQL语句/存储过程
+thread_cache_size       -- 线程缓存,降低多次反复打开线程开销,模拟连接池
)
 
内存相关配置参数介绍:

全局内存部分:

innodb_buffer_pool
• InnoDB高速缓冲(简称IBP),对Innodb很重要。
• 应该把它设置得大一些,单实例,建议设置为可用RAM的50~80%。
• InnoDB不依赖OS,而自己缓存了所有数据,包括索引数据,行数据,等等。这点跟MyISAM有差别。
• 查询或更新需要对IBP加锁,影响并发
• IBP有一块buffer用于插入缓冲。在插入的时候,先写入内存,之后再合并后顺序写入磁盘。在命并到磁盘上的时候,会引发较大的IO操作,对实时操作造成影响(看上去是抖动,tps变低)
• show global status like ‘innodb_buffer_pool_%’ 查看IBP状态,单位是page(16kb)
• Innodb_buffer_pool_wait_free 如果较大,需要加大IBP设置
• InnoDB会定时(约每10秒)将脏页刷新到磁盘,默认每次刷新10页;
• 要是脏页超过了指定数量(innodb_max_dirty_pages_pct),InnoDB则会每秒刷100页脏页 
 innodb_buffer_pool_instances可以设置pool的数量
 show engine innodb status\G    可以查看innodb引擎状态
mysql> show global status like 'innodb_buffer_%';
+---------------------------------------+---------+
| Variable_name                         | Value   |
+---------------------------------------+---------+
| Innodb_buffer_pool_pages_data         | 154     |
| Innodb_buffer_pool_bytes_data         | 2523136 |
| Innodb_buffer_pool_pages_dirty        | 0       |                    脏数据
| Innodb_buffer_pool_bytes_dirty        | 0       |
| Innodb_buffer_pool_pages_flushed      | 1       |
| Innodb_buffer_pool_pages_free         | 8038    |                空闲,要乘以16k
| Innodb_buffer_pool_pages_misc         | 0       |
| Innodb_buffer_pool_pages_total        | 8192    |
| Innodb_buffer_pool_read_ahead_rnd     | 0       |
| Innodb_buffer_pool_read_ahead         | 0       |    预读的页数
| Innodb_buffer_pool_read_ahead_evicted | 0       |    预读的页数,但是没有被读取就从缓冲池中被替换的页的数量,一般用来判断预读的效率。
| Innodb_buffer_pool_read_requests      | 563     |    从缓冲池中读取的次数。
| Innodb_buffer_pool_reads              | 155     |    表示从物理磁盘读取的页数
| Innodb_buffer_pool_wait_free          | 0       |
| Innodb_buffer_pool_write_requests     | 1       |
+---------------------------------------+---------+
15 rows in set (0.00 sec)
Innodb_data_read:总共读入的字节数。
Innodb_data_reads:发起读请求的次数,每次读取可能需要读取多个页。
 buffer pool利用率:
ib_bp_hit=(1 - Innodb_buffer_pool_reads/Innodb_buffer_pool_read_requests)*100%
 buffer poo命中率 
= (Innodb_buffer_pool_read_requests)/(Innodb_buffer_pool_read_requests + Innodb_buffer_pool_read_ahead + Innodb_buffer_pool_reads)
 平均每次读取的字节数 = Innodb_data_read/Innodb_data_reads
 
 innodb_additional_mem_pool_size
数据字典以及内部数据结构缓存,表数量越多,相应的内存需要越大。
默认8M,通常设置为8~32M足够,一般建议设置为16M,如果确实不够用,那么会从系统中请求增加分配内存,并且错误日志中会提醒,目前至少还未发生过。
 
 innodb_log_buffer_size
show global status 查看 Innodb_log_waits 是否大于0,是的话,就需要提高 innodb_log_buffer_size,否则维持原样。
show global stauts 查看30~60秒钟 Innodb_os_log_written 的间隔差异值,即可计算出 innodb_log_buffer_size 设置多大合适。
默认8M,一般设置为16 ~ 64M足够了。
  1. Innodb_log_waits,可用log buffer不足,等待释放次数,数量较大时需要加大log buffer
  2. Innodb_log_write_requests, log写请求次数
  3. Innodb_log_writes, log物理写次数
  4. Innodb_os_log_fsyncs, log写入时,调用rsync()次数 
  5. Innodb_os_log_pending_fsyncslog文件等待fsync()操作次数 
  6. Innodb_os_log_pending_writes, log写等待次数
  7. Innodb_os_log_written, log写入总字节数
  8. innodb log buffer作用:InnoDB log随机IO
整合率Innodb_log_write_requests/ Innodb_log_writes
 
key_buffer_size :myisam引擎中表的索引   的缓存大小,默认值  =   16M,单个key_buffer_size最大只有4G(32-bit系统下最大4G,64-bit下可以超过)
 若主要使用myisam,设置最高不超过物理内存的20%~50%,即便全是innodb表,没用MyISAM,也有必要设置该值用于缓存临时表之索引,推荐32MB,(如果内存tmp_table_sizeCreated_tmp_tables不够的话,内部的临时磁盘表是MyISAM表Created_tmp_disk_tables(新版本可能是innodb表)
可以使用检查状态(show global status)值'created_tmp_disk_tables'得知详情。
| Created_tmp_disk_tables                  | 0           |
| Created_tmp_files                        | 5           |
| Created_tmp_tables                       | 4           |
 Key_read_requests        myisam引擎上总读取请求次数
Key_reads                        myisam从物理硬盘上读索引的次数
Key_write_requests        myisam引擎上总写入请求次数
Key_writes                        myisam从物理硬盘上写索引的次数
 key buffer命中率
读命中率key_buffer_read_hits = (1 - key_reads/key_read_requests) * 100%

写命中率key_buffer_write_hits = (1 - key_writes/key_write_requests) * 100%
 
 query_cache_size
• 建议直接关闭不使用
• MySQL高速查询缓存池(简称QC)。
• 将SELECT语句和查询结果存放在缓冲区中,若有同样的SELECT语句(区分大小写),将直接从缓冲区中读取结果。
• show global status like ‘Qcache_%‘ 查看QC,可以知道QC设置是否合理
     如果 Qcache_lowmem_prunes 的值非常大,则表明经常出现缓冲不够的情况
     如果 Qcache_hits 的值非常大,则表明查询缓冲使用非常频繁,此时需要增加缓冲大小
     如果 Qcache_hits 的值不大,则表明你的查询重复率很低,这种情况下使用查询缓冲反而会影响效率,那么可以考虑不用查询缓冲
• 在SELECT语句中加入SQL_NO_CACHE可以明确表示不使用查询缓冲
• query_cache_limit = 2M,不缓存超过2M的查询结果
query_cache_min_res_unit = 512K,设置每个QC单元大小,提高QC利用率(Qcache_queries_in_cache不大,但Qcache_free_memory较大,就需要减小query_cache_min_res_unit )
 query cache命中率:
Query_cache_hits = 1 – (qcache_hits / (qcache_hits + com_select)) * 100%
 
thread_cache_size
Thread_Cache 中存放的最大连接线程数。

在短连接的应用中Thread_Cache的功效非常明显,因为在应用中数据库的连接和创建是非常频繁的,如果不使用 Thread_Cache那么消耗的资源是非常可观的!在长连接中虽然带来的改善没有短连接的那么明显,但是好处是显而易见的。
但并不是越大越好,有可能大了反而浪费资源。
thread cache命中率:
Thread_Cache_Hit=(Connections-Thread_created)/Connections*100%
 
TABLE_OPEN_CACHE(5.1.3及以前版本名为TABLE_CACHE)
由于MySQL是多线程的机制,为了提高性能,每个线程都是独自打开自己需要的表的文件描述符,而不是通过共享已经打开的.针对不同存储引擎处理的方法当然也不一样。
在MyISAM表引擎中,数据文件的描述符(descriptor)是不共享的,但是索引文件的描述符却是所有线程共享的。
Innodb中和使用表空间类型有关,假如是共享表空间那么实际就一个数据文件,当然占用的数据文件描述符就会比独立表空间少。
 几个关于table_cache的状态值:
Open_tables:当前打开的表的数量
Opened_tables:历史上全部已经打开的表总数,如果 Opened_tables 较大,table_open_cache 值可能需要加大。
 
如果Open_tables的值已经接近table_cache的值,且Opened_tables还在不断变大,则说明mysql正在将缓存的表释放以容纳新的表,此时可能需要加大table_cache的值。对于大多数情况。通常比较适合的建议值:
 Open_tables / table_open_cache <= 0.95
 
 table_definition_cache
从MySQL 5.1开始,数据表文件描述符被分开为数据文件及数据表定义文件两部分。表定义文件缓存可以放在专属的 table_definition_cache 中。
表定义文件缓存相比表文件描述符缓存所消耗的内存更小,其默认值是 400。
 状态值:
Open_table_definitions:表定义文件 .frm 被缓存的数量
Opened_table_definitions:历史上总共被缓存过的 .frm 文件数量。
 
其它几个小内存,内存计算公式:
• adaptive index hash, size= innodb_buffer_pool / 64,自适应哈希索引,用来管理buffer pool的哈希索引。随着buffer的频繁更新,会随之上升
• system dictionary hash, size = innodb_buffer_pool_size / 256,基本固定,数据字典信息
• memory for sync_array, which is used for syncronization primitives, size = OS_THREADS * 152
• memory for os_events, which are also used for syncronization primitives, OS_THREADS * 216
• memory for locking system, size=5 * 4 * NBLOCKS(NBLOCKS,innodb buffer pool的block数量),随着并发/行锁增加,会随之上升
其中 
OS_THREADS = 
如果 innodb_buffer_pool_size >= 1000Mb,则为:50000
否则如果 innodb_buffer_pool_size >= 8Mb,则为:10000
否则为: 1000 (*nixes平台下通用)
• NBLOCKS = innodb_buffer_pool_size/8192
 


会话级内存部分:

tmp_table_size(相当于pga)
是MySQL的临时表缓冲大小。所有联合在一个DML指令内完成,并且大多数联合甚至可以不用临时表即可以完成。大多数临时表是基于内存的(HEAP)表。具有大的记录长度的临时表 (所有列的长度的和)或包含BLOB列的表存储在硬盘上。如果某个内部heap(堆积)表大小超过tmp_table_size,MySQL可以根据需要自动将内存中的heap表改为基于硬盘的MyISAM表。还可以通过设置tmp_table_size选项来增加临时表的大小。也就是说,如果调高该值,MySQL同时将增加heap表的大小,可达到提高联接查询速度的效果。(Using temporary)
不负责限制 MEMORY/HEAP表最大容量,如果执行SQL产生临时表超过 tmp_table_size/max_heap_table_size,则会产生基于磁盘的MyISAM表。
一般64~128m就可以.
排序时sort_buffer_size放不下时,要用到内存tmp_table_size,还是磁盘临时表?
 tmp table命中率
每次使用临时表都会增大 Created_tmp_tables;基于磁盘的表也会增大 Created_tmp_disk_tables

对于这个比率,并没有什么严格的规则,因为这依赖于所涉及的查询。长时间观察 Created_tmp_disk_tables 会显示所创建的磁盘表的比率,您可以确定设置的效率。 
tmp_table_size 和 max_heap_table_size 都可以控制临时表的最大大小,因此请确保在 my.cnf 中对这两个值都进行了设置。
 
 max_heap_table_size
这个变量定义了用户可以创建的内存表(memory table)的大小.这个值用来计算内存表的最大行数值。
这个变量支持动态改变,即set @max_heap_table_size=#,但是对于已经存在的内存表就没有什么用了,除非这个表被重新创建(CREATE TABLE IF NOT EXISTS)或者修改(alter table)或者truncate table。
服务重启也会设置已经存在的内存表为全局max_heap_table_size的值。
这个变量和tmp_table_size一起限制了内部内存表的大小。
它和tmp_table_size的区别是,负责设置MEMORY/HEAP表最大容量,不管其他执行SQL产生的临时表,如果内存不够用,则不允许写入新的数据,MEMORY/HEAP表也不会转成磁盘表,只会告警超限后拒绝写入。
一般它和tmp_table_size设置一样就可以了。
 
 binlog_cache_size
(dml在执行commit前,将日志写入缓存。如果语句大于该值,线程则打开临时文件来保存事务。线程结束后临时文件被删除。commit时,mysqld将事务写入binlog文件。)
在事务过程中容纳二进制日志SQL 语句的缓存大小。二进制日志缓存是服务器支持事务存储引擎并且服务器启用了二进制日志(—log-bin 选项)的前提下为每个客户端分配的内存。
如果系统中经常会出现多语句事务的话,可以尝试增加该值的大小,以获得更好的性能。当然,我们可以通过MySQL 的以下两个状态变量来判断当前的binlog_cache_size 的状况:Binlog_cache_use 和Binlog_cache_disk_use。“max_binlog_cache_size”:和"binlog_cache_size"相对应,但是所代表的是binlog 能够使用的最大cache 内存大小。当我们执行多语句事务的时候,max_binlog_cache_size 如果不够大的话,系统可能会报出“ Multi-statement transaction required more than 'max_binlog_cache_size' bytes ofstorage”的错误。
binlog cache命中率
binlog hit ratio = (Binlog_cache_use)/( Binlog_cache_use + Binlog_cache_disk_use) ,一般要大于98%
Binlog_cache_use状态变量显示了使用该缓冲区(也可能是临时文件)保存语句的事务的数量。
Binlog_cache_disk_use状态变量显示了这些事务中实际上有多少必须使用临时文件。
DML 在 commit后,发现这2个值会有变化
 
bulk_insert_buffer_size(每线程分配,MyISAM特有,表的插入缓存)
专用于MyISAM引擎,用一个特别的类似树形结构体缓存,用以提高 INSERT ... SELECT, INSERT ... VALUES (...), (...) 以及 LOAD DATA写数据到非空表的情景。
每个线程分配,默认8M,可以设置为 0 来关闭这个buffer。
 
 
myisam_sort_buffer_size(用到才分配,MyISAM特有)
MyISAM表在做修复时,用于提高索引文件修复效率的buffer,或者用以创建索引时提高效率。
默认值8M,一般128M ~ 256M 足够了。
 
下面几个buffer size,一般设置为128K ~ 2M足够。如果单进程需求量大,set read_buffer_size = 128 * 1024 * 1024;
read_buffer_size  顺序读buffer
是MySQL读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySQL会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。如果对表的顺序扫描请求非常频繁,并且你认为频繁扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能。
Handler_read_next / Com_select 得出了表扫描比率
 
read_rnd_buffer_size   随机读buffer
是MySQL的随机读缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,MySQL会首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,如果需要排序大量数据,可适当调高该值。但MySQL会为每个客户连接分配该缓冲区,所以应尽量适当设置该值,以避免内存开销过大。
[上面有可能不准,看下面这段]
当执行完根据索引排序操作后,按照一定排序顺序读取数据时,这些数据会放在 read_rnd_buffer 中以避免的磁盘搜索。不是指随机读取的缓冲。
 
 
sort_buffer_size
是MySQL执行排序使用的缓冲大小。如果想要增加ORDER BY的速度,首先看是否可以让MySQL使用索引而不是额外的排序阶段。如果不能,可以尝试增加sort_buffer_size变量的大小(执行计划中,如果显示using filesort,就说明会用到sort buffer)。
Sort_merge_passes 包括两步。MySQL 首先会尝试在内存中做排序,使用的内存大小由系统变量 Sort_buffer_size 决定,如果它的大小不够把所有的记录都读到内存中,MySQL 就会把每次在内存中排序的结果存到临时文件中,等 MySQL 找到所有记录之后,再把临时文件中的记录做一次排序。这个临时文件也会增加Created_tmp_disk_tables吗?
再次排序就会增加 Sort_merge_passes.实际上,MySQL 会用另一个临时文件来存再次排序的结果,所以通常会看到 Sort_merge_passes 增加的数值是建临时文件数的两倍。
因为用到了临时文件,所以速度可能会比较慢,增加 Sort_buffer_size 会减少 Sort_merge_passes 和 创建临时文件的次数。但不能盲目增加 Sort_buffer_size ,因为并不一定能提高速度。

join_buffer_size
应用程序经常会出现一些两表(或多表)JOIN的操作需求,MySQL在完成某些 Join 需求的时候(all row join/ all index join/ range index scan join),为了减少参与JOIN的“被驱动表”的读取次数以提高性能,需要使用到 JOIN Buffer 来协助完成 JOIN操作。当 JOIN Buffer 太小,MySQL 不会将该 Buffer 存入磁盘文件,而是先将Join Buffer中的结果集与需要 Join 的表进行 Join 操作,然后清空 Join Buffer 中的数据,继续将剩余的结果集写入此 Buffer 中,如此往复。这势必会造成被驱动表需要被多次读取,成倍增加 IO 访问,降低效率。(执行计划中,如果显示Using join buffer,就说明会用到JOIN Buffer).
 
 多种JOIN情况:plain index scans(普通索引扫描), range index scans(范围索引扫描), do not use indexes and thus perform full table scans(没有索引的全表扫描)
最好是添加适当的索引,而不是纯粹的加大 join_buffer_size。
任何两个表间的全表 join 就会分配一次 join buffer,也就是说,如果有3个表join,就会分配2次join buffer。
 
Select_full_join,表关联时,由于没有索引产生的扫描次数,大于0时,需要注意检查是否有合适的索引
Select_full_range_join,表关联时,驱动表使用范围扫描次数
 
 thread_stack 
主要用来存放每一个线程自身的标识信息,如线程id,线程运行时基本信息等等,我们可以通过 thread_stack 参数来设置为每一个线程栈分配多大的内存。一般默认的256KB就足够了。
 
net_buffer_length(每线程分配)
每个客户端连接时,用以维持连接缓冲以及读取结果缓冲。初试分配预设值,在有需要时,则会自动扩大到 max_allowed_packet 大小,然后再回收到预设的 net_buffer_length 大小。
最小1K,最大1M,默认值是16K。

About Us

Since 1996, our company has been focusing on domain name registration, web hosting, server hosting, website construction, e-commerce and other Internet services, and constantly practicing the concept of "providing enterprise-level solutions and providing personalized service support". As a Dell Authorized Solution Provider, we also provide hardware product solutions associated with the company's services.
 

Contact Us

Address: No. 2, Jingwu Road, Zhengzhou City, Henan Province

Phone: 0086-371-63520088 

QQ:76257322

Website: 800188.com

E-mail: This email address is being protected from spambots. You need JavaScript enabled to view it.