2013-04-09 66 views
1

沒有人有你如何能存儲比8MB的緩存天青較大的物體的任何建議。在我的情況下,我使用byte []將文件存儲在blob中。但是,如果我能以某種方式分裂的byte []分成較小的塊,並將其存儲爲部分文件,然後從緩存中檢索文件後進行合併。技術用於存儲比8MB大的物體在Azure的緩存

Pseudokode:

存儲

bs <- split file into byte[] that are smaller than 8MB 
s <- string[bs.Length] 
foreach bs with index i 
    s[i] <- name of bs[i] 
    Add bs[i] to Azure cache using s[i] as key 

Add s to cache 

檢索:

s <- Get list of byte[] names 
bs <- byte[s.Length] 
foreach s with index i 
    bs[i] <- Get byte[] using s[i] 

outBs <- Join bs to one byte[] 
  • 是否有任何性能問題嗎?

  • 是否有超出執行Azure的緩存中的任何其他方式?

回答

4

經過幾個小時的工作,我發現可以將大文件分割成更小的文件並將其存儲到Azure緩存中。我想與你分享代碼。

類用於分離和接合字節[]

public class CacheHelper 
    { 
     private const int kMaxFileSize = 8000000; 
     private readonly int fFileSize; 
     private readonly string fFileName; 
     public CacheHelper(int sizeOfFile, string nameOfFile) 
     { 
      fFileSize = sizeOfFile; 
      fFileName = nameOfFile; 
     } 

     public CachingObjectHolder Split(byte[] file) 
     { 
      var remainingSize = file.Length; 
      var partialList = new List<byte[]>(); 
      var partial = new byte[file.Length > kMaxFileSize ? kMaxFileSize : file.Length]; 
      for (int i = 0; i < file.Length; i++) 
      { 
       if (i % kMaxFileSize == 0 && i > 0) 
       { 
        partialList.Add(partial); 
        partial = new byte[remainingSize > kMaxFileSize ? kMaxFileSize : remainingSize]; 
       } 

       partial[i % kMaxFileSize] = file[i]; 
       remainingSize--; 
      } 

      partialList.Add(partial); 

      return new CachingObjectHolder(fFileName, partialList); 
     } 

     public static byte[] Join(CachingObjectHolder cachingObjectHolder) 
     { 
      var totalByteSize = cachingObjectHolder.Partials.Sum(x => x.Length); 
      var output = new byte[totalByteSize]; 
      var globalCounter = 0; 
      for (int i = 0; i < cachingObjectHolder.Partials.Count; i++) 
      { 
       for (int j = 0; j < cachingObjectHolder.Partials[i].Length; j++) 
       { 
        output[globalCounter] = cachingObjectHolder.Partials[i][j]; 
        globalCounter++; 
       } 
      } 

      return output; 
     } 

     public static byte[] CreateFile(int size) 
     { 
      var tempFile = Path.GetTempFileName(); 
      using (var stream = new FileStream(tempFile, FileMode.OpenOrCreate)) 
      { 
       using (var memStream = new MemoryStream()) 
       { 
        stream.SetLength(size); 
        stream.CopyTo(memStream); 
        return memStream.ToArray(); 
       } 
      } 
     } 
    } 

這裏是與用於數據持有人天青緩存

public class Cache 
    { 
     private const string kFileListName = "FileList"; 

     public static DataCacheFactory DataCacheFactory 
     { 
      get 
      { 
       return new DataCacheFactory(); 
      } 
     } 

     private static DataCache fDataCache; 
     public static DataCache DataCache 
     { 
      get 
      { 
       if(fDataCache == null) 
       { 
        fDataCache = DataCacheFactory.GetDefaultCache(); 
       } 

       return fDataCache; 
      } 
     } 

     public static byte[] Get(string name) 
     { 
      var dic = GetFileList(); 
      if (dic == null) 
      { 
       return (byte[])DataCache.Get(name); 
      } 
      if (dic.ContainsKey(name)) 
      { 
       var list = dic[name]; 
       var input = new List<byte[]>(); 
       var cache = DataCache; 
       list = list.OrderBy(x => x.Item2).ToList(); 
       for (int i = 0; i < list.Count; i++) 
       { 
        input.Add(cache.Get(list[i].Item1) as byte[]); 
       } 

       var holder = new CachingObjectHolder(name, input); 
       return CacheHelper.Join(holder); 
      } 
      else 
      { 
       return (byte[])DataCache.Get(name); 
      } 
     } 

     public static void Put(string name, byte[] file) 
     { 
      if (file.Length > CacheHelper.kMaxFileSize) 
      { 
       var helper = new CacheHelper(file.Length, name); 
       var output = helper.Split(file); 
       var dic = GetFileList(); 
       if (dic == null) 
       { 
        dic = new Dictionary<string, List<Tuple<string, int>>>(); 
       } 

       var partials = new List<Tuple<string, int>>(); 
       for (int i = 0; i < output.CachingObjects.Count; i++) 
       { 
        DataCache.Add(output.CachingObjects[i].Name, output.Partials[output.CachingObjects[i].Index]); 
        partials.Add(new Tuple<string, int>(output.CachingObjects[i].Name, 
               output.CachingObjects[i].Index)); 
       } 

       dic.Add(name, partials.OrderBy(x => x.Item2).ToList()); 
       PutFileList(dic); 
      } 
      else 
      { 
       DataCache.Add(name, file); 
      } 
     } 

     public static void Remove(string name) 
     { 
      var dic = GetFileList(); 
      if (dic == null) 
      { 
       DataCache.Remove(name); 
       return; 
      } 

      if (dic.ContainsKey(name)) 
      { 
       var list = dic[name]; 
       for (int i = 0; i < list.Count; i++) 
       { 
        DataCache.Remove(list[i].Item1); 
       } 

       dic.Remove(name); 
       PutFileList(dic); 
      } 
      else 
      { 
       DataCache.Remove(name); 
      } 
     } 

     private static void PutFileList(Dictionary<string, List<Tuple<string, int>>> input) 
     { 
      DataCache.Put(kFileListName, input); 
     } 

     private static Dictionary<string, List<Tuple<string, int>>> GetFileList() 
     { 
      return DataCache.Get(kFileListName) as Dictionary<string, List<Tuple<string, int>>>; 
     } 
    } 

Aaaand兩類用於通信的代碼

public class CachingObjectHolder 
    { 
     public readonly List<byte[]> Partials; 
     public readonly List<CachingObject> CachingObjects; 
     public readonly string CacheName; 

     public CachingObjectHolder(string name, List<byte[]> partialList) 
     { 
      Partials = partialList; 
      CacheName = name; 
      CachingObjects = new List<CachingObject>(); 
      CreateCachingObjects(); 
     } 

     private void CreateCachingObjects() 
     { 
      for (int i = 0; i < Partials.Count; i++) 
      { 
       CachingObjects.Add(new CachingObject(string.Format("{0}_{1}", CacheName, i), i)); 
      } 
     } 
    } 

    public class CachingObject 
    { 
     public int Index { get; set; } 
     public string Name { get; set; } 

     public CachingObject(string name, int index) 
     { 
      Index = index; 
      Name = name; 
     } 
    } 

以下是在雲上測試解決方案的結果。讀/寫時間以毫秒爲單位。 Results from live testing

+0

我將運行在雲中的性能測試,並隨時向你通報的速度有多快,這是。 – 2013-04-11 08:27:59

+1

從現場測試結果已經完成,編輯到答案。 – 2013-04-12 06:48:15