[Network] 05. Cache & Redis

 · 3 mins read

前端 Cache

Client 瀏覽器緩存,不再去向 Server 溝通。(存放在:瀏覽器 > F12 > App > Cache)

  • 瀏覽器收到這個 Response 之後就會把這個資源給快取起來,當下一次使用者再度造訪這個頁面或是要求這個圖片的資源的時候,瀏覽器會檢視「現在的時間」是否有超過這個 Expires。如果沒有超過的話,那瀏覽器「不會發送任何 Request」,而是直接從電腦裡面已經存好的 Cache 拿資料。
  • 舊的 Cache 期限過了就會被刪除。
  • HTTP Response Header 裡面加上一個 Expires 的字段,裡面就是這個 Cache 到期的時間,例如說:
      Expires: Wed, 21 Oct 2017 07:28:00 GMT
    
  • CSRF 攻擊1:因為沒有限制網域,所以在導向攻擊者頁面時,Cache 沒過期就可能會被竊取 Cache 的資料。




MemoryCache 1

系統資料來自遠端資料庫及 WebAPI 等,若頻繁地從資料源撈取資料,可能造成資料提供者的負擔,可使用 Cache 來增加資料讀取效率。

  • 電商網站的首頁可能會有很多商品,如果你今天每一個訪客到首頁你都去資料庫重新抓一次所有的資料,那對資料庫的負擔會非常非常大,為了增加處理速度跟效率,Server 會將一些 Request 的內容儲存在某個地方,通常這地方稱做為 Cache,之後如果有 Request 想要同樣的內容,就直接傳送給它。(這樣 Server 就不用每次都根據 Request 去 DB 或其它地方收集資訊再 Response)
  • 以資料時效性及記憶體空間來換取資料獲得效能,所以可能資料不同步(資料源與快取)。
  • 程式開發需考量何時要收回快取來向資料源重新撈取資料。



.NET 4.0 System.Runtime.Caching ObjectCache 1

public class DataSourceProvider
{
    // fields
    private ObjectCache _cache = MemoryCache.Default; 

    // proterties
    public CacheEntryRemovedCallback OnFileContentsCacheRemove;
    public string PolicyType { get; set; }
    public string FileContents
    {
        get
        {
            string cacheKey = "FileContents";
            string fileContents = _cache[cacheKey] as string;
            if (string.IsNullOrWhiteSpace(fileContents))
            {
                // load file
                string filePath = @"D:\Holidays.txt";
                fileContents = File.ReadAllText(filePath, Encoding.Default); 

                // set policy (when to remove cache)
                var policy = new CacheItemPolicy();
                policy.RemovedCallback = OnFileContentsCacheRemove;

                // dynamic change policy for testing 
                switch (PolicyType)
                {
                    case "1":
                        // 距離設定快取時間超過2秒後,回收快取
                        policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(2);
                        break;
                    case "2":
                        // 3秒期限內未使用快取時,回收快取
                        policy.SlidingExpiration = TimeSpan.FromSeconds(3);
                        break;
                    default:
                        // 資料異動時,回收快取
                        policy.ChangeMonitors.Add(new HostFileChangeMonitor(new List<string>() { filePath }));
                        break;
                }
                // set cache
                _cache.Set(cacheKey, fileContents, policy);
            }
            return fileContents;
        }
    }
}




CDN (Content delivery network,內容傳遞網路) 1

Web Sever 把產生的內容放入各個節點的機房中,各地用戶在讀取網站資料的時後會依據所在地去最近的機房拿資料,這樣一來就算Web Sever架在美國或歐洲,也不影響用戶讀取網站的速度。

  • 加速網頁瀏覽效能:因為已經將緩存資料放在最近的機房中,不需要重新像伺服器讀取。
  • 有效分流(頻寬):當所有用戶都不再向同一個伺服器讀取資料,大幅降低集中流量。
  • 網站穩定度:網站流量分散後,網站的穩定度大幅提高,即使短暫當機也不怕用戶無法使用。
  • 安全性增加:因網站透過CDN分散出去,駭客較難直接攻擊網站本體。




Database Redis

短網址、統計系統資料不須存放太久的。

  • Redis 是一個 in-memory 的 key-value 快取 Database,因此常常被用在需要快取(Cache)一些資料的場合,做為 Cache Server,可以減輕許多後端資料庫的壓力。
  • 是一個開源、支援網路、基於記憶體、鍵值對儲存資料庫,使用 ANSI C 編寫。
  • 可用在叢集架構有多台 Server,因為不同 Server 的資料不共用,那就存在 Server 共同對應的 Redis Server。
  • Local Server(ex.DB)拿些資料(如一些用戶的key/瀏覽器放在 Redis Server,之後要用就不用再去 Server 拿,直接去 Redis 要。
  • 減少記憶體的使用量,只保持某些「熱資料」會存在 Redis,其他比較冷門、不常被訪問的數據,就存在 Database,等到被訪問的時候再寫到 Redis 即可。



短網址實現方式:1

  1. 使用者新增短網址,系統亂數產生 abc123 對應到 http://techbridge.cc
  2. 把 key=abc123, value=http://techbridge.cc 寫進資料庫
  3. 同上,但是是儲存在 Redis
  4. 當有使用者點擊:abc123 這個網址時,先去 Redis 查有沒有這個 key
  5. 有的話,redirect 到對應的網址
  6. 沒有的話,只好去資料庫查,查完之後記得寫一份到 Redis
  7. 可以新增一個 Expire time 的參數,當這個時間一到之後,這個 key 就會自動被清除。



.NET Web.config Redis 連線設定

<add key="RedisConnectionString"
 value="192.168.50.115:6379,abortConnect=false,connectRetry=3,connectTimeout=10000,defaultDatabase=10,syncTimeout=3000,version=3.2.1,responseTimeout=3000"/>