<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 5. redis 實現 cache 系統原理 #### 1. 介紹 cache就是人們所說的緩存。我們這里所說的cache是web上的。對用戶來說,衡量一個網站是否具有良好的體驗,其中一個標準就是響應速度的快慢。可能網站剛上線,功能還較少,數據庫的記錄也不多的情況下,網站可能訪問速度比較快,也不需要優化。但是隨著網站發展起來,功能越來越多,數據庫越來越大的時候,這個時候可能網站的訪問速度就會下降。無論網站剛上線初期還是到一定程度的情況,我們都希望網站具有良好的響應速度。 而要怎樣提高頁面響應速度呢?其中一個方法當然就是本章所說的cache。先來說整個網站的請求響應的過程:用戶從瀏覽器發出一個請求,比如點擊一個按鈕或在瀏覽器輸入網址回車,然后經過層層的網絡最終到達網站的服務器,假設我們用nginx來作為靜態文件服務器,而用unicorn作為運行ruby代碼的容器,先經過nginx處理,nginx一般是處理html,css,js的,它會默認處理帶有htlm,css,js后綴的請求,比如/articles.html,如果發現有它處理不了的,比如/articles/1這樣的請求地址,因為nginx沒有匹配這樣的地址,就會反向代理到unicorn,unicorn是運行ruby代碼的,它會連接數據庫,它可能從數據庫取到一些數據,把數據處理完,再返回給nginx,最nginx返回給用戶。 這里所說的unicorn是運行ruby代碼的應用容器,當然也可以是php或java的容器,比如tomcat等。道理是一樣的。 ``` server { listen 80 default_server; server_name www.rails365.net; root /home/yinsigan/rails365/current/public; ... try_files $uri/index.html $uri @rails365; location @rails365 { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://rails365; } ... } ``` 上面是nginx的配置文件的部分內容,網站根目錄是`/home/yinsigan/rails365/current/public`,具體看`try_files $uri/index.html $uri @rails365;`這一句,當用戶在瀏覽器請求/about.html地址時,nginx會首先看網站根目錄有沒有about.html這個文件,有的話就直接讀出根目錄下的about.html,因為nginx默認會對html后綴的文件作處理的,讀完后直接返回響應給用戶,就完成了這一次請求,沒有的話,就會請求@rails365的內容,也就是反向代理到unicorn服務器。 整個請求過程無論哪一階段都是需要時間的。而最影響速度也最容易產生性能瓶頸的主要有三個地方: 1. nginx處理靜態文件的過程 2. nginx和unicorn交互的過程 3. unicorn和數據庫交互的過程 第一點,nginx處理靜態文件的過程主要指的是處理圖片、javascript、css文件的過程。假如這些文件數量很多,體積又很大,在這一過程是需要耗費很多時間的,但是這些可以通過nginx的gzip來壓縮大小、瀏覽器cache或CDN等技術來解決,這點不在cache的范圍內。 第二點,nginx作為反向代理服務器和應用服務器unicorn的交互也是需要時間的,nginx也作為靜態服務器只能處理一些簡單的靜態服務器,而unicorn可以處理復雜的邏輯,不過最后unicorn還是要轉化成html給nginx,nginx再給用戶,所以整個請求過程如果不到unicorn,由nginx直接返回那就更好了。這樣是能大大增快響應速度的,因為不僅nginx到unicorn那步少了,而unicorn到數據庫這一步也不用了,所以還是有效的,但是它有一些不好的弊端,具體的我們下面會說到。第二點的解決方案是通過nginx的proxy\_cache或者文件cache來解決。 第三點,應用服務器和數據庫的交互,這個數據庫我們一般指的是關系型數據庫,比如MySQL、PostgreSQL等。這個過程是很重要且很常見的,畢竟幾乎所有網站都需要數據庫來存儲數據吧,但數據庫很龐大時或者對數據庫處理不當時,這個交互過程是很耗費時間的,所以我們會在這個過程用redis作為cache來解決。 #### 2. cache的種類 cache有很多種,比如上文提到的文件cache,nginx的proxy\_cache,瀏覽器的cache,html片斷的cache,除此之外,還有代理服務器的cache,CDN的cache,數據庫級的查詢cache。這篇文章我們只會講述文件cache還有用redis來實現cache的情況。 #### 3. 文件cache 文件cache在上文有提到,就是在nginx和unicorn交互的過程中發揮作用的,就是讓請求直接給nginx處理,而不經過unicorn。打個比方,比如要瀏覽一個博客網站的首頁,首頁列出了最近的十篇博文,這些博文肯定是存儲在數據庫中,請求先通過nginx,nginx再通過unicorn,unicorn去數據庫取到這些博文,再組裝成html文件再給nginx,nginx再給用戶,整個過程完成。而文件cache要做的是當unicorn組裝成html給nginx的時候,也順便在網站根目錄下生成.html結尾的文件,這樣下次訪問就不用經過unicorn了,直接在網站根目錄取文件就可以了。這種方式,說白了,就是把動態的查詢靜態化,讓請求過程少了,當數據庫有查詢瓶頸的時候用這種方式是有好處的。但是這種方式有一個弊端,就是有登錄系統的情況,比如一個首頁,同樣是相同的網址,每個人訪問就有不同的頁面,因為是不同的用戶在訪問,比如導航菜單,可以就會出現你的名字。文件cache辦不到這種事,因為它是根據地址來處理的,比如訪問`http://www.example.com/articles.html`,它會找根目錄的articles.html文件,可是這個文件只有一個啊,但我們需要的是有多少個用戶就有不同的頁面,所以它不好判斷,就算判斷了,也失去了本來靜態化的意義。所以文件cache只適合那種展示頁面用的,很多時候并不適用,畢竟現在誰的網站沒個登錄系統呢。 #### 4. 用redis實現cache的原理 上文也有提到文件cache的情況,cache的原理就是用一種訪問更快的介質或更少的請求來提高查詢速度。用redis來實現cache也是一樣的道理。我們先不管redis最終會存儲什么內容,我們有個對比的介質,那就是關系型數據庫,把存到關系型數據庫的內容換到redis來存,那就是用redis來實現的cache。這樣就出現了兩種存儲介質的數據的對比,這個數據的存儲是有時間性的。當第一次瀏覽帶有數據庫查詢的頁面的時候,頁面的數據先從數據庫那里獲取,獲取完之后存一份到redis,比如存成string,`articles_count: 100`,意思是把文章的總數存到redis中。當存到redis時,我們可以設置過期時間,也可以讓它永遠不過期。第二次以及以后的訪問,就會直接到redis去查找key為articles\_count的是不是有值(數據過期就等于沒有值),有的話,直接取,沒有話,還是會取數據庫,然后再放到redis。當你的真實的數據庫記錄更新的時候,比如這個時候增加了一篇文章,除了把這一篇文章存進數據庫外,還要把redis中的對應的值改過來,這樣就能保證取到最新的值的。 #### 5. 頁面哪些地方需要cache 現在以本站作為實例,來考慮下頁面上哪些地方要使用cache。使用cache有個原則,就是這個頁面部分的內容可能是耗時的,也有可能是很少改變的。比如底部,這個部分是基本不變的。 ![](https://box.kancloud.cn/fba4c289d9c5c5842a1aab095c53bbc6_1199x278.png) 還有首頁的中間部分"最近的文章"、"最熱門的文章"、"所有的分類"部分,這部分的數據是取數據庫的,我讓它隔一段時間變一次或者有更改才變。 ![](https://box.kancloud.cn/b8fa469e77c1fcd264083562967597f2_1192x588.png) 還有文章的內容頁,這部分是用markdown寫的,最終要轉成有格式的html,如果先轉好放到redis就能提高性能了。 還有文章詳情頁的"相關推薦"和"標簽“部分也是需要放到cache中的。 ![](https://box.kancloud.cn/67c9127ff988c412401608f76573f5b0_419x603.png) #### 6. html片斷cache 我們從數據庫獲取的數據最終還是要和html標簽結合在一起,組裝之后再給瀏覽器客戶端,而這種就叫html片斷,可以存放以string的方式存放在redis中。 完結。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看