1. 程式人生 > 其它 >Nginx生產環境配置、elasticsearch生產環境配置、rocketmq生產環境配置 (史上最全)

Nginx生產環境配置、elasticsearch生產環境配置、rocketmq生產環境配置 (史上最全)

Nginx生產環境配置: 實現10萬+併發

在優化核心時,可以做的事情很多,不過,我們通常會根據業務特點來進行調整,當Nginx作為靜態web內容伺服器、反向代理或者提供壓縮伺服器的伺服器時,期核心引數的調整都是不同的,

概述
由於預設的linux核心引數考慮的是最通用場景,這明顯不符合用於支援高併發訪問的Web伺服器的定義,所以需要修改Linux核心引數,讓Nginx可以擁有更高的效能;

參考關鍵的Linux核心優化引數

/etc/sysctl.conf

修改 /etc/sysctl.conf 來更改核心引數

修改好配置檔案,執行 sysctl -p 命令,使配置立即生效


fs.file-max = 2024000
fs.nr_open = 1024000

net.ipv4.tcp_tw_reuse = 1

ner.ipv4.tcp_keepalive_time = 600

net.ipv4.tcp_fin_timeout = 30

net.ipv4.tcp_max_tw_buckets = 5000

net.ipv4.ip_local_port_range = 1024 65000

net.ipv4.tcp_rmem = 10240 87380 12582912

net.ipv4.tcp_wmem = 10240 87380 12582912

net.core.netdev_max_backlog = 8096

net.core.rmem_default = 6291456

net.core.wmem_default = 6291456

net.core.rmem_max = 12582912

net.core.wmem_max = 12582912

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_max_syn_backlog = 8192

net.ipv4.tcp_tw_recycle = 1

net.core.somaxconn=262114

net.ipv4.tcp_max_orphans=262114


針對Nginx支援超高吞吐,需要優化的,主要是檔案控制代碼數,TCP網路引數:

系統最大可以開啟的控制代碼數

fs.file-max = 2024000

將TIME_WAIT狀態的socket重新用於新的TCP連結

net.ipv4.tcp_tw_reuse = 1

#引數設定為 1 ,表示允許將TIME_WAIT狀態的socket重新用於新的TCP連結,這對於伺服器來說意義重大,因為總有大量TIME_WAIT狀態的連結存在;

TCP傳送keepalive訊息的頻度

ner.ipv4.tcp_keepalive_time = 600
#當keepalive啟動時,TCP傳送keepalive訊息的頻度;
預設是2小時,將其設定為10分鐘,可以更快的清理無效連結。

socket保持在FIN_WAIT_2狀態的最大時間


net.ipv4.tcp_fin_timeout = 30 
#當伺服器主動關閉連結時,socket保持在FIN_WAIT_2狀態的最大時間

允許TIME_WAIT套接字數量的最大值

net.ipv4.tcp_max_tw_buckets = 5000
# 這個引數表示作業系統允許TIME_WAIT套接字數量的最大值,
# 如果超過這個數字,TIME_WAIT套接字將立刻被清除並列印警告資訊。
# 該引數預設為180000,過多的TIME_WAIT套接字會使Web伺服器變慢。

本地埠的取值範圍


net.ipv4.ip_local_port_range = 1024 65000 
#定義UDP和TCP連結的本地埠的取值範圍。

每個Socket在Linux中都對映為一個檔案,並與核心中兩個緩衝區(讀緩衝區、寫緩衝區)相關聯。或者說,每個Socket擁有兩個核心緩衝區。通過下面的四個選項配置

  • rmem_default:一個Socket的被創建出來時,預設的讀緩衝區大小,單位位元組;

  • wmem_default:一個Socket的被創建出來時,預設的寫緩衝區大小,單位位元組;

  • rmem_max:一個Socket的讀緩衝區可由程式設定的最大值,單位位元組;

  • wmem_max:一個Socket的寫緩衝區可由程式設定的最大值,單位位元組;

net.core.rmem_default = 6291456 
#表示核心套接字接受快取區預設大小。

net.core.wmem_default = 6291456 
#表示核心套接字傳送快取區預設大小。

net.core.rmem_max = 12582912 
#表示核心套接字接受快取區最大大小。

net.core.wmem_max = 12582912 
#表示核心套接字傳送快取區最大大小。

注意:以上的四個引數,需要根據業務邏輯和實際的硬體成本來綜合考慮;

還有兩個引數,tcp_rmem、tcp_wmem。為每個TCP連線分配的讀、寫緩衝區記憶體大小,單位是Byte

tcp_rmem接受快取的最小值、預設值、最大值

net.ipv4.tcp_rmem = 10240 87380 12582912 
#定義了TCP接受快取的最小值、預設值、最大值。

第一個數字表示緩衝區最小值,為TCP連線分配的最小記憶體,預設為pagesize(4K位元組),每一個socket接收視窗大小下限;

第二個數字表示緩衝區的預設值,為TCP連線分配的預設記憶體,預設值為16K,為接收視窗大小,所謂的視窗大小隻是一個限制數值,實際對應的記憶體緩衝區由協議棧管理分配;

第三個數字表示緩衝區的最大值,為TCP連線分配的最大記憶體,每個socket鏈路接收視窗大小上限,用於tcp協議棧自動調整視窗大小的上限。

注意:實際對應的記憶體緩衝區由協議棧管理分配

一般按照預設值分配,上面的例子最新為10KB,預設86KB

傳送快取的最小值、預設值、最大值。


net.ipv4.tcp_wmem = 10240 87380 12582912 
#定義TCP傳送快取的最小值、預設值、最大值。

以上是TCP socket的讀寫緩衝區的設定,每一項裡面都有三個值:

  • 第一個值是緩衝區最小值
  • 中間值是緩衝區的預設值
  • 最後一個是緩衝區的最大值

net.core與net.ipv4開頭的區別

net.core開頭的配置為網路層通用配置,net.ipv4開頭的配置為ipv4使用網路配置。

雖然ipv4緩衝區的值不受core緩衝區的值的限制,但是緩衝區的最大值仍舊受限於core的最大值。

net.core.netdev_max_backlog = 8096 
#當網絡卡接收資料包的速度大於核心處理速度時,會有一個列隊儲存這些資料包。這個引數表示該列隊的最大值。

TCP socket緩衝區大小是他自己控制而不是由core核心緩衝區控制。

用於解決TCP的SYN攻擊

net.ipv4.tcp_syncookies = 1
#與效能無關。用於解決TCP的SYN攻擊。

接受SYN請求列隊的最大長度

net.ipv4.tcp_max_syn_backlog = 8192
#這個引數表示TCP三次握手建立階段接受SYN請求列隊的最大長度,預設1024,
# 將其設定的大一些
# 可以使出現Nginx繁忙來不及accept新連線的情況時,Linux不至於丟失客戶端發起的連結請求。

啟用timewait快速回收

net.ipv4.tcp_tw_recycle = 1 
#這個引數用於設定啟用timewait快速回收。

調節系統同時發起的TCP連線數

net.core.somaxconn=262114 
# 選項預設值是128,
# 這個引數用於調節系統同時發起的TCP連線數,
# 在高併發的請求中,預設的值可能會導致連結超時或者重傳,因此需要結合高併發請求數來調節此值。

防止簡單的DOS攻擊

net.ipv4.tcp_max_orphans=262114 
# 選項用於設定系統中最多有多少個TCP套接字不被關聯到任何一個使用者檔案控制代碼上。
# 如果超過這個數字,孤立連結將立即被複位並輸出警告資訊。
# 這個限制只是為了防止簡單的DOS攻擊,
# 不用過分依靠這個限制甚至認為的減小這個值,更多的情況是增加這個值。

單程序的檔案控制代碼數配置

/etc/security/limits.conf

/etc/security/limits.conf

* soft nofile 1024000
* hard nofile 1024000
* soft nproc 655360
* hard nproc 655360
* soft stack unlimited
* hard stack unlimited
* soft   memlock    unlimited
* hard   memlock    unlimited

程序最大開啟檔案描述符數

* soft nofile 1000000
* hard nofile 1000000
* soft nproc 655360
* hard nproc 655360

# *代表針對所有使用者
# nproc 是代表最大程序數
# nofile 是代表最大檔案開啟數

hard和soft的區別:在設定上,通常soft會比hard小,

舉例來說,soft可以設定為80,而hard設定為100,那麼你可以使用到90(沒有超過100),但介於80~100之間時,系統會有警告資訊通知你。

總之:

a. 所有程序開啟的檔案描述符數不能超過/proc/sys/fs/file-max

b. 單個程序開啟的檔案描述符數不能超過user limit中nofile的soft limit

c. nofile的soft limit不能超過其hard limit

d. nofile的hard limit不能超過/proc/sys/fs/nr_open

RocketMQ生產環境配置

參考的broker 配置

叢集架構為非同步刷盤、同步複製

#請修改
brokerClusterName=XXXCluster
brokerName=broker-a
brokerId=0
listenPort=10911
#請修改
namesrvAddr=x.x.x.x:9876;x.x.x.x::9876
defaultTopicQueueNums=4
autoCreateTopicEnable=false
autoCreateSubscriptionGroup=false
deleteWhen=04
fileReservedTime=48
mapedFileSizeCommitLog=1073741824
mapedFileSizeConsumeQueue=50000000
destroyMapedFileIntervalForcibly=120000
redeleteHangedFileInterval=120000
diskMaxUsedSpaceRatio=88
#儲存路徑
storePathRootDir=/data/rocketmq/store
#commitLog儲存路徑
storePathCommitLog=/data/rocketmq/store/commitlog
#消費佇列儲存路徑
storePathConsumeQueue=/data/rocketmq/store/consumequeue
# 訊息索引儲存路徑
storePathIndex=/data/rocketmq/store/index
# checkpoint 檔案儲存路徑
storeCheckpoint=/data/rocketmq/store/checkpoint
#abort 檔案儲存路徑
abortFile=/data/rocketmq/store/abort
maxMessageSize=65536
flushCommitLogLeastPages=4
flushConsumeQueueLeastPages=2
flushCommitLogThoroughInterval=10000
flushConsumeQueueThoroughInterval=60000
brokerRole=SYNC_MASTER
flushDiskType=ASYNC_FLUSH
checkTransactionMessageEnable=false
maxTransferCountOnMessageInMemory=1000
transientStorePoolEnable=true
warmMapedFileEnable=true
pullMessageThreadPoolNums=128
slaveReadEnable=true
transferMsgByHeap=false
waitTimeMillsInSendQueue=1000

ElasticSearch生產環境配置

參考的配置檔案

/etc/sysctl.conf

fs.file-max = 2024000
fs.nr_open = 1024000

net.ipv4.tcp_tw_reuse = 1

ner.ipv4.tcp_keepalive_time = 600

net.ipv4.tcp_fin_timeout = 30

net.ipv4.tcp_max_tw_buckets = 5000

net.ipv4.ip_local_port_range = 1024 65000

net.ipv4.tcp_rmem = 10240 87380 12582912

net.ipv4.tcp_wmem = 10240 87380 12582912

net.core.netdev_max_backlog = 8096

net.core.rmem_default = 6291456

net.core.wmem_default = 6291456

net.core.rmem_max = 12582912

net.core.wmem_max = 12582912

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_max_syn_backlog = 8192

net.ipv4.tcp_tw_recycle = 1

net.core.somaxconn=262114

net.ipv4.tcp_max_orphans=262114
net.ipv4.tcp_retries2 = 5
vm.max_map_count = 262144

作業系統

較大的檔案描述符

Lucene使用了非常大量的檔案。 並且Elasticsearch使用大量的套接字在節點和HTTP客戶端之間進行通訊。

所有這些都需要可用的檔案描述符。
可悲的是,許多現代的Linux發行版每個程序允許一個不允許的1024個檔案描述符。

這對於一個小的Elasticsearch節點來說太低了,更不用說處理數百個索引的節點了。

設定MMap

Elasticsearch還針對各種檔案使用NioFS和MMapFS的混合。

確保配置最大對映計數,以便有足夠的虛擬記憶體可用於mmapped檔案。

Elasticsearch預設使用一個mappfs目錄來儲存索引。預設作業系統對mmap計數的限制可能太低,這可能會導致記憶體不足異常。

暫時設定 sysctl -w vm.max_map_count=262144

永久設定

$ vim /etc/sysctl.conf

# 設定作業系統mmap數限制,Elasticsearch與Lucene使用mmap來對映部分索引到Elasticsearch的地址空間
# 為了讓mmap生效,Elasticsearch還需要有建立需要記憶體對映區的能力。最大map數檢查是確保核心允許建立至少262144個記憶體對映區
vm.max_map_count = 262144

JVM虛擬機器

除非Elasticsearch網站上另有說明,否則應始終執行最新版本的Java虛擬機器(JVM)。

Elasticsearch和Lucene都是比較苛刻的軟體。

Lucene的單元和整合測試通常暴露JVM本身的錯誤。

Number of threads(執行緒數或者程序數)

Elasticsearch為不同型別的操作使用了許多執行緒池。它能夠在需要時建立新執行緒,這一點很重要。確保Elasticsearch使用者可以建立的執行緒數量至少是4096個。

$ vim /etc/security/limits.conf

elasticsearch soft nproc 4096
elasticsearch hard nproc 4096

給lucene留下一半的記憶體空間

一個常見的問題是配置一個太大的堆。你有一個64GB的機器,並且你想給Elasticsearch所有64GB的記憶體。

更多更好?!堆對Elasticsearch絕對重要,它被許多記憶體資料結構使用以提供快速操作。

但是還有另一個主要的記憶體使用者是 Lucene。Lucene旨在利用底層作業系統來快取記憶體中的資料結構。

Lucene的segment 段儲存在單獨的檔案中,因為段是不可變的,所以這些檔案從不改變。這使得它們非常易於快取,並且底層作業系統將適合的保持segment駐留在記憶體中以便更快地訪問。

這些段包括反向索引(用於全文搜尋)和docvalues(用於聚合)。

Lucene的效能依賴於與作業系統的這種互動。但是如果你給Elasticsearch的堆提供所有可用的記憶體,Lucene就不會有任何剩餘的記憶體。

這會嚴重影響效能。

標準建議是給Elasticsearch堆提供50%的可用記憶體,同時保留其他50%的空閒記憶體。

它不會不使用; Lucene會愉快地吞噬剩下的任何東西。

如果你不是聚合在分析的字串欄位(例如你不需要fielddata),你可以考慮降低堆更多。你可以做的堆越小,你可以期望從

Elasticsearch(更快的GC)和Lucene(更多的記憶體快取)更好的效能。

不要超過32G

事實證明,當堆大小小於32GB時,HotSpot JVM使用一個技巧來壓縮物件指標。

可以通過-XX:+PrintFlagsFinal來檢視,在es2.2.0後不用設定,啟動後會列印compressed ordinary object pointers [true]
在Java中,所有物件都在堆上分配並由指標引用。

Ordinary object pointers(OOP)指向這些物件,並且通常是CPU本地字的大小:32位或64位,取決於處理器。

指標引用值的確切位元組位置。 對於32位系統,這最大堆大小為4GB。

對於64位系統,堆大小可以變得更大,但64位指標的開銷意味著更多的浪費空間,因為指標更大。並且比浪費的空間更糟,當在主儲存器和各種快取記憶體(LLC,L1等)之間移動值時,較大的指標佔用更多的頻寬。
Java使用一個名為compress oops的技巧來解決這個問題。指標不是指向儲存器中的精確位元組位置,而是引用物件偏移。這意味著32位指標可以引用四十億個物件,而不是40億位元組。

最終,這意味著堆可以增長到大約32 GB的物理大小,同時仍然使用32位指標。
一旦你超越32GB邊界,指標切換回Ordinary object pointers

每個指標的大小增加,使用更多的CPU記憶體頻寬,並且您有效地丟失了記憶體。

事實上,它需要直到大約40到50GB的分配的堆,你有一個堆的相同有效記憶體剛剛低於32GB使用壓縮oops。所以即使你有記憶體,儘量避免跨越32 GB堆邊界。它浪費記憶體,降低CPU效能,並使GC與大堆爭奪。

swapping是效能的死穴

它應該是顯而易見的,但它明確拼寫出來:將主記憶體交換到磁碟會破壞伺服器效能。 記憶體中操作是需要快速執行的操作。如果記憶體交換到磁碟,100微秒操作將花費10毫秒。 現在重複所有其他10us操作的延遲增加。 不難看出為什麼交換對於效能來說是可怕的。
1、最好的辦法是在系統上完全禁用交換。 這可以臨時完成:

sudo swapoff -a

要永久禁用則需要編輯/etc/fstab。請查閱作業系統的文件。
2、如果完全禁用交換不是一個選項,您可以嘗試

sysctl vm.swappiness = 1(檢視cat /proc/sys/vm/swappiness)

這個設定控制作業系統如何積極地嘗試交換記憶體。 以防止在正常情況下交換,但仍然允許作業系統在緊急情況下交換。swappiness值1比0好,因為在一些核心版本上,swappiness為0可以呼叫OOM-killer。
3、最後,如果兩種方法都不可能,就應該啟用mlockall。 這允許JVM鎖定其記憶體,並防止它被作業系統交換。 可以在elasticsearch.yml中設定:

bootstrap.mlockall: true

TCP retransmission timeout(TCP重傳超時)

叢集中的每一對節點通過許多TCP連線進行通訊,這些TCP連線一直保持開啟狀態,直到其中一個節點關閉或由於底層基礎設施中的故障而中斷節點之間的通訊。

TCP通過對通訊應用程式隱藏臨時的網路中斷,在偶爾不可靠的網路上提供可靠的通訊。在通知傳送者任何問題之前,您的作業系統將多次重新傳輸任何丟失的訊息。大多數Linux發行版預設重傳任何丟失的資料包15次。重傳速度呈指數級下降,所以這15次重傳需要900秒才能完成。這意味著Linux使用這種方法需要花費許多分鐘來檢測網路分割槽或故障節點。Windows預設只有5次重傳,相當於6秒左右的超時。

Linux預設允許在可能經歷很長時間包丟失的網路上進行通訊,但是對於單個數據中心內的生產網路來說,這個預設值太大了,就像大多數Elasticsearch叢集一樣。高可用叢集必須能夠快速檢測節點故障,以便它們能夠通過重新分配丟失的碎片、重新路由搜尋以及可能選擇一個新的主節點來迅速作出反應。因此,Linux使用者應該減少TCP重傳的最大數量。

$ vim /etc/sysctl.conf

net.ipv4.tcp_retries2 = 5

config/ jvm.options

  • Elasticsearch有足夠的可用堆是非常重要的。
  • 堆的最小值(Xms)與堆的最大值(Xmx)設定成相同的。
  • Elasticsearch的可用堆越大,它能在記憶體中快取的資料越多。但是需要注意堆越大在垃圾回收時造成的暫停會越長。
  • 設定Xmx不要大於實體記憶體的50%。用來確保有足夠多的實體記憶體預留給作業系統快取。
  • 禁止用序列收集器來執行Elasticsearch(-XX:+UseSerialGC),預設JVM配置通過Elasticsearch的配置將使用CMS回收器。
-Xms32g
-Xmx32g

硬體方面

記憶體

首先最重要的資源是記憶體,排序和聚合都可能導致記憶體匱乏,因此足夠的堆空間來容納這些是重要的。

即使堆比較小,也要給作業系統快取記憶體提供額外的記憶體,因為Lucene使用的許多資料結構是基於磁碟的格式,Elasticsearch利用作業系統快取有很大的影響。
64GB RAM的機器是最理想的,但32GB和16GB機器也很常見。

少於8GB往往適得其反(你最終需要許多,許多小機器),大於64GB可能會有問題,我們將在討論在堆:大小和交換。

CPU

大多數Elasticsearch部署往往對CPU要求很不大。因此,確切的處理器設定比其他資源更重要,應該選擇具有多個核心的現代處理器。通用叢集使用2到8核機器。
如果需要在較快的CPU或更多核之間進行選擇,請選擇更多核。 多核提供的額外併發將遠遠超過稍快的時鐘速度。

硬碟

磁碟對於所有叢集都很重要,尤其是對於索引很重的叢集(例如攝取日誌資料的磁碟)。 磁碟是伺服器中最慢的子系統,這意味著大量寫入的群集可以輕鬆地飽和其磁碟,這反過來成為群集的瓶頸。

如果你能買得起SSD,他們遠遠優於任何旋轉磁碟。 支援SSD的節點看到查詢和索引效能方面的提升。
如果使用旋轉磁碟,請嘗試獲取儘可能最快的磁碟(高效能伺服器磁碟,15k轉速驅動器)。
使用RAID 0是提高磁碟速度的有效方法,適用於旋轉磁碟和SSD。 沒有必要使用RAID的映象或奇偶校驗變體,因為高可用性是通過副本建立到Elasticsearch中。
最後,避免網路連線儲存(NAS)。 NAS通常較慢,顯示較大的延遲,平均延遲的偏差較大,並且是單點故障。

網路

快速和可靠的網路對於分散式系統中的效能顯然是重要的。低延遲有助於確保節點可以輕鬆地進行通訊,而高頻寬有助於分段移動和恢復。現代資料中心網路(1GbE,10GbE)對於絕大多數叢集都是足夠的。
避免跨越多個數據中心的群集,即使資料中心位置非常接近。絕對避免跨越大地理距離的叢集。
Elasticsearch叢集假定所有節點相等,而不是一半的節點距離另一個數據中心中有150ms。較大的延遲往往會加劇分散式系統中的問題,並使除錯和解決更加困難。
與NAS引數類似,每個人都聲稱資料中心之間的管道是穩健的和低延遲。(吹牛)。從我們的經驗,管理跨資料中心叢集的麻煩就是浪費成本。

其他配置

現在可以獲得真正巨大的機器如數百GB的RAM和幾十個CPU核心。 另外也可以在雲平臺(如EC2)中啟動數千個小型虛擬機器。 哪種方法最好?
一般來說,最好選擇中到大盒子。 避免使用小型機器,因為您不想管理具有一千個節點的叢集,而簡單執行Elasticsearch的開銷在這種小型機器上更為明顯。
同時,避免真正巨大的機器。 它們通常導致資源使用不平衡(例如,所有記憶體正在使用,但沒有CPU),並且如果您必須為每臺機器執行多個節點,可能會增加後期的運維複雜性。