A. 什麼是分布式緩存
分布式緩存能夠處理大量的動態數據,因此比較適合應用在Web 2.0時代中的社交網站等需要由用戶生成內容的場景。從本地緩存擴展到分布式緩存後,關注重點從CPU、內存、緩存之間的數據傳輸速度差異也擴展到了業務系統、資料庫、分布式緩存之間的數據傳輸速度差異。
常用的分布式緩存包括Redis和Memcached。
Memcached
Memcached是一個高性能的分布式內存對象緩存系統,用於動態Web應用以減輕資料庫負載。Memcached通過在內存中緩存數據和對象來減少讀取資料庫的次數,從而提高動態、資料庫驅動網站的速度。
特點:哈希方式存儲;全內存操作;簡單文本協議進行數據通信;只操作字元型數據;集群由應用進行控制,採用一致性哈希演算法。
限制性:數據保存在內存當中的,一旦機器重啟,數據會全部丟失;只能操作字元型數據,數據類型貧乏;以root許可權運行,而且Memcached本身沒有任何許可權管理和認證功能,安全性不足;能存儲的數據長度有限,最大鍵長250個字元,儲存數據不能超過1M。
Redis
Redis是一個開源的使用ANSI C語言編寫、支持網路、可基於內存亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。
特點:
Redis支持的數據類型包括:字元串、string、hash、set、sortedset、list;Redis實現持久化的方式:定期將內存快照寫入磁碟;寫日誌;Redis支持主從同步。
限制性:單核運行,在存儲大數據的時候性能會有降低;不是全內存操作;主從復制是全量復制,對實際的系統運營造成了一定負擔。
B. EhCache 分布式緩存/緩存集群
一 緩存系統簡介 EhCache 是一個純 Java 的進程內緩存框架 具有快速 精乾等特點 是 Hibernate 中默認的 CacheProvider EhCache 應用架構圖 下圖是 EhCache 在應用程序中的位置
EhCache 的主要特性有 快速 精幹 簡單 多種緩存策略 緩存數據有兩級 內存和磁碟 因此無需擔心容量問題 緩存數據會在虛擬機重啟的過程中寫入磁碟 可以通過 RMI 可插入 API 等方式進行分布式緩存 具有緩存和緩存管理器的偵聽介面 支持多緩存管理器實例 以及一個實例的多個緩存區域 提供 Hibernate 的緩存實現 由於 EhCache 是進程中的緩存系統 一旦將應用部署在集群環境中 每一個節點維護各自的緩存數據 當某個節點對緩存數據進行更新 這些更新的數據無法在其它節點 *** 享 這不僅會降低節點運行的效率 而且會導致數據不同步的情況發生 例如某個網站採用 A B 兩個節點作為集群部署 當 A 節點的緩存更新後 而 B 節點緩存尚未更新就可能出現用戶在瀏覽頁面的時候 一會是更新後的數據 一會是尚未更新的數據 盡管我們也可以通過 Session Sticky 技術來將用戶鎖定在某個節點上 但對於一些交互性比較強或者是非 Web 方式的系統來說 Session Sticky 顯然不太適合 所以就需要用到 EhCache 的集群解決方案 從 版本開始 Ehcache可以使用分布式的緩存了 EhCache 從 版本開始 支持五種集群方案 分別是 ? Terracotta ? RMI ? JMS ? JGroups ? EhCache Server 其中的三種最為常用集群方式 分別是 RMI JGroups 以及 EhCache Server 本文主要介紹RMI的方式 分布式這個特性是以plugin的方式實現的 Ehcache自帶了一些默認的分布式緩存插件實現 這些插件可以滿足大部分應用的需要 如果需要使用其他的插件那就需要自己開發了 開發者可以通過查看distribution包里的源代碼及JavaDoc來實現它 盡管不是必須的 在使用分布式緩存時理解一些ehcahce的設計思想也是有幫助的 這可以參看分布式緩存設計的頁面 以下的部分將展示如何讓分布式插件同ehcache一起工作 下面列出的是一些分布式緩存中比較重要的方面 ? 你如何知道集群環境中的其他緩存? ? 分布式傳送的消息是什麼形式? ? 什麼情況需要進行復制?增加(Puts) 更新(Updates)或是失效(Expiries)? ? 採用什麼方式進行復制?同步還是非同步方式? 為了安裝分布式緩存 你需要配置一個PeerProvider 一個CacheManagerPeerListener 它們對於一個CacheManager來說是全局的 每個進行分布式操作的cache都要添加一個cacheEventListener來傳送消息
二 集群緩存概念及其配置 正確的元素類型 只有可序列化的元素可以進行復制 一些操作 比如移除 只需要元素的鍵值而不用整個元素 在這樣的操作中即使元素不是可序列化的但鍵值是可序列化的也可以被復制 成員發現(Peer Discovery) Ehcache進行集群的時候有一個cache組的概念 每個cache都是其他cache的一個peer 沒有主cache的存在 剛才我們問了一個問題 你如何知道集群環境中的其他緩存?這個問題可以命名為成員發現(Peer Discovery) Ehcache提供了兩種機制用來進行成員發現 就像一輛汽車 手動檔和自動檔 要使用一個內置的成員發現機制要在ehcache的配置文件中指定元素的class屬性為 net sf ehcache distribution 自動的成員發現 自動的發現方式用TCP廣播機制來確定和維持一個廣播組 它只需要一個簡單的配置可以自動的在組中添加和移除成員 在集群中也不需要什麼優化伺服器的知識 這是默認推薦的 成員每秒向群組發送一個 心跳 如果一個成員 秒種都沒有發出信號它將被群組移除 如果一個新的成員發送了一個 心跳 它將被添加進群組 任何一個用這個配置安裝了復制功能的cache都將被其他的成員發現並標識為可用狀態 要設置自動的成員發現 需要指定ehcache配置文件中元素的properties屬性 就像下面這樣 peerDiscovery=automatic multicastGroupAddress=multicast address | multicast host name multicastGroupPort=port timeToLive= (timeToLive屬性詳見常見問題部分的描述) 示例 假設你在集群中有兩台伺服器 你希望同步sampleCache 和sampleCache 每台獨立的伺服器都要有這樣的配置 配置server 和server <class= net sf ehcache distribution properties= peerDiscovery=automatic multicastGroupAddress= />multicastGroupPort= timeToLive= 手動進行成員發現 進行手動成員配置要知道每個監聽器的IP地址和埠 成員不能在運行時動態地添加和移除 在技術上很難使用廣播的情況下就可以手動成員發現 例如在集群的伺服器之間有一個不能傳送廣播報文的路由器 你也可以用手動成員發現進行單向的數據復制 只讓server 知道server 而server 不知道server 配置手動成員發現 需要指定ehcache配置文件中的properties屬性 像下面這樣 peerDiscovery=manual rmiUrls=//server:port/cacheName //server:port/cacheName … rmiUrls配置的是伺服器cache peers的列表 注意不要重復配置 示例 假設你在集群中有兩台伺服器 你要同步sampleCache 和sampleCache 下面是每個伺服器需要的配置 配置server <class= net sf ehcache distribution properties= peerDiscovery=manual />rmiUrls=//server : /sampleCache |//server : /sampleCache 配置server <class= net sf ehcache distribution properties= peerDiscovery=manual />rmiUrls=//server : /sampleCache |//server : /sampleCache 配置CacheManagerPeerListener 每個CacheManagerPeerListener監聽從成員們發向當前CacheManager的消息 配置CacheManagerPeerListener需要指定一個 它以插件的機制實現 用來創建CacheManagerPeerListener 的屬性有 class – 一個完整的工廠類名 properties – 只對這個工廠有意義的屬性 使用逗號分隔 Ehcache有一個內置的基於RMI的分布系統 它的監聽器是RMICacheManagerPeerListener 這個監聽器可以用 RMI來配置 <class= net sf ehcache distribution RMI properties= hostName=localhost port= />socketTimeoutMillis= 有效的屬性是 hostname (可選) – 運行監聽器的伺服器名稱 標明了做為集群群組的成員的地址 同時也是你想要控制的從集群中接收消息的介面在CacheManager初始化的時候會檢查hostname是否可用 如果hostName不可用 CacheManager將拒絕啟動並拋出一個連接被拒絕的異常 如果指定 hostname將使用InetAddress getLocalHost() getHostAddress()來得到 警告 不要將localhost配置為本地地址 因為它在網路中不可見將會導致不能從遠程伺服器接收信息從而不能復制 在同一台機器上有多個CacheManager的時候 你應該只用localhost來配置 port – 監聽器監聽的埠 socketTimeoutMillis (可選) – Socket超時的時間 默認是 ms 當你socket同步緩存請求地址比較遠 不是本地區域網 你可能需要把這個時間配置大些 不然很可能延時導致同步緩存失敗 配置CacheReplicators 每個要進行同步的cache都需要設置一個用來向CacheManagerr的成員復制消息的緩存事件監聽器 這個工作要通過為每個cache的配置增加一個cacheEventListenerFactory元素來完成 <! Sample cache named sampleCache ><cache name= sampleCache maxElementsInMemory= eternal= false timeToIdleSeconds= timeToLiveSeconds= overflowToDisk= false ><cacheEventListenerFactory class= net sf ehcache distribution RMICacheReplicatorFactory properties= replicateAsynchronously=true replicatePuts=true replicateUpdates=true replicateUpdatesViaCopy=false replicateRemovals=true /></cache>class – 使用net sf ehcache distribution RMICacheReplicatorFactory 這個工廠支持以下屬性 replicatePuts=true | false – 當一個新元素增加到緩存中的時候是否要復制到其他的peers 默認是true replicateUpdates=true | false – 當一個已經在緩存中存在的元素被覆蓋時是否要進行復制 默認是true replicateRemovals= true | false – 當元素移除的時候是否進行復制 默認是true replicateAsynchronously=true | false – 復制方式是非同步的(指定為true時)還是同步的(指定為false時) 默認是true replicatePutsViaCopy=true | false – 當一個新增元素被拷貝到其他的cache中時是否進行復制指定為true時為復制 默認是true replicateUpdatesViaCopy=true | false – 當一個元素被拷貝到其他的cache中時是否進行復制(指定為true時為復制) 默認是true 你可以使用ehcache的默認行為從而減少配置的工作量 默認的行為是以非同步的方式復制每件事 你可以像下面的例子一樣減少RMICacheReplicatorFactory的屬性配置 <! Sample cache named sampleCache All missing RMICacheReplicatorFactory properties default to true ><cache name= sampleCache maxElementsInMemory= eternal= true overflowToDisk= false memoryStoreEvictionPolicy= LFU ><cacheEventListenerFactory class= net sf ehcache distribution RMICacheReplicatorFactory /></cache> 常見的問題 Windows上的Tomcat 有一個Tomcat或者是JDK的bug 在tomcat啟動時如果tomcat的安裝路徑中有空格的話 在啟動時RMI監聽器會失敗 參見 bin/wa?A =ind &L=rmi users&P= 和 doc/faq howto bugs/l 由於在Windows上安裝Tomcat默認是裝在 Program Files 文件夾里的 所以這個問題經常發生 廣播阻斷 自動的peer discovery與廣播息息相關 廣播可能被路由阻攔 像Xen和VMWare這種虛擬化的技術也可以阻攔廣播 如果這些都打開了 你可能還在要將你的網卡的相關配置打開 一個簡單的辦法可以告訴廣播是否有效 那就是使用ehcache remote debugger來看 心跳 是否可用 廣播傳播的不夠遠或是傳得太遠 你可以通過設置badly misnamed time to live來控制廣播傳播的距離 用廣播IP協議時 timeToLive的值指的是數據包可以傳遞的域或是范圍 約定如下 是限制在同一個伺服器 是限制在同一個子網 是限制在同一個網站 是限制在同一個region 是限制在同一個大洲 是不限制 譯者按 上面這些資料翻譯的不夠准確 請讀者自行尋找原文理解吧 在Java實現中默認值是 也就是在同一個子網中傳播 改變timeToLive屬性可以限制或是擴展傳播的范圍
三 RMI方式緩存集群/配置分布式緩存 RMI 是 Java 的一種遠程方法調用技術 是一種點對點的基於 Java 對象的通訊方式 EhCache 從 版本開始就支持 RMI 方式的緩存集群 在集群環境中 EhCache 所有緩存對象的鍵和值都必須是可序列化的 也就是必須實現 java io Serializable 介面 這點在其它集群方式下也是需要遵守的 下圖是 RMI 集群模式的結構圖
採用 RMI 集群模式時 集群中的每個節點都是對等關系 並不存在主節點或者從節點的概念 因此節點間必須有一個機制能夠互相認識對方 必須知道其它節點的信息 包括主機地址 埠號等 EhCache 提供兩種節點的發現方式 手工配置和自動發現 手工配置方式要求在每個節點中配置其它所有節點的連接信息 一旦集群中的節點發生變化時 需要對緩存進行重新配置 由於 RMI 是 Java 中內置支持的技術 因此使用 RMI 集群模式時 無需引入其它的 Jar 包 EhCache 本身就帶有支持 RMI 集群的功能 使用 RMI 集群模式需要在 ehcache xml 配置文件中定義 節點 分布式同步緩存要讓這邊的cache知道對方的cache 叫做Peer Discovery(成員發現) EHCache實現成員發現的方式有兩種 手動查找 A 在ehcache xml中配置PeerDiscovery成員發現對象 Server 配置 配置本地hostName port是 分別監聽 : 的mobileCache和 : 的mobileCache 注意這里的mobileCache是緩存的名稱 分別對應著server server 的cache的配置 <?xml version= encoding= gbk ?><ehcache xmlns:xsi= instance xsi:noNamespaceSchemaLocation= ehcache xsd > <diskStore path= java io tmpdir /> <! 集群多台伺服器中的緩存 這里是要同步一些伺服器的緩存 server hostName: port: cacheName:mobileCache server hostName: port: cacheName:mobileCache server hostName: port: cacheName:mobileCache 注意 每台要同步緩存的伺服器的RMI通信socket埠都不一樣 在配置的時候注意設置 > <! server 的配置 > < class= net sf ehcache distribution properties= hostName=localhost port= socketTimeoutMillis= peerDiscovery=manual rmiUrls=// : /mobileCache|// : /mobileCache /></ehcache>以上注意元素出現的位置在diskStore下
同樣在你的另外 台伺服器上增加配置 Server 配置本地host port為 分別同步 : 的mobileCache和 : 的mobileCache <! server 的配置 >< class= net sf ehcache distribution properties= hostName=localhost port= socketTimeoutMillis= peerDiscovery=manual rmiUrls=// : /mobileCache|// : /mobileCache />Server 配置本地host port為 分別同步 : 的mobileCache緩存和 : 的mobileCache緩存 <! server 的配置 >< class= net sf ehcache distribution properties= hostName=localhost port= socketTimeoutMillis= peerDiscovery=manual rmiUrls=// : /mobileCache|// : /mobileCache />這樣就在三台不同的伺服器上配置了手動查找cache的PeerProvider成員發現的配置了 值得注意的是你在配置rmiUrls的時候要特別注意url不能重復出現 並且埠 地址都是對的 如果指定 hostname將使用InetAddress getLocalHost() getHostAddress()來得到 警告 不要將localhost配置為本地地址 因為它在網路中不可見將會導致不能從遠程伺服器接收信息從而不能復制 在同一台機器上有多個CacheManager的時候 你應該只用localhost來配置 B 下面配置緩存和緩存同步監聽 需要在每台伺服器中的ehcache xml文件中增加cache配置和cacheEventListenerFactory cacheLoaderFactory的配置 <defaultCache maxElementsInMemory= eternal= false timeToIdleSeconds= timeToLiveSeconds= overflowToDisk= false /><! 配置自定義緩存 maxElementsInMemory:緩存中允許創建的最大對象數 eternal:緩存中對象是否為永久的 如果是 超時設置將被忽略 對象從不過期 timeToIdleSeconds:緩存數據空閑的最大時間 也就是說如果有一個緩存有多久沒有被訪問就會被銷毀 如果該值是 就意味著元素可以停頓無窮長的時間 timeToLiveSeconds:緩存數據存活的時間 緩存對象最大的的存活時間 超過這個時間就會被銷毀 這只能在元素不是永久駐留時有效 如果該值是 就意味著元素可以停頓無窮長的時間 overflowToDisk:內存不足時 是否啟用磁碟緩存 memoryStoreEvictionPolicy:緩存滿了之後的淘汰演算法 每一個小時更新一次緩存( 小時過期) ><cache name= mobileCache maxElementsInMemory= eternal= false overflowToDisk= true timeToIdleSeconds= timeToLiveSeconds= memoryStoreEvictionPolicy= LFU > <! RMI緩存分布同步查找 class使用net sf ehcache distribution RMICacheReplicatorFactory 這個工廠支持以下屬性 replicatePuts=true | false – 當一個新元素增加到緩存中的時候是否要復制到其他的peers 默認是true replicateUpdates=true | false – 當一個已經在緩存中存在的元素被覆蓋時是否要進行復制 默認是true replicateRemovals= true | false – 當元素移除的時候是否進行復制 默認是true replicateAsynchronously=true | false – 復制方式是非同步的 指定為true時 還是同步的 指定為false時 默認是true replicatePutsViaCopy=true | false – 當一個新增元素被拷貝到其他的cache中時是否進行復制 指定為true時為復制 默認是true replicateUpdatesViaCopy=true | false – 當一個元素被拷貝到其他的cache中時是否進行復制 指定為true時為復制 默認是true = > <! 監聽RMI同步緩存對象配置 注冊相應的的緩存監聽類 用於處理緩存事件 如put remove update 和expire > <cacheEventListenerFactory class= net sf ehcache distribution RMICacheReplicatorFactory properties= replicateAsynchronously=true /> replicatePuts=true replicateUpdates=true replicateUpdatesViaCopy=false replicateRemovals=true <! 用於在初始化緩存 以及自動設置 > <bootstrapCacheLoaderFactory class= net sf ehcache bootstrap BootstrapCacheLoaderFactory /></cache> C 這樣就完成了 台伺服器的配置 下面給出server 的完整的ehcache xml的配置 <?xml version= encoding= gbk ?><ehcache xmlns:xsi= instance xsi:noNamespaceSchemaLocation= ehcache xsd > <diskStore path= java io tmpdir /> <!集群多台伺服器中的緩存 這里是要同步一些伺服器的緩存 server hostName: port: cacheName:mobileCache server hostName: port: cacheName:mobileCache server hostName: port: cacheName:mobileCache 注意每台要同步緩存的伺服器的RMI通信socket埠都不一樣 在配置的時候注意設置 > <! server 的配置 > < class= net sf ehcache distribution properties= hostName=localhost port= socketTimeoutMillis= peerDiscovery=manual rmiUrls=// : /mobileCache|// : /mobileCache /> <defaultCache maxElementsInMemory= eternal= false timeToIdleSeconds= timeToLiveSeconds= overflowToDisk= false /> <! 配置自定義緩存 maxElementsInMemory:緩存中允許創建的最大對象數 eternal:緩存中對象是否為永久的 如果是 超時設置將被忽略 對象從不過期 timeToIdleSeconds:緩存數據空閑的最大時間 也就是說如果有一個緩存有多久沒有被訪問就會被銷毀 如果該值是 就意味著元素可以停頓無窮長的時間 timeToLiveSeconds:緩存數據存活的時間 緩存對象最大的的存活時間 超過這個時間就會被銷毀 這只能在元素不是永久駐留時有效 如果該值是 就意味著元素可以停頓無窮長的時間 overflowToDisk:內存不足時 是否啟用磁碟緩存 memoryStoreEvictionPolicy:緩存滿了之後的淘汰演算法 每一個小時更新一次緩存( 小時過期) > <cache name= mobileCache maxElementsInMemory= eternal= false overflowToDisk= true timeToIdleSeconds= timeToLiveSeconds= memoryStoreEvictionPolicy= LFU > <! RMI緩存分布同步查找 class使用net sf ehcache distribution RMICacheReplicatorFactory 這個工廠支持以下屬性 replicatePuts=true | false – 當一個新元素增加到緩存中的時候是否要復制到其他的peers 默認是true replicateUpdates=true | false – 當一個已經在緩存中存在的元素被覆蓋時是否要進行復制 默認是true replicateRemovals= true | false – 當元素移除的時候是否進行復制 默認是true replicateAsynchronously=true | false – 復制方式是非同步的 指定為true時 還是同步的 指定為false時 默認是true replicatePutsViaCopy=true | false – 當一個新增元素被拷貝到其他的cache中時是否進行復制 指定為true時為復制 默認是true replicateUpdatesViaCopy=true | false – 當一個元素被拷貝到其他的cache中時是否進行復制 指定為true時為復制 默認是true = > <! 監聽RMI同步緩存對象配置 注冊相應的的緩存監聽類 用於處理緩存事件 如put remove update 和expire > <cacheEventListenerFactory class= net sf ehcache distribution RMICacheReplicatorFactory properties= replicateAsynchronously=true /> replicatePuts=true replicateUpdates=true replicateUpdatesViaCopy=false replicateRemovals=true <! 用於在初始化緩存 以及自動設置 > <bootstrapCacheLoaderFactory class= net sf ehcache bootstrap BootstrapCacheLoaderFactory /> </cache></ehcache> 自動發現 自動發現配置和手動查找的方式有一點不同 其他的地方都基本是一樣的 同樣在ehcache xml中增加配置 配置如下 <! 搜索某個網段上的緩存timeToLive 是限制在同一個伺服器 是限制在同一個子網 是限制在同一個網站 是限制在同一個region 是限制在同一個大洲 是不限制 >< class= net sf ehcache distribution properties= peerDiscovery=automatic multicastGroupAddress= multicastGroupPort= timeToLive= /> lishixin/Article/program/Java/hx/201311/25706
C. 什麼是遠程分布式緩存 什麼是遠程緩存
緩存這種能夠提升指令和數據讀取速度的特性,隨著本地計算機系統向分布式系統的擴展,在分布式計算領域中得到了廣泛的應用,稱為分布式緩存。
D. 大型互聯網架構概述,看完文章又漲知識了
1. 大型網站系統的特點
2. 大型網站架構演化歷程
2.1. 初始階段架構
問題:網站運營初期,訪問用戶少,一台伺服器綽綽有餘。
特徵:應用程序、資料庫、文件等所有的資源都在一台伺服器上。
描述:通常伺服器操作系統使用 linux,應用程序使用 PHP 開發,然後部署在 Apache 上,資料庫使用 Mysql,通俗稱為 LAMP。匯集各種免費開源軟體以及一台廉價伺服器就可以開始系統的發展之路了。
2.2. 應用服務和數據服務分離
問題:越來越多的用戶訪問導致性能越來越差,越來越多的數據導致存儲空間不足,一台伺服器已不足以支撐。
特徵:應用伺服器、資料庫伺服器、文件伺服器分別獨立部署。
描述:三台伺服器對性能要求各不相同:應用伺服器要處理大量業務邏輯,因此需要更快更強大的 CPU;資料庫伺服器需要快速磁碟檢索和數據緩存,因此需要更快的硬碟和更大的內存;文件伺服器需要存儲大量文件,因此需要更大容量的硬碟。
2.3. 使用緩存改善性能
問題:隨著用戶逐漸增多,資料庫壓力太大導致訪問延遲。
特徵:由於網站訪問和財富分配一樣遵循二八定律:80% 的業務訪問集中在 20% 的數據上。將資料庫中訪問較集中的少部分數據緩存在內存中,可以減少資料庫的訪問次數,降低資料庫的訪問壓力。
描述:緩存分為兩種:應用伺服器上的本地緩存和分布式緩存伺服器上的遠程緩存,本地緩存訪問速度更快,但緩存數據量有限,同時存在與應用程序爭用內存的情況。分布式緩存可以採用集群方式,理論上可以做到不受內存容量限制的緩存服務。
2.4. 使用應用伺服器集群
問題:使用緩存後,資料庫訪問壓力得到有效緩解。但是單一應用伺服器能夠處理的請求連接有限,在訪問高峰期,成為瓶頸。
特徵:多台伺服器通過負載均衡同時向外部提供服務,解決單一伺服器處理能力和存儲空間不足的問題。
描述:使用集群是系統解決高並發、海量數據問題的常用手段。通過向集群中追加資源,提升系統的並發處理能力,使得伺服器的負載壓力不再成為整個系統的瓶頸。
2.5. 資料庫讀寫分離
問題:網站使用緩存後,使絕大部分數據讀操作訪問都可以不通過資料庫就能完成,但是仍有一部分讀操作和全部的寫操作需要訪問資料庫,在網站的用戶達到一定規模後,資料庫因為負載壓力過高而成為網站的瓶頸。
特徵:目前大部分的主流資料庫都提供主從熱備功能,通過配置兩台資料庫主從關系,可以將一台資料庫伺服器的數據更新同步到一台伺服器上。網站利用資料庫的主從熱備功能,實現資料庫讀寫分離,從而改善資料庫負載壓力。
描述:應用伺服器在寫操作的時候,訪問主資料庫,主資料庫通過主從復制機制將數據更新同步到從資料庫。這樣當應用伺服器在讀操作的時候,訪問從資料庫獲得數據。為了便於應用程序訪問讀寫分離後的資料庫,通常在應用伺服器端使用專門的數據訪問模塊,使資料庫讀寫分離的對應用透明。
2.6. 反向代理和 CDN 加速
問題:中國網路環境復雜,不同地區的用戶訪問網站時,速度差別也極大。
特徵:採用 CDN 和反向代理加快系統的靜態資源訪問速度。
描述:CDN 和反向代理的基本原理都是緩存,區別在於 CDN 部署在網路提供商的機房,使用戶在請求網站服務時,可以從距離自己最近的網路提供商機房獲取數據;而反向代理則部署在網站的中心機房,當用戶請求到達中心機房後,首先訪問的伺服器時反向代理伺服器,如果反向代理伺服器中緩存著用戶請求的資源,就將其直接返回給用戶。
2.7. 分布式文件系統和分布式資料庫
問題:隨著大型網站業務持續增長,資料庫經過讀寫分離,從一台伺服器拆分為兩台伺服器,依然不能滿足需求。
特徵:資料庫採用分布式資料庫,文件系統採用分布式文件系統。
描述:分布式資料庫是資料庫拆分的最後方法,只有在單表數據規模非常龐大的時候才使用。不到不得已時,更常用的資料庫拆分手段是業務分庫,將不同的業務資料庫部署在不同的物理伺服器上。
2.8. 使用 NoSQL 和搜索引擎
問題:隨著網站業務越來越復雜,對數據存儲和檢索的需求也越來越復雜。
特徵:系統引入 NoSQL 資料庫及搜索引擎。
描述:NoSQL 資料庫及搜索引擎對可伸縮的分布式特性具有更好的支持。應用伺服器通過統一數據訪問模塊訪問各種數據,減輕應用程序管理諸多數據源的麻煩。
2.9. 業務拆分
問題:大型網站的業務場景日益復雜,分為多個產品線。
特徵:採用分而治之的手段將整個網站業務分成不同的產品線。系統上按照業務進行拆分改造,應用伺服器按照業務區分進行分別部署。
描述:應用之間可以通過超鏈接建立關系,也可以通過消息隊列進行數據分發,當然更多的還是通過訪問同一個數據存儲系統來構成一個關聯的完整系統。
縱向拆分:將一個大應用拆分為多個小應用,如果新業務較為獨立,那麼就直接將其設計部署為一個獨立的 Web 應用系統。縱向拆分相對較為簡單,通過梳理業務,將較少相關的業務剝離即可。
橫向拆分:將復用的業務拆分出來,獨立部署為分布式服務,新增業務只需要調用這些分布式服務橫向拆分需要識別可復用的業務,設計服務介面,規范服務依賴關系。
2.10. 分布式服務
問題:隨著業務越拆越小,存儲系統越來越龐大,應用系統整體復雜程度呈指數級上升,部署維護越來越困難。由於所有應用要和所有資料庫系統連接,最終導致資料庫連接資源不足,拒絕服務。
特徵:公共業務提取出來,獨立部署。由這些可復用的業務連接資料庫,通過分布式服務提供共用業務服務。
3. 大型網站架構模式
3.1. 分層
大型網站架構中常採用分層結構,將軟體系統分為應用層、服務層、數據層:
分層架構的約束:禁止跨層次的調用(應用層直接調用數據層)及逆向調用(數據層調用服務層,或者服務層調用應用層)。
分層結構內部還可以繼續分層,如應用可以再細分為視圖層和業務邏輯層;服務層也可以細分為數據介面層和邏輯處理層。
3.2. 分割
將不同的功能和服務分割開來,包裝成高內聚低耦合的模塊單元。這有助於軟體的開發和維護,便於不同模塊的分布式部署,提高網站的並發處理能力和功能擴展能力。
3.3. 分布式
大於大型網站,分層和分割的一個主要目的是為了切分後的模塊便於分布式部署,即將不同模塊部署在不同的伺服器上,通過遠程調用協同工作。
分布式意味可以用更多的機器工作,那麼 CPU、內存、存儲資源也就更豐富,能夠處理的並發訪問和數據量就越大,進而能夠為更多的用戶提供服務。
分布式也引入了一些問題:
常用的分布式方案:
3.4. 集群
集群即多台伺服器部署相同應用構成一個集群,通過負載均衡設備共同對外提供服務。
集群需要具備伸縮性和故障轉移機制:伸縮性是指可以根據用戶訪問量向集群添加或減少機器;故障轉移是指,當某台機器出現故障時,負載均衡設備或失效轉移機制將請求轉發到集群中的其他機器上,從而不影響用戶使用。
3.5. 緩存
緩存就是將數據存放在距離最近的位置以加快處理速度。緩存是改善軟體性能的第一手段。
網站應用中,緩存除了可以加快數據訪問速度以外,還可以減輕後端應用和數據存儲的負載壓力。
常見緩存手段:
使用緩存有兩個前提:
3.6. 非同步
軟體發展的一個重要目標和驅動力是降低軟體耦合性。事物之間直接關系越少,彼此影響就越小,也就更容易獨立發展。
大型網站架構中,系統解耦的手段除了分層、分割、分布式等,還有一個重要手段——非同步。
業務間的消息傳遞不是同步調用,而是將一個業務操作拆分成多階段,每個階段間通過共享數據的方式非同步執行進行協作。
非同步架構是典型的生產者消費模式,二者不存在直接調用。非同步消息隊列還有如下特性:
3.7. 冗餘
大型網站,出現伺服器宕機是必然事件。要保證部分伺服器宕機的情況下網站依然可以繼續服務,不丟失數據,就需要一定程度的伺服器冗餘運行,數據冗餘備份。這樣當某台伺服器宕機是,可以將其上的服務和數據訪問轉移到其他機器上。
訪問和負載很小的服務也必須部署 至少兩台伺服器構成一個集群,目的就是通過冗餘實現服務高可用。數據除了定期備份,存檔保存,實現 冷備份 外;為了保證在線業務高可用,還需要對資料庫進行主從分離,實時同步實現 熱備份。
為了抵禦地震、海嘯等不可抗因素導致的網站完全癱瘓,某些大型網站會對整個數據中心進行備份,全球范圍內部署 災備數據中心。網站程序和數據實時同步到多個災備數據中心。
3.8. 自動化
大型網站架構的自動化架構設計主要集中在發布運維方面:
3.9. 安全
4. 大型網站核心架構要素
架構 的一種通俗說法是:最高層次的規劃,難以改變的決定。
4.1. 性能
性能問題無處不在,所以網站性能優化手段也十分繁多:
4.2. 可用性
可用性指部分伺服器出現故障時,還能否對用戶提供服務
4.3. 伸縮性
衡量伸縮的標准就是是否可以用多台伺服器構建集群,是否容易向集群中增刪伺服器節點。增刪伺服器節點後是否可以提供和之前無差別的服務。集群中可容納的總伺服器數是否有限制。
4.4. 擴展性
衡量擴展性的標准就是增加新的業務產品時,是否可以實現對現有產品透明無影響,不需要任何改動或很少改動,既有功能就可以上線新產品。主要手段有:事件驅動架構和分布式服務。
4.5. 安全性
安全性保護網站不受惡意攻擊,保護網站重要數據不被竊取。
歡迎工作一到五年的Java工程師朋友們加入Java程序員開發: 721575865
群內提供免費的Java架構學習資料(裡面有高可用、高並發、高性能及分布式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用"沒有時間「來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!
E. 常用的緩存技術
第一章 常用的緩存技術
1、常見的兩種緩存
本地緩存:不需要序列化,速度快,緩存的數量與大小受限於本機內存
分布式緩存:需要序列化,速度相較於本地緩存較慢,但是理論上緩存的數量與大小無限(因為緩存機器可以不斷擴展)
2、本地緩存
Google guava cache:當下最好用的本地緩存
Ehcache:spring默認集成的一個緩存,以spring cache的底層緩存實現類形式去操作緩存的話,非常方便,但是欠缺靈活,如果想要靈活使用,還是要單獨使用Ehcache
Oscache:最經典簡單的頁面緩存
3、分布式緩存
memcached:分布式緩存的標配
Redis:新一代的分布式緩存,有替代memcached的趨勢
3.1、memcached
經典的一致性hash演算法
基於slab的內存模型有效防止內存碎片的產生(但同時也需要估計好啟動參數,否則會浪費很多的內存)
集群中機器之間互不通信(相較於Jboss cache等集群中機器之間的相互通信的緩存,速度更快<--因為少了同步更新緩存的開銷,且更適合於大型分布式系統中使用)
使用方便(這一點是相較於Redis在構建客戶端的時候而言的,盡管redis的使用也不困難)
很專一(專做緩存,這一點也是相較於Redis而言的)
3.2、Redis
可以存儲復雜的數據結構(5種)
strings-->即簡單的key-value,就是memcached可以存儲的唯一的一種形式,接下來的四種是memcached不能直接存儲的四種格式(當然理論上可以先將下面的一些數據結構中的東西封裝成對象,然後存入memcached,但是不推薦將大對象存入memcached,因為memcached的單一value的最大存儲為1M,可能即使採用了壓縮演算法也不夠,即使夠,可能存取的效率也不高,而redis的value最大為1G)
hashs-->看做hashTable
lists-->看做LinkedList
sets-->看做hashSet,事實上底層是一個hashTable
sorted sets-->底層是一個skipList
有兩種方式可以對緩存數據進行持久化
RDB
AOF
事件調度
發布訂閱等
4、集成緩存
專指spring cache,spring cache自己繼承了ehcache作為了緩存的實現類,我們也可以使用guava cache、memcached、redis自己來實現spring cache的底層。當然,spring cache可以根據實現類來將緩存存在本地還是存在遠程機器上。
5、頁面緩存
在使用jsp的時候,我們會將一些復雜的頁面使用Oscache進行頁面緩存,使用非常簡單,就是幾個標簽的事兒;但是,現在一般的企業,前台都會使用velocity、freemaker這兩種模板引擎,本身速度就已經很快了,頁面緩存使用的也就很少了。
總結:
在實際生產中,我們通常會使用guava cache做本地緩存+redis做分布式緩存+spring cache就集成緩存(底層使用redis來實現)的形式
guava cache使用在更快的獲取緩存數據,同時緩存的數據量並不大的情況
spring cache集成緩存是為了簡單便捷的去使用緩存(以註解的方式即可),使用redis做其實現類是為了可以存更多的數據在機器上
redis緩存單獨使用是為了彌補spring cache集成緩存的不靈活
就我個人而言,如果需要使用分布式緩存,那麼首先redis是必選的,因為在實際開發中,我們會緩存各種各樣的數據類型,在使用了redis的同時,memcached就完全可以舍棄了,但是現在還有很多公司在同時使用memcached和redis兩種緩存。
F. 如何用java 建立一個分布式系統
分布式架構的演進
系統架構演化歷程-初始階段架構
初始階段 的小型系統 應用程序、資料庫、文件等所有的資源都在一台伺服器上通俗稱為LAMP
特徵:
應用程序、資料庫、文件等所有的資源都在一台伺服器上。
描述:
通常伺服器操作系統使用Linux,應用程序使用PHP開發,然後部署在Apache上,資料庫使用MySQL,匯集各種免費開源軟體以及一台廉價伺服器就可以開始系統的發展之路了。
系統架構演化歷程-應用服務和數據服務分離
好景不長,發現隨著系統訪問量的再度增加,webserver機器的壓力在高峰期會上升到比較高,這個時候開始考慮增加一台webserver
特徵:
應用程序、資料庫、文件分別部署在獨立的資源上。
描述:
數據量增加,單台伺服器性能及存儲空間不足,需要將應用和數據分離,並發處理能力和數據存儲空間得到了很大改善。
系統架構演化歷程-使用緩存改善性能
特徵:
資料庫中訪問較集中的一小部分數據存儲在緩存伺服器中,減少資料庫的訪問次數,降低資料庫的訪問壓力。
描述:
系統訪問特點遵循二八定律,即80%的業務訪問集中在20%的數據上。
緩存分為本地緩存和遠程分布式緩存,本地緩存訪問速度更快但緩存數據量有限,同時存在與應用程序爭用內存的情況。
系統架構演化歷程-使用應用伺服器集群
在做完分庫分表這些工作後,資料庫上的壓力已經降到比較低了,又開始過著每天看著訪問量暴增的幸福生活了,突然有一天,發現系統的訪問又開始有變慢的趨勢了,這個時候首先查看資料庫,壓力一切正常,之後查看webserver,發現apache阻塞了很多的請求,而應用伺服器對每個請求也是比較快的,看來 是請求數太高導致需要排隊等待,響應速度變慢
特徵:
多台伺服器通過負載均衡同時向外部提供服務,解決單台伺服器處理能力和存儲空間上限的問題。
描述:
使用集群是系統解決高並發、海量數據問題的常用手段。通過向集群中追加資源,提升系統的並發處理能力,使得伺服器的負載壓力不再成為整個系統的瓶頸。
系統架構演化歷程-資料庫讀寫分離
享受了一段時間的系統訪問量高速增長的幸福後,發現系統又開始變慢了,這次又是什麼狀況呢,經過查找,發現資料庫寫入、更新的這些操作的部分資料庫連接的資源競爭非常激烈,導致了系統變慢
特徵:
多台伺服器通過負載均衡同時向外部提供服務,解決單台伺服器處理能力和存儲空間上限的問題。
描述:
使用集群是系統解決高並發、海量數據問題的常用手段。通過向集群中追加資源,使得伺服器的負載壓力不在成為整個系統的瓶頸。
系統架構演化歷程-反向代理和CDN加速
特徵:
採用CDN和反向代理加快系統的 訪問速度。
描述:
為了應付復雜的網路環境和不同地區用戶的訪問,通過CDN和反向代理加快用戶訪問的速度,同時減輕後端伺服器的負載壓力。CDN與反向代理的基本原理都是緩存。
系統架構演化歷程-分布式文件系統和分布式資料庫
隨著系統的不斷運行,數據量開始大幅度增長,這個時候發現分庫後查詢仍然會有些慢,於是按照分庫的思想開始做分表的工作
特徵:
資料庫採用分布式資料庫,文件系統採用分布式文件系統。
描述:
任何強大的單一伺服器都滿足不了大型系統持續增長的業務需求,資料庫讀寫分離隨著業務的發展最終也將無法滿足需求,需要使用分布式資料庫及分布式文件系統來支撐。
分布式資料庫是系統資料庫拆分的最後方法,只有在單表數據規模非常龐大的時候才使用,更常用的資料庫拆分手段是業務分庫,將不同的業務資料庫部署在不同的物理伺服器上。
系統架構演化歷程-使用NoSQL和搜索引擎
特徵:
系統引入NoSQL資料庫及搜索引擎。
描述:
隨著業務越來越復雜,對數據存儲和檢索的需求也越來越復雜,系統需要採用一些非關系型資料庫如NoSQL和分資料庫查詢技術如搜索引擎。應用伺服器通過統一數據訪問模塊訪問各種數據,減輕應用程序管理諸多數據源的麻煩。
系統架構演化歷程-業務拆分
特徵:
系統上按照業務進行拆分改造,應用伺服器按照業務區分進行分別部署。
描述:
為了應對日益復雜的業務場景,通常使用分而治之的手段將整個系統業務分成不同的產品線,應用之間通過超鏈接建立關系,也可以通過消息隊列進行數據分發,當然更多的還是通過訪問同一個數據存儲系統來構成一個關聯的完整系統。
縱向拆分:
將一個大應用拆分為多個小應用,如果新業務較為獨立,那麼就直接將其設計部署為一個獨立的Web應用系統
縱向拆分相對較為簡單,通過梳理業務,將較少相關的業務剝離即可。
橫向拆分:將復用的業務拆分出來,獨立部署為分布式服務,新增業務只需要調用這些分布式服務
橫向拆分需要識別可復用的業務,設計服務介面,規范服務依賴關系。
系統架構演化歷程-分布式服務
特徵:
公共的應用模塊被提取出來,部署在分布式伺服器上供應用伺服器調用。
描述:
隨著業務越拆越小,應用系統整體復雜程度呈指數級上升,由於所有應用要和所有資料庫系統連接,最終導致資料庫連接資源不足,拒絕服務。
Q:分布式服務應用會面臨哪些問題?
A:
(1) 當服務越來越多時,服務URL配置管理變得非常困難,F5硬體負載均衡器的單點壓力也越來越大。
(2) 當進一步發展,服務間依賴關系變得錯蹤復雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關系。
(3) 接著,服務的調用量越來越大,服務的容量問題就暴露出來,這個服務需要多少機器支撐?什麼時候該加機器?
(4) 服務多了,溝通成本也開始上升,調某個服務失敗該找誰?服務的參數都有什麼約定?
(5) 一個服務有多個業務消費者,如何確保服務質量?
(6) 隨著服務的不停升級,總有些意想不到的事發生,比如cache寫錯了導致內存溢出,故障不可避免,每次核心服務一掛,影響一大片,人心慌慌,如何控制故障的影響面?服務是否可以功能降級?或者資源劣化?
Java分布式應用技術基礎
分布式服務下的關鍵技術:消息隊列架構
消息對列通過消息對象分解系統耦合性,不同子系統處理同一個消息
分布式服務下的關鍵技術:消息隊列原理
分布式服務下的關鍵技術:服務框架架構
服務框架通過介面分解系統耦合性,不同子系統通過相同的介面描述進行服務啟用
服務框架是一個點對點模型
服務框架面向同構系統
適合:移動應用、互聯網應用、外部系統
分布式服務下的關鍵技術:服務框架原理
分布式服務下的關鍵技術:服務匯流排架構
服務匯流排同服務框架一樣,均是通過介面分解系統耦合性,不同子系統通過相同的介面描述進行服務啟用
服務匯流排是一個匯流排式的模型
服務匯流排面向同構、異構系統
適合:內部系統
分布式服務下的關鍵技術:服務匯流排原理
分布式架構下系統間交互的5種通信模式
request/response模式(同步模式):客戶端發起請求一直阻塞到服務端返回請求為止。
Callback(非同步模式):客戶端發送一個RPC請求給伺服器,服務端處理後再發送一個消息給消息發送端提供的callback端點,此類情況非常合適以下場景:A組件發送RPC請求給B,B處理完成後,需要通知A組件做後續處理。
Future模式:客戶端發送完請求後,繼續做自己的事情,返回一個包含消息結果的Future對象。客戶端需要使用返回結果時,使用Future對象的.get(),如果此時沒有結果返回的話,會一直阻塞到有結果返回為止。
Oneway模式:客戶端調用完繼續執行,不管接收端是否成功。
Reliable模式:為保證通信可靠,將藉助於消息中心來實現消息的可靠送達,請求將做持久化存儲,在接收方在線時做送達,並由消息中心保證異常重試。
五種通信模式的實現方式-同步點對點服務模式
五種通信模式的實現方式-非同步點對點消息模式1
五種通信模式的實現方式-非同步點對點消息模式2
五種通信模式的實現方式-非同步廣播消息模式
分布式架構下的服務治理
服務治理是服務框架/服務匯流排的核心功能。所謂服務治理,是指服務的提供方和消費方達成一致的約定,保證服務的高質量。服務治理功能可以解決將某些特定流量引入某一批機器,以及限制某些非法消費者的惡意訪問,並在提供者處理量達到一定程度是,拒絕接受新的訪問。
基於服務框架Dubbo的服務治理-服務管理
可以知道你的系統,對外提供了多少服務,可以對服務進行升級、降級、停用、權重調整等操作
可以知道你提供的服務,誰在使用,因業務需求,可以對該消費者實施屏蔽、停用等操作
基於服務框架Dubbo的服務治理-服務監控
可以統計服務的每秒請求數、平均響應時間、調用量、峰值時間等,作為服務集群規劃、性能調優的參考指標。
基於服務框架Dubbo的服務治理-服務路由
基於服務框架Dubbo的服務治理-服務保護
基於服務匯流排OSB的服務治理-功能介紹
基於服務匯流排OSB的服務治理
Q:Dubbo到底是神馬?
A:
淘寶開源的高性能和透明化的RPC遠程調用服務框架
SOA服務治理方案
Q:Dubbo原理是?
A:
-結束-
G. 什麼叫緩存
所謂的緩存,就是將程序或系統經常要調用的對象存在內存中,一遍其使用時可以快速調用,不必再去創建新的重復的實例。這樣做可以減少系統開銷,提高系統效率。
1、通過文件緩存;顧名思義文件緩存是指把數據存儲在磁碟上,不管你是以XML格式,序列化文件DAT格式還是其它文件格式;
2、內存緩存;也就是創建一個靜態內存區域,將數據存儲進去,例如我們B/S架構的將數據存儲在Application中或者存儲在一個靜態Map中。
3、本地內存緩存;就是把數據緩存在本機的內存中。
4、分布式緩存機制;可能存在跨進程,跨域訪問緩存數據
對於分布式的緩存,此時因為緩存的數據是放在緩存伺服器中的,或者說,此時應用程序需要跨進程的去訪問分布式緩存伺服器。
(7)什麼是遠程分布式緩存擴展閱讀
當我們在應用中使用跨進程的緩存機制,例如分布式緩存memcached或者微軟的AppFabric,此時數據被緩存在應用程序之外的進程中。
每次,當我們要把一些數據緩存起來的時候,緩存的API就會把數據首先序列化為位元組的形式,然後把這些位元組發送給緩存伺服器去保存。
同理,當我們在應用中要再次使用緩存的數據的時候,緩存伺服器就會將緩存的位元組發送給應用程序,而緩存的客戶端類庫接受到這些位元組之後就要進行反序列化的操作了,將之轉換為我們需要的數據對象。
H. 分布式緩存是什麼
分布式緩存使用CARP(Caching Array Routing Protocol)技術,可以產生一種高效率無接縫式的緩存,使用上讓多台緩存伺服器形同一台,並且不會造成數據重復存放的情況。
同時還有層次式緩存、動態緩存和計劃緩存三種。