两个数据库之间的Red for Diff

时间:2015-09-21 04:07:44

标签: redis

查看两个不同Redis数据库内容之间差异的最佳方法是什么?我们有一个开发和生产部署,我们的生产实例似乎没有与开发相同的确切数据,但我们需要一个简单的方法来测试 - 有一个很好的方法来做到这一点,而无需编写太多我们自己的代码?

2 个答案:

答案 0 :(得分:3)

如果您的生产数据变化率很高,那么这样做很难。因此,对于这个答案,让我们假设您没有高数据流失,或者您可以在数据流失率较低的静止时间执行此操作。

为了使其从shell脚本角度工作,您需要并行完成第一个任务。

  1. 使用redis-cli中的RDB保存选项下拉每个服务器的本地数据副本。
  2. 比较文件的哈希值,例如md5sum。如果它们相同,则数据相同。
  3. 如果流失率足够低,您可以获得类似的转储,这将确定它们是否不同,但不确定数据是否有所不同。但是,您可以将此作为避免更深层次潜水的条件,这必须从根本上掠夺数据库。

    或者,如果它们不同,您可以编写一些使用RDB文件和一个RDB文件解析器来比较它们并输出它找到的差异。

    实际上,这种方法比洗劫服务器要好得多,因为数据可以在过程中发生变化,而转储文件分析方法则比较一个固定的时间点。

答案 1 :(得分:0)

因为我们正在使用Redis Sentinel,所以我认为我找不到一些代码来窃取,所以写了我自己的真实快速

代码使用ioredis Redis客户端NPM模块比较两个不同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);

}