架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇

WBOY
發布: 2016-07-30 13:29:58
原創
1245 人瀏覽過

1、概述

很明顯透過前面的八篇文章的介紹,並不能涵蓋負載平衡層的所有技術,但是可以作為一個引子,告訴各位讀者一個學習和使用負載平衡技術的思路。雖然後面我們將轉向「業務層」和「業務通訊」層的介紹,但對負載平衡層的介紹也不會停止。在後續的時間我們將穿插進行負載平衡層的新文章的發布,包括Nginx技術的再介紹、HaProxy、LVS新的使用場景等等。

這篇文章我們對前面的知識點進行總結,並有意進行一些擴展,以便於各位讀者找到新的學習思路。

2、負載平衡層的核心思想

2-1、一致性雜湊與Key的選取

架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇

在《架構設計:負載平衡層設計方案(2)—Nginx安裝》 文章中我們詳細介紹了一致性哈希演算法。並且強調了一致性Hash演算法是現代系統架構中最關鍵的演算法之一,在分散式運算系統、分散式儲存系統、資料分析等眾多領域中廣泛應用。針對我的博文,在負載平衡層、業務通訊層、資料儲存層都會有它的身影。

一致性演算法的核心是:

  • 使用物件的某一個屬性(這個屬性可以是伺服器的IP位址、開放埠還可以是使用者名稱、某種加密串。凡是你可以想到的有雜湊意義的屬性),算出一個整數,讓其分佈在0 至2的32次方範圍內。
  • 一台伺服器的某個或某些屬性當然也可以進行hash計算,並且根據計算分佈在這個圓環上的某一點,也就是圖中圓環上的藍色點。
  • 一個處理請求到來時,根據這個請求的某一個或某一些屬性進行hash計算,並且根據計算記過分佈在這個圓環上的某一個點上。也就是上圖圓環上的黃色點。
  • 我們約定落在某一個藍點A左側和藍點B右側的黃色點所代表的請求,都有藍點A所代表的伺服器進行處理,這樣就完成解決了「誰來處理」的問題。在藍色點穩定存在的前提下,來自於同一個Hash約定的請求所落在的位置都是一樣的,這就保證了服務處理映射的穩定性。
  • 當某一個藍色點由於某種原因下線,其所影響到的黃點也是有限的。即下一次客戶端的請求將由其他的藍色點所代表的伺服器進行處理。

2-2、輪詢與權

架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇

  • 不加權輪詢,就是主控節點(任務來源點)在不考慮目標節點的任何因素的情況下(例如CPU效能、磁碟效能、網路效能),依照目標節點的列表順序依序分配任務。這是最簡單的輪詢,也是對主控節點實現複雜性要求最低的輪詢。我之前的部落格文章《架構設計:負載平衡層設計方案(2)-Nginx安裝》、《架構設計:負載平衡層設計方案(4)-LVS原理》 都對這種最簡輪詢進行了介紹:例如LVS中的“rr”參數。

  • 加權輪詢中的“權”,您可以看成是“輪詢”依據的意思。 「權」可以是很多種可能,可以是目標機器的效能量化值、可以是一個固定的數字(以固定數字加權)、可以是目標節點的網路速度。例如LVS中的「l​​c」參數,就是指依照目標機器,現在已有的「連接」數量進行加權:連線數量越少,越有更大的幾率獲得這個任務的處理權。

2-3、租約與健康檢查

架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇

租約協議主要為了保證一個事實:如果伺服器對客戶端的檢查操作在「最遲時間」失敗後,那麼伺服器端肯定會註銷客戶端的登錄訊息,同時客戶端上伺服器的連接資訊也會消失(並且不在向下提供服務)。每一次檢查成功,這個「最遲時間」都會向後推移。

租約協定和我們提到的雜湊演算法一下一樣,也是系統架構設計中最基本的設計思想,並且大量運用在各類型的系統中,它的工作原理是每一位架構師都需要掌握的。例如:zookeeper使用這個協定來保證Flow節點和Leader節點的連結是正常的;分散式儲存系統用這個協定保證datanode和namenode的連接是正常的;

3、負載平衡層技術總合

在前面的在博文中,我重點介紹了Nginx、LVS、Keepalived技術。由於時間有限,這裡我們對博文中提到的幾種技術進行一個總結,然後再擴展介紹一下DNS技術、CDN技術和硬體負載技術。

3-1、Nginx技術

在负载均衡层这个大的章节中,我有三篇文章都在直接介绍Nginx的原理和使用。但是之后有朋友给我反映还想了解更多的Nginx知识,特别点名要求我再做一篇文章介绍Nginx的动态缓存。是的,我在后面的时间里是有计划介绍Nginx的动态缓存技术,还会介绍Nginx和多款主流的反向代理软件的性能对比。但这需要时间,特别是我不想去网上找一些已有的性能对比图,还是自己一边做这样的性能测试,一边做性能报告比较靠谱。

下面这些技术是我在博文中已经重点介绍过得,我们再做一下总结:

  • Nginx中的连接数限制问题

重要的配置项包括:worker_processes、worker_connections。但是光是配置这些属性是不够的,最关键的是我们要打开操作系统级别的“最大文件数”限制问题。使用“ulimit -n 65535”设置本次会话的“最大文件数”限制;还要使用“vim /etc/security/limits.conf”命令,修改内核的配置信息。主要是以下两项:

<code><span>* </span>soft nofile 65535 
<span>* </span>hard nofile 65535</code>
登入後複製

另外,还要注意和nginx配置项中的“worker_rlimit_nofile”属性共同使用:

<code>user root root; 
worker_processes <span>4</span>; 
worker_rlimit_nofile <span>65535</span>;

<span>#error_log logs/error.log; </span><span>#error_log logs/error.log notice; </span><span>#error_log logs/error.log info;</span><span>#pid logs/nginx.pid; </span>
events { 
    use epoll; 
    worker_connections <span>65535</span>; 
}</code>
登入後複製
  • Nginx中的Gzip技术

gzip是Nginx进行HTTP Body数据压缩的技术。下面这段Nginx配置信息是启用gzip压缩的实例:

<code><span>#开启gzip压缩服务, </span>
gzip <span><span>on</span></span>;

<span>#gzip压缩是要申请临时内存空间的,假设前提是压缩后大小是小于等于压缩前的。例如,如果原始文件大小为10K,那么它超过了8K,所以分配的内存是8 * 2 = 16K;再例如,原始文件大小为18K,很明显16K也是不够的,那么按照 8 * 2 * 2 = 32K的大小申请内存。如果没有设置,默认值是申请跟原始数据相同大小的内存空间去存储gzip压缩结果。 </span>
gzip_buffers <span>2</span><span>8</span>k;

<span>#进行压缩的原始文件的最小大小值,也就是说如果原始文件小于5K,那么就不会进行压缩了 </span>
gzip_min_length <span>5</span>K;

<span>#gzip压缩基于的http协议版本,默认就是HTTP 1.1 </span>
gzip_http_version <span>1.1</span>;

<span># gzip压缩级别1-9,级别越高压缩率越大,压缩时间也就越长CPU越高 </span>
gzip_comp_level <span>5</span>;

<span>#需要进行gzip压缩的Content-Type的Header的类型。建议js、text、css、xml、json都要进行压缩;图片就没必要了,gif、jpge文件已经压缩得很好了,就算再压,效果也不好,而且还耗费cpu。 </span>
gzip_types <span>text</span>/HTML <span>text</span>/plain <span>application</span>/x-javascript <span>text</span>/css <span>application</span>/xml;</code>
登入後複製

http返回数据进行压缩的功能在很多场景下都实用:

a、 如果浏览器使用的是3G/4G网络,那么流量对于用户来说就是money。

b、 压缩可节约服务器机房的对外带宽,为更多用户服务。按照目前的市场价良好的机房带宽资源的一般在200RMB/Mbps,而服务器方案的压力往往也来自于机房带宽。

c、 不是Nginx开启了gzip功能,HTTP响应的数据就一定会被压缩,除了满足Nginx设置的“需要压缩的http格式”以外,客户端(浏览器)也需要支持gzip(不然它怎么解压呢),一个好消息是,目前大多数浏览器和API都支持http压缩。

  • Nginx中的rewrite(重写)技术

Nginx的强大在于其对URL请求的重写(重定位)。Nginx的rewrite功能依赖于PCRE Lib,请一定在Nginx编译安装时,安装Pcre lib。

Nginx的rewrite功能在我《架构设计:负载均衡层设计方案(3)——Nginx进阶》 这边博客中进行了讲解。

下面是一段rewrite的示例:

<code><span>#示例1:</span>
location ~* ^<span>/(.+)/</span>(.+)\.(jpg|gif|png|jpeg)<span>$ </span>{
    rewrite ^<span>/orderinfo/</span>(.+)\.(jpg|gif|png|jpeg)<span>$ </span>  /img/<span>$1</span>.<span>$2</span><span>break</span>;
    root   /cephclient;
}

<span>#location在不进行大小写区分的情况下利用正则表达式对$url进行匹配。当匹配成功后进行rewrite重定位。</span><span>#rewrite进行重写url的规则是:regex表达式第一个括号中的内容对应$1,regex表达式第二个括号中的内容对应$2,以此类推。</span><span>#这样重定位的意义就很明确了:将任何目录下的文件名重定位到img目录下的对应文件名,</span><span>#并且马上在这个location中(注意是Nginx,而不是客户端)执行这个重写后的URL定位。</span><span>#示例2:</span>
server {
    。。。。
    。。。。
    location ~* ^<span>/orderinfo/</span>(.+)\.(jpg|gif|png|jpeg)<span>$ </span>{
        rewrite ^<span>/orderinfo/</span>(.+)\.(.+)<span>$ </span> /img/<span>$1</span>.<span>$2</span>   last;
    }

    location / {
        root   /cephclient;
    }
}

<span>#在server中,有两个location位置,当url需要访问orderinfo目录下的某一个图片时,rewrite将重写这个url,</span><span>#并且重新带入这个url到server执行,这样“location /”这个location就会执行了,并找到图片存储的目录。</span></code>
登入後複製
  • Nginx的图片处理模块

http_image_filter_module 是nginx的图片处理模块,是使用nginx进行静态资源和动态资源分开管理的关键引用技术。通过这个模块可以对静态资源进行缩放、旋转、验证。

需要注意的是,http_image_filter_module模块所处理的缩率图片是不进行保存的,完全使用节点的CPU性能进行计算,使用节点的内存进行临时存储。所以如果要使用http_image_filter_module进行图片处理,一定要根据客户端的请求规模进行nginx节点的调整。并且当站点的PV达到一定的规模时,一定要使用CDN技术进行访问加速、对图片的访问处理手段进行规划。

由于我们在之前涉及Nginx的文章中,并没有详细讲解Nginx的图片处理模块,只是说了要进行介绍,所以这里我给出一个较为详细的安装和配置示例:

nginx的http_image_filter_module模块由GD library进行支持,所以要使用这个图片处理模块,就必须进行第三方依赖包的安装:

<code>yum <span>install</span> gd-devel</code>
登入後複製

然后,Nginx要进行重新编译:

<code>configure <span>--</span><span>with</span><span>-http_image_filter_module</span>
make <span>&&</span> make install</code>
登入後複製

使用图片处理模块的配置示例:

<code>location ~* /(.+)_(\d+)_(\d+)\.(jpg|gif|png|ioc|jpeg)$ {
    <span>set</span><span>$h</span><span>$3</span>;
    <span>set</span><span>$w</span><span>$2</span>;
    rewrite /(.+)_(\d+)_(\d+)\.(jpg|gif|png|ioc|jpeg)$ /<span>$1</span>.<span>$4</span><span>break</span>;

    image_filter resize <span>$w</span><span>$h</span>;
    image_filter_buffer <span>2</span>M;
}</code>
登入後複製

其中关于正则表达式的语法和已经介绍过的rewrite的语法就不再进行介绍了,主要看http_image_filter_module相关的属性设置:

image_filter test:测试图片文件合法性
image_filter rotate:进行图片旋转,只能按照90 | 180 | 270进行旋转
image_filter size:返回图片的JSON数据
image_filter resize width height:按比例进行图片的等比例缩小,注意,是只能缩小,第二缩小是等比例的。
image_filter_buffer:限制图片最大读取大小,没有设置就是1M;根据不同的系统最好设置为2M—3M
image_filter_jpeg_quality:设置jpeg图片的压缩比例(1-99,越高越好)
image_filter_transparency:禁用gif和png图片的透明度。

  • 和Nginx类似的其他技术/软件

目前行业内也有很多与Nginx解决同类问题的软件,他们分别是Apache基金会的 Apache HTTP Server、淘宝开源的Tengine、Haproxy、包括Windows 下运行的IIS,也支持反向代理 。

这里笔者再次重点提到Tengine,建议各位读者有时间的时候可以使用一下,这个对Nginx进行了深度再开发的软件。

3-2、LVS技术

LVS是Linux Virtual Server的簡寫,意即Linux虛擬伺服器,是一個虛擬的伺服器叢集系統。本計畫於1998年5月由章文嵩博士成立。

LVS叢集採用IP負載平衡技術和基於內容請求分發技術。調度器具有很好的吞吐率,將請求均衡地轉移到不同的伺服器上執行,且調度器自動屏蔽掉伺服器的故障,從而將一組伺服器構成一個高效能的、高可用的虛擬伺服器。整個伺服器叢集的結構對客戶是透明的,而且無需修改客戶端和伺服器端的程式。

在我的系列文章中,《架構設計:負載平衡層設計方案(4)-LVS原理》 、《架構設計:負載平衡層設計方案(5)-LVS單節點安裝》 、《負載平衡層設計方案(7)-LVS + Keepalived + Nginx安裝及設定》 都涉及到LVS的講解。

這裡我們再總結一下LVS中的三種工作模式:

3-2-1、NAT模式

NAT方式是一種由LVS Master服務節點收到資料報,然後轉給下層的Real Server節點,當Real Server處理完成後回發給LVS Master節點接著又由LVS Master節點轉送出去的工作方式。 LVS的管理程式IPVSADMIN負責綁定轉送規則,並完成IP資料封包和TCP資料封包中屬性的重寫。

架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇

LVS-NAT模式的優點在於:

  • 配置管理簡單。 LVS-NAT的工作方式是LVS三種工作模式中最容易理解、最容易配置、最容易管理的工作模式。

  • 節省外網IP資源,一般機房分配給使用者的IP數量是有限的,特別是您購買的機架的數量不多時。 LVS-NAT工作方式將您的系統架構封裝在區域網路中,只需要LVS有一個外網路位址或外網路位址對映就可以實現存取了。

  • 系統架構相對封閉。在內網環境下我們對防火牆的設定要求不會很高,也相對容易進行實體伺服器的運維。您可以設定來自外網的請求需要進行防火牆過濾,而對內部網路請求開放存取。

  • 另外改寫後轉給Real Server的資料報文,Real Server並不會關心它的真實性,只要TCP校驗和IP校驗都能通過,Real Server就可以進行處理。所以LVS-NAT工作模式下Real Server可以是任何作業系統,只要它支援TCP/IP協定即可。

3-2-2、DR模式

LVS的DR工作模式,是目前生產環境中最常用的一種工作模式,網路上的資料也是最多的,有的文章對DR工作模式的講解還是比較透徹的:

架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇

LVS-DR模式的優點在於:

  • 解決了LVS-NAT工作模式中的轉送瓶頸問題,能夠支撐規模更大的負載平衡場景。

  • 比較耗費網外IP資源,機房的外網IP資源都是有限的,如果在正式生產環境中確實存在這個問題,可以採用LVS-NAT和LVS-DR混合使用的方式來緩解。

LVS-DR當然也有缺點:

  • 配置工作較LVS-NAT方式稍微麻煩一點,您至少需要了解LVS-DR模式的基本工作方式才能更好的指導自己進行LVS-DR模式的配置和運行過程中問題的解決。

  • 由於LVS-DR模式的封包改寫規則,導致LVS節點和Real Server節點必須在一個網段,因為二層交換是沒法跨子網路的。但是這個問題針對大多數系統架構方案來說,其實並沒有本質限制。

3-2-3、TUN模式

LVS-DR模式和LVS-TUN模式的工作原理完全不一樣,工作場景完全不一樣。 DR是根據資料封包重寫,TUN模式基於IP隧道,後者是資料封包的重新封裝:

架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇

IPIP隧道。將一個完整的IP封包封裝成另一個新的IP封包的資料部分,並透過路由器傳送到指定的地點。在這個過程中路由器並不在意被封裝的原始協定的內容。到達目的地點後,由目的地方依靠自己的計算能力和對IPIP隧道協議的支持,打開封裝協議,取得原始協議:

架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇

可以說LVS-TUN方式基本上具有LVS-DR的優點。在此基礎上又支援跨子網間穿透。

3-3、CDN技術

CDN技術Content Delivery Network:內容傳遞網路。為什麼有時我們會上網的影片資源、圖片資源會比較慢,甚至是存取失敗。其中有一個重要的原因,是資源的實體位置離客戶端太遠了,可能其中有4層NAT設備(相當於使用網通的線路存取電信伺服器上的資源)。

我們試想一下,如果將我們要存取的資源放到離我們客戶端最近的一個服務上(例如在廣州的客戶端訪問的資源就在廣州的機房)。那麼是不是就解決了這個問題(這個點稱為「邊緣節點」)。這就是CDN網路解決​​的問題,如下圖所示:

架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇

目前CDN服務不需要我們進行開發,市面上有很多公司都提供免費的/付費的CDN服務(請直接在google或百度上面輸入:CDN,就會有很多「推廣」訊息了,在我的博文中不打廣告^_^)。當然如果您想自行建立CDN網絡,可以參考以下技術方案:

Squid:Squid是一個快取internet資料的一個軟體,它接收使用者的下載申請,並自動處理所下載的資料。目前,國內許多CDN服務商的網路都是基於Squid搭建的

利用Nginx的proxy_cache搭建:Nginx中的rewrite技術其實可以實作URL請求重寫,實現請求轉送。而Nginx中的proxy_cache元件可以使得從遠端請求的來源資料保存在本地,從而實現一個CDN網路的搭建。

自己寫:CDN網路沒有特別複雜的技術門檻,如果您有特別的需求,可以自己寫一個。當然上圖所介紹的CDN網絡屬於第一代CDN網絡,將第二代/第三代P2P技術加入CDN原理中,可以形成第二代CDN網絡:如下圖:

架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇

第三代P2P技術又稱為混合型P2P技術主要是為了解決元資料伺服器的處理壓力,加速資源的在地化速度。關於P2P技術我會在講完「業務系統設計」、「業務通訊系統設計」後,專門做一個新的專題介紹。另外提一下,YouTube的P2P網路就是自己做的。

4、後文介紹

要總結的內容實在太多了,我決定再開一篇文章《架構設計:負載平衡層設計方案(9)-負載平衡層總結下篇》,繼續進行負載均衡層技術的總結。我們將總結Keepalived、DNS技術、硬體負載,並且向大家介紹更廣義的負載平衡技術。

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。

以上就介紹了 架構設計:負載平衡層設計方案(8)-負載平衡層總結上篇,包含了方面的內容,希望對PHP教學有興趣的朋友有所幫助。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!