2015-09-21 2 views
0

Каков наилучший способ увидеть различия между содержимым двух разных баз данных Redis? У нас есть развертывание разработки и производства, и наш производственный экземпляр, похоже, не имеет точных данных, как разработка, но нам нужен прочный простой способ проверить это - есть ли хороший способ сделать это, не пиши слишком много собственного кода ?Diff for Redis между двумя базами данных

+1

Вы можете сделать Keys *, затем сохранить результат в файл и выполнить diff на нем. –

+0

Каждая база данных находится на другом сервере redis? –

+1

Нет, @BasitAnwer никогда не рекомендует использовать команду 'keys' на производственных серверах. Особенно, когда он не ответил бы на данный вопрос. все, что можно было бы сделать, это сказать вам, имеют ли они одинаковые ключевые имена, а не то, что или что * данные * отличаются. –

ответ

0

Поскольку мы используем Redis Sentinel, я предположил, что я не мог найти какой-то код, чтобы украсть, так что написал мой собственный реальный быстрый

код сравнивает содержимое двух различных баз данных Redis, используя модуль НПМ ioredis Redis клиента , Код отлично подходит для небольших баз данных Redis, которые не сильно меняются, для больших объемов данных или для баз данных, которые видят много операций записи в минуту, это может оказаться неприемлемым.

код выглядит следующим образом:

var async = require('async'); 

var Redis = require('ioredis'); 


var REDIS_SENTINEL_MASTER_NAME_STAGING = 'smartconndevredis01'; 
var REDIS_SENTINEL_MASTER_NAME_PROD = 'smartconnect_curr_master'; 

var SENTINEL_ENDPOINTS_STAGING = [ 
    { 
     "host": "XXX.XX.XX.XX", 
     "port": "26379" 
    }, 
    { 
     "host": "XXX.XX.X.XX", 
     "port": "26379" 
    }, 
    { 
     "host": "XXX.XX.X.XX", 
     "port": "26379" 
    } 
]; 


var SENTINEL_ENDPOINTS_PROD = [ 
    { 
     "host": "XXX.XX.X.XX", 
     "port": "26379" 
    }, 
    { 
     "host": "XXX.XX.X.XX", 
     "port": "26379" 
    }, 
    { 
     "host": "XXX.X.XX.XX", 
     "port": "26379" 
    } 
]; 


var clientStaging = new Redis({ 
    sentinels: SENTINEL_ENDPOINTS_STAGING, 
    name: REDIS_SENTINEL_MASTER_NAME_STAGING, 
    db: 0 
}); 


var clientProd = new Redis({ 
    sentinels: SENTINEL_ENDPOINTS_PROD, 
    name: REDIS_SENTINEL_MASTER_NAME_PROD, 
    db: 0 
}); 


var dbStaging = {}; 
var dbProd = {}; 


async.parallel([ 

     function (callback) { 
      clientStaging.keys('*', function (err, keys) { 

       async.each(keys, function (key, cb) { 

        clientStaging.get(key, function (err, result) { 
         //console.log('staging> key: "'+key+'", result:', result); 
         dbStaging[key] = result; 
         cb(err); 
        }); 

       }, function done(err, res) { 
        callback(err, res); 
       }); 
      }); 

     }, 
     function (callback) { 
      clientProd.keys('*', function (err, keys) { 

       async.each(keys, function (key, cb) { 

        clientProd.get(key, function (err, result) { 
         //console.log('production> key: "'+key+'", result:', result); 
         dbProd[key] = result; 
         cb(err); 
        }); 

       }, function done(err, res) { 
        callback(err, res); 
       }); 
      }); 

     } 
    ], 
    function done(err, results) { 

     if (err) { 
      throw err; 
     } 
     else { 
      diffDbs(); 
     } 

    }); 


function diffDbs() { 

    Object.keys(dbStaging).forEach(function (key) { 

     if (!dbProd.hasOwnProperty(key)) { 
      console.log('staging redis has key, prod redis does not:',key); 
     } 
     else { 

      var stagingVal = dbStaging[key]; 
      var prodVal = dbProd[key]; 

      if(String(stagingVal).valueOf() != String(prodVal).valueOf()){ 
       console.log('staging redis and prod redis have DIFFERENT values for key:',key); 
      } 
     } 

    }); 

    Object.keys(dbProd).forEach(function (key) { 

     if (!dbStaging.hasOwnProperty(key)) { 
      console.log('prod redis has key, staging redis does not:',key); 
     } 
     else { 

      var stagingVal = String(dbStaging[key]).replace(/ /g, ''); //remove all whitespace 
      var prodVal = String(dbProd[key]).replace(/ /g, ''); //remove all whitespace 

      if(stagingVal.valueOf() != prodVal.valueOf()){ 
       console.log('staging redis and prod redis have DIFFERENT values for key:',key); 
      } 
     } 
    }); 

    process.exit(0); 

} 
+1

В качестве общего совета я бы рекомендовал использовать одно и то же имя подкаста, как в prod, так как у вас есть дозорные созвездия, предназначенные для каждой среды. Таким образом, дозорный код, использующий код, не должен быть награжден той средой, в которой он находится. И для вашего кода не используйте ключи. Используйте сканирование. Это разрушит производительность на занятом сервере с большим количеством ключей, поскольку алгоритмически сложный и блокирующий. Отлично подходит для постановки, а не для продукта. –

+0

спасибо, да, наши экземпляры Redis маленькие, менее 1 мб каждый, и у них не много опыта - я согласен, что имеет смысл найти способ получить снимок базы данных, чтобы сделать справедливую сравнение.Как вы говорите, может быть целесообразно сделать запланированный дамп обеих БД, а затем сравнить эти два разных файла dump.rdb. –

+0

, но я не знал, что вы имели в виду под именем «pod», вы имеете в виду «master_name»? вы, вероятно, ссылаетесь на то, что они разные: var REDIS_SENTINEL_MASTER_NAME_STAGING = 'smartconndevredis01'; var REDIS_SENTINEL_MASTER_NAME_PROD = 'smartconnect_curr_master'; –

2

Если данные производства имеет высокую скорость изменения, делать это будет очень тяжело. Поэтому для этого ответа давайте предположим, что у вас либо нет высокого оттока данных, либо вы можете сделать это в спокойное время, когда уровень сбоя данных низкий.

Для этого, чтобы работать с перспективой сценария оболочки, вам необходимо выполнить первую задачу параллельно.

  1. Используйте функцию сохранения RDB в redis-cli, чтобы вытащить локальную копию данных для каждого сервера.
  2. Сравните хэш файлов, таких как md5sum. Если они одинаковы, данные одинаковы.

Если скорость оттока достаточно низкая, что вы можете получить сопоставимый дамп, это будет определять, отличаются ли они, но не какие данные отличаются, если таковые имеются. Однако вы можете использовать это как условие для избежания более глубокого погружения, которое должно по существу обыгрывать базу данных.

Альтернативно, если они отличаются друг от друга, вы можете написать что-то, что использует файлы RDB и один из парсеров RDB-файлов, чтобы сравнить их и вывести найденные различия.

Действительно, этот метод будет работать намного лучше, чем обыск сервера, поскольку данные могут изменяться во время процесса, тогда как метод анализа файла дампа сравнивается для фиксированного момента времени.

Смежные вопросы