2013-04-09 3 views
1

Azure 캐시에 8MB보다 큰 개체를 저장하는 방법에 대한 제안이있는 사람이 있습니까? 제 경우에는 byte []를 사용하여 blob에 파일을 저장합니다. 그러나 어떻게 든 바이트 []를 작은 덩어리로 분할하여 부분 파일로 저장 한 다음 캐시에서 파일을 검색 한 후에 병합을 수행 할 수 있다면.Azure 캐시에 8MB보다 큰 개체를 저장하는 기술

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; 
     } 
    } 

다음은 클라우드에서 솔루션을 테스트 한 결과입니다. R/W 시간은 ms입니다. Results from live testing

+0

클라우드에 대한 성능 테스트를 실행하고 이것이 얼마나 빨리 수행되는지 알려줄 것입니다. –

+1

라이브 테스트의 결과가 완료되고 대답으로 편집됩니다. –