自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

那些分布式系統(tǒng)設計常用的開源模塊

云計算 分布式
分布式系統(tǒng)是個由多個互相連接的處理資源組成的計算機系統(tǒng),它們在整個系統(tǒng)的控制下協(xié)同執(zhí)行同一個任務,最少依賴于集中的程序、數據或硬件。本文對大家常用的分布式系統(tǒng)設計開源模塊進行了總結,包括HBase、Nginx、Zookeeper。

HBase開發(fā):

HBase

HBase介紹

HBase - Hadoop Base 是一個高可靠、高性能的、面向列、可伸縮的分布式系統(tǒng)、利用HBase技術可在廉價PC Server上搭建大規(guī)模結構化存儲集群。HBase是Google Bigtable的 java開源實現,類似Google Bigtable利用GFS作為其文件存儲系統(tǒng),HBase利用Hadoop HDFS作為其文件存儲系統(tǒng),Google運行MapReduce來處理Bigtable中的海量數據,HBase同樣利用Hadoop MapReduce來處理HBase中的海量數據,Google Bigtable利用Chubby作為協(xié)同服務,HBase利用Zookeeper作為協(xié)同服務。

HBase使用

適用場景

HBase的這些特點適用于數據海量、持續(xù)增長的情況,例如開源監(jiān)控平臺OpenTSDB;網易的logtracer數據存儲、監(jiān)控平臺的數據存儲;淘寶的交易歷史記錄查詢系統(tǒng),淘寶指數等。

Facebook公司整理HBase集群使用的場景如下:

  1. 需要很高的寫吞吐量
  2. 在大規(guī)模數據集中進行隨機訪問
  3. 方便的水平擴展
  4. 結構化和半結構化數據
  5. 不需要全部的關系數據庫特性,例如交叉列、交叉表,事務,連接等等

HBase表的設計

HBase的表包含如下屬性:

(1)最大版本數:通常是3,如果對于更新比較頻繁的應用完全可以設置為1,能夠快速的淘汰無用數據,對于節(jié)省存儲空間和提高查詢速度有效果。

(2)壓縮算法:可以嘗試一下最新出爐的snappy算法,相對lzo來說,壓縮率接近,壓縮效率稍高,解壓效率高很多。

(3)inmemory:表在內存中存放,一直會被忽略的屬性。如果完全將數據存放在內存中,那么hbase和現在流行的內存數據庫memorycached和redis性能差距有多少,尚待實測。

(4)bloomfilter:根據應用來定,看需要精確到rowkey還是column。不過這里需要理解一下原理,bloomfilter的作用是對一個region下查找記錄所在的hfile有用。即如果一個region下的hfile數量很多,bloomfilter的作用越明顯。適合那種 compaction趕不上flush速度的應用。

默認情況下,在創(chuàng)建HBase表的時候會自動創(chuàng)建一個region分區(qū),當導入數據的時候,所有的HBase客戶端都向這一個region寫數據, 直到這個region足夠大了才進行切分。一種可以加快批量寫入速度的方法是通過預先創(chuàng)建一些空的regions,這樣當數據寫入HBase時,會按照 region分區(qū)情況,在集群內做數據的負載均衡。

有關預分區(qū),詳情參見:Table Creation: Pre-Creating Regions。

HBase的RowKey設計

rowkey是hbase的key-value存儲中的key,通常使用用戶要查詢的字段作為rowkey,查詢結果作為value??梢酝ㄟ^設計滿足幾種不同的查詢需求。

數字rowkey的從大到小排序:原生hbase只支持從小到大的排序,這樣就對于排行榜一類的查詢需求很尷尬。那么采用rowkey = Integer.MAX_VALUE-rowkey的方式將rowkey進行轉換,最大的變最小,最小的變最大。在應用層再轉回來即可完成排序需求。

rowkey的散列原則:如果rowkey是類似時間戳的方式遞增的生成,建議不要使用正序直接寫入rowkey,而是采用reverse的方式反轉rowkey,使得rowkey大致均衡分布,這樣設計有個好處是能將regionserver的負載均衡,否則容易產生所有新數據都在一個 regionserver上堆積的現象,這一點還可以結合table的預切分一起設計。

columnfamily columnfamily盡量少,原因是過多的columnfamily之間會互相影響。

Column 對于column需要擴展的應用,column可以按普通的方式設計,但是對于列相對固定的應用,最好采用將一行記錄封裝到一個column中的方式,這樣能夠節(jié)省存儲空間。封裝的方式推薦protocolbuffer。

Hbase的row key設計較為靈活,根據業(yè)務需求可靈活運用,在此不展開說明。Row key 高級設計

HBase Memstore

hbase.hregion.memstore.flush.size參數注意

hbase.hregion.memstore.flush.size 是出發(fā)系統(tǒng)對Memstore進行flush的閾值,但是該參數并非單個Memstore flush的閾值而是一個Region內所有Memstore的大小之后閾值

深入理解HBase Memstore

MemStore是HBase非常重要的組成部分,深入理解MemStore的運行機制、工作原理、相關配置,對HBase集群管理以及性能調優(yōu)有非常重要的幫助。

首先通過簡單介紹HBase的讀寫過程來理解一下MemStore到底是什么,在何處發(fā)揮作用,如何使用到以及為什么要用MemStore。

當RegionServer(RS)收到寫請求的時候(write request),RS會將請求轉至相應的Region。每一個Region都存儲著一些列(a set of rows)。根據其列族的不同,將這些列數據存儲在相應的列族中(Column Family,簡寫CF)。不同的CFs中的數據存儲在各自的HStore中,HStore由一個Memstore及一系列HFile組成。 Memstore位于RS的主內存中,而HFiles被寫入到HDFS中。當RS處理寫請求的時候,數據首先寫入到Memstore,然后當到達一定的閥值的時候,Memstore中的數據會被刷到HFile中。

用到Memstore最主要的原因是:存儲在HDFS上的數據需要按照row key 排序。而HDFS本身被設計為順序讀寫(sequential reads/writes),不允許修改。這樣的話,HBase就不能夠高效的寫數據,因為要寫入到HBase的數據不會被排序,這也就意味著沒有為將來的檢索優(yōu)化。為了解決這個問題,HBase將最近接收到的數據緩存在內存中(in Memstore),在持久化到HDFS之前完成排序,然后再快速的順序寫入HDFS。需要注意的一點是實際的HFile中,不僅僅只是簡單地排序的列數據的列表,詳見Apache HBase I/O – HFile

除了解決“無序”問題外,Memstore還有一些其他的好處,例如:

作為一個內存級緩存,緩存最近增加數據。一種顯而易見的場合是,新插入數據總是比老數據頻繁使用。

在持久化寫入之前,在內存中對Rows/Cells可以做某些優(yōu)化。比如,當數據的version被設為1的時候,對于某些CF的一些數據,Memstore緩存了數個對該Cell的更新,在寫入HFile的時候,僅需要保存一個最新的版本就好了,其他的都可以直接拋棄。

有一點需要特別注意:每一次Memstore的flush,會為每一個CF創(chuàng)建一個新的HFile。在讀方面相對來說就會簡單一些:HBase首先檢查請求的數據是否在Memstore,不在的話就到HFile中查找,最終返回merged的一個結果給用戶。

HBase Memstore關注要點

迫于以下幾個原因,HBase用戶或者管理員需要關注Memstore并且要熟悉它是如何被使用的:

  1. Memstore有許多配置可以調整以取得好的性能和避免一些問題。HBase不會根據用戶自己的使用模式來調整這些配置,你需要自己來調整。
  2. 頻繁的Memstore flush會嚴重影響HBase集群讀性能,并有可能帶來一些額外的負載。
  3. Memstore flush的方式有可能影響你的HBase schema設計

Memstore配置要點

第一組是關于觸發(fā)“普通”flush,這類flush發(fā)生時,并不影響并行的寫請求。該類型flush的配置項有:

hbase.hregion.memstore.flush.size

base.regionserver.global.memstore.lowerLimit

需要注意的是第一個設置是每個Memstore的大小,當你設置該配置項時,你需要考慮一下每臺RS承載的region總量??赡芤婚_始你設置的該值比較小,后來隨著region增多,那么就有可能因為第二個設置原因Memstore的flush觸發(fā)會變早許多。

第二組設置主要是出于安全考慮:有時候集群的“寫負載”非常高,寫入量一直超過flush的量,這時,我們就希望memstore不要超過一定的安全設置。在這種情況下,寫操作就要被阻止(blocked)一直到memstore恢復到一個“可管理”(manageable)的大小。該類型 flush配置項有:

hbase.regionserver.global.memstore.upperLimit

hbase.hregion.memstore.block.multiplier

某個節(jié)點“寫阻塞”對該節(jié)點來說影響很大,但是對于整個集群的影響更大。HBase設計為:每個Region僅屬于一個RS但是“寫負載”是均勻分布于整個集群(所有Region上)。有一個如此“慢”的節(jié)點,將會使得整個集群都會變慢(最明顯的是反映在速度上)。

提示:嚴重關切Memstore的大小和Memstore Flush Queue的大小。理想情況下,Memstore的大小不應該達到 hbase.regionserver.global.memstore.upperLimit的設置,Memstore Flush Queue 的size不能持續(xù)增長。

頻繁的Memstore Flushes帶來的影響

要避免“寫阻塞”,貌似讓Flush操作盡量的早于達到觸發(fā)“寫操作”的閾值為宜。但是,這將導致頻繁的Flush操作,而由此帶來的后果便是讀性能下降以及額外的負載。

每次的Memstore Flush都會為每個CF創(chuàng)建一個HFile。頻繁的Flush就會創(chuàng)建大量的HFile。這樣HBase在檢索的時候,就不得不讀取大量的HFile,讀性能會受很大影響。

為預防打開過多HFile及避免讀性能惡化,HBase有專門的HFile合并處理(HFile Compaction Process)。HBase會周期性的合并數個小HFile為一個大的HFile。明顯的,有Memstore Flush產生的HFile越多,集群系統(tǒng)就要做更多的合并操作(額外負載)。更糟糕的是:Compaction處理是跟集群上的其他請求并行進行的。當 HBase不能夠跟上Compaction的時候(同樣有閾值設置項),會在RS上出現“寫阻塞”。像上面說到的,這是最最不希望的。

提示:嚴重關切RS上Compaction Queue 的size。要在其引起問題前,阻止其持續(xù)增大。

想了解更多HFile 創(chuàng)建和合并,可參看 Visualizing HBase Flushes And Compactions。

理想情況下,在不超過hbase.regionserver.global.memstore.upperLimit的情況下,Memstore應該盡可能多的使用內存(配置給Memstore部分的,而不是真?zhèn)€Heap的)。

HLog (WAL) Size & Memstore Flush

當數據被寫入時會默認先寫入Write-ahead Log(WAL)。WAL中包含了所有已經寫入Memstore但還未Flush到HFile的更改(edits)。在Memstore中數據還沒有持久化,當RegionSever宕掉的時候,可以使用WAL恢復數據。

當WAL(在HBase中成為HLog)變得很大的時候,在恢復的時候就需要很長的時間。因此,對WAL的大小也有一些限制,當達到這些限制的時候,就會觸發(fā)Memstore的flush。Memstore flush會使WAL 減少,因為數據持久化之后(寫入到HFile),就沒有必要在WAL中再保存這些修改。有兩個屬性可以配置:

l hbase.regionserver.hlog.blocksize

l hbase.regionserver.maxlogs

WAL的最大值由hbase.regionserver.maxlogs * hbase.regionserver.hlog.blocksize (2GB by default)決定。一旦達到這個值,Memstore flush就會被觸發(fā)。所以,當你增加Memstore的大小以及調整其他的Memstore的設置項時,你也需要去調整HLog的配置項。否則,WAL 的大小限制可能會首先被觸發(fā),因而,你將利用不到其他專門為Memstore而設計的優(yōu)化。拋開這些不說,通過WAL限制來觸發(fā)Memstore的 flush并非最佳方式,這樣做可能會會一次flush很多Region,盡管“寫數據”是很好的分布于整個集群,進而很有可能會引發(fā)flush“大風暴”

提示:最好將hbase.regionserver.hlog.blocksize * hbase.regionserver.maxlogs 設置為稍微大于hbase.regionserver.global.memstore.lowerLimit * HBASE_HEAPSIZE.

HBase Compaction

Compaction是buffer->flush->merge的Log-Structured Merge-Tree模型的關鍵操作,主要起到如下幾個作用:

  1. 合并文件
  2. 清除刪除、過期、多余版本的數據
  3. 提高讀寫數據的效率

HBase 有兩種方式的Compaction,Minor和Major

  1. Minor Compaction操作只用來做部分文件的合并操作以及包括minVersion=0并且設置ttl的過期版本清理,不做任何刪除數據、多版本數據的清理工作。
  2. Major Compaction操作是對Region下的HStore下的所有StoreFile執(zhí)行合并操作,最終的結果是整理合并出一個文件。

#p#

Compaction如何發(fā)生

在什么情況下會發(fā)生Compaction呢?

CompactionChecker是RS上的工作線程,設置執(zhí)行周期是通過threadWakeFrequency指定,大小通過 hbase.server.thread.wakefrequency配置(默認10000),然后乘以默認倍數multiple(1000),毫秒時間轉換為秒。因此,在不做參數修改的情況下,CompactionChecker大概是2hrs, 46mins, 40sec執(zhí)行一次。

首先,對于HRegion里的每個HStore進行一次判斷,needsCompaction()判斷是否足夠多的文件觸發(fā)了Compaction 的條件。條件為:HStore中StoreFIles的個數 – 正在執(zhí)行Compacting的文件個數 > minFilesToCompact

操作:以最低優(yōu)先級提交Compaction申請。

在大多數情況下,Major是發(fā)生在storefiles和filesToCompact文件個數相同,并且滿足各種條件的前提下執(zhí)行。這里進行幾個參數配置的簡介:

  1. hbase.hregion.majorcompaction: 設置系統(tǒng)進行一次MajorCompaction的啟動周期,如果設置為0,則系統(tǒng)不會主動觸發(fā)MC過程。
  2. hbase.hstore.compaction.max:設置執(zhí)行Compaction(包括Major &Minor)的待合并文件的最大個數。默認值為10,如果超過該設置值,會對部分文件執(zhí)行一次MinorCompaction,選擇算法如 Figure1。
  3. hbase.hstore.compactionThreshold: 設置執(zhí)行Compaction(Major && Minor)操作的閾值,默認是3,如果想降低過頻繁的合并操作,可以稍微調大一點,對于HBase負載較重的系統(tǒng),可以設置成5。

Compaction對讀寫操作的影響

Compaction與Flush不同之處在于:Flush是針對一個Region整體執(zhí)行操作,而Compaction操作是針對Region上的一個Store而言,因此,從邏輯上看,Flush操作粒度較大。這屬于一個LSM存儲模型最核心的設計:

Flush操作如果只選擇某個Region的Store內的MemStore寫入磁盤,而不是統(tǒng)一寫入磁盤,那么HLog上key的一致性在Reigon不同ColumnFamily(Store)下的MemStore內就會有不一致的key區(qū)間。

如下圖所示,我們假定該RegionServer上僅有一個Region,由于不同的Row是在列簇上有所區(qū)別,就會出現有些不同Store內占用的內存不一致的情況,這里會根據整體內存使用的情況,或者RS使用內存的情況來決定是否執(zhí)行Flush操作。如果僅僅刷入使用內存較大的 memstore,那么在使用的過程中,一是Scan操作在執(zhí)行時就不夠統(tǒng)一,二是在HLog Replayer還原Region內Memstore故障前的狀態(tài),只需根據Hlog的Flush_marker的標記位來執(zhí)行Replay即可。

Compaction執(zhí)行結束之后會生成臨時文件,臨時文件所在的hdfs位置如下:/hbase-weibo/bi_weibo_cluster /ffd87a50c3df3080183d4910d183d0ee/.tmp ffd87a50c3df3080183d4910d183d0ee 是bi_weibo_cluster表格的Region名。臨時文件的意義在于,在Compaction執(zhí)行期間,對于原數據訪問沒有影響。 Compaction執(zhí)行合并操作生成的文件生效過程,需要對Store的寫操作加鎖,阻塞Store內的更新操作,直到更新Store的 storeFiles完成為止。(注意,這個操作過程執(zhí)行會影響到更新服務,但是影響不會太大)

對于讀服務的影響,類似于Flush操作,也是通過ChangedReaderObserver為StoreScanner注冊監(jiān)聽類來實現的。具體內容可以參考之前的”HBase Flush操作流程以及對讀寫服務的影響”。

HBase Region Server Compact過程占用大量網絡出口帶寬的問題

該問題較為普遍,當Regionserver帶寬被大量占用的時候,客戶端的寫入基本全都超時,有網友分析并提供了解決方案。

HBase Region

Region的分配問題

當Region數量變多的時候,就需要把它們分配給不同的Region Server來保證每個Region Server都有事情做,但是當region數量遠遠大于Region Server個數的時候,就需要保證一個load balance問題,不能讓一個Region Server上有大量的regions,而其他Region Server上只有幾個regions,這樣很可能導致負載不均衡。

Region split問題

hbase通過split region實現水平的sharding,但在split的過程中舊的region會下線,新region還會做compaction,中間有一段時間大量的數據不能被讀寫,這對于我們這種online系統(tǒng)是不能忍受的。我們同樣禁掉自動的split,而在晚上系統(tǒng)空閑時執(zhí)行我們的splittool手動的split。

禁用方法把hbase.hregion.max.filesize參數值設成較大的值例如536870912000

(500g)

在對Region進行手工split的過程中,出現以下異常

./hbase org.apache.hadoop.hbase.util.RegionSplitter -r lsmp_lottery_presplit HexStringSplit

這個HBase的一個bug,HBase0.94 出現以上錯誤,需要打補丁即可,https://issues.apache.org/jira/browse/HBASE-7048

HBase寫客戶端優(yōu)化

多HTable并發(fā)寫

創(chuàng)建多個HTable客戶端用于寫操作,提高寫數據的吞吐量。另外還可以使用HTablePool來實現多線程寫入。

HTable參數設置

  1. Auto Flush

通過調用HTable.setAutoFlush(false)方法可以將HTable寫客戶端的自動flush關閉,這樣可以批量寫入數據到 HBase,而不是有一條put就執(zhí)行一次更新,只有當put填滿客戶端寫緩存時,才實際向HBase服務端發(fā)起寫請求。默認情況下auto flush是開啟的。

  1. Write Buffer

通過調用HTable.setWriteBufferSize(writeBufferSize)方法可以設置 HTable客戶端的寫buffer大小,如果新設置的buffer小于當前寫buffer中的數據時,buffer將會被flush到服務端。其 中,writeBufferSize的單位是byte字節(jié)數,可以根據實際寫入數據量的多少來設置該值。

  1. WAL Flag

在HBae中,客戶端向集群中的RegionServer提交數據時(Put/Delete操作),首先會先寫WAL(Write Ahead Log)日志(即HLog,一個RegionServer上的所有Region共享一個HLog),只有當WAL日志寫成功后,再接著寫 MemStore,然后客戶端被通知提交數據成功;如果寫WAL日志失敗,客戶端則被通知提交失敗。這樣做的好處是可以做到RegionServer宕機 后的數據恢復。

因此,對于相對不太重要的數據,可以在Put/Delete操作時,通過調用Put.setWriteToWAL(false)或Delete.setWriteToWAL(false)函數,放棄寫WAL日志,從而提高數據寫入的性能。

需要注意的是:謹慎選擇關閉WAL日志,因為這樣的話,一旦RegionServer宕機,Put/Delete的數據將會無法根據WAL日志進行恢復。

批量寫入

通過調用HTable.put(Put)方法可以將一個指定的row key記錄寫入HBase,同樣HBase提供了另一個方法:通過調用HTable.put(List)方法可以將指定的row key列表,批量寫入多行記錄,這樣做的好處是批量執(zhí)行,只需要一次網絡I/O開銷,這對于對數據實時性要求高,網絡傳輸RTT高的情景下可能帶來明顯的 性能提升。

多線程并發(fā)寫

在客戶端開啟多個HTable寫線程,每個寫線程負責一個HTable對象的flush操作,這樣結合定時flush和寫 buffer(writeBufferSize),可以既保證在數據量小的時候,數據可以在較短時間內被flush(如1秒內),同時又保證在數據量大的 時候,寫buffer一滿就及時進行flush。

其他

enable和disable表時出現表未disable/enable異常處理

今天在為表增加LZO壓縮,在enable表時,發(fā)現耗時很長都未結束,就ctrl+c退出hbase shell,再進入繼續(xù)enable表,但此時出現如下錯誤:

錯誤說表未禁用,但進行disable表操作時,又出現如下錯誤:

那肯定是剛才強行退出導致出問題了,根據大家的經驗,指出這是因為zookeeper保持了要enable的這個表信息,只需要登錄zk刪除該記錄就行。

登錄到zookeeper也有兩種方式,一是到zk目錄運行腳本連接,而是直接在hbase安裝目錄bin下運行:

hbase zkcli

都是小寫字母。之后就能連接上zookeeper了,跟著刪除/hbase/table下對應的表項就行:

delete /hbase/table/user_video_recommend2

之后就可以成功的enable表了。

如果此時仍然失敗,則可以運行一下命了修復META:

hbase hbck -fixMeta -fixAssignments

HBase元數據損壞修復

hbase hbck -repair -sidelineDir hdfs://mycluster/hbase/rbu

但是出問題的時候有可能出現RIT中大量任務無法結束,只要沒有長期PENDING_OPEN的任務,就可以先將有問題的表先disable一下。這里要提到的是hbase的hbck很弱,會形成一個死循環(huán),一方面region由于元數據破壞無法開啟需要repair,造成大量的RIT長期hang 在上面,但是repair的操作卻要等待這些RIT結束才能繼續(xù),而且repair操作也不是離線操作,必須要先保證hbase能正常起來。因此打破死循環(huán)的關鍵就是先處理掉RIT中hang的操作,這需要經驗和仔細排查。

如果出現長期的pending_open,則要觀察pending_open的原因,要嘗試解決,這次我們出現的問題是元數據出錯,某個 Region的對row的加鎖范圍超出region本身的key的取值范圍,引起不斷地PENING_OPEN,通過離線的merge操作將該 region隨便找了個region merge下解決了該問題,./hbase org.apache.hadoop.hbase.util.Merge

最后可通過hbck恢復元數據,但是hbck恢復過程中可能會丟失數據,因此要慎用,最好通過SNAPSHOT做備份來解決這類問題

HBaseClient異常:java.io.IOException: Connection reset by peer

hbase客戶端每次和regionserver交互的時候,都會在服務器端生成一個租約(Lease),租約的有效期由參數hbase.regionserver.lease.period確定。

客戶端去regionserver取 數據的時候,hbase中存得數據量很大并且很多region的時候的,客戶端請求的region不在內存中,或是沒有被cache住,需要從磁盤中加 載,如果這時候加載需要的時間超過hbase.regionserver.lease.period所配置的時間,并且客戶端沒有和 regionserver報告其還活著,那么regionserver就會認為本次租約已經過期,并從LeaseQueue從刪除掉本次租約,當 regionserver加載完成后,拿已經被刪除的租約再去取數據的時候,就會出現如上的錯誤現象。

解決的辦法:

1)、適當的增大 hbase.regionserver.lease.period參數的值,默認是1分鐘

2)、增大regionserver的cache大小

#p#

Nginx:

概要介紹

Nginx是一款高性能的HTTP和反向代理服務器,也是一個IMAP/POP3/SMTP代理服務器。第一個公開版本發(fā)布于2004年10月4日,其將源代碼以類BSD許可證的形式發(fā)布,因它的穩(wěn)定性、豐富的功能集和低系統(tǒng)資源的消耗而聞名。Nginx的最新穩(wěn)定版本是1.4.4。與Apache、Lighttpd不同,Nginx充分使用異步邏輯,削減了上下文調度開銷,所以并發(fā)服務能力更強。Nginx整體采用模塊化設計,有豐富的模塊庫和第三方模塊庫,配置靈活。 在Linux操作系統(tǒng)下,Nginx使用epoll事件模型,得益于此,其在效率相當高。在國內,各大主流站點都在使用Nginx作為Web服務器或反向代理服務器。據統(tǒng)計,截止今年2013年7月,在全球Top 1000網站中,有34.9%的網站在使用Nginx,這使得Nginx超越Apache,成為了TOP站點最信任的Web服務器。下圖可見Nginx在 TOP站點的受歡迎程度(見橙色條目)。

 

主要功能

  • 輕松搞定C10K問題,且占內存極少,據稱C10K idle連接僅需內存2.5MB;
  • 處理靜態(tài)文件的性能非常優(yōu)秀,支持sendfile、AIO等高級特性,支持靜態(tài)文件Auto Index;
  • 支持反向代理,對后端服務進行健康檢查;
  • 支持反向代理緩存,避免與后端的頻繁交互;
  • 支持郵件服務代理:IMAP、POP3、SMTP;
  • 支持負載均衡策略,包括:round-robin、weight、hash、consistent hash、fair等;
  • 支持HTTPS安全訪問;
  • 支持虛擬主機的配置;
  • 支持基本Web認證機制;
  • 支持基于IP的訪問控制;
  • 支持URL規(guī)則重寫;
  • 支持并發(fā)連接數限制和單條連接的限速;
  • 支持WebSocket和SPDY;
  • 支持Referer 過濾防盜鏈;
  • 支持靈活配置輸出日志;

擴展功能

  • 能夠在配置文件中嵌入ngx_perl和ngx_lua腳本,擴展功能超強;
  • 提供了與Memcached、Redis、MySQL、PostgreSQL、MangoDB、MogileFS、TaobaoFS等常見服務器交互的模塊;
  • Image 模塊實現了簡單的圖片功能,包括:縮略、裁剪、質量參數等;
  • 視頻支持包括:FLV和MP4視頻播放,RTMP模塊具有在線ffmpeg轉碼以及M3U8的支持;
  • PageSpeed模塊實現網頁加速功能,具體包括:圖片優(yōu)化,CSS&JS 壓縮合并,資源內聯,HTML重寫;
  • 與后端Tomcat的連接可以使用AJP 模塊進行協(xié)議優(yōu)化;
  • Push 模塊實現長連接輪詢服務,實現Web推送服務(Comet);
  • UploadRate 模塊實現上傳的流量限制功能;

常用配置

虛擬主機

  1. http { 
  2.   index index.html; 
  3.   
  4.   # 虛擬主機 www.domain1.com; 
  5.   server { 
  6.     server_name www.domain1.com; 
  7.     access_log logs/domain1.access.log main; 
  8.     root /var/www/domain1.com/htdocs; 
  9.   } 
  10.   # 虛擬主機 www.domain2.com 
  11.   server { 
  12.     server_name www.domain2.com; 
  13.     access_log  logs/domain2.access.log main; 
  14.     root /var/www/domain2.com/htdocs; 
  15.   } 

負載均衡

  1. # 默認的負載均衡,Round-Robin 
  2. upstream backend1  { 
  3.   server backend1.example.com; 
  4.   server backend2.example.com; 
  5.   server backend3.example.com; 
  6. # 基于權重的負載均衡 
  7. upstream backend2  { 
  8.   server backend1.example.com weight=5; 
  9.   server backend2.example.com weight=2; 
  10.   server backend3.example.com weight=3; 
  11. # 基于request_uri hash的負載均衡 
  12. upstream backend3  { 
  13.   server backend1.example.com; 
  14.   server backend2.example.com; 
  15.   server backend3.example.com; 
  16.   hash   $request_uri; 
  17. # 基于request_uri consistent hash的負載均衡 
  18. upstream backend4  { 
  19.   server backend1.example.com; 
  20.   server backend2.example.com; 
  21.   server backend3.example.com; 
  22.   consistent_hash   $request_uri; 
  23. # 基于后端響應時間的負載均衡 
  24. upstream backend5  { 
  25.   server backend1.example.com; 
  26.   server backend2.example.com; 
  27.   server backend3.example.com; 
  28.   fair; 
  29. server { 
  30.   location / { 
  31.     proxy_pass  http://backend1; 
  32.     # proxy_pass  http://backend2; 
  33.     # proxy_pass  http://backend3; 
  34.     # proxy_pass  http://backend4; 
  35.     # proxy_pass  http://backend5; 
  36.   } 

以上可見,Nginx支持的負載均衡策略非常全面,總結有五種策略,即:

  • Round-Robin:輪詢;
  • Weight:基于權重;
  • Hash:基于Nginx內置參數的哈希,內置參數可以為ClientIP、Request_URI等;
  • Consistent Hash:基于Nginx內置參數的一致性哈希;
  • Fair:公平策略,根據響應時間來判定應該將請求發(fā)往那個后端服務器;

除此之外,Nginx負載均衡還支持以下關鍵參數:

  • down:表示當前的server暫時不參與負載;
  • max_fails:允許重試的最大次數,當達到該次數,Nginx將暫停向該server發(fā)送請求;
  • fail_timeout:max_fails次失敗后,暫停的時間;
  • backup: 其它所有的非backup機器down或者忙的時候,請求backup機器,這臺機器壓力會最輕;

流量限制

  1. server { 
  2.   location / { 
  3.     root html;            # 靜態(tài)文件root目錄 
  4.     limit_rate_after 1m;  # 文件下載1M后 
  5.     limit_rate 100k;      # 限制其下載流量為100k 
  6.   } 

注:limit_rate只能限制單條連接的流量

連接限制

  1. http { 
  2.   # 并發(fā)連接統(tǒng)計粒度為 $binary_remote_addr 
  3.   # 粒度還可以為 $request_uri 等任意的Nginx內置變量 
  4.   limit_conn_zone  $binary_remote_addr  zone=one:2m; 
  5.   server { 
  6.     location /download { 
  7.       limit_conn  one  100; # 同一個remote_addr只允許100個并發(fā)連接 
  8.     } 
  9.   } 

代理緩存

  1. server { 
  2.   # 設置Web緩存區(qū)名稱為cache_one,內存緩存空間大小為200MB,1天沒有被訪問的內容自動清除,硬盤緩存空間大小為30GB。 
  3.   proxy_cache_path /data0/proxy_cache_dir levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g; 
  4.   location / { 
  5.     # 如果后端的服務器返回502、504、執(zhí)行超時等錯誤,自動將請求轉發(fā)到upstream負載均衡池中的另一臺服務器,實現故障轉移。 
  6.     proxy_next_upstream http_502 http_504 error timeout invalid_header; 
  7.     proxy_cache cache_one; 
  8.     # 對不同的HTTP狀態(tài)碼設置不同的緩存時間 
  9.     proxy_cache_valid  200 304 12h; 
  10.     # 以域名、URI、參數組合成Web緩存的Key值,Nginx根據Key值哈希,存儲緩存內容到二級緩存目錄內 
  11.     proxy_cache_key $host$uri$is_args$args; 
  12.     proxy_set_header Host  $host; 
  13.     proxy_set_header X-Forwarded-For  $remote_addr; 
  14.     proxy_pass http://backend_server; 
  15.     expires 1d; 
  16.   } 

注1:Nginx反向代理緩存應用于云閱讀縮略圖服務的緩存;

注2:Nginx仍舊以小文件的方式存儲緩存數據,導致磁盤IOUtil較高,當前線上使用SSD;

視頻播放

  1. server { 
  2.   # mp4后綴的文件走mp4播放模塊 
  3.   location ~ \.mp4$ { 
  4.     mp4; 
  5.     mp4_buffer_size       1m; 
  6.     mp4_max_buffer_size   5m; 
  7.     mp4_limit_rate        on; 
  8.     mp4_limit_rate_after  30s; 
  9.   } 
  10.   # flv后綴的文件走flv播放模塊 
  11.   location ~ \.flv$ { 
  12.     flv; 
  13.   } 

注1:云課堂、公開課就是使用這種方式進行視頻播放;

注2:線上環(huán)境更加復雜,還編譯了第三方的mp4播放模塊以支持android4.4的播放;

常見問題

  • CLOUD-6824:與后端服務務必保持長連接,否則將出現大量TIME_WAIT,并且會影響性能;
  • CLOUD-6832:HTTP1.0的請求在過Nginx反向代理時,默認將不會保持Keep-Alive,需要專門進行配置;
  • CLOUD-6833:錯誤日志error.log是監(jiān)控Nginx狀態(tài)的重要途徑,可以寫腳本監(jiān)控其輸出并報警;
  • CLOUD-6332:Nginx默認會緩存上傳和下載的臨時文件,大量的上傳下載可能導致臨時文件目錄磁盤IO成為瓶頸,需要適當調整;
  • CLOUD-6519:Nginx與后端并發(fā)量不是很大的時候,可以開啟流式下載,以避免臨時文件導致的額外磁盤IO;
  • CLOUD-7493:Nginx讀靜態(tài)文件時默認不會開啟AIO,可能導致Worker進程D狀態(tài);
  • CLOUD-7065:Nginx默認情況下,worker_rlimit_nofile為1024,導致大并發(fā)請求失敗,因此大并發(fā)需要設置合理的worker_rlimit_nofile值;
  • CLOUD-6334:對于服務海量請求的Nginx,需要做專門的優(yōu)化,具體這里有專門的總結;
  • CLOUD-5582:Nginx與后端服務器Keep-Alive連接的數量為 worker_count * keep_alive 配置;
  • CLOUD-7224:可以配置Nginx coredump時產生的core路徑,以便事后分析原因;
  • CLOUD-7461:臨時文件緩存大小和后端連接的超時需要綜合考慮,否則可能出問題;
  • SDFS-497:如果后端服務返回的HTTP請求沒有Content-Length頭,Nginx默認將使用Transfer-Encoding:chunked對Body進行編碼;

#p#

Zookeeper:

ZooKeeper

一、簡介

ZooKeeper是一個開源的分布式應用協(xié)調服務,以Fast Paxos算法為理論基礎,可保證分布式環(huán)境中數據的強一致性,可用于解決分布式應用中經常遇到的數據管理問題。

二、ZooKeeper編程模型

ZooKeeper的數據模型風格很像文件系統(tǒng)的目錄結構,可看做一個樹形結構的數據庫,與文件系統(tǒng)不同的是文件系統(tǒng)中的節(jié)點有目錄和文件的區(qū)分, 目錄是中間節(jié)點,其本身并不存數據,而文件是葉節(jié)點,只有內容沒有子項;而zookeeper的樹形結構中所有的節(jié)點上都能存儲數據內容,也能包含子項。 其節(jié)點被成為zNode,zNode有臨時(EPHEMERAL)和遞增(SEQUENTIAL)等可選屬性,zNode可以通過配置Watcher來監(jiān) 控狀態(tài)變化,并引導客戶端觸發(fā)相應操作。關于Zookeeper的介紹和數據模型等可參考以下文章:

http://shiyanjun.cn/archives/474.html

http://stblog.baidu-tech.com/?p=1164

三、應用場景

常見的應用場景如下:

場景1 心跳狀態(tài)檢測

利用zookeeper的EPHEMERAL節(jié)點的特征,記錄server的活動狀態(tài)。server宕機時,zookeeper連接斷開,EPHEMERAL自動刪除,可通過watch EPHEMERAL節(jié)點的存在狀況判斷server的存活狀態(tài)。

場景2 全局自增ID的生成

利用Zookeeper的SEQUENTIAL的特征,單個節(jié)點下的SEQUENTIAL節(jié)點名稱都帶有自增的序號,獲取ID是只需創(chuàng)建一個SEQUENTIAL節(jié)點即可。

場景3 統(tǒng)一命名服務(Naming Service)

利用zk的樹形結構特征,每個節(jié)點有全局唯一的路徑,可用來提供全局命名。

景4 配置管理(即發(fā)布訂閱)

利用zookeeper可以配置Watcher的特征,可以將分布式系統(tǒng)的配置寫入到不同的樹形節(jié)點中,客戶端對關心的配置項設置watcher,當配置發(fā)生變更時自動獲取最新配置,從而實現分布式環(huán)境下不同節(jié)點上配置的實時更新。

場景5 集群管理

利用zookeeper基于fast paxos算法的選舉功能,實現集群master節(jié)點的選舉。可以在集群環(huán)境中master宕機時動態(tài)選擇master,解決傳統(tǒng)上很容易出現的單點故障問題。

場景6 共享鎖Locks

利用EPHEMERAL_SEQUENTIAL節(jié)點的特征,實現共享鎖,需要獲得鎖的 Server 創(chuàng)建一個 EPHEMERAL_SEQUENTIAL 目錄節(jié)點,然后調用 getChildren方法獲取當前的目錄節(jié)點列表中最小的目錄節(jié)點是不是就是自己創(chuàng)建的目錄節(jié)點,如果正是自己創(chuàng)建的,那么它就獲得了這個鎖,如果不是 那么它就調用 exists(String path, boolean watch) 方法并監(jiān)控 Zookeeper 上目錄節(jié)點列表的變化,一直到自己創(chuàng)建的節(jié)點是列表中最小編號的目錄節(jié)點,從而獲得鎖,釋放鎖時直接刪除自己創(chuàng)建的節(jié)點。

場景7 隊列管理

ZooKeeper 可以處理兩種類型的隊列:

1. 當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達,這種是同步隊列。

2. 隊列按照 FIFO 方式進行入隊和出隊操作,例如實現生產者和消費者模型。關于應用場景的描述和實現具體可參考以下博文:

http://django-china.cn/topic/135/ (原文http://rdc.taobao.com/team/jm/archives/1232 )

四、應用陷阱

并不是任何分布式應用都適合使用ZooKeeper來構建協(xié)調服務,以下是幾種可能出現的問題:

1. 丟失ZNode上的變更通知

客戶端連接到ZooKeeper Server以后,會維護一個TCP連接,在CONNECTED狀態(tài)下,客戶端設置了某個ZNode的Watch監(jiān)聽器,可以收到來自該節(jié)點變更的通知并 觸發(fā)相應的事件。但是如果由于網絡異??蛻舳藬嚅_了與ZooKeeper Server的連接,在斷開的過程中,是無法收到ZooKeeper在ZNode上發(fā)送的節(jié)點數據變更通知的。如果使用ZooKeeper的Watch, 必須要尋找保持CONNECTED的Watch,才能保證不會丟失該Watch監(jiān)控的ZNode上的數據變更通知。

2. 無效ZooKeeper集群節(jié)點列表

與ZooKeeper集群交互時,一般情況下客戶端會持有一個ZooKeeper集群節(jié)點的列表,或者列表的子集,那么會存在如下兩種情況: 一種情況是,如果客戶端持有ZooKeeper集群節(jié)點列表或列表子集,如果列表中的某些節(jié)點因為故障退出了集群客戶端再次連接這一類失效的節(jié)點,就無法 獲取服務。所以在應用中使用ZooKeeper集群時,一定要明確這一點,或者跳過無效的節(jié)點,或者重新尋找有效的節(jié)點繼續(xù)業(yè)務處理,或者檢查 ZooKeeper集群,使整個集群恢復正常。

3. 配置導致的性能問題

如果設置Java堆內存(Heap)不合理,會導致ZooKeeper內存不足,會在內存與文件系統(tǒng)之間進行數據交換,導致ZooKeeper的性 能極大地下降,從而可能會影響應用程序。為了避免Swapping問題的出現,主要考慮設置足夠的Java堆內存,同時減少被操作系統(tǒng)和Cache使用的 內存,盡量避免在內存與文件系統(tǒng)之間發(fā)生數據交換,或者可以將交換限制在一定的范圍之內。

4. 事務日志存儲設備性能

ZooKeeper會同步事務到存儲設備,如果存儲設備不是專用的,而是和其他I/O密集型應用共享同一磁盤,會導致ZooKeeper的效率降 低。因為客戶端請求ZNode數據變更而發(fā)生的事務,ZooKeeper會在響應之前將事務日志寫入存儲設備,為zookeeper配置專用的存儲設備可 以使整個服務以及外部應用都會獲得極大地性能提升。

5. ZNode存儲大量數據導致性能問題

ZooKeeper的設計初衷是,每個ZNode只存放少量的同步數據(一般一個節(jié)點上的數據小于1M),如果存儲了大量數據,導致 ZooKeeper每次節(jié)點發(fā)生變更時需要將事務寫入存儲設備,同時還要在集群內部復制傳播,這將導致不可避免的延遲和性能問題。所以,如果需要與大量的 數據相關,可以將大量數據存儲在其他設備中,而只是在ZooKeeper中存儲一個簡單的映射,如指針、引用等等。

五、其他

  • zookeeper節(jié)點的size限制,和超限后的解決方法

Zookeeper單個Znode能存放的數據大小在1M左右,如果數據量過大客戶端會出現異常,異常信息類似如下:Packet len5187750 is out of range!

這種情況可以通過修改java環(huán)境變量來解決,但是還是需要在應用中避免在zookeeper上存儲大量數據的情況,這是一種不好的使用方式。-Djute.maxbuffer=51877500

如:$JAVA -cp “$CLASSPATH” -Djute.maxbuffer=51877500 com.netease.datastream.tool.zkUtil.opers.ZkUtilMain $* 2>&1 &

  • 配置完ZooKeeper集群服務之后要配置Snapshot和Transaction log的定時清理任務

由于所有zookeeper上的數據操作都會觸發(fā)事務日志,事務日志在達到一定大小之后會歸檔為鏡像文件snapshot,如果不配置定時清理任務,這些文件會很快耗盡磁盤空間。可以在linux的crontab任務列表中配置如下項:# m h dom mon dow command

0 7 * * * /home/ds/zookeeper/bin/zkCleanup.sh -n 5 >/dev/null以上任務表示每日7:00執(zhí)行清理任務,僅保留最新的5個鏡像文件和事務日志。

  • 查看指定某個節(jié)點狀態(tài)

可通過以下腳本echo stat|nc

  • 相關工具

Eclipse插件 update-site http://www.massedynamic.org/eclipse/updates/

Zookeeper瀏覽器客戶端 https://issues.apache.org/jira/secure/attachment/12436620/ZooInspector.zip

附、參考文檔

官方文檔: http://zookeeper.apache.org/doc/r3.4.5/

安裝配置: http://shiyanjun.cn/archives/469.html

原文鏈接:http://thinkinginjavablog.sinaapp.com/?p=599&utm_source=tuicool&utm_medium=referral

責任編輯:Ophira 來源: 機會永遠留給有準備的人
相關推薦

2023-10-08 10:49:16

搜索系統(tǒng)分布式系統(tǒng)

2013-06-18 14:13:43

HDFS分布式文件系統(tǒng)

2021-07-09 05:49:53

分布式代碼算法

2019-09-05 09:02:45

消息系統(tǒng)緩存高可用

2022-04-07 17:13:09

緩存算法服務端

2023-05-12 08:23:03

分布式系統(tǒng)網絡

2022-04-14 10:24:27

分布式系統(tǒng)性能

2015-05-26 11:18:06

分布式系統(tǒng)可擴展性

2013-06-13 11:29:14

分布式分布式緩存

2023-02-11 00:04:17

分布式系統(tǒng)安全

2013-01-07 10:29:31

大數據

2017-12-12 14:51:15

分布式緩存設計

2020-10-30 07:47:42

分布式

2023-05-29 14:07:00

Zuul網關系統(tǒng)

2015-05-12 13:03:54

開源分布式存儲HDFS

2017-05-22 09:58:01

虛擬機虛擬化分布式

2023-11-07 12:00:05

分布式系統(tǒng)數據訪問

2017-10-27 08:40:44

分布式存儲剪枝系統(tǒng)

2023-10-26 18:10:43

分布式并行技術系統(tǒng)

2023-05-05 06:13:51

分布式多級緩存系統(tǒng)
點贊
收藏

51CTO技術棧公眾號