<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【Azure Developer】一個復制Redis Key到另一個Redis服務的工具(redis_copy_net8)

      介紹一個簡單的工具,用于將Redis數據從一個redis端點復制到另一個redis端點,基于原始存儲庫轉換為.NET 8:https://github.com/LuBu0505/redis-copy-net8

       

      Redis Copy .NET8

      Redis Copy 控制臺工具允許將 Redis 數據從一個 Redis 服務端復制到另一個。

       Note: 不支持redis集群

       

      軟件要求

      運行 Redis Copy 工具需要以下軟件。它可能會在其他版本上運行.

      • .NET 8
      • VS Code / Visual Studio 2022

      下載源代碼

      clone https://github.com/LuBu0505/redis-copy-net8.git

       

      使用方式

      選項 1 -- 使用 AppSetting.json

      將“< ... >”替換為真實的redis端點

      {
        "SourceRedisConnectionString": "<source redis name>:6380,password=<your password>,ssl=True,abortConnect=False", //Source Redis ConnectionString
        "DestRedisConnectionString": "<Destination redis name>:6380,password=<your password>,ssl=True,abortConnect=False" //Destination Redis ConnectionString
      }

       

      選項 2 -- 使用命令參數

      redis-copy-net8.exe
      Parameter Description:
        --se           Required. SourceEndpoint *.redis.cache.windows.net
        --sa           Required. Source password
        --sp           (Default: 6380) Source port
        --sssl         (Default: true) Connect Source over ssl
      
        --de           Required. DestinationEndpoint *.redis.cache.windows.net
        --da           Required. Destination Password
        --dp           (Default: 6380) Destination port
        --dssl         (Default: true) Destination Source over ssl
        --help         Display this help screen.
        --version      Display version information.
      
      eg:
      
      redis-copy-net8.exe --se <xxxxxx.redis.cache.chinacloudapi.cn> --sa <******************> --de <xxxxxx.redis.cache.chinacloudapi.cn> --da <******************> 

       

      Redis Copy 工具的工作流程

      第 1 階段:準備Redis源和目標信息

      • 使用 StackExchange.Redis ConnectionMultiplexer 類,默認創建20個連接。
      • 檢查源redis的Used Memory、Keyspace信息
      • 根據Keys數量拆分成更多子任務
                  var infoGroup = sourcecon.BasicRetryInfo((conn) => conn.GetServer(conn.GetEndPoints()[0]).Info());
      
                  foreach (var info in infoGroup)
                  {
                      if (info.Key.Equals("Memory"))
                      {
                          Console.WriteLine($"==\t# {info.Key}");
                          var lists = info.ToList().Where(i => i.Key.Equals("used_memory_human") || i.Key.Equals("maxmemory_human")).ToList();
                          foreach (var list in lists)
                              Console.WriteLine($"==\t  {list.ToString()}");
                      }
      
                      if (info.Key.Equals("Keyspace"))
                      {
                          Console.WriteLine($"==\t# {info.Key}");
                          foreach (var list in info.ToList())
                          {
                              long dbindex, dbkeys = 0;
      
                              long.TryParse(Regex.Match(list.Key, @"\d+\.*\d*").Value, out dbindex);
                              long.TryParse(list.Value.Split(new char[] { ',' })[0].Split(new char[] { '=' })[1], out dbkeys);
      
                              dictdbIdxKeysNum[dbindex] = dbkeys;
      
                              totalKeysSource += dbkeys;
      
                              Console.WriteLine($"==\t  {list.ToString()}");
                          }
                      }
                  }

       

      第二階段:復制

      • 循環執行復制Redis Keys的子任務,SCAN列出所有Keys。
      • 創建更多子任務以使用 StackExchange.Redis bacth 操作進行 TTL,驗證Key是否過期,DUMP出Key的byte[]信息
      • 使用批量操作將Key恢復到目標Redis
      • 如果遇到異常,則將Key信息添加到失敗隊列中。
      • 檢查移動的keys的進度,同時檢查失敗的隊列,如果不為空,將重新運行移動任務
       var allkeys = sourcecon.BasicRetryInfo((conn) => conn.GetServer(conn.GetEndPoints()[0]).Keys(dbindex).Skip(skipKeys).Take(takeKeys)).ToArray();
      var sourcedb = sourcecon.GetConection().GetDatabase(dbindex);
       var destdb = destcon.GetConection().GetDatabase(dbindex);
      
       foreach (var keys in SplitKeys(allkeys))
       {
           var rbatch = sourcedb.CreateBatch();
           var ttltask = new List<Task<TimeSpan?>>();
           var dumptask = new List<Task<byte[]?>>();
           foreach (var key in keys)
           {
               ttltask.Add(rbatch.KeyTimeToLiveAsync(key));
      
               dumptask.Add(rbatch.KeyDumpAsync(key));
           }
           rbatch.Execute();
      
           var ttlResults = Task.WhenAll(ttltask).Result;
           var dumpkResults = Task.WhenAll(dumptask).Result;
      
           //Restore the key to destation DB.
           var destBatch = destdb.CreateBatch();
      
           var i = 0;
           foreach (var key in keys)
           {
               destBatch.KeyRestoreAsync(key, dumpkResults[i], ttlResults[i]);
               i++;
           }
           destBatch.Execute();
      
           //Random select one key to verify in Phase 3. 
           if (keys.Count() > 0)
           {
               int index = RandomNumberGenerator.GetInt32(keys.Count());
               verifiedKeys.Add((dbindex, keys.ElementAt<RedisKey>(index).ToString()));
           }
      
      
           lock (lockObject)
           {
               totalKeysCopied += keys.Count();
           }
       }

       

      第三階段:驗證

      • 隨機選取某個key, 一個一個的檢查他們的值在兩個Redis服務器之間是否相同
                  foreach (var key in verifiedKeys)
                  {
                      try
                      {
                          var sourdump = await sourcecon.BasicRetryInfo(async (sc) => sc.GetDatabase(key.Item1).KeyDumpAsync(key.Item2));
                          var destdump = await destcon.BasicRetryInfo(async (sc) => sc.GetDatabase(key.Item1).KeyDumpAsync(key.Item2));
      
                          if (!sourdump.Result.SequenceEqual(destdump.Result))
                          {
                              Console.Write($"\n");
                              Console.WriteLine($"== {key} Verify Failed");
                          }
                          else
                          {
                              Console.Write($"{key}, ");
                          }
                      }
                      catch (Exception ex)
                      {
                          Console.BackgroundColor = ConsoleColor.Red;
                          Console.WriteLine($"=={DateTime.Now.ToLocalTime()} Verify {key} failed ({ex.Message})");
                          Console.BackgroundColor = ConsoleColor.Black;
                      }
                  }

       

      測試結果

      Copied 369886 keys(812MB) from Redis1 to Redis2 in 233 seconds

       

       

       

      posted @ 2024-07-11 20:20  路邊兩盞燈  閱讀(323)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 国产国语一级毛片| 99久久国产精品无码| 欧美日韩国产一区二区三区欧 | 嘉荫县| 日韩在线观看精品亚洲| 东方av四虎在线观看| 熟女人妻视频| 4399理论片午午伦夜理片| 中文字幕亚洲精品第一页| 无码小电影在线观看网站免费| 人妻日韩人妻中文字幕| 乱老年女人伦免费视频| 欧美不卡无线在线一二三区观| 嫩江县| 性男女做视频观看网站| 88国产精品视频一区二区三区| 日韩精品国内国产一区二| 久久人人妻人人做人人爽| 亚洲国产精品老熟女乱码| 一道本AV免费不卡播放| 免费观看的av在线播放| 午夜精品福利亚洲国产| a级亚洲片精品久久久久久久| 亚洲中文字幕在线二页| 那曲县| 欧美牲交a欧美牲交aⅴ一| 国产青榴视频在线观看| 一卡2卡三卡4卡免费网站| 极品一区二区三区水蜜桃| 久久久久免费看黄a片app| 久久一日本道色综合久久| 亚洲国产在一区二区三区| 中国女人高潮hd| 午夜福利宅福利国产精品| 国产日韩综合av在线| 无套内谢少妇毛片aaaa片免费| 国产精品综合在线免费看| 国产精品久久久久免费观看| 免费人成在线观看网站| 熟女性饥渴一区二区三区| 国产亚洲精品成人av一区|