<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Darts 是用于構建雙數組 Double-Array [Aoe 1989] 的簡單的 C++ Template Library . 雙數組 (Double-Array) 是用于實現 Trie 的一種數據結構, 比其它的類 Trie 實現方式(Hash-Tree, Digital Trie, Patricia Tree, Suffix Array) 速度更快。 原始的 Double-Array 使能夠支持動態添加刪除 key, 但是 Darts 只支持把排好序的詞典文件轉換為靜態的 Double-Array.

    Darts 既可以像 Hash 一樣作為簡單的詞典使用,也能非常高效的執行分詞詞典中必須的 Common Prefix Search 操作。

    自2003年7月起, 兩個開源的日語分詞系統 MeCabChaSen 都使用了 Darts .

    下載

    • Darts 是自由軟件.遵循 LGPL(Lesser GNU General Public License) 和 BSD 協議, 可以修改后重新發布.

    Source

    • darts-0.32.tar.gz: HTTP

    安裝

    % ./configure 
    % make
    % make check
    % make install
    然后在程序中 include /usr/local/include/darts.h

    使用方法

    Darts 只提供了 darts.h 這個 C++ 模板文件。每次使用的時候 include 該文件即可.
    使用這樣的發布方式是希望通過內聯函數實現高效率。

    類接口

    namespace Darts {

    template <class NodeType, class NodeUType class ArrayType,
    class ArrayUType, class LengthFunc = Length<NodeType> >

    class DobuleArrayImpl
    {
    public:
    typedef ArrayType result_type;
    typedef NodeType key_type;

    DoubleArrayImpl();
    ~DoubleArrayImpl();

    int set_array(void *ptr, size_t = 0);
    void *array();
    void clear();
    size_t size ();
    size_t unit_size ();
    size_t nonzero_size ();
    size_t total_size ();

    int build (size_t key_size,
    key_type **key,
    size_t *len = 0,
    result_type *val = 0,
    int (*pg)(size_t, size_t) = 0);

    int open (const char *file,
    const char *mode = "rb",
    size_t offset = 0,
    size_t _size = 0);

    int save (const char *file,
    const char *mode = "wb",
    size_t offset = 0);

    result_type exactMatchSearch (const key_type *key,
    size_t len = 0,
    size_t node_pos = 0)

    size_t commonPrefixSearch (const key_type *key,
    result_type *result,
    size_t result_size,
    size_t len = 0,
    size_t node_pos = 0)

    result_type traverse (const key_type *key,
    size_t &node_pos,
    size_t &key_pos,
    size_t len = 0)
    };

    typedef Darts::DoubleArrayImpl<char, unsigned char,
    int, unsigned int> DoubleArray;
    };

    模板參數說明

     

    NodeTypeTrie 節點類型, 對普通的 C 字符串檢索, 設置為 char 型即可.
    NodeUTypeTrie 節點轉為無符號整數的類型, 對普通的 C 字符串檢索, 設置為 unsigned char 型即可.
    ArrayTypeDouble-Array 的 Base 元素使用的類型, 通常設置為有符號 32bit 整數
    ArrayUTypeDouble-Array 的 Check 元素使用的類型, 通常設置為無符號 32bit 整數
    LengthFunc使用 NodeType 數組的時候,使用該函數對象獲取數組的大小, 在該函數對象中對 operator() 進行重載. 
    NodeType 是 char 的時候, 缺省使用 strlen 函數, 否則以 0 作為數組結束標志計算數組的大小 .

    typedef 說明

    模板參數類型的別名. 在外部需要使用這些類型的時候使用 .

    key_type待檢索的 key 的單個元素的類型. 等同于 NodeType.
    result_type單個結果的類型. 等同于 ArrayType .

    方法說明

    int Darts::DoubleArrayImpl::build(size_t size, const key_type **str, const size_t *len = 0, const result_type *val = 0, int (*progress_func)(size_t, size_t) = 0)
    構建 Double Array .

    size 詞典大小 (記錄的詞條數目),
    str 指向各詞條的指針 (共 size個指針)
    len 用于記錄各個詞條的長度的數組(數組大小為 size)
    val 用于保存各詞條對應的 value 的數組 (數組大小為 size)
    progress_func 構建進度函數.

    str 的各個元素必須按照字典序排好序.
    另外 val 數組中的元素不能有負值.
    len, val, progress_func 可以省略,
    省略的時候, len 使用 LengthFunc 計算,
    val 的各元素的值為從 0 開始的計數值。 


    構建成功,返回 0; 失敗的時候返回值為負.
    進度函數 progress_func 有兩個參數.
    第一個 size_t 型參數表示目前已經構建的詞條數 
    第二個 size_t 型參數表示所有的詞條數 

    result_type Darts::DoubleArrayImpl::exactMatchSearch(const key_type *key, size_t len = 0, size_t node_pos = 0)
    進行精確匹配(exact match) 檢索, 判斷給定字符串是否為詞典中的詞條.

    key 待檢索字符串,
    len 字符串長度,
    node_pos 指定從 Double-Array 的哪個節點位置開始檢索.

    len, 和 node_pos 都可以省略, 省略的時候, len 缺省使用 LengthFunc 計算,
    node_pos 缺省為 root 節點.

    檢索成功時, 返回 key 對應的 value 值, 失敗則返回 -1. 

    size_t Darts::DoubleArrayImpl::commonPrefixSearch (const key_type *key, result_type *result, size_t result_size, size_t len = 0, size_t node_pos = 0)
    執行 common prefix search. 檢索給定字符串的哪些的前綴是詞典中的詞條

    key 待檢索字符串,
    result 用于保存多個命中結果的數組,
    result_size 數組 result 大小,
    len 待檢索字符串長度,
    node_pos 指定從 Double-Array 的哪個節點位置開始檢索.

    len, 和 node_pos 都可以省略, 省略的時候, len 缺省使用 LengthFunc 計算,
    node_pos 缺省為 root 節點.

    函 數返回命中的詞條個數. 對于每個命中的詞條, 詞條對應的 value 值存依次放在 result 數組中. 如果命中的詞條個數超過 result_size 的大小, 則 result 數組中只保存 result_size 個結果。函數的返回值為實際的命中詞條個數, 可能超過 result_size 的大小。 

    result_t Darts::DoubleArrayImpl::traverse (const key_type *key, size_t &node_pos, size_t &key_pos, size_t len = 0)
    traverse Trie, 檢索當前字符串并記錄檢索后到達的位置 

    key 待檢索字符串,
    node_pos 指定從 Double-Array 的哪個節點位置開始檢索.
    key_pos 從待檢索字符串的哪個位置開始檢索
    len 待檢索字符串長度,

    該函數和 exactMatchSearch 很相似. traverse 過程是按照檢索串 key 在 TRIE 的節點中進行轉移.
    但是函數執行后, 可以獲取到最后到達的 Trie 節點位置,最后到達的字符串位置 . 這和 exactMatchSearch 是有區別的. 

    node_pos 通常指定為 root 位置 (0) . 函數調用后, node_pos 的值記錄最后到達的 DoubleArray 節點位置。 
    key_pos 通常指定為 0. 函數調用后, key_pos 保存最后到達的字符串 key 中的位置。 

    檢索失敗的時候, 返回 -1 或者 -2 .
    -1 表示再葉子節點失敗, -2 表示在中間節點失敗,.
    檢索成功的時候, 返回 key 對應的 value. 

    int Darts::DoubleArrayImpl::save(const char *file, const char *mode = "wb", size_t offset = 0)
    把 Double-Array 保存為文件.

    file 保存文件名,
    mode 文件打開模式 
    offset 保存的文件位置偏移量, 預留將來使用, 目前沒有實現 .

    成功返回 0 , 失敗返回 -1 

    int Darts::DoubleArrayImpl::open (const char *file, const char *mode = "rb", size_t offset = 0, size_t size = 0)
    讀入 Double-Array 文件.

    file 讀取文件名,
    mode 文件打開模式 
    offset 讀取的文件位置偏移量 

    size 為 0 的時候, size 使用文件的大小 .

    成功返回 0 , 失敗返回 -1 

    size_t Darts::DoubleArrayImpl::size()
    返回 Double-Array 大小. 

    size_t Darts::DoubleArrayImpl::unit_size()
    Double-Array 一個元素的大小(byte).

    size() * unit_size() 是, 存放 Double-Array 所需要的內存(byte) 大小. 

    size_t Darts::DoubleArrayImpl::nonzero_size()
    Double-Array 的所有元素中, 被使用的元素的數目, .
    nonezero_size()/size() 用于計算壓縮率. 

    例子程序

    從靜態詞典構建雙數組 Double-Array.

    #include <iostream>
    #include <darts.h>

    int main (int argc, char **argv)
    {
    using namespace std;

    Darts::DoubleArray::key_type *str[] = { "ALGOL", "ANSI", "ARCO", "ARPA", "ARPANET", "ASCII" }; // same as char*
    Darts::DobuleArray::result_type val[] = { 1, 2, 3, 4, 5, 6 }; // same as int

    Darts::DoubleArray da;
    da.build (6, str, 0, val);

    cout << da.exactMatchSearch("ALGOL") << endl;
    cout << da.exactMatchSearch("ANSI") << endl;
    cout << da.exactMatchSearch("ARCO") << endl;;
    cout << da.exactMatchSearch("ARPA") << endl;;
    cout << da.exactMatchSearch("ARPANET") << endl;;
    cout << da.exactMatchSearch("ASCII") << endl;;
    cout << da.exactMatchSearch("APPARE") << endl;

    da.save("some_file");
    }

    執行結果
    1
    2
    3
    4
    5
    6
    -1

    從標準輸入讀取字符串, 對 Double-Array 執行 Common Prefix Search

    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <darts.h>

    int main (int argc, char **argv)
    {
    using namespace std;

    Darts::DoubleArray da;
    if (da.open("some_file") == -1) return -1;

    Darts::DoubleArray::result_type r [1024];
    Darts::DoubleArray::key_type buf [1024];

    while (cin.getline (buf, 1024)) {
    size_t result = da.commonPrefixSearch(buf, r, 1024);
    if (result == 0) {
    cout << buf << ": not found" << endl;
    } else {
    cout << buf << ": found, num=" << result << " ";
    copy (r, r + result, ostream_iterator<Darts::DoubleArray::result_type>(cout, " "));
    cout << endl;
    }
    }

    return 0;
    }

    付屬程序說明

    mkdarts

    % ./mkdarts DictionaryFile DoubleArrayFile 
    把排序好的詞典 DictionaryFile 轉換為 DoubleArrayFile

    darts

    % ./darts DoubleArrayFile 

    使用 DoubleArrayFile 做 common prefix search .

    使用例子

    % cd tests
    % head -10 linux.words
    ALGOL
    ANSI
    ARCO
    ARPA
    ARPANET
    ASCII
    ..

    % ../mkdarts linux.words dar
    Making Double Array: 100% |*******************************************|
    Done!, Compression Ratio: 94.6903 %

    % ../darts dar
    Linux
    Linux: found, num=2 3697 3713
    Windows
    Windows: not found
    LaTeX
    LaTeX: found, num=1 3529

    參考文獻, 鏈接

    posted @ 2013-08-13 16:45 小馬歌 閱讀(445) | 評論 (0)編輯 收藏
     
         摘要: from: http://blog.chinaunix.net/uid-13746440-id-3152484.html0.引言基于DPDK的發包工具的性能今天已經達到雙向1900Wpps了,比昨天又高了200Wpps,正是得益于oProfile檢測與調優的結果,而且今天還只是很簡單的用了一下(類似于下面的示例),跟蹤出對幾個結構體字段的訪問比較緩慢,于是對結構體字段進行了仔細的順序調整...  閱讀全文
    posted @ 2013-08-12 14:13 小馬歌 閱讀(360) | 評論 (0)編輯 收藏
     
    When you running a highload website with PHP-FPM via FastCGI, the following tips may be useful to you : )
    如果您高負載網站使用PHP-FPM管 理FastCGI,這些技巧也許對您有用:)

    1. Compile PHP’s modules as less as possible, the simple the best (fast);
    1.盡量少安裝PHP模塊,最簡單是最好(快)的

    2. Increas PHP FastCGI child number to 100 and even more. Sometime, 200 is OK! ( On 4GB memory server);
    2.把您的PHP FastCGI子進程數調到100或以上,在4G內存的服務器上200就可以
    注:我的1g測試機,開64個是最好的,建議使用壓力測試獲取最佳值

    3. Using SOCKET PHP FastCGI, and put into /dev/shm on Linux;
    3.使用socket連接FastCGI,linux操作系統可以放在 /dev/shm中
    注: 在php-fpm.cnf 里設置<value name="listen_address">/tmp/nginx.socket</value>就可以通過socket連接 FastCGI了,/dev/shm是內存文件系統,放在內存中肯定會快了

    4. Increase Linux “max open files”, using the following command (must be root):
    # echo ‘ulimit -HSn 65536′ >> /etc/profile
    # echo ‘ulimit -HSn 65536 >> /etc/rc.local
    # source /etc/profile
    4.調高linux內核打開文件數量,可以使用這些命令(必須是root帳號)
    echo 'ulimit -HSn 65536' >> /etc/profile
    echo 'ulimit -HSn 65536' >> /etc/rc.local
    source /etc/profile
    注:我是修改/etc/rc.local,加入ulimit -SHn 51200的

    5. Increase PHP-FPM open file description rlimit:
    # vi /path/to/php-fpm.conf
    Find “<value name=”rlimit_files”>1024</value>”
    Change 1024 to 4096 or higher number.
    Restart PHP-FPM.
    5. 增加 PHP-FPM 打開文件描述符的限制:
    # vi /path/to/php-fpm.conf
    找到“<value name="rlimit_files">1024</value>”
    把1024 更改為 4096 或者更高.
    重啟 PHP-FPM.

    6. Using PHP code accelerator, e.g eAccelerator, XCache. And set “cache_dir” to /dev/shm on Linux.
    6.使用php代碼加速器,例如 eAccelerator, XCache.在linux平臺上可以把`cache_dir`指向 /dev/shm
    posted @ 2013-08-05 16:19 小馬歌 閱讀(547) | 評論 (0)編輯 收藏
     

    原文出處:http://blog.chenlb.com/2010/04/nginx-proxy-cache.html

    動態網站使用緩存是很有必要的。前段時間使用了 nginx proxy_stroe 來保存靜態頁面,以達到緩存的目的。當然 proxy stroe 用來做緩存是不夠好的方案。

    緩存這一塊當然還有 squid 之類的獨立緩存服務器。如果使用 nginx 為 web 服務器,還要加個 squid 來緩存,是覺得多了一個 http 請求層。幸好 nginx 0.7 有了 proxy_cache 來做這個緩存的事。

    之前來有個 ncache 是新浪員工開發的 nginx 模塊(好像只能在 nginx 0.6 中編譯無運行)。已經停止維護了,已經被加到 nginx 標準庫里了。昨天還不知道 proxy_cache 就是 ncache 的功能時,還在努力匹配 ncahce,浪費了N多時間,最終沒看到可以緩存。后來嘗試 proxy_cache 才解決,且使用簡單。

    安裝 Nginx 請看:安裝 Nginx 配置負載均衡,如果沒有 pcre 庫,可以到http://sourceforge.net/projects/pcre/files/ 下載(我用的是 8.02)。

    nginx 0.7.65 默認安裝就可以了。

    安裝好后開始匹配 proxy_cache,先準備后臺服務器的文件,如是 time.jsp,內容:

    1. <%=new java.util.Date() %>  

    conf/nginx.conf:

    1. user  nobody;  
    2. worker_processes  1;  
    3. error_log  logs/error.log;  
    4. pid        logs/nginx.pid;  
    5.   
    6. events {  
    7.     worker_connections  1024;  
    8.     use epoll;  
    9. }  
    10.   
    11. http {  
    12.     include       mime.types;  
    13.     default_type  application/octet-stream;  
    14.   
    15.     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '  
    16.                       '$status $body_bytes_sent "$http_referer" "$request_body" '  
    17.                       '"$http_user_agent" "$http_x_forwarded_for" "$request_time"';  
    18.   
    19.     sendfile        on;  
    20.     keepalive_timeout  60;  
    21.   
    22.     proxy_cache_path /var/cache0 levels=1:2 keys_zone=pnc:100m inactive=2h max_size=10g;  
    23.     upstream backend {  
    24.         server 192.168.1.2:8080  weight=6;  
    25.         #server 192.168.1.3:8080  weight=4;  
    26.     }  
    27.   
    28.     server {  
    29.         listen       80;  
    30.         server_name  localhost;  
    31.   
    32.         access_log  logs/access.80.log  main;  
    33.   
    34.         location / {  
    35.             proxy_cache pnc;  
    36.             proxy_temp_path /var/nginx_temp;  
    37.             #proxy_cache_key "$request_uri$request_body";  
    38.             #proxy_cache_methods GET POST;  
    39.             proxy_cache_valid 200 304 1m;  
    40.             proxy_pass http://backend;  
    41.         }  
    42.   
    43.         error_page   500 502 503 504  /50x.html;  
    44.         location = /50x.html {  
    45.             root   html;  
    46.         }  
    47.     }  
    48. }  

    啟動 nginx 后,打開瀏覽器,可以狂刷 Ctrl + F5,可以看到一樣的頁面。一分鐘后再會一個新的頁面。

    是 proxy_cache_valid 200 304 1m; 告訴 nginx 后臺返回的結果是 200 或 304 的響應,用 1m(分鐘)的緩存。

    proxy_cache_key 默認是 "$scheme$host$request_uri"。

    proxy_cache_methods 默認是 GET HEAD。

    當要緩存 post 請求后,要用 proxy_cache_methods POST 來打開。并且 proxy_cache_key 要對,post 的請求 query string 是在請求體內,所以加 $request_body 作為 key 的一部分。要用 post ,上面匹配去了注釋就可以了。

    這些匹配指令詳情請看官方:http://wiki.nginx.org/NginxHttpProxyModule,中文版:http://wiki.nginx.org/NginxChsHttpProxyModule

    posted @ 2013-08-02 16:14 小馬歌 閱讀(943) | 評論 (0)編輯 收藏
     

    這里主要講的是Nginx的優化方法,同時還需要優化php-fpm配置,方法請參考:http://blog.haohtml.com/archives/11162.

    優化前:

    優化后:

    看得出差距還是特別的大的.

    /etc/sysctl.conf

    一般來說nginx配置文件中對優化比較有作用的為以下幾項:

    worker_processes 8;
    nginx進程數,建議按照cpu數目來指定,一般為它的倍數,平時設置為2倍。

    cpu個數查看方法參考:http://blog.haohtml.com/archives/11123 和 http://blog.haohtml.com/archives/9236

    worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
    為每個進程分配cpu,上例中將8個進程分配到8個cpu,當然可以寫多個,或者將一個進程分配到多個cpu。

    worker_rlimit_nofile 102400;
    這個指令是指當一個nginx進程打開的最多文件描述符數目,理論值應該是最多打開文件數(ulimit -n)與nginx進程數相除,但是nginx分配請求并不是那么均勻,所以最好與ulimit -n的值保持一致。ulimit的用法參考:http://blog.haohtml.com/archives/9883

    use epoll;
    使用epoll的I/O模型,這個不用說了吧。

    worker_connections 102400;
    每個進程允許的最多連接數,理論上每臺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時間內一次沒被使用,它將被移除。

    關于內核參數的優化:

    net.ipv4.tcp_max_tw_buckets = 6000
    timewait的數量,默認是180000。

    net.ipv4.ip_local_port_range = 1024    65000
    允許系統打開的端口范圍。

    net.ipv4.tcp_tw_recycle = 1
    啟用timewait快速回收。

    net.ipv4.tcp_tw_reuse = 1
    開啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接。

    net.ipv4.tcp_syncookies = 1
    開啟SYN Cookies,當出現SYN等待隊列溢出時,啟用cookies來處理。

    net.core.somaxconn = 262144
    web應用中listen函數的backlog默認會給我們內核參數的net.core.somaxconn限制到128,而nginx定義的NGX_LISTEN_BACKLOG默認為511,所以有必要調整這個值。

    net.core.netdev_max_backlog = 262144
    每個網絡接口接收數據包的速率比內核處理這些包的速率快時,允許送到隊列的數據包的最大數目。

    net.ipv4.tcp_max_orphans = 262144
    系統中最多有多少個TCP套接字不被關聯到任何一個用戶文件句柄上。如果超過這個數字,孤兒連接將即刻被復位并打印出警告信息。這個限制僅僅是為了防止簡單的DoS攻擊,不能過分依靠它或者人為地減小這個值,更應該增加這個值(如果增加了內存之后)。

    net.ipv4.tcp_max_syn_backlog = 262144
    記錄的那些尚未收到客戶端確認信息的連接請求的最大值。對于有128M內存的系統而言,缺省值是1024,小內存的系統則是128。

    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_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_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 = 262144
    net.core.somaxconn = 262144
    net.ipv4.tcp_max_orphans = 3276800
    net.ipv4.tcp_max_syn_backlog = 262144
    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

    下面是一個簡單的nginx配置文件:

    user  www www;
    worker_processes 8;
    worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000;
    error_log  /www/log/nginx_error.log  crit;
    pid        /usr/local/nginx/nginx.pid;
    worker_rlimit_nofile 204800;

    events
    {
    use epoll;
    worker_connections 204800;
    }

    http
    {
    include       mime.types;
    default_type  application/octet-stream;

    charset  utf-8;

    server_names_hash_bucket_size 128;
    client_header_buffer_size 2k;
    large_client_header_buffers 4 4k;
    client_max_body_size 8m;

    sendfile on;
    tcp_nopush     on;

    keepalive_timeout 60;

    fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2
    keys_zone=TEST:10m
    inactive=5m;
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 8 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;
    fastcgi_cache TEST;
    fastcgi_cache_valid 200 302 1h;
    fastcgi_cache_valid 301 1d;
    fastcgi_cache_valid any 1m;
    fastcgi_cache_min_uses 1;
    fastcgi_cache_use_stale error timeout invalid_header http_500;

    open_file_cache max=204800 inactive=20s;
    open_file_cache_min_uses 1;
    open_file_cache_valid 30s;
    tcp_nodelay on;

    gzip on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_types       text/plain application/x-javascript text/css application/xml;
    gzip_vary on;
    server
    {
    listen       8080;
    server_name  backup.aiju.com;
    index index.php index.htm;
    root  /www/html/;  #這里的位置很重要,不要寫在其它指令里面,我曾經就調試了好久才發現這個問題的

    location /status
    {
    stub_status on;
    }

    location ~ .*\.(php|php5)?$
    {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    include fcgi.conf;
    }

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
    {
    expires      30d;
    }

    log_format  access  '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" $http_x_forwarded_for';
    access_log  /www/log/access.log  access;
    }
    }

    關于FastCGI的幾個指令(http://wiki.nginx.org/NginxChsHttpFcgiModule):

    fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
    這個指令為FastCGI緩存指定一個路徑,目錄結構等級,關鍵字區域存儲時間和非活動刪除時間。

    fastcgi_connect_timeout 300;
    指定連接到后端FastCGI的超時時間。

    fastcgi_send_timeout 300;
    向FastCGI傳送請求的超時時間,這個值是指已經完成兩次握手后向FastCGI傳送請求的超時時間。

    fastcgi_read_timeout 300;
    接收FastCGI應答的超時時間,這個值是指已經完成兩次握手后接收FastCGI應答的超時時間。

    fastcgi_buffer_size 64k;
    指定讀取FastCGI應答第一部分需要用多大的緩沖區,一般第一部分應答不會超過1k,由于頁面大小為4k,所以這里設置為4k。

    fastcgi_buffers 8 64k;
    指定本地需要用多少和多大的緩沖區來緩沖FastCGI的應答。

    fastcgi_busy_buffers_size 128k;
    這個指令我也不知道是做什么用,只知道默認值是fastcgi_buffers的兩倍。

    fastcgi_temp_file_write_size 128k;
    在寫入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來管理FastCGI,可以修改配置文件中的以下值:
    <value name="max_children">60</value>
    同時處理的并發請求數,即它將開啟最多60個子線程來處理并發連接。

    <value name="rlimit_files">102400</value>
    最多打開文件數。

    <value name="max_requests">204800</value>
    每個進程在重置之前能夠執行的最多請求數。

    下面貼幾張測試結果圖。

    靜態頁面為我在squid配置4W并發那篇文章中提到的測試文件,下圖為同時在6臺機器運行webbench -c 30000 -t 600 http://backup.aiju.com:8080/index.html命令后的測試結果:
    使用netstat過濾后的連接數:
    php頁面在status中的結果(php頁面為調用phpinfo):
    php頁面在netstat過濾后的連接數:
    未使用FastCGI緩存之前的服務器負載:
    此時打開php頁面已經有些困難,需要進行多次刷新才能打開。上圖中cpu0負載偏低是因為測試時將網卡中斷請求全部分配到cpu0上,并且在nginx中開啟7個進程分別制定到cpu1-7。
    使用FastCGI緩存之后:
    此時可以很輕松的打開php頁面。

    這個測試并沒有連接到任何數據庫,所以并沒有什么參考價值,不過不知道上述測試是否已經到達極限,根據內存和cpu的使用情況來看似乎沒有,但是已經沒有多余的機子來讓我運行webbench了。

    參考資料:

    http://hi.baidu.com/myus/blog/item/f37d05d1b1d1ad399a5027ff.html

    http://kenwublog.com/docs/linux-kernel-2-6-36-optimization.htm

    http://blog.sina.com.cn/s/blog_50a736440100j023.html

    2 THOUGHTS ON “NGINX優化配置(轉)

    posted @ 2013-08-01 22:18 小馬歌 閱讀(249) | 評論 (0)編輯 收藏
     
    都知道 http加速器 現在 varnish 比 squid 名聲大,所以 先整了一把varnish,但是研究之后,發現不支持SSL,只得作罷,開始換上squid.

    到網上下了一個最新版 3.3.8,開始搜索配置資料,發現都是以前的舊的,不適用,后來發現了一個 針對3.0的配置: http://linux008.blog.51cto.com/2837805/618731
     
      按照提示安裝完成了,啟用了 --enable-ssl選項。

    后來又參考官方文檔 加上了https支持,參考:http://wiki.squid-cache.org/ConfigExamples/Reverse/SslWithWildcardCertifiate

     
     但是很不辛,居然報錯:“FATAL: http(s)_port: defaultsite option requires Acceleration mode flag.”

    然后根據提示 去 查找https_port用法,參考資料:http://www.squid-cache.org/Doc/config/https_port/

    原來 是 缺少[mode]選項,根據我的需要,加了“accel”,問題解決.

    具體業務的完整配置參考附件。
    https_port 443 cert=/usr/local/squid/cert.pem key=/usr/local/squid/cert.key accel defaultsite=img0-yoursite.yourdomain.com vhost
    cache_peer 1.2.3.4 parent 80 0 no-query originserver ssl sslflags=DONT_VERIFY_PEER name=img0
    acl sites_server_img0 dstdomain img0-yoursite.yourdomain.com
    cache_peer_access img0 allow sites_server_img0
    http_access allow sites_server_img0

    https_port 443 cert=/usr/local/squid/cert.pem key=/usr/local/squid/cert.key accel defaultsite=img1-yoursite.yourdomain.com vhost
    cache_peer 1.2.3.4 parent 80 0 no-query originserver ssl sslflags=DONT_VERIFY_PEER name=img1
    acl sites_server_img1 dstdomain img1-yoursite.yourdomain.com
    cache_peer_access img1 allow sites_server_img1
    http_access allow sites_server_img1

    ####base######
    visible_hostname localhost
    cache_mgr xiaomage234@163.com
    cache_effective_user nobody
    cache_effective_group nobody
    ####cache#####
    cache_mem 600 MB
    cache_swap_low 90
    cache_swap_high 95
    maximum_object_size 12000 KB
    maximum_object_size_in_memory 1024 KB
    cache_dir ufs /usr/local/squid/var/cache 10000 16 256
    cache_access_log /usr/local/squid/var/logs/access.log
    cache_log /usr/local/squid/var/logs/cache.log
    cache_store_log /usr/local/squid/var/logs/store.log
    #####no-cache##########
    hierarchy_stoplist cgi-bin ?/.php
    acl QUERY urlpath_regex cgi-bin /?/.php
    #acl DIRECT url_regex -i ^http://192.168.0.201
    cache deny QUERY
    #cache deny DIRECT
    #####refresh_pattern####
    refresh_pattern ^ftp: 60 20% 10080
    refresh_pattern ^gopher: 60 0% 1440

    refresh_pattern ^gopher: 60 0% 1440
    refresh_pattern . 0 20% 1440
    refresh_pattern -i /.css$       360     50%     2880     reload-into-ims
    refresh_pattern -i /.js$        1440    50%     2880     reload-into-ims
    refresh_pattern -i /.html$      720     50%     1440     reload-into-ims
    refresh_pattern -i /.jpg$       1440    90%     2880     ignore-reload
    refresh_pattern -i /.gif$       1440    90%     2880     ignore-reload
    refresh_pattern -i /.swf$       1440    90%     2880     ignore-reload
    refresh_pattern -i /.jpg$       1440    50%     2880     ignore-reload
    refresh_pattern -i /.png$       1440    50%     2880     ignore-reload
    refresh_pattern -i /.bmp$       1440    50%     2880     ignore-reload
    refresh_pattern -i /.doc$       1440    50%     2880     ignore-reload
    refresh_pattern -i /.ppt$       1440    50%     2880     ignore-reload
    refresh_pattern -i /.xls$       1440    50%     2880     ignore-reload
    refresh_pattern -i /.pdf$       1440    50%     2880     ignore-reload
    refresh_pattern -i /.rar$       1440    50%     2880     ignore-reload
    refresh_pattern -i /.zip$       1440    50%     2880     ignore-reload
    refresh_pattern -i /.txt$       1440    50%     2880     ignore-reload
    ######proxy agent###        
    http_port 80 accel vhost vport
    cache_peer 1.2.3.4 parent 80 0 no-query originserver name=img00
    cache_peer_domain img00 img0-yoursite.yourdomain.com

    cache_peer 1.2.3.4 parent 80 0 no-query originserver name=img01
    cache_peer_domain img01 img1-yoursite.yourdomain.com
    ######alc#####
    acl manager2 proto cache_object
    acl localhost src 127.0.0.1/32
    acl to_localhost dst 127.0.0.0/8
    acl localnet src 10.0.0.0/8     # RFC1918 possible internal network
    acl localnet src 172.16.0.0/12  # RFC1918 possible internal network
    acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
    acl LanSrc src all
    acl LanDst dst all
    acl SSL_ports port 443
    acl Safe_ports port 80          # http
    acl Safe_ports port 21          # ftp
    acl Safe_ports port 443         # https
    acl Safe_ports port 70          # gopher
    acl Safe_ports port 210         # wais
    acl Safe_ports port 1025-65535  # unregistered ports
    acl Safe_ports port 280         # http-mgmt
    acl Safe_ports port 488         # gss-http
    acl Safe_ports port 591         # filemaker
    acl Safe_ports port 777         # multiling http
    acl CONNECT method CONNECT
    acl LanDstDM dstdomain .kanbox.com

    http_access allow manager2 localhost
    http_access deny manager2
    http_access deny !Safe_ports
    http_access deny CONNECT !SSL_ports
    http_access allow LanDstDM
    http_access allow LanSrc
    http_access allow LanDst
    http_access allow localnet
    http_access deny all

    下載附件:
    /Files/xiaomage234/squid.conf.txt

    v
    arnish的配置,不支持https:
    /Files/xiaomage234/default.vcl.txt
    posted @ 2013-07-31 13:58 小馬歌 閱讀(4292) | 評論 (1)編輯 收藏
     
    from:http://blog.csdn.net/langeldep/article/details/6641682
    分類: Linux操作與使用2011-07-28 17:49 4999人閱讀 評論(4) 收藏 舉報

    要使用分布式文件系統來降低成本,于是搜尋了開源的分布式文件系統。


    經過安裝部署和測試,把我使用中碰到的一些問題總結一下, 希望對大家有所幫助, 我也有一些問題沒有搞懂,希望和大家一起交流,共同進步。


    第一:CEPH

    網上搜索了一些資料, 說 ceph 性能最高,C++編寫的代碼,支持Fuse,并且沒有單點故障依賴, 于是下載安裝, 由于 ceph 使用 btrfs 文件系統, 而btrfs 文件系統需要 Linux 2.6.34 以上的內核才支持, 顯然我使用的 RHEL5 的內核還不支持 btrfs文件系統, 于是下載最新的內核進行升級, 搞了2天沒有升級成功, 編譯一次都要耗費1個多小時才能完成,最后發現最新版的 ubuntu 系統支持btrfs文件系統, 于是安裝 ubuntu 的虛擬機,btrfs 文件系統搞定了, 但是啟動ceph的相關進程出錯, 無法啟動成功。所以談不上對其進行過測試。


    CEPH中使用了一個比較先進的算法 crush算法, 據翻譯出來,為分布式基于對象的存儲系統設計了一個可升級的偽隨機的數據分布函數,它能夠有效地管理數據對象和存儲設備,而不需要通過一個中心目錄。由于大系統都是動態的,CRUSH被設計成為一個當把不需要的數據遷移最小化時,能方便的增加或移除存儲設備。這個算法提供了一個大范圍的不同種類的數據復制和可靠性機制,以及根據用戶自定義的策略來分配數據,這種策略迫使數據復制從故障領域分離出來。


    另外CEPH使用的文件系統為btrfs, 這個文件系統具有很多先進的特性, 為下一代Linux使用的文件系統。

    BTRFS最終可能會給ZFS等帶來更多威脅,它具有在線碎片整理功能(只有固態盤有這項功能)、Copy-On-Write技術、數據壓縮、鏡像、數據條帶和快照等等。

      另外,BTRFS在數據存儲方面比ext更完善。它包括一些邏輯卷管理和RAID硬件功能,可以對內部元數據和用戶數據進行檢驗和,同時內嵌了快照功能。ext4也可以實現以上一些功能,但是需要與文件系統和邏輯卷管理器進行通信。


    這么多先進的功能, 可惜現在還無法消受啊。。。。。。


    第二:glusterfs

    網上說glusterfs比較不錯, 穩定,適合大型應用, 關鍵是沒有單點故障依賴,C語言的代碼, 支持FUSE,于是下載安裝研究。 安裝配置還算簡單,啟動后進行測試。

    開始感覺確實不錯,很爽。 后來用壓力測試工具對其吞吐量進行測試 , 發現性能不能滿足我們的生產需求,不知道是哪里的配置問題,

    我們測試的都是大文件的讀操作和大文件的寫操作, 吞吐量在 5MB/秒左右, 顯然不能滿足要求。但是沒有找到具體的瓶頸,畢竟程序是別人寫的,要查瓶頸也不容易。


    關于 glusterfs的詳細的資料, 可以看這位弟兄的文章, 他做的比較深入  。

    http://zhoubo.sinaapp.com/?cat=22


    第三:moosefs

    這個網上說性能不錯,有單點故障依賴, C代碼編寫,支持FUSE, 下載試試吧。

    安裝配置還算簡單。很快就搭建好環境了, 于是進行測試。測試性能還不錯。吞吐量在15MB/秒以上。


    第四:mogilefs 

    網上說這個是性能最高的, 不過是perl編寫的代碼, 對外提供API來進行使用, 搭建相對比較復雜一點, 因為需要安裝很多依賴的第三方perl包,另外還要安裝Mysql數據庫來支持。

    安裝完畢后, 服務器端起來了, 客戶端有JAVA, PHP,  PERL, RUBY 等開發的, 我需要的是要支持 FUSE 的, 但是這個分布式的文件系統,對FUSE的支持需要安裝一個PERL與C通信的模塊, 這個模塊死活編譯不過去, 最后無法測試成功,無奈只能有時間了繼續研究。


    第五:fastDFS

    網上說是“國人在mogileFS的基礎上進行改進的key-value型文件系統,同樣不支持FUSE,提供比mogileFS更好的性能”, 這不是扯蛋嗎 ? Mogilefs 是perl寫的, 如果 fastDFS是在 mogilefs 的基礎上改進的話, 應該也是perl寫的, 但是下載了fastDFS的代碼后, 人家都是C的代碼, 怎么可能是在mogilefs的基礎上改進呢 ?看了一下fastDFS具體的結構,準確的說應該是“借鑒了MogileFS的思路”,而不能說“在MogileFS的基礎上改進”。


    我安裝了一下, 安裝還算簡單, 不支持fuse, 上傳文件后會生成一個http的下載地址, 通過http的方式進行下載。這種方式顯然不適合我想要的生產環境。



    下面是一個網友寫的 FastFDS和MogileFS的對比文章, 感覺比較客觀真實, 所以在這里給大家轉帖一下。



    FastDFS設計時借鑒了MogileFS的一些思路。FastDFS是一個完善的分布式文件存儲系統,通過客戶端API對文件進行讀寫。可以說,MogileFS的所有功能特性FastDFS都具備,MogileFS網址:http://www.danga.com/mogilefs/。

    另外,相對于MogileFS,FastDFS具有如下特點和優勢:
    1. FastDFS完善程度較高,不需要二次開發即可直接使用;
    2. 和MogileFS相比,FastDFS裁減了跟蹤用的數據庫,只有兩個角色:tracker和storage。FastDFS的架構既簡化了系統,同時也消除了性能瓶頸;
    3. 在系統中增加任何角色的服務器都很容易:增加tracker服務器時,只需要修改storage和client的配置文件(增加一行tracker配置);增加storage服務器時,通常不需要修改任何配置文件,系統會自動將該卷中已有文件復制到該服務器;
    4. FastDFS比MogileFS更高效。表現在如下幾個方面:
      1)參見上面的第2點,FastDFS和MogileFS相比,沒有文件索引數據庫,FastDFS整體性能更高;
      2)從采用的開發語言上看,FastDFS比MogileFS更底層、更高效。FastDFS用C語言編寫,代碼量不到2萬行,沒有依賴其他開源軟件或程序包,安裝和部署特別簡潔;而MogileFS用perl編寫;
      3)FastDFS直接使用socket通信方式,相對于MogileFS的HTTP方式,效率更高。并且FastDFS使用sendfile傳輸文件,采用了內存零拷貝,系統開銷更小,文件傳輸效率更高。
    5. FastDFS有著詳細的設計和使用文檔,而MogileFS的文檔相對比較缺乏。
    6. FastDFS的日志記錄非常詳細,系統運行時發生的任何錯誤信息都會記錄到日志文件中,當出現問題時方便管理員定位錯誤所在。
    7. FastDFS還對文件附加屬性(即meta data,如文件大小、圖片寬度、高度等)進行存取,應用不需要使用數據庫來存儲這些信息。
    8. FastDFS從V1.14開始支持相同文件內容只保存一份,這樣可以節省存儲空間,提高文件訪問性能。


    第六:Lustre

    本來還對這個分布式文件系統抱有無限的希望, 被Oracle公司收購后, 這個東西連下載地址都沒有了。。。。。。, 狂暈一吧!!!

    如果那個弟兄找到下載地址, 麻煩給通知一下, 謝謝。

    posted @ 2013-07-18 14:38 小馬歌 閱讀(428) | 評論 (0)編輯 收藏
     

    1.     ccmalloc-Linux和Solaris下對C和C++程序的簡單的使用內存泄漏和malloc調試庫。

    2.     Dmalloc-Debug Malloc Library.

    3.     Electric Fence-Linux分發版中由Bruce Perens編寫的malloc()調試庫。

    4.     Leaky-Linux下檢測內存泄漏的程序。

    5.     LeakTracer-Linux、Solaris和HP-UX下跟蹤和分析C++程序中的內存泄漏。

    6.     MEMWATCH-由Johan Lindh編寫,是一個開放源代碼C語言內存錯誤檢測工具,主要是通過gcc的precessor來進行。

    7.     Valgrind-Debugging and profiling Linux programs, aiming at programs written in C and C++.

    8.     KCachegrind-A visualization tool for the profiling data generated by Cachegrind and Calltree.

    9.     Leak Monitor-一個Firefox擴展,能找出跟Firefox相關的泄漏類型。

    10. IE Leak Detector (Drip/IE Sieve)-Drip和IE Sieve leak detectors幫助網頁開發員提升動態網頁性能通過報告可避免的因為IE局限的內存泄漏。

    11. Windows Leaks Detector-探測任何Win32應用程序中的任何資源泄漏(內存,句柄等),基于Win API調用鉤子。

    12. SAP Memory Analyzer-是一款開源的JAVA內存分析軟件,可用于輔助查找JAVA程序的內存泄漏,能容易找到大塊內存并驗證誰在一直占用它,它是基于Eclipse RCP(Rich Client Platform),可以下載RCP的獨立版本或者Eclipse的插件。

    13. DTrace-即動態跟蹤Dynamic Tracing,是一款開源軟件,能在Unix類似平臺運行,用戶能夠動態檢測操作系統內核和用戶進程,以更精確地掌握系統的資源使用狀況,提高系統性能,減少支持成本,并進行有效的調節。

    14. IBM Rational PurifyPlus-幫助開發人員查明C/C++、托管.NET、Java和VB6代碼中的性能和可靠性錯誤。PurifyPlus 將內存錯誤和泄漏檢測、應用程序性能描述、代碼覆蓋分析等功能組合在一個單一、完整的工具包中。

    15. Parasoft Insure++-針對C/C++應用的運行時錯誤自動檢測工具,它能夠自動監測C/C++程序,發現其中存在著的內存破壞、內存泄漏、指針錯誤和I/O等錯誤。并通過使用一系列獨特的技術(SCI技術和變異測試等),徹底的檢查和測試我們的代碼,精確定位錯誤的準確位置并給出詳細的診斷信息。能作為Microsoft Visual C++的一個插件運行。

    16. Compuware DevPartner for Visual C++ BoundsChecker Suite-為C++開發者設計的運行錯誤檢測和調試工具軟件。作為Microsoft Visual Studio和C++ 6.0的一個插件運行。

    17. Electric Software GlowCode-包括內存泄漏檢查,code profiler,函數調用跟蹤等功能。給C++和.Net開發者提供完整的錯誤診斷,和運行時性能分析工具包。

    18. Compuware DevPartner Java Edition-包含Java內存檢測,代碼覆蓋率測試,代碼性能測試,線程死鎖,分布式應用等幾大功能模塊。

    19. Quest JProbe-分析Java的內存泄漏。

    20. ej-technologies JProfiler-一個全功能的Java剖析工具,專用于分析J2SE和J2EE應用程序。它把CPU、執行緒和內存的剖析組合在一個強大的應用中。JProfiler可提供許多IDE整合和應用服務器整合用途。JProfiler直覺式的GUI讓你可以找到效能瓶頸、抓出內存泄漏、并解決執行緒的問題。4.3.2注冊碼:A-G666#76114F-1olm9mv1i5uuly#0126

    21. BEA JRockit-用來診斷Java內存泄漏并指出根本原因,專門針對Intel平臺并得到優化,能在Intel硬件上獲得最高的性能。

    22. SciTech Software AB .NET Memory Profiler-找到內存泄漏并優化內存使用針對C#,VB.Net,或其它.Net程序。

    23. YourKit .NET & Java Profiler-業界領先的Java和.NET程序性能分析工具。

    24. AutomatedQA AQTime-AutomatedQA的獲獎產品performance profiling和memory debugging工具集的下一代替換產品,支持Microsoft, Borland, Intel, Compaq 和 GNU編譯器。可以為.NET和Windows程序生成全面細致的報告,從而幫助您輕松隔離并排除代碼中含有的性能問題和內存/資源泄露問題。支持.Net 1.0,1.1,2.0,3.0和Windows 32/64位應用程序。

    25. JavaScript Memory Leak Detector-微軟全球產品開發歐洲團隊(Global Product Development- Europe team, GPDE) 發布的一款調試工具,用來探測JavaScript代碼中的內存泄漏,運行為IE系列的一個插件。

    附錄:內存泄漏的發生方式

    1.     常發性內存泄漏。發生內存泄漏的代碼會被多次執行到,每次被執行的時候都會導致一塊內存泄漏。

    2.     偶發性內存泄漏。發生內存泄漏的代碼只有在某些特定環境或操作過程下才會發生。常發性和偶發性是相對的。對于特定的環境,偶發性的也許就變成了常發性的。所以測試環境和測試方法對檢測內存泄漏至關重要。

    3.     一次性內存泄漏。發生內存泄漏的代碼只會被執行一次,或者由于算法上的缺陷,導致總會有一塊且僅有一塊內存發生泄漏。

    4.     隱 式內存泄漏。程序在運行過程中不停的分配內存,但是直到結束的時候才釋放內存。嚴格的說這里并沒有發生內存泄漏,因為最終程序釋放了所有申請的內存。但是 對于一個服務器程序,需要運行幾天,幾周甚至幾個月,不及時釋放內存也可能導致最終耗盡系統的所有內存。所以,我們稱這類內存泄漏為隱式內存泄漏。

    什么是系統資源?

    當應用程序在Windows中運行時,Windows必須實時"跟蹤"該應用程序的運行,并保留與之相關的許多信息,如按鈕、光標、菜單的位置和位圖、窗口的狀況等,這些信息由Windows保留在一種叫堆的內存塊中,堆的英文為Heap。簡單地說,堆是采用特殊機制管理的內存塊。由Windows的一個系統內核User.exe管理的堆叫做User資源堆(User Resource Heap),由另一個系統內核Gdi.exe管理的堆叫做GDI資源堆(Graphical Device Interface Resource Heap,簡稱GDI Resource Heap),User資源堆和GDI資源堆合稱為系統資源堆(System Resource Heap),習慣上就把它們叫做系統資源(System Resource)。

      微軟將Windows的系統資源(堆)分為五個堆,其中User資源堆為三個,而GDI資源堆為兩個。

      三個User資源堆分別是:16位的用戶堆(User Heap,64KB);32位的窗口堆(Windows Heap,2MB);32位的用戶菜單堆(User Menu Heap,2MB)。

      兩個GDI資源堆分別是:16位的GDI堆(GDI Heap,64KB);32位的GDI堆(GDI,2MB)。

      從這里的系統資源分類和大小我們應該明白,不管CPU是P4還是486,內存是8M還是1G,所有Windows的用戶都擁有同樣大小的系統資源(堆),用戶不能自已增加或減少系統資源的大小,這是由操作系統決定的,與硬件檔次沒有任何關系。

      Windows的User資源堆和GDI資源堆的可用(Free)空間稱為可用 User資源和可用GDI資源,Windows中以百分數表示它們,用戶可以選擇 "開始/附件/系統工具/系統信息",來實時查看它們的大小。 
    為了您的安全,請只打開來源可靠的網址


    來自: http://hi.baidu.com/jrckkyy/blog/item/6947f42332ec80589922ed6d.html 

    posted @ 2013-06-26 15:12 小馬歌 閱讀(1591) | 評論 (0)編輯 收藏
     

    1. Tair總述

    1.1 系統架構

    一個Tair集群主要包括3個必選模塊:configserver、dataserver和client,一個可選模塊:invalidserver。通常情況下,一個集群中包含2臺configserver及多臺dataServer。兩臺configserver互為主備并通過維護和dataserver之間的心跳獲知集群中存活可用的dataserver,構建數據在集群中的分布信息(對照表)。dataserver負責數據的存儲,并按照configserver的指示完成數據的復制和遷移工作。client在啟動的時候,從configserver獲取數據分布信息,根據數據分布信息和相應的dataserver交互完成用戶的請求。invalidserver主要負責對等集群的刪除和隱藏操作,保證對等集群的數據一致。

    從架構上看,configserver的角色類似于傳統應用系統的中心節點,整個集群服務依賴于configserver的正常工作。但實際上相對來說,tair的configserver是非常輕量級的,當正在工作的服務器宕機的時候另外一臺會在秒級別時間內自動接管。而且,如果出現兩臺服務器同時宕機的最惡劣情況,只要應用服務器沒有新的變化, tair依然服務正常。而有了configserver這個中心節點,帶來的好處就是應用在使用的時候只需要配置configserver的地址(現在可以直接配置Diamond key),而不需要知道內部節點的情況。

    1.1.1 ConfigServer的功能

    1) 通過維護和dataserver心跳來獲知集群中存活節點的信息
    2) 根據存活節點的信息來構建數據在集群中的分布表。
    3) 提供數據分布表的查詢服務。
    4) 調度dataserver之間的數據遷移、復制。

    1.1.2 DataServer的功能

    1) 提供存儲引擎
    2) 接受client的put/get/remove等操作
    3) 執行數據遷移,復制等
    4) 插件:在接受請求的時候處理一些自定義功能
    5) 訪問統計

    1.1.3 InvalidServer的功能

    1) 接收來自client的invalid/hide等請求后,對屬于同一組的集群(雙機房獨立集群部署方式)做delete/hide操作,保證同一組集群的一致。
    2) 集群斷網之后的,臟數據清理。
    3) 訪問統計。

    1.1.4 client的功能

    1) 在應用端提供訪問Tair集群的接口。
    2) 更新并緩存數據分布表和invalidserver地址等。
    3) LocalCache,避免過熱數據訪問影響tair集群服務。
    4) 流控

    1.2 存儲引擎與應用場景

    Tair經過這兩年的發展演進,除了應用于cache緩存外,在存儲(持久化)上支持的應用需求也越來越廣泛。現在主要有mdb,rdb,ldb三種存儲引擎。

    1.2.1 mdb

    定位于cache緩存,類似于memcache。
    支持k/v存取和prefix操作

    1.2.1.1 mdb的應用場景
    在實際業務中,大部分當緩存用(后端有DB之類的數據源)。
    也可用做大訪問少量臨時數據的存儲(例如session登錄,防攻擊統計等)。
    集團內絕對多數cache服務都是采用的tair mdb。

    1.2.2 rdb

    定位于cache緩存,采用了redis的內存存儲結構。
    支持k/v,list,hash,set,sortedset等數據結構。

    1.2.2.1 rdb的應用場景
    適用于需要高速訪問某些數據結構的應用,例如SNS中常見的的粉絲存儲就可以采用set等結構;或者存儲一個商品的多個屬性(hashmap);高效的消息隊列(list)等。現在有30個左右的應用在使用rdb服務。

    1.2.3 ldb

    定位于高性能存儲,并可選擇內嵌mdb cache加速,這種情況下cache與持久化存儲的數據一致性由tair進行維護。 支持k/v,prefix等數據結構。今后將支持list,hash,set,sortedset等redis支持的數據結構。

    1.2.3.1 ldb的應用場景
    存儲,里面可以細分如下場景:
    1) 持續大數據量的存入讀取,類似淘寶交易快照。
    2) 高頻度的更新讀取,例如計數器,庫存等。
    3) 離線大批量數據導入后做查詢。參見fastdump
    也可以用作cache:
    數據量大,響應時間敏感度不高的cache需求可以采用。例如天貓實時推薦。

    1.3 基本概念

    1.3.1 configID

    唯一標識一個tair集群,每個集群都有一個對應的configID,在當前的大部分應用情況下configID是存放在diamond中的,對應了該集群的configserver地址和groupname。業務在初始化tairclient的時候需要配置此ConfigID。

    1.3.2 namespace

    又稱area, 是tair中分配給應用的一個內存或者持久化存儲區域, 可以認為應用的數據存在自己的namespace中。 
    同一集群(同一個configID)中namespace是唯一的。
    通過引入namespace,我們可以支持不同的應用在同集群中使用相同的key來存放數據,也就是key相同,但內容不會沖突。一個namespace下是如果存放相同的key,那么內容會受到影響,在簡單K/V形式下會被覆蓋,rdb等帶有數據結構的存儲引擎內容會根據不同的接口發生不同的變化。

    1.3.3 quota配額

    對應了每個namespace儲存區的大小限制,超過配額后數據將面臨最近最少使用(LRU)的淘汰。
    持久化引擎(ldb)本身沒有配額,ldb由于自帶了mdb cache,所以也可以設置cache的配額。超過配額后,在內置的mdb內部進行淘汰。

    1.3.3.1 配額是怎樣計算的
    配額大小直接影響數據的命中率和資源利用效率,業務方需要給出一個合適的值,通常的計算方法是評估在保證一定命中率情況下所需要的記錄條數,這樣配額大小即為: 記錄條數 * 平均單條記錄大小。

    1.3.3.2 管理員如何配置配額
    單份數據情況下,業務提供的配額就是需要配置在Tair系統中的配額。但對于多備份,在系統中實際計算的配額為: 業務配額 * 備份數

    1.3.4 expireTime:過期時間

    expiredTime 是指數據的過期時間,當超過過期時間之后,數據將對應用不可見,這個設置同樣影響到應用的命中率和資源利用率。不同的存儲引擎有不同的策略清理掉過期的數據。調用接口時,expiredTime單位是秒,可以是相對時間(比如:30s),也可以是絕對時間(比如:當天23時,轉換成距1970-1-1 00:00:00的秒數)。 小于0,不更改之前的過期時間
    如果不傳或者傳入0,則表示數據永不過期;
    大于0小于當前時間戳是相對時間過期;
    大于當前時間戳是絕對時間過期;

    1.3.5 version

    Tair中存儲的每個數據都有版本號,版本號在每次更新后都會遞增,相應的,在Tair put接口中也有此version參數,這個參數是為了解決并發更新同一個數據而設置的,類似于樂觀鎖。
    很多情況下,更新數據是先get,修改get回來的數據,然后put回系統。如果有多個客戶端get到同一份數據,都對其修改并保存,那么先保存的修改就會被后到達的修改覆蓋,從而導致數據一致性問題,在大部分情況下應用能夠接受,但在少量特殊情況下,這個是我們不希望發生的。
    比如系統中有一個值”1”, 現在A和B客戶端同時都取到了這個值。之后A和B客戶端都想改動這個值,假設A要改成12,B要改成13,如果不加控制的話,無論A和B誰先更新成功,它的更新都會被后到的更新覆蓋。Tair引入的version機制避免了這樣的問題。剛剛的例子中,假設A和B同時取到數據,當時版本號是10,A先更新,更新成功后,值為12,版本為11。當B更新的時候,由于其基于的版本號是10,此時服務器會拒絕更新,返回version error,從而避免A的更新被覆蓋。B可以選擇get新版本的value,然后在其基礎上修改,也可以選擇強行更新。

    1.3.5.1 如何獲取到當前key的version
    get接口返回的是DataEntry對象,該對象中包含get到的數據的版本號,可以通過getVersion()接口獲得該版本號。在put時,將該版本號作為put的參數即可。 如果不考慮版本問題,則可設置version參數為0,系統將強行覆蓋數據,即使版本不一致。

    1.3.5.2 version是如何改變的
    Version改變的邏輯如下:
    1) 如果put新數據且沒有設置版本號,會自動將版本設置成1。
    2) 如果put是更新老數據且沒有版本號,或者put傳來的參數版本與當前版本一致,版本號自增1。
    3) 如果put是更新老數據且傳來的參數版本與當前版本不一致,更新失敗,返回VersionError。
    4) put時傳入的version參數為0,則強制更新成功,版本號自增1。

    1.3.5.3 version返回不一致的時候,該如何處理
    如果更新所基于的version和系統中當前的版本不一致,則服務器會返回ResultCode.VERERROR。 這時你可以重新get數據,然后在新版本的數據上修改;或者設置version為0重新請求,以達到強制更新的效果,應用可以根據自身對數據一致性的要求在這兩種策略間進行選擇。

    1.3.5.4 version具體使用案例
    如果應用有10個client會對key進行并發put,那么操作過程如下: 
    1) get key。如果get key成功,則進入步驟2;如果數據不存在,則進入步驟3. 
    2) 在調用put的時候將get key返回的verison重新傳入put接口。服務端根據version是否匹配來返回client是否put成功。 
    3) get key數據不存在,則新put數據。此時傳入的version必須不是0和1,其他的值都可以(例如1000,要保證所有client是一套邏輯)。因為傳入0,tair會認為強制覆蓋;而傳入1,第一個client寫入會成功,但是新寫入時服務端的version以0開始計數啊,所以此時version也是1,所以下一個到來的client寫入也會成功,這樣造成了沖突

    1.3.5.5 version分布式鎖
    Tair中存在該key,則認為該key所代表的鎖已被lock;不存在該key,在未加鎖。操作過程和上面相似。業務方可以在put的時候增加expire,已避免該鎖被長期鎖住。
    當然業務方在選擇這種策略的情況下需要考慮并處理Tair宕機帶來的鎖丟失的情況。

    1.3.5.6 什么情況下需要使用version
    業務對數據一致性有較高的要求,并且訪問并發高,那么通過version可以避免數據的意外結果。
    如果不關心并發,那么建議不傳入version或者直接傳0。

    1.4 集群部署方式

    Tair通過多種集群部署方式,來滿足各類應用的容災需求。
    下面所述的雙機房可以擴展到多機房,現階段基本還是采用的雙機房。
    現總共有4種方式:
    mdb存儲引擎適用于雙機房單集群單份,雙機房獨立集群,雙機房單集群雙份。
    rdb存儲引擎適用于雙機房單集群單份。
    ldb存儲引擎適用于雙機房主備集群,雙機房單集群單份。

    1.4.1 雙機房單集群單份

    雙機房單集群單備份數是指,該Tair集群部署在兩個機房中(也就是該Tair集群的機器分別在兩個機房), 數據存儲份數為1, 該類型集群部署示意圖如下所示。數據服務器(Dataserver)分布在兩個機房中,他們都屬于同一集群。

    使用場景:
    1) 后端有無數據源都可。
    2) 后端有數據源,且更新比例很高的場景。
    優點:
    1) 服務器存在于雙機房,任一機房宕機保持可用。
    2) 單份數據,無論應用在哪個機房,看到的都是同一個數據。
    缺點:
    1) 應用服務器會跨機房訪問。如上圖,并假設應用服務器在cm3和cm4,那么cm3的應用服務器也可能調用到cm4的tair機器,cm4的亦然。
    2) 當一邊機房出現故障時,tair中的數據會失效一半(一半這個數值是按兩邊機房tair機器數相同估計的,如果不相同,則按對應比例估算)
    該部署方式,應用在刪除數據時,只需要調用delete即可,無需調用invalid。當然,調用invalid也可,這種方式下會直接退化到delete。

    1.4.2 雙機房獨立集群

    雙機房獨立集群是指,在兩個機房中同時部署2個獨立的Tair集群,這兩個集群沒有直接關系。下圖是一個典型的雙機房獨立集部署示意圖,可以看到,cm3和cm4各有一個完整的tair集群(2個configserver+多個dataserver)。圖中還多了一個invalidserver的角色, invalidserver接收客戶端的invalid或者hide請求后,會對各機房內的集群進行delete或者hide操作,以此保障Tair中的數據和后端數據源保持一致的。

    適用場景:
    1) 后端必須要有數據源,否則則退化成單機房集群,Tair集群本身不做同步。
    2) 讀寫比不能過小,不然可能會帶來Tair命中率降低。例如某個key,在數據庫中被頻繁更新,那么此時應用必須調用invalid來確保Tair和DB的一致性。此時應用讀Tair一直會不命中,導致整體命中率低,可能造成DB壓力比較大。 如果依然有疑問的話,請聯系 tair答疑。
    優點:
    1) 每個機房擁有獨立Tair集群,應用在哪個機房就訪問相同機房的Tair集群,不會出現跨機房調用和流量。
    2) 單邊機房故障,不會影響業務訪問tair命中率。
    缺點:
    1) 后端必須要有數據源,也就是這種部署方式下,Tair必然是當作傳統意義上的cache存在的。因為Tair mdb集群之間本身不會做數據同步,多集群間一致性保證依賴于后端數據源,如DB。
    2) 當后端數據源數據發生更新后,業務不能直接把數據put到Tair,而是先需要調用invalid接口來失效這些對等集群中的數據(來保持各Tair集群的數據和后端數據源的一致性)。之后業務可以把數據put到當前Tair集群(注意:只會put到本機房的Tair集群,不會put到對端集群)或者在讀Tair時發生not exist的時候從后端數據源取來放入Tair。

    1.4.3 雙機房單集群雙份

    雙機房單集群雙份,是指一個Tair集群部署在2個機房中,數據保存2份,并且同一數據的2個備份不會放在同一個數據服務器上。根據數據分布策略的不同,還可以將同一份數據的不同備份分布到不同的機房上。該類型的集群部署方式與雙機房單集群單份數據的部署方式一樣。其不同之處,數據保存份數不一樣。該類型集群部署方式示意圖如下圖所示,數據服務器分別部署在兩個不同的機房里,所有的數據服務器都被相同的配置服務器管理,在邏輯上,他們構成一個獨立的集群。

    現只有tbsession集群使用了這種部署方式。
    適用場景:
    后端無數據源,臨時數據的存放,非cache。
    cache類應用推薦使用雙機房獨立集群和雙機房單集群單份部署方式。
    優點:
    1) 數據存放兩份,數據安全性有一定保障。但由于存儲引擎是mdb,數據存放在內存中,無法絕對保證數據不丟失。
    2) 當一邊機房故障時,另外一邊機房依然可以服務,并且數據不丟失。
    缺點:
    1) 如果機房間網絡出現異常情況,依然有較小幾率丟失數據。

    1.4.4 雙機房主備集群

    這種部署方式中,存在一個主集群和一個備份集群,分別在兩個機房中。如下圖所示,不妨假設CM3中部署的是主集群,CM4中部署的是備份集群。那么,在正常情況下,用戶只使用主集群,讀寫數據都與主集群交互。主備集群會自動同步數據(不需要業務去更新兩邊),保證兩個機房數據的最終一致性。當一個機房發生故障后,備集群會自動切換成主集群,提供服務,保證系統可用性。

    適用場景:
    該方式只在ldb存儲引擎中存在,也就是業務將Tair當作最終存儲使用。我們會在當前主集群存兩份數據,并由Tair異步將數據更新到備集群,確保數據安全和服務可用。
    優點:
    1) 數據安全和服務可用性高。
    2) 用戶調用方便,無需考慮多集群間數據一致性的問題。

    posted @ 2013-06-25 11:58 小馬歌 閱讀(407) | 評論 (0)編輯 收藏
     
     相對于SOCKET開發者,TCP創建過程和鏈接折除過程是由TCP/IP協議棧自動創建的.因此開發者并不需要控制這個過程.但是對于理解TCP底層運作機制,相當有幫助.
     
       而且對于有網絡協議工程師之類筆試,幾乎是必考的內容.企業對這個問題熱情之高,出乎我的意料:-)。有時上午面試前強調這個問題,并重復講一次,下午幾乎每一個人都被問到這個問題。
     
    因此在這里詳細解釋一下這兩個過程。
     
    TCP三次握手
     
    所謂三次握手(Three-way Handshake),是指建立一個TCP連接時,需要客戶端和服務器總共發送3個包。
     
    三次握手的目的是連接服務器指定端口,建立TCP連接,并同步連接雙方的序列號和確認號并交換 TCP 窗口大小信息.在socket編程中,客戶端執行connect()時。將觸發三次握手。
     
     
     
     
    • 第一次握手:
      客戶端發送一個TCP的SYN標志位置1的包指明客戶打算連接的服務器的端口,以及初始序號X,保存在包頭的序列號(Sequence Number)字段里。
    • 第二次握手:
      服務器發回確認包(ACK)應答。即SYN標志位和ACK標志位均為1同時,將確認序號(Acknowledgement Number)設置為客戶的I S N加1以.即X+1。

     

    • 第三次握手.
      客戶端再次發送確認包(ACK) SYN標志位為0,ACK標志位為1.并且把服務器發來ACK的序號字段+1,放在確定字段中發送給對方.并且在數據段放寫ISN的+1

    SYN攻擊

       在三次握手過程中,服務器發送SYN-ACK之后,收到客戶端的ACK之前的TCP連接稱為半連接(half-open connect).此時服務器處于Syn_RECV狀態.當收到ACK后,服務器轉入ESTABLISHED狀態.

      Syn攻擊就是 攻擊客戶端 在短時間內偽造大量不存在的IP地址,向服務器不斷地發送syn包,服務器回復確認包,并等待客戶的確認,由于源地址是不存在的,服務器需要不斷的重發直 至超時,這些偽造的SYN包將長時間占用未連接隊列,正常的SYN請求被丟棄,目標系統運行緩慢,嚴重者引起網絡堵塞甚至系統癱瘓。

     Syn攻擊是一個典型的DDOS攻擊。檢測SYN攻擊非常的方便,當你在服務器上看到大量的半連接狀態時,特別是源IP地址是隨機的,基本上可以斷定這是一次SYN攻擊.在Linux下可以如下命令檢測是否被Syn攻擊

    netstat -n -p TCP | grep SYN_RECV

    一般較新的TCP/IP協議棧都對這一過程進行修正來防范Syn攻擊,修改tcp協議實現。主要方法有SynAttackProtect保護機制、SYN cookies技術、增加最大半連接和縮短超時時間等.

    但是不能完全防范syn攻擊。

    TCP 四次揮手

    TCP的連接的拆除需要發送四個包,因此稱為四次揮手(four-way handshake)。客戶端或服務器均可主動發起揮手動作,在socket編程中,任何一方執行close()操作即可產生揮手操作。

     

     

     

    參見wireshark抓包,實測的抓包結果并沒有嚴格按揮手時序。我估計是時間間隔太短造成。

    source url:http://bluedrum.cublog.cn


    TCP狀態變遷圖及狀態說明

    狀態:描述
    CLOSED:無連接是活動的或正在進行
    LISTEN:服務器在等待進入呼叫
    SYN_RECV:一個連接請求已經到達,等待確認
    SYN_SENT:應用已經開始,打開一個連接
    ESTABLISHED:正常數據傳輸狀態
    FIN_WAIT1:應用說它已經完成
    FIN_WAIT2:另一邊已同意釋放
    ITMED_WAIT:等待所有分組死掉
    CLOSING:兩邊同時嘗試關閉
    TIME_WAIT:另一邊已初始化一個釋放
    LAST_ACK:等待所有分組死掉
    posted @ 2013-06-24 16:33 小馬歌 閱讀(372) | 評論 (0)編輯 收藏
    僅列出標題
    共95頁: First 上一頁 25 26 27 28 29 30 31 32 33 下一頁 Last 
     
    主站蜘蛛池模板: 亚洲AV色香蕉一区二区| 久久久久国色av免费看| 亚洲成人免费网址| 亚洲成AV人在线观看天堂无码| 无码人妻精品一二三区免费| 亚洲日韩乱码中文无码蜜桃臀网站| 免费无码又黄又爽又刺激| 十九岁在线观看免费完整版电影| 久青草国产免费观看| 美女被免费网站视频在线| 亚洲 欧洲 日韩 综合在线| 亚洲黄色在线观看网站| 亚洲日韩精品一区二区三区| 四只虎免费永久观看| 免费看黄的成人APP| 亚洲香蕉在线观看| 亚洲精品成人片在线观看| 日本高清免费观看| 国产高潮流白浆喷水免费A片 | 午夜免费福利小电影| jizz在线免费观看| 特级毛片A级毛片100免费播放| 亚洲精品无码久久久久久| 中文字幕亚洲综合久久综合| 亚洲另类古典武侠| 精品亚洲国产成人| 亚洲自国产拍揄拍| 亚洲日产乱码一二三区别| 亚洲精品国产首次亮相| 亚洲色无码一区二区三区| 免费又黄又硬又爽大片| 亚洲AⅤ无码一区二区三区在线| 日产乱码一卡二卡三免费| 国产麻豆免费观看91| 免费的黄色网页在线免费观看| 亚洲日本天堂在线| 亚洲爆乳少妇无码激情| 久久亚洲中文字幕无码| 国产精品亚洲一区二区三区久久 | 中文毛片无遮挡高潮免费| 91制片厂制作传媒免费版樱花|