ivaneeo's blog

          自由的力量,自由的生活。

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

          #

          roundrobin  Each server is used in turns, according to their weights.
                           This is the smoothest and fairest algorithm when the server's
                           processing time remains equally distributed. This algorithm
                           is dynamic, which means that server weights may be adjusted
                           on the fly for slow starts for instance. It is limited by
                           design to 4128 active servers per backend. Note that in some
                           large farms, when a server becomes up after having been down
                           for a very short time, it may sometimes take a few hundreds
                           requests for it to be re-integrated into the farm and start
                           receiving traffic. This is normal, though very rare. It is
                           indicated here in case you would have the chance to observe
                           it, so that you don't worry.

                           roundrobin:每個server根據權重依次被輪詢,

          這個算法是動態的,意味著
                           server的權重可以實時地被調整。對于每個haproxy的backend servers的數目
                           而言被限制在4128個活躍數目之內。


               static-rr   Each server is used in turns, according to their weights.
                           This algorithm is as similar to roundrobin except that it is
                           static, which means that changing a server's weight on the
                           fly will have no effect. On the other hand, it has no design
                           limitation on the number of servers, and when a server goes
                           up, it is always immediately reintroduced into the farm, once
                           the full map is recomputed. It also uses slightly less CPU to
                           run (around -1%).
                           靜態roundrobin(static-rr):跟roundrobin類似,唯一的區別是不可以動態實時
                           server權重和backend 的server數目沒有上限。

               leastconn   The server with the lowest number of connections receives the
                           connection. Round-robin is performed within groups of servers
                           of the same load to ensure that all servers will be used. Use
                           of this algorithm is recommended where very long sessions are
                           expected, such as LDAP, SQL, TSE, etc... but is not very well
                           suited for protocols using short sessions such as HTTP. This
                           algorithm is dynamic, which means that server weights may be
                           adjusted on the fly for slow starts for instance.
                           最小連接數目負載均衡策略(leastconn):round-robin適合于各個server負載相同的情況。
                           最小連接數目算法適合于長時間會話,如LDAP,SQL,TSE,但是并不適合于HTTP短連接的協議。

               source      The source IP address is hashed and divided by the total
                           weight of the running servers to designate which server will
                           receive the request. This ensures that the same client IP
                           address will always reach the same server as long as no
                           server goes down or up. If the hash result changes due to the
                           number of running servers changing, many clients will be
                           directed to a different server. This algorithm is generally
                           used in TCP mode where no cookie may be inserted. It may also
                           be used on the Internet to provide a best-effort stickiness
                           to clients which refuse session cookies. This algorithm is
                           static by default, which means that changing a server's
                           weight on the fly will have no effect, but this can be
                           changed using "hash-type".
                           源IP hash散列調度:將源ip地址進行hash,再根據hasn求?;蛘咭恢滦詇ash定位到
                           hash表中的server上。相同的ip地址的請求被分發到同一個server上。但當server的數量變化時,
                           來自于同一client的請求可能會被分發到不同的server上。這個算法通常用在沒有cookie的tcp模式下。

               uri         The left part of the URI (before the question mark) is hashed
                           and divided by the total weight of the running servers. The
                           result designates which server will receive the request. This
                           ensures that a same URI will always be directed to the same
                           server as long as no server goes up or down. This is used
                           with proxy caches and anti-virus proxies in order to maximize
                           the cache hit rate. Note that this algorithm may only be used
                           in an HTTP backend. This algorithm is static by default,
                           which means that changing a server's weight on the fly will
                           have no effect, but this can be changed using "hash-type".

                           This algorithm support two optional parameters "len" and
                           "depth", both followed by a positive integer number. These
                           options may be helpful when it is needed to balance servers
                           based on the beginning of the URI only. The "len" parameter
                           indicates that the algorithm should only consider that many
                           characters at the beginning of the URI to compute the hash.
                           Note that having "len" set to 1 rarely makes sense since most
                           URIs start with a leading "/".

                           The "depth" parameter indicates the maximum directory depth
                           to be used to compute the hash. One level is counted for each
                           slash in the request. If both parameters are specified, the
                           evaluation stops when either is reached.

               url_param   The URL parameter specified in argument will be looked up in
                           the query string of each HTTP GET request.

                           If the modifier "check_post" is used, then an HTTP POST
                           request entity will be searched for the parameter argument,
                           when it is not found in a query string after a question mark
                           ('?') in the URL. Optionally, specify a number of octets to
                           wait for before attempting to search the message body. If the
                           entity can not be searched, then round robin is used for each
                           request. For instance, if your clients always send the LB
                           parameter in the first 128 bytes, then specify that. The
                           default is 48. The entity data will not be scanned until the
                           required number of octets have arrived at the gateway, this
                           is the minimum of: (default/max_wait, Content-Length or first
                           chunk length). If Content-Length is missing or zero, it does
                           not need to wait for more data than the client promised to
                           send. When Content-Length is present and larger than
                           <max_wait>, then waiting is limited to <max_wait> and it is
                           assumed that this will be enough data to search for the
                           presence of the parameter. In the unlikely event that
                           Transfer-Encoding: chunked is used, only the first chunk is
                           scanned. Parameter values separated by a chunk boundary, may
                           be randomly balanced if at all.

                           If the parameter is found followed by an equal sign ('=') and
                           a value, then the value is hashed and divided by the total
                           weight of the running servers. The result designates which
                           server will receive the request.

                           This is used to track user identifiers in requests and ensure
                           that a same user ID will always be sent to the same server as
                           long as no server goes up or down. If no value is found or if
                           the parameter is not found, then a round robin algorithm is
                           applied. Note that this algorithm may only be used in an HTTP
                           backend. This algorithm is static by default, which means
                           that changing a server's weight on the fly will have no
                           effect, but this can be changed using "hash-type".

               hdr(name)   The HTTP header <name> will be looked up in each HTTP request.
                           Just as with the equivalent ACL 'hdr()' function, the header
                           name in parenthesis is not case sensitive. If the header is
                           absent or if it does not contain any value, the roundrobin
                           algorithm is applied instead.

                           An optional 'use_domain_only' parameter is available, for
                           reducing the hash algorithm to the main domain part with some
                           specific headers such as 'Host'. For instance, in the Host
                           value "
                           This algorithm is static by default, which means that
                           changing a server's weight on the fly will have no effect,
                           but this can be changed using "hash-type".

               rdp-cookie
               rdp-cookie(name)
                           The RDP cookie <name> (or "mstshash" if omitted) will be
                           looked up and hashed for each incoming TCP request. Just as
                           with the equivalent ACL 'req_rdp_cookie()' function, the name
                           is not case-sensitive. This mechanism is useful as a degraded
                           persistence mode, as it makes it possible to always send the
                           same user (or the same session ID) to the same server. If the
                           cookie is not found, the normal roundrobin algorithm is
                           used instead.

                           Note that for this to work, the frontend must ensure that an
                           RDP cookie is already present in the request buffer. For this
                           you must use 'tcp-request content accept' rule combined with
                           a 'req_rdp_cookie_cnt' ACL.

                           This algorithm is static by default, which means that
                           changing a server's weight on the fly will have no effect,
                           but this can be changed us

          1.安裝mariadb on ubuntu
          http://blog.secaserver.com/2013/07/install-mariadb-galera-cluster-ubuntu/

          3 在服務器上用mysql -h 192.168.0.1 -u root -p mysql命令登錄mysql數據庫

          然后用grant命令下放權限。

          GRANT ALL PRIVILEGES ON *.* TO root@localhost IDENTIFIED BY 'root-password' WITH GRANT OPTION;

          GRANT ALL PRIVILEGES ON *.* TO root@127.0.0.1 IDENTIFIED BY 'root-password' WITH GRANT OPTION;

          GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY 'root-password' WITH GRANT OPTION;

          例如:
          GRANT   ALL   PRIVILEGES   ON   *.*   TO   root@'%'   identified   by   '123456'  

          注意:自己根據情況修改以上命令中的 “用戶”“ip地址”“密碼”。 

          2 安裝和配置haproxy
          option mysql-check [ user <username> ]   
          USE mysql; INSERT INTO user (Host,User) values ('<ip_of_haproxy>','<username>'); FLUSH PRIVILEGESheck

          only consists in parsing the Mysql Handshake Initialisation packet or Error packet, we don't send anything in this mode. It was reported that it can generate lockout if check is too frequent and/or if there is not enough traffic. In fact, you need in this case to check MySQL "max_connect_errors" value as if a connection is established successfully within fewer than MySQL "max_connect_errors" attempts after a previous connection was interrupted, the error count for the host is cleared to zero. If HAProxy's server get blocked, the "FLUSH HOSTS" statement is the only way to unblock it.

          配置:
          # this config needs haproxy-1.1.28 or haproxy-1.2.1 global
          log 127.0.0.1
          local0 info
          #日志相關
          log 127.0.0.1
          local1 notice
          maxconn 4096
          daemon
          #debug
          #quiet defaults
          log global mode http #option httplog option dontlognull retries 3 option redispatch maxconn 2000 contimeout 5000 clitimeout 50000 srvtimeout 50000 listen mysql bind 0.0.0.0:3333 #代理端口 mode tcp #模式 TCP option mysql-check user haproxy #mysql健康檢查 root為mysql登錄用戶名 balance roundrobin #調度算法 server mysql1 172.20.21.1:3306 weight 1 check inter 1s rise 2 fall 2 server mysql2 172.20.21.2:3306 weight 1 check inter 1s rise 2 fall 2 server mysql3 172.20.21.3:3306 weight 1 check inter 1s rise 2 fall 2 listen stats :1936 mode http stats enable stats hide-version stats realm Haproxy\ Statistics stats uri / stats auth admin:admin
          posted @ 2013-12-22 02:57 ivaneeo 閱讀(1257) | 評論 (0)編輯 收藏

          如何安裝RabbitMQ Cluster


          建立測試環境與測試系統總是最花時間的,趁著今天重新安裝一組RabbitMQ 的測試環境,把所有的步驟和順序都整理起來吧。

          安裝RabbitMQ

          Our APT repository

          To use our APT repository:

          1. Add the following line to your /etc/apt/sources.list:
            deb http://www.rabbitmq.com/debian/ testing main
            (Please note that the word testing in this line refers to the state of our release of RabbitMQ, not any particular Debian distribution. You can use it with Debian stable, testing or unstable, as well as with Ubuntu. We describe the release as "testing" to emphasise that we release somewhat frequently.)
          2. (optional) To avoid warnings about unsigned packages, add our public key to your trusted key list using apt-key(8):
            wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc sudo apt-key add rabbitmq-signing-key-public.asc
          3. Run apt-get update.
          4. Install packages as usual; for instance,
            sudo apt-get install rabbitmq-server


          設定Cluster


          最簡易的方法就是先啟動,cluster master node產生 /var/lib/rabbitmq/.erlang.cookie 這份文件,然後再把這份文件copy 到 每一個cluster node鄉對應的目錄下面去,接下來就參考RabbitMQ - create cluster這份文件,範例事先建立3臺的cluster。
           
          1. 啟動每臺rabbitMQ
          # rabbit1$ rabbitmq-server -detached
          # rabbit2$ rabbitmq-server -detached
          # rabbit3$ rabbitmq-server -detached

          2. 確認每一臺rabbitmq 是否是standalone狀態

          # rabbit1$ rabbitmqctl cluster_status
          Cluster status of node rabbit@rabbit1 ...
          [{nodes,[{disc,[rabbit@rabbit1]}]},{running_nodes,[rabbit@rabbit1]}]
          ...done.
          # rabbit2$ rabbitmqctl cluster_status
          Cluster status of node rabbit@rabbit2 ...
          [{nodes,[{disc,[rabbit@rabbit2]}]},{running_nodes,[rabbit@rabbit2]}]
          ...done.
          # rabbit3$ rabbitmqctl cluster_status
          Cluster status of node rabbit@rabbit3 ...
          [{nodes,[{disc,[rabbit@rabbit3]}]},{running_nodes,[rabbit@rabbit3]}]
          ...done.

          3. 依序加入cluster

          rabbit2$ rabbitmqctl stop_app
          Stopping node rabbit@rabbit2 ...done.
          rabbit2$ rabbitmqctl reset
          Resetting node rabbit@rabbit2 ...done.
          rabbit2$ rabbitmqctl cluster rabbit@rabbit1
          Clustering node rabbit@rabbit2 with [rabbit@rabbit1] ...done.
          rabbit2$ rabbitmqctl start_app
          Starting node rabbit@rabbit2 ...done. 


          4. 確認cluster status是否正確加入

          rabbit1$ rabbitmqctl cluster_status
          Cluster status of node rabbit@rabbit1 ...
          [{nodes,[{disc,[rabbit@rabbit1]},{ram,[rabbit@rabbit2]}]},
          {running_nodes,[rabbit@rabbit2,rabbit@rabbit1]}]
          ...done.
          rabbit2$ rabbitmqctl cluster_status
          Cluster status of node rabbit@rabbit2 ...
          [{nodes,[{disc,[rabbit@rabbit1]},{ram,[rabbit@rabbit2]}]},
          {running_nodes,[rabbit@rabbit1,rabbit@rabbit2]}]
          ...done.


          設定Web Management Plugin


          參考 rabbitmq - Management Plugin,重點是要在Cluster node的每一臺都要安裝這個plugin
          # rabbitmq-plugins enable rabbitmq_management 
          安裝好以後,要記得重啟服務
          # service rabbitmq-server restart

          設定好就可以連到http://server-name:55672/#/ 看看web 介面有沒有起來,預設的帳號密碼都是guest,如果是內部測試那還沒關係,如果是要連到外面,一定記得要改帳號密碼和permission。


          設定帳號


          最後我們可以設定一個vhost 以及這個vhost的帳號密碼和權限

          #rabbitmqctl add_vhost /demo
          #rabbitmqctl add_user demo mypass
          #rabbitmqctl set_permissions -p /demo demo ".*" ".*" ".*"

          啟動HAProxy
          /etc/default/haproxy
          # Set ENABLED to 1 if you want the init script to start haproxy.
          ENABLED=1

          啟動日志
          /etc/rsyslog.d

          添加文件haproxy.conf:
          $ModLoad imudp
          $UDPServerRun 514

          local0.*                        -/var/log/haproxy-0.log
          local1.*                        -/var/log/haproxy-1.log

          HAProxy配置
          # this config needs haproxy-1.1.28 or haproxy-1.2.1

          global
                  log 127.0.0.1   local0
                  log 127.0.0.1   local1 notice
                  #log loghost    local0 info
                  maxconn 4096
                  #chroot /usr/share/haproxy
                  user haproxy
                  group haproxy
                  daemon
                  #debug
                  #quiet

          defaults
                  log     global
                  mode    tcp
                  option  tcplog
                  option  dontlognull
                  retries 3
                  option redispatch
                  maxconn 2000
                  contimeout      5000
                  clitimeout      50000
                  srvtimeout      50000

          listen rabbitmq_cluster 0.0.0.0:5678
                 mode tcp
                 balance roundrobin
                 server   rabbit65 192.168.1.200:5672 check inter 2000 rise 2 fall 3
                 server   rabbit66 192.168.1.201:5672 check inter 2000 rise 2 fall 3
          listen stats :1936
              mode http
              stats enable
              stats hide-version
              stats realm Haproxy\ Statistics
              stats uri /
              stats auth admin:admin
          posted @ 2013-12-16 19:11 ivaneeo 閱讀(552) | 評論 (0)編輯 收藏

           Linux下高并發socket最大連接數所受的限制問題

            1、修改用戶進程可打開文件數限制

            在Linux平臺上,無論編寫客戶端程序還是服務端程序,在進行高并發TCP連接處理時,最高的并發數量都要受到系統對用戶單一進程同時可打開文件數量的限制(這是因為系統為每個TCP連接都要創建一個socket句柄,每個socket句柄同時也是一個文件句柄)??墒褂胾limit命令查看系統允許當前用戶進程打開的文件數限制:

            [speng@as4 ~]$ ulimit -n

            1024

            這表示當前用戶的每個進程最多允許同時打開1024個文件,這1024個文件中還得除去每個進程必然打開的標準輸入,標準輸出,標準錯誤,服務器監聽 socket,進程間通訊的unix域socket等文件,那么剩下的可用于客戶端socket連接的文件數就只有大概1024-10=1014個左右。也就是說缺省情況下,基于Linux的通訊程序最多允許同時1014個TCP并發連接。

            對于想支持更高數量的TCP并發連接的通訊處理程序,就必須修改Linux對當前用戶的進程同時打開的文件數量的軟限制(soft limit)和硬限制(hardlimit)。其中軟限制是指Linux在當前系統能夠承受的范圍內進一步限制用戶同時打開的文件數;硬限制則是根據系統硬件資源狀況(主要是系統內存)計算出來的系統最多可同時打開的文件數量。通常軟限制小于或等于硬限制。

            修改上述限制的最簡單的辦法就是使用ulimit命令:

            [speng@as4 ~]$ ulimit -n

            上述命令中,在中指定要設置的單一進程允許打開的最大文件數。如果系統回顯類似于"Operation notpermitted"之類的話,說明上述限制修改失敗,實際上是因為在中指定的數值超過了Linux系統對該用戶打開文件數的軟限制或硬限制。因此,就需要修改Linux系統對用戶的關于打開文件數的軟限制和硬限制。

            第一步,修改/etc/security/limits.conf文件,在文件中添加如下行:

            speng soft nofile 10240

            speng hard nofile 10240

            其中speng指定了要修改哪個用戶的打開文件數限制,可用'*'號表示修改所有用戶的限制;

            soft或hard指定要修改軟限制還是硬限制;10240則指定了想要修改的新的限制值,即最大打開文件數(請注意軟限制值要小于或等于硬限制)。修改完后保存文件。

            第二步,修改/etc/pam.d/login文件,在文件中添加如下行:

            session required /lib/security/pam_limits.so 這是告訴Linux在用戶完成系統登錄后,應該調用pam_limits.so模塊來設置系統對該用戶可使用的各種資源數量的最大限制(包括用戶可打開的最大文件數限制),而pam_limits.so模塊就會從/etc/security/limits.conf文件中讀取配置來設置這些限制值。修改完后保存此文件。

            第三步,查看Linux系統級的最大打開文件數限制,使用如下命令:

            [speng@as4 ~]$ cat /proc/sys/fs/file-max

            12158

            這表明這臺Linux系統最多允許同時打開(即包含所有用戶打開文件數總和)12158個文件,是Linux系統級硬限制,所有用戶級的打開文件數限制都不應超過這個數值。通常這個系統級硬限制是Linux系統在啟動時根據系統硬件資源狀況計算出來的最佳的最大同時打開文件數限制,如果沒有特殊需要,不應該修改此限制,除非想為用戶級打開文件數限制設置超過此限制的值。

            修改此硬限制的方法是修改/etc/rc.local腳本,在腳本中添加如下行:

            echo 22158 > /proc/sys/fs/file-max

            這是讓Linux在啟動完成后強行將系統級打開文件數硬限制設置為22158.修改完后保存此文件。

            完成上述步驟后重啟系統,一般情況下就可以將Linux系統對指定用戶的單一進程允許同時打開的最大文件數限制設為指定的數值。如果重啟后用 ulimit-n命令查看用戶可打開文件數限制仍然低于上述步驟中設置的最大值,這可能是因為在用戶登錄腳本/etc/profile中使用ulimit -n命令已經將用戶可同時打開的文件數做了限制。由于通過ulimit-n修改系統對用戶可同時打開文件的最大數限制時,新修改的值只能小于或等于上次 ulimit-n設置的值,因此想用此命令增大這個限制值是不可能的。

            所以,如果有上述問題存在,就只能去打開/etc/profile腳本文件,在文件中查找是否使用了ulimit-n限制了用戶可同時打開的最大文件數量,如果找到,則刪除這行命令,或者將其設置的值改為合適的值,然后保存文件,用戶退出并重新登錄系統即可。 通過上述步驟,就為支持高并發TCP連接處理的通訊處理程序解除關于打開文件數量方面的系統限制。

            2、修改網絡內核對TCP連接的有關限制

            在Linux上編寫支持高并發TCP連接的客戶端通訊處理程序時,有時會發現盡管已經解除了系統對用戶同時打開文件數的限制,但仍會出現并發TCP連接數增加到一定數量時,再也無法成功建立新的TCP連接的現象。出現這種現在的原因有多種。

            第一種原因可能是因為Linux網絡內核對本地端口號范圍有限制。此時,進一步分析為什么無法建立TCP連接,會發現問題出在connect()調用返回失敗,查看系統錯誤提示消息是"Can't assign requestedaddress".同時,如果在此時用tcpdump工具監視網絡,會發現根本沒有TCP連接時客戶端發SYN包的網絡流量。這些情況說明問題在于本地Linux系統內核中有限制。

            其實,問題的根本原因在于Linux內核的TCP/IP協議實現模塊對系統中所有的客戶端TCP連接對應的本地端口號的范圍進行了限制(例如,內核限制本地端口號的范圍為1024~32768之間)。當系統中某一時刻同時存在太多的TCP客戶端連接時,由于每個TCP客戶端連接都要占用一個唯一的本地端口號(此端口號在系統的本地端口號范圍限制中),如果現有的TCP客戶端連接已將所有的本地端口號占滿,則此時就無法為新的TCP客戶端連接分配一個本地端口號了,因此系統會在這種情況下在connect()調用中返回失敗,并將錯誤提示消息設為"Can't assignrequested address".

            有關這些控制邏輯可以查看Linux內核源代碼,以linux2.6內核為例,可以查看tcp_ipv4.c文件中如下函數:

            static int tcp_v4_hash_connect(struct sock *sk)

            請注意上述函數中對變量sysctl_local_port_range的訪問控制。變量sysctl_local_port_range的初始化則是在tcp.c文件中的如下函數中設置:

            void __init tcp_init(void)

            內核編譯時默認設置的本地端口號范圍可能太小,因此需要修改此本地端口范圍限制。

            第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:

            net.ipv4.ip_local_port_range = 1024 65000

            這表明將系統對本地端口范圍限制設置為1024~65000之間。請注意,本地端口范圍的最小值必須大于或等于1024;而端口范圍的最大值則應小于或等于65535.修改完后保存此文件。

            第二步,執行sysctl命令:

            [speng@as4 ~]$ sysctl -p

            如果系統沒有錯誤提示,就表明新的本地端口范圍設置成功。如果按上述端口范圍進行設置,則理論上單獨一個進程最多可以同時建立60000多個TCP客戶端連接。

            第二種無法建立TCP連接的原因可能是因為Linux網絡內核的IP_TABLE防火墻對最大跟蹤的TCP連接數有限制。此時程序會表現為在 connect()調用中阻塞,如同死機,如果用tcpdump工具監視網絡,也會發現根本沒有TCP連接時客戶端發SYN包的網絡流量。由于 IP_TABLE防火墻在內核中會對每個TCP連接的狀態進行跟蹤,跟蹤信息將會放在位于內核內存中的conntrackdatabase中,這個數據庫的大小有限,當系統中存在過多的TCP連接時,數據庫容量不足,IP_TABLE無法為新的TCP連接建立跟蹤信息,于是表現為在connect()調用中阻塞。此時就必須修改內核對最大跟蹤的TCP連接數的限制,方法同修改內核對本地端口號范圍的限制是類似的:

            第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:

            net.ipv4.ip_conntrack_max = 10240

            這表明將系統對最大跟蹤的TCP連接數限制設置為10240.請注意,此限制值要盡量小,以節省對內核內存的占用。

            第二步,執行sysctl命令:

            [speng@as4 ~]$ sysctl -p

            如果系統沒有錯誤提示,就表明系統對新的最大跟蹤的TCP連接數限制修改成功。如果按上述參數進行設置,則理論上單獨一個進程最多可以同時建立10000多個TCP客戶端連接。

            3、使用支持高并發網絡I/O的編程技術在Linux上編寫高并發TCP連接應用程序時,必須使用合適的網絡I/O技術和I/O事件分派機制??捎玫腎/O技術有同步I/O,非阻塞式同步I/O(也稱反應式I/O),以及異步I/O.在高TCP并發的情形下,如果使用同步I/O,這會嚴重阻塞程序的運轉,除非為每個TCP連接的I/O創建一個線程。

            但是,過多的線程又會因系統對線程的調度造成巨大開銷。因此,在高TCP并發的情形下使用同步 I/O是不可取的,這時可以考慮使用非阻塞式同步I/O或異步I/O.非阻塞式同步I/O的技術包括使用select(),poll(),epoll等機制。異步I/O的技術就是使用AIO.

            從I/O事件分派機制來看,使用select()是不合適的,因為它所支持的并發連接數有限(通常在1024個以內)。如果考慮性能,poll()也是不合適的,盡管它可以支持的較高的TCP并發數,但是由于其采用"輪詢"機制,當并發數較高時,其運行效率相當低,并可能存在I/O事件分派不均,導致部分TCP連接上的I/O出現"饑餓"現象。而如果使用epoll或AIO,則沒有上述問題(早期Linux內核的AIO技術實現是通過在內核中為每個 I/O請求創建一個線程來實現的,這種實現機制在高并發TCP連接的情形下使用其實也有嚴重的性能問題。但在最新的Linux內核中,AIO的實現已經得到改進)。

            綜上所述,在開發支持高并發TCP連接的Linux應用程序時,應盡量使用epoll或AIO技術來實現并發的TCP連接上的I/O控制,這將為提升程序對高并發TCP連接的支持提供有效的I/O保證。

            內核參數sysctl.conf的優化

            /etc/sysctl.conf 是用來控制linux網絡的配置文件,對于依賴網絡的程序(如web服務器和cache服務器)非常重要,RHEL默認提供的最好調整。

            推薦配置(把原/etc/sysctl.conf內容清掉,把下面內容復制進去):

            net.ipv4.ip_local_port_range = 1024 65536

            net.core.rmem_max=16777216

            net.core.wmem_max=16777216

            net.ipv4.tcp_rmem=4096 87380 16777216

            net.ipv4.tcp_wmem=4096 65536 16777216

            net.ipv4.tcp_fin_timeout = 10

            net.ipv4.tcp_tw_recycle = 1

            net.ipv4.tcp_timestamps = 0

            net.ipv4.tcp_window_scaling = 0

            net.ipv4.tcp_sack = 0

            net.core.netdev_max_backlog = 30000

            net.ipv4.tcp_no_metrics_save=1

            net.core.somaxconn = 262144

            net.ipv4.tcp_syncookies = 0

            net.ipv4.tcp_max_orphans = 262144

            net.ipv4.tcp_max_syn_backlog = 262144

            net.ipv4.tcp_synack_retries = 2

            net.ipv4.tcp_syn_retries = 2

            這個配置參考于cache服務器varnish的推薦配置和SunOne 服務器系統優化的推薦配置。

            varnish調優推薦配置的地址為:http://varnish.projects.linpro.no/wiki/Performance

            不過varnish推薦的配置是有問題的,實際運行表明"net.ipv4.tcp_fin_timeout = 3"的配置會導致頁面經常打不開;并且當網友使用的是IE6瀏覽器時,訪問網站一段時間后,所有網頁都會

            打不開,重啟瀏覽器后正常。可能是國外的網速快吧,我們國情決定需要調整"net.ipv4.tcp_fin_timeout = 10",在10s的情況下,一切正常(實際運行結論)。

            修改完畢后,執行:

            /sbin/sysctl -p /etc/sysctl.conf

            /sbin/sysctl -w net.ipv4.route.flush=1

            命令生效。為了保險起見,也可以reboot系統。

            調整文件數:

            linux系統優化完網絡必須調高系統允許打開的文件數才能支持大的并發,默認1024是遠遠不夠的。

            執行命令:

            Shell代碼

            echo ulimit -HSn 65536 》 /etc/rc.local

            echo ulimit -HSn 65536 》/root/.bash_profile

            ulimit -HSn 65536

          posted @ 2013-11-15 20:00 ivaneeo 閱讀(516) | 評論 (0)編輯 收藏

          如何設置呢,官方是這樣的:

          第一步:配置/etc/security/limits.conf

          sudo vim /etc/security/limits.conf 文件尾追加  * hard nofile 40960 * soft nofile 40960
          4096可以自己設置,四列參數的設置見英文,簡單講一下:

          第一列,可以是用戶,也可以是組,要用@group這樣的語法,也可以是通配符如*%

          第二列,兩個值:hard,硬限制,soft,軟件限制,一般來說soft要比hard小,hard是底線,決對不能超過,超過soft報警,直到hard數

          第三列,見列表,打開文件數是nofile

          第四列,數量,這個也不能設置太大


          第二步:/etc/pam.d/su(官方)或/etc/pam.d/common-session(網絡)

          sudo vim /etc/pam.d/su 將 pam_limits.so 這一行注釋去掉  重起系統
          sudo vim /etc/pam.d/common-session 加上以下一行 session required pam_limits.so 

          打開/etc/pam.d/su,發現是包含/etc/pam.d/common-session這個文件的,所以修改哪個文件都應該是可以的

          我的修改是在/etc/pam.d/common-session文件中進行的。


          官方只到第二步,就重啟系統了,沒有第三步,好象不行,感覺是不是全是第三步的作用?!

          第三步:配置/etc/profile

          最后一行加上

          ulimit -SHn 40960

          重啟,ulimit -n 驗證,顯示40960就沒問題了


          注意以上三步均是要使用root權限進行修改。

          posted @ 2013-11-15 19:58 ivaneeo 閱讀(3608) | 評論 (0)編輯 收藏

          /etc/sysctl.conf

          net.core.rmem_default = 25696000
          net.core.rmem_max = 25696000
          net.core.wmem_default = 25696000
          net.core.wmem_max = 25696000
          net.ipv4.tcp_timestamps = 0
          net.ipv4.tcp_sack =1
          net.ipv4.tcp_window_scaling = 1

          hotrod方式:
          nohup ./bin/startServer.sh -r hotrod -l 172.20.21.1 -c ./etc/config-samples/distributed-udp.xml -p 11222 &
          posted @ 2013-11-14 17:56 ivaneeo 閱讀(450) | 評論 (0)編輯 收藏

          From a convenience perspective, I want to authenticate as infrequently as possible. However, security requirements suggest that I should be authenticated for all sorts of services. This means that Single Sign On and forwardable authentication credentials would be useful.

          Within an individual organisation at least, it is useful and fairly straightforward to have centralised control for authentication services. More and more authorisation and applications services are able to use centralised authentication services such as Kerberos.

          This document will demonstrate how to configure a machine running OpenSSH server to use GSSAPI so that users can log in if they have authorised kerberos tickets. This is not the place for extensive explanations about tickets or how to set up the Key Distribution Center(KDC) in the first place or how to build or install the necessary software on various different unixlike systems. Likely, your distribution's package management system can provide you with what you need.

          Kerberos

          All destination machines should have /etc/krb5.conf modified to allow forwardable tickets:

          [libdefaults]     default_realm = ALLGOODBITS.ORG     forwardable = TRUE [realms]     ALLGOODBITS.ORG = {                     kdc = kerberos.allgoodbits.org                     } 

          Using kadmin, create a principal for a user:

          kadmin> ank <username>@<REALM> 

          Here the process differs depending upon whether you're using MIT Kerberos (probably) or Heimdal.

          MIT

          Create a principal for the host:

          kadmin> ank -randkey host/<FQDN>@<REALM> 

          Extract the key for the host principal to a keytab file and locate it correctly on the ssh server:

          kadmin> ktadd -k /tmp/<FQDN>.keytab host/<FQDN> 

          Heimdal

          Create a principal for the host:

          kadmin> ank -r host/<FQDN>@<REALM> 

          Extract the key for the host principal to a keytab file and locate it correctly on the ssh server:

          kadmin> ext -k /tmp/<FQDN>.keytab host/<FQDN>@<REALM> 

          SSH

          Then we need to take the keytab file into which you extracted the key for the host principal and copy it to the location on the ssh server where sshd will look for it, probably /etc/krb5.keytab.

          We need to configure sshd_config(5). The important options start with GSSAPI, not to be confused with the Kerberos options which are merely for KDC-validated password authentication; the GSSAPI method allows authentication and login based upon existing tickets. In other words, the "Kerberos" method requires you to enter your password (again), GSSAPI will allow login based on upon the tickets you already have.

          sshd_config:

          GSSAPIAuthentication yes GSSAPICleanupCredentials yes PermitRootLogin without-password 

          ssh_config:

          GSSAPIAuthentication yes GSSAPIDelegateCredentials yes 

          PAM

          Linux Pluggable Authentication Modules(PAM) provide a common framework for authentication/authorisation for applications.

          /etc/pam.d/common-account:

          account sufficient      pam_krb5.so     use_first_pass 

          /etc/pam.d/common-auth:

          auth    sufficient      pam_krb5.so     use_first_pass 

          /etc/pam.d/common-password:

          password        sufficient      pam_krb5.so 

          /etc/pam.d/common-session:

          session optional      pam_krb5.so 

          This is sufficient to allow OpenAFS based home directories because although AFS uses Kerberosv4, MIT Kerberos does 5 to 4 ticket conversion on the fly.

          Troubleshooting

          • As with anything concerned with kerberos, make sure you have NTP and DNS working properly before you even start.
          • ssh -v can give you a lot of valuable information.
          • read your logs.
          posted @ 2013-10-12 18:12 ivaneeo 閱讀(319) | 評論 (0)編輯 收藏

          nohup ./bin/startServer.sh -r hotrod -l 172.20.21.3 -c ./etc/config-samples/distributed-udp.xml -p 11222 &
          posted @ 2013-10-08 10:49 ivaneeo 閱讀(453) | 評論 (0)編輯 收藏

          https://github.com/sksamuel/elasticsearch-river-hazelcast
          posted @ 2013-10-08 00:57 ivaneeo 閱讀(418) | 評論 (0)編輯 收藏

          ElasticSearch是一個基于Lucene構建的開源,分布式,RESTful搜索引擎。設計用于云計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。支持通過HTTP使用JSON進行數據索引。 

            我們建立一個網站或應用程序,并要添加搜索功能,令我們受打擊的是:搜索工作是很難的。我們希望我們的搜索解決方案要快,我們希望 有一個零配置和一個完全免費的搜索模式,我們希望能夠簡單地使用JSON通過HTTP的索引數據,我們希望我們的搜索服務器始終可用,我們希望能夠一臺開 始并擴展到數百,我們要實時搜索,我們要簡單的多租戶,我們希望建立一個云的解決方案。Elasticsearch旨在解決所有這些問題和更多的。

          安裝

            以windows操作系統和ES0.19.7版本為例:

           

            ①下載elasticsearch-0.19.7.zip

           

            ②直接解壓至某目錄,設置該目錄為ES_HOME環境變量

           

            ③安裝JDK,并設置JAVA_HOME環境變量

           

            ④在windows下,運行 %ES_HOME%\bin\elasticsearch.bat即可運行

          分布式搜索elasticsearch單機與服務器環境搭建

                先到http://www.elasticsearch.org/download/下 載最新版的elasticsearch運行包,本文寫時最新的是0.19.1,作者是個很勤快的人,es的更新很頻繁,bug修復得很快。下載完解開有三 個包:bin是運行的腳本,config是設置文件,lib是放依賴的包。如果你要裝插件的話就要多新建一個plugins的文件夾,把插件放到這個文件 夾中。

          1.單機環境:

          單機版的elasticsearch運行很簡單,linux下直接 bin/elasticsearch就運行了,windows運行bin/elasticsearch.bat。如果是在局域網中運行elasticsearch集群也是很簡單的,只要cluster.name設置一致,并且機器在同一網段下,啟動的es會自動發現對方,組成集群。

          2.服務器環境:

          如果是在服務器上就可以使用elasticsearch-servicewrapper這個es插件,它支持通過參數,指定是在后臺或前臺運行es,并且支持啟動,停止,重啟es服務(默認es腳本只能通過ctrl+c關閉es)。使用方法是到https://github.com/elasticsearch/elasticsearch-servicewrapper下載service文件夾,放到es的bin目錄下。下面是命令集合:
          bin/service/elasticsearch +
          console 在前臺運行es
          start 在后臺運行es
          stop 停止es
          install 使es作為服務在服務器啟動時自動啟動
          remove 取消啟動時自動啟動

          在service目錄下有個elasticsearch.conf配置文件,主要是設置一些java運行環境參數,其中比較重要的是下面的

          參數:

          #es的home路徑,不用用默認值就可以
          set.default.ES_HOME=<Path to ElasticSearch Home>

          #分配給es的最小內存
          set.default.ES_MIN_MEM=256

          #分配給es的最大內存
          set.default.ES_MAX_MEM=1024


          # 啟動等待超時時間(以秒為單位)
          wrapper.startup.timeout=300

          # 關閉等待超時時間(以秒為單位)

          wrapper.shutdown.timeout=300

          # ping超時時間(以秒為單位)

          wrapper.ping.timeout=300

          安裝插件

            以head插件為例:

           

            聯網時,直接運行%ES_HOME%\bin\plugin -install mobz/elasticsearch-head

           

            不聯網時,下載elasticsearch-head的zipball的master包,把內容解壓到%ES_HOME%\plugin\head\_site目錄下,[該插件為site類型插件]

           

            安裝完成,重啟服務,在瀏覽器打開 http://localhost:9200/_plugin/head/ 即可

          ES概念

            cluster

           

            代表一個集群,集群中有多個節點,其中有一個為主節點,這個主節點是可以通過選舉產生的,主從節點是對于集群內部來說 的。es的一個概念就是去中心化,字面上理解就是無中心節點,這是對于集群外部來說的,因為從外部來看es集群,在邏輯上是個整體,你與任何一個節點的通 信和與整個es集群通信是等價的。

           

            shards

           

            代表索引分片,es可以把一個完整的索引分成多個分片,這樣的好處是可以把一個大的索引拆分成多個,分布到不同的節點上。構成分布式搜索。分片的數量只能在索引創建前指定,并且索引創建后不能更改。

           

            replicas

           

            代表索引副本,es可以設置多個索引的副本,副本的作用一是提高系統的容錯性,當個某個節點某個分片損壞或丟失時可以從副本中恢復。二是提高es的查詢效率,es會自動對搜索請求進行負載均衡。

           

            recovery

           

            代表數據恢復或叫數據重新分布,es在有節點加入或退出時會根據機器的負載對索引分片進行重新分配,掛掉的節點重新啟動時也會進行數據恢復。

           

            river

           

            代表es的一個數據源,也是其它存儲方式(如:數據庫)同步數據到es的一個方法。它是以插件方式存在的一個es服 務,通過讀取river中的數據并把它索引到es中,官方的river有couchDB的,RabbitMQ的,Twitter的,Wikipedia 的。

           

            gateway

           

            代表es索引的持久化存儲方式,es默認是先把索引存放到內存中,當內存滿了時再持久化到硬盤。當這個es集群關閉再 重新啟動時就會從gateway中讀取索引數據。es支持多種類型的gateway,有本地文件系統(默認),分布式文件系統,Hadoop的HDFS和 amazon的s3云存儲服務。

           

            discovery.zen

           

            代表es的自動發現節點機制,es是一個基于p2p的系統,它先通過廣播尋找存在的節點,再通過多播協議來進行節點之間的通信,同時也支持點對點的交互。

           

            Transport

           

            代表es內部節點或集群與客戶端的交互方式,默認內部是使用tcp協議進行交互,同時它支持http協議(json格式)、thrift、servlet、memcached、zeroMQ等的傳輸協議(通過插件方式集成)。

          分布式搜索elasticsearch中文分詞集成

          elasticsearch官方只提供smartcn這個中文分詞插件,效果不是很好,好在國內有medcl大神(國內最早研究es的人之一)寫的兩個中文分詞插件,一個是ik的,一個是mmseg的,下面分別介紹下兩者的用法,其實都差不多的,先安裝插件,命令行:
          安裝ik插件:

          plugin -install medcl/elasticsearch-analysis-ik/1.1.0  

          下載ik相關配置詞典文件到config目錄

          1. cd config  
          2. wget http://github.com/downloads/medcl/elasticsearch-analysis-ik/ik.zip --no-check-certificate  
          3. unzip ik.zip  
          4. rm ik.zip  

          安裝mmseg插件:

          1. bin/plugin -install medcl/elasticsearch-analysis-mmseg/1.1.0  

          下載相關配置詞典文件到config目錄

          1. cd config  
          2. wget http://github.com/downloads/medcl/elasticsearch-analysis-mmseg/mmseg.zip --no-check-certificate  
          3. unzip mmseg.zip  
          4. rm mmseg.zip  

          分詞配置

          ik分詞配置,在elasticsearch.yml文件中加上

          1. index:  
          2.   analysis:                     
          3.     analyzer:        
          4.       ik:  
          5.           alias: [ik_analyzer]  
          6.           type: org.elasticsearch.index.analysis.IkAnalyzerProvider  

          1. index.analysis.analyzer.ik.type : “ik”  

          這兩句的意義相同
          mmseg分詞配置,也是在在elasticsearch.yml文件中

          1. index:  
          2.   analysis:  
          3.     analyzer:  
          4.       mmseg:  
          5.           alias: [news_analyzer, mmseg_analyzer]  
          6.           type: org.elasticsearch.index.analysis.MMsegAnalyzerProvider  

          1. index.analysis.analyzer.default.type : "mmseg"  

          mmseg分詞還有些更加個性化的參數設置如下

          1. index:  
          2.   analysis:  
          3.     tokenizer:  
          4.       mmseg_maxword:  
          5.           type: mmseg  
          6.           seg_type: "max_word"  
          7.       mmseg_complex:  
          8.           type: mmseg  
          9.           seg_type: "complex"  
          10.       mmseg_simple:  
          11.           type: mmseg  
          12.           seg_type: "simple"  

          這樣配置完后插件安裝完成,啟動es就會加載插件。

          定義mapping

          在添加索引的mapping時就可以這樣定義分詞器

          1. {  
          2.    "page":{  
          3.       "properties":{  
          4.          "title":{  
          5.             "type":"string",  
          6.             "indexAnalyzer":"ik",  
          7.             "searchAnalyzer":"ik"  
          8.          },  
          9.          "content":{  
          10.             "type":"string",  
          11.             "indexAnalyzer":"ik",  
          12.             "searchAnalyzer":"ik"  
          13.          }  
          14.       }  
          15.    }  
          16. }  

          indexAnalyzer為索引時使用的分詞器,searchAnalyzer為搜索時使用的分詞器。

          java mapping代碼如下:

          1. XContentBuilder content = XContentFactory.jsonBuilder().startObject()  
          2.         .startObject("page")  
          3.           .startObject("properties")         
          4.             .startObject("title")  
          5.               .field("type", "string")             
          6.               .field("indexAnalyzer", "ik")  
          7.               .field("searchAnalyzer", "ik")  
          8.             .endObject()   
          9.             .startObject("code")  
          10.               .field("type", "string")           
          11.               .field("indexAnalyzer", "ik")  
          12.               .field("searchAnalyzer", "ik")  
          13.             .endObject()       
          14.           .endObject()  
          15.          .endObject()  
          16.        .endObject()  

          定義完后操作索引就會以指定的分詞器來進行分詞。

           附:

          ik分詞插件項目地址:https://github.com/medcl/elasticsearch-analysis-ik

          mmseg分詞插件項目地址:https://github.com/medcl/elasticsearch-analysis-mmseg

          如果覺得配置麻煩,也可以下載個配置好的es版本,地址如下:https://github.com/medcl/elasticsearch-rtf

           

          elasticsearch的基本用法


          最大的特點: 
          1. 數據庫的 database, 就是  index 
          2. 數據庫的 table,  就是 tag 
          3. 不要使用browser, 使用curl來進行客戶端操作.  否則會出現 java heap ooxx... 

          curl:  -X 后面跟 RESTful :  GET, POST ... 
          -d 后面跟數據。 (d = data to send) 

          1. create:  

          指定 ID 來建立新記錄。 (貌似PUT, POST都可以) 
          $ curl -XPOST localhost:9200/films/md/2 -d ' 
          { "name":"hei yi ren", "tag": "good"}' 

          使用自動生成的 ID 建立新紀錄: 
          $ curl -XPOST localhost:9200/films/md -d ' 
          { "name":"ma da jia si jia3", "tag": "good"}' 

          2. 查詢: 
          2.1 查詢所有的 index, type: 
          $ curl localhost:9200/_search?pretty=true 

          2.2 查詢某個index下所有的type: 
          $ curl localhost:9200/films/_search 

          2.3 查詢某個index 下, 某個 type下所有的記錄: 
          $ curl localhost:9200/films/md/_search?pretty=true 

          2.4 帶有參數的查詢:  
          $ curl localhost:9200/films/md/_search?q=tag:good 
          {"took":7,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":2,"max_score":1.0,"hits":[{"_index":"film","_type":"md","_id":"2","_score":1.0, "_source" : 
          { "name":"hei yi ren", "tag": "good"}},{"_index":"film","_type":"md","_id":"1","_score":0.30685282, "_source" : 
          { "name":"ma da jia si jia", "tag": "good"}}]}} 

          2.5 使用JSON參數的查詢: (注意 query 和 term 關鍵字) 
          $ curl localhost:9200/film/_search -d ' 
          {"query" : { "term": { "tag":"bad"}}}' 

          3. update  
          $ curl -XPUT localhost:9200/films/md/1 -d { ...(data)... } 

          4. 刪除。 刪除所有的: 
          $ curl -XDELETE localhost:9200/films
          posted @ 2013-10-04 02:09 ivaneeo 閱讀(16763) | 評論 (0)編輯 收藏

          僅列出標題
          共67頁: First 上一頁 6 7 8 9 10 11 12 13 14 下一頁 Last 
          主站蜘蛛池模板: 九江市| 林甸县| 叶城县| 阿拉善右旗| 廊坊市| 英德市| 漳平市| 汾阳市| 工布江达县| 桐乡市| 盐源县| 和静县| 阿合奇县| 邵东县| 康定县| 泾阳县| 山阴县| 兴和县| 板桥市| 巴彦县| 清徐县| 桃园市| 江陵县| 砀山县| 江阴市| 阜康市| 武冈市| 青河县| 谷城县| 行唐县| 江口县| 泗阳县| 林周县| 瑞安市| 崇左市| 嘉黎县| 玉龙| 徐水县| 淳安县| 长岭县| 德州市|